Skip to content

Technology Sample you can rely on to build your own Design System, based on React and a System UI theme (Theme UI | styled-components).

License

Notifications You must be signed in to change notification settings

sbahir/react-sui-l3ld9efr

Repository files navigation

backlight.dev Github Repo

System UI Tech Sample by ‹div›RIOTS

This is a Technology Sample you can rely on to build your own Design System, based on React and a System UI theme.

Disclaimer: Technology Samples aren't comprehensive Design Systems but showcases a given technology so you free to build you own solution upon it.

Architecture

This tech sample uses React and JSX to implement its components with TypeScript. The Tokens are following the System UI theme specification, and are consumed in two flavors: Theme UI and styled-components.

Tokens

The Tokens are separated in different components:

  • typography: fonts definitions
  • colors: colors and variants
  • space: relative and absolute spaces
  • sizes: screensize breakpoints
  • shadows: inset and outset shadows
  • radii: border radius
  • border: borders definitions
  • z-index: z-axe indices

The System UI tokens specification allows you to define scales (like font-sizes, radius, etc) in arrays. You can also refer to previously declared values as aliases.

Your tokens should be organized by following the key reference in the specification:

Theme Key CSS Properties
space margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, grid-gap, grid-column-gap, grid-row-gap
fontSizes font-size
colors color, background-color, border-color
fonts font-family
fontWeights font-weight
lineHeights line-height
letterSpacings letter-spacing
sizes width, height, min-width, max-width, min-height, max-height
borders border, border-top, border-right, border-bottom, border-left
borderWidths border-width
borderStyles border-style
radii border-radius
shadows box-shadow, text-shadow
zIndices z-index
transitions transition

All tokens are declared in dedicated *.ts files in each tokens' components. They're then all exposed by the all/index.ts component file in a theme constant.

Your theme tokens can be imported anywhere with

import { theme } from '~/all';

Components

This tech sample exposes components in two flavor. They all use the same theme tokens imported as above, so your React components and your theme are not hard-linked together, and you can rely on the theme abstraction you're the most comfortable with.

Both Theme UI and styled-components exposes a <ThemeProvider /> JSX wrapper that take as theme argument a system-ui theme tokens definition:

<ThemeProvider theme={theme}>
  <!-- Your component(s) here -->
</ThemeProvider>

To avoid the need of loading the <ThemeProvider /> decorator in each components, we have overridden the stories and doc layouts in the tui-utils component.

export const Layout = (props) => (
  <ThemeProvider theme={theme}>
    <MdxLayout {...props} />
  </ThemeProvider>
);

Theme-UI

In the tui-utils component, the global theme as well as all components variations are loaded and merged in a common theme definition in the variants.ts file. This definition is then used by the <ThemeProvider /> that decorates the different layouts.

Creating theme-ui components

To add new theme-ui based components, you have to create a component with two files: your component itself, and a variants.ts file that declares the theme-ui compatible components definitions.

Your component's variants.ts file have to be loaded in the tui-utils/variants.ts file to be used by the wrapped theme.

styled-components

On the contrary of Theme UI, styled-component doesn't declares variations at theme level, but let you customize your components' styles directly by using the theme definitions:

import styled from 'styled-components';

const StyledButton = styled.button(
  ({ theme, primary = true, secondary, disabled = false, loading = false }) => {
    return {
      'font-size': theme.fontSizes[2],
      padding: `${theme.space[2]} ${theme.space[3]}`,
    };
  }
);

export const Button = () => <StyledButton />;

Creating a styled-components component

To add new styled-components component, create a component that import the styled-components core utils:

import * as React from 'react';
import styled from 'styled-components';
import { ThemeContext } from 'styled-components';

export const MyComponent = () => {
  const theme = React.useContext(ThemeContext);

  return (
    // Your component here
  );
};

Stories

Stories are written in Storybook's Component Story Format.

You can defined multiple stories for your components to visualize their variations:

import { Button } from '../index';
import { layout } from '~/tui-utils';
export default layout;

export const primary = () => <Button variant="primary">Primary</Button>;
export const secondary = () => <Button variant="secondary">Secondary</Button>;
export const disabled = () => <Button disabled>Disabled</Button>;
export const secondary_disabled = () => (
  <Button variant="secondary" disabled>
    Disabled
  </Button>
);

Stories for the components are located in their stories/ folder.

Documentation

Documentation pages are decorated by a React layout using the @divriots/dockit-react helpers. See the layout component.

Pages

Each component embed its own documentation in its doc/ folder. You can use any web format for your documentation but we recommend you to write it with the mdx format, allowing you to embed your components live in the documentation.


Links

About

Technology Sample you can rely on to build your own Design System, based on React and a System UI theme (Theme UI | styled-components).

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published