/indigo-react

React components that implement Tlon's design language

Primary LanguageTypeScriptMIT LicenseMIT

indigo-react

npm (scoped) GitHub commit activity npm bundle size NPM

Related: indigo-tokens, indigo-static

Quick Start

npm install --save @tlon/indigo-react

Install peer dependencies

npm install --save @tlon/indigo-tokens styled-components styled-system react react-dom

If you need forms, install formik and yup

npm install --save formik yup

Setting up your project

import * as React from "react";
import { Text } from '@tlon/indigo-react';
import theme from '@tlon/indigo-tokens';
import styled, { ThemeProvider, createGlobalStyle } from 'styled-components';

class App extends React.Component {
  render() {
    return (
      <ThemeProvider theme={theme}>
        <Text fontSize='4'>Urbit</Text>
      </ThemeProvider>
    );
  }
}

In the above, we are wrapping our application in styled-component's ThemeProvider and passing in our theme from @tlon/indigo-tokens.

Do you need to reset styles for browser compatibility or set some global styles? This might be the place to do it. Check out Style and Root in /example/src/App.js.

Component Props

Each component takes specific props.

If we look at <Text>:

import styled from 'styled-components';

import {
  color,
  ColorProps,
  layout,
  LayoutProps,
  space,
  SpaceProps,
  typography,
  TypographyProps,
  compose,
} from 'styled-system';

type Props = ColorProps &
  LayoutProps &
  SpaceProps &
  TypographyProps & {
    gray?: boolean;
    bold?: boolean;
    mono?: boolean;
  };

const Text = styled.div<Props>`
  color: ${p => (p.gray ? p.theme.colors.gray5 : p.theme.colors.black)};

  font-weight: ${p => (p.bold ? p.theme.fontWeights.bold : p.theme.fontWeights.regular)};

  font-family: ${p => (p.mono ? p.theme.fonts.mono : p.theme.fonts.sans)};

  ${compose(color, layout, space, typography)};
`;

Text.defaultProps = {
  lineHeight: 'short',
  fontWeight: 400,
  fontSize: 2,
};

export default Text;
export {Props};

We see that <Text> accepts color, layout, space, and typography props.

The space utility from styled-system includes props for all CSS properties for padding and margin (and shorthand) :

  • margin, m margin
  • marginTop, mt margin-top
  • marginRight, mr margin-right
  • marginBottom, mb margin-bottom
  • marginLeft, ml margin-left
  • marginX, mx margin-left and margin-right
  • marginY, my margin-top and margin-bottom
  • padding, p padding
  • paddingTop, pt padding-top
  • paddingRight, pr padding-right
  • paddingBottom, pb padding-bottom
  • paddingLeft, pl padding-left
  • paddingX, px padding-left and padding-right
  • paddingY, py padding-top and padding-bottom

So, if we wanted to apply 16px of margin-top to a <Text>, we should do:

<Text mt="16px">Urbit is your last computer.</Text>

You can look at the API reference for the styled-system props here: https://styled-system.com/api

Using theme values

Each one of the above props can pull values from our theme for design consistency.

In <Text>, you might have noticed the defaultProps for fontSize was set to 2.:

...

Text.defaultProps = {
  lineHeight: 'short',
  fontWeight: 400,
  fontSize: 2,
};

export default Text;
export {Props};

This is not 2px, but rather a reference to a value within our theme.

When looking in our theme (indigo-tokens), we see that we have the following values for fontSize:

fontSizes: [10, 11, 12, 14, 16, 20, 24, 32, 48, 64, 72],

So, the 2 corresponds to 12(px) here.

Each prop type pulls from specific values within the theme.

For example:

  • space values like marginLeft, mr, and paddingTop pull from the space property of our theme
  • color values like color, bgColor, and backgroundColor pull from the colors property of our theme.

To see how props map to values in our theme, check out styled-system's mapping: https://styled-system.com/table

You may still use custom props here, for example: you might find yourself on a project looking to use a font size not specified in the theme. You could do the following:

<Text fontSize="7px">Urbit is your last computer.</Text>

Consult a designer.

Default Props

Some components have default props (seen above), these can be overridden by specifying a new prop value.

Component Docs

Component Documentation

Indigo is built with styled-components, styled-system and formik.

Styled Components

  • Allows writing 'CSS' in JS with template string via styled.div etc.
  • Transforms these strings into class names.

Styled System

  • Provides notion of a 'Theme' if given a theme.js or indigo-tokens.
  • Knows how to take a prop named p or padding and look for a relevant value in the theme. Knows how to differentiate a value like p='4' (targets the theme) vs p='4px' (uses 4px).

For a more in-depth tutorial, see Usage.md.

Styled System Property Reference

Development

Work in Progress

The react library comes with an example site (create-react-app) where your components are available as you develop. You can use this as a playground for new ideas, a documentation site, or a learning resource for other developers.

Benefits of CSS-in-JS

Peer Deps

Since this is a module that will be consumed by an application that may already use certain dependancies - react, formik, etc - certain deps need to be install as peer dependancies AND dev dependancies in the library, and as normal deps in the example site.

Multiple Versions of styled-components

If there are two versions of styled-components installed, you may have to add the react-indigo version as an alias in package.json, depending on your build system

lint:fix

There is a git hook which will not allow you to commit changes without passing a linting test. You can fix most linting 'errors' by running npm run lint:fix.

Semicolons in styled-components

You must ensure the CSS properties in template strings are terminated with ;, like valid CSS. Can't tell you how many times this has tripped me up.

License

MIT © urbit