Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/mimshins/react-design-tokens

An optimized and creative theming solution that generates CSS variables based on the tokens provided.
https://github.com/mimshins/react-design-tokens

design design-system react theme theme-provider tokens

Last synced: 4 days ago
JSON representation

An optimized and creative theming solution that generates CSS variables based on the tokens provided.

Awesome Lists containing this project

README

        

# React Design Tokens

An optimized and creative theming solution that generates CSS variables based on the tokens provided.


## Installation

> Please note that [react](https://www.npmjs.com/package/react) >= 17 and [react-dom](https://www.npmjs.com/package/react-dom) >= 17 are peer dependencies.

Run the following script to install and save in your `package.json` dependencies:

```bash
# with npm
npm install react-design-tokens

# or with yarn
yarn add react-design-tokens

# or with pnpm
pnpm add react-design-tokens
```


## API Documentation

The library exposes two APIs, `create` and `defaultCSSVariableGenerator`:

### 1. `create`

```ts
declare const create: (tokens, config?) => {
VariantSelector,
useTokens,
generateCSSVariablesAsInlineStyle,
}
```

This is the main API exposed by the library. It will take your tokens and an optional config options to create your theming client.

The `tokens` param expects to have `variants` and `common` tokens provided.

```ts
const tokens = {
variants: {/* The variant tokens map */},
common: {/* Tokens that are common and non-variant */}
}
```

> Please note that we shallow-merge tokens of a selected variant with common tokens to generate the result tokens. (Merging order: `{ ...variantTokens, ...commonTokens }`)
Common tokens can therefore potentially override variant tokens. Make sure they don't have any intersected keys.

The `config` options are:

| Property Name | Type | Default | Description |
|---------------|------|---------|-------------|
| cssVariableGenerator | `context => ({ variableName: string; variableValue: string; } \| null)` | `defaultCSSVariableGenerator` | The function which is being used to generate CSS variables based on the provided variants map. |

The theming client consists of:

#### ``:

A wrapper component which will activate a variant for the tree it's wrapping. The properties are:

| Property Name | Type | Default | Description |
|---------------|------|---------|-------------|
| children? | `React.ReactNode` | - | The content of the component. |
| disableCSSVariableGeneration? | `boolean` | `false` | If `true`, CSS variable generation will be disabled.
Useful when you are manually controlling or populating CSS variables using `generateCSSVariablesAsInlineStyle`. |
| variant | `string` | - | The variant to be activated. It has to be a valid variant key that exists in the provided variants map. |

#### `useTokens()`:

A React hook to use in a component that is descendant of `` wrapper. It returns the tokens of the selected variant.

#### `generateCSSVariablesAsInlineStyle(variant, options?)`:

A helper function to generate CSS variables in valid CSS syntax (`--variable=value`). It is helpful when you want to manually control the population of the CSS variables (e.g. Put initial tokens on html tag with ``)

The `options` are:

| Property Name | Type | Default | Description |
|---------------|------|---------|-------------|
| disableCommonTokensGeneration | `boolean` | `false` | If `true`, Common tokens CSS variable generation will be disabled. |

### 2. `defaultCSSVariableGenerator`

```ts
declare const defaultCSSVariableGenerator: (context: {
tokenFamilyKey: string;
tokenKey: string;
tokenPath: string;
tokenValue: unknown;
}) => {
variableName: string;
variableValue: string;
} | null;
```

The default CSS variable generate function. The generated variables obey the following rules:
- Values that are not of type `string` or `number` will be omitted (returns `null`).
- Values of type `number` will be converted into `{tokenValue}px`.
- The generated variable format: `{ variableName: 'PATH-TO-TOKEN', variableValue: 'tokenValue' }`

#### `context.tokenFamilyKey`:

The key of a root token family.

For example, The `colors` key is a `tokenFamilyKey` in the following variants map:

```ts
{
dark: {
colors: {
primary: {},
secondary: {},
// ...
}
},
light: {
colors: {
primary: {},
secondary: {},
// ...
}
},
}
```

#### `context.tokenKey`:

The key (name) of the token.

#### `context.tokenValue`:

The value of the token.

#### `context.tokenPath`:

The dot-separated path to the token from which the root key has been omitted.


## Basic Usage

To getting started, all you need to do is:

1. Create your own variants map:

```ts
// theming.ts

const tokens = {
variants: {
dark: {
colors: {
primary: {
base: "d1",
hover: "d2",
active: "d3",
disabled: "d4",
},
secondary: {
base: "d5",
hover: "d6",
active: "d7",
disabled: "d8",
},
neutral: {
text: {
base: "d9",
secondary: "d10",
tertiary: "d11",
},
background: {
base: "d12",
container: "d13",
elevated: "d14",
},
},
},
},
light: {
colors: {
primary: {
base: "l1",
hover: "l2",
active: "l3",
disabled: "l4",
},
secondary: {
base: "l5",
hover: "l6",
active: "l7",
disabled: "l8",
},
neutral: {
text: {
base: "l9",
secondary: "l10",
tertiary: "l11",
},
background: {
base: "l12",
container: "l13",
elevated: "l14",
},
},
},
},
},
common: {
typefaces: {
monospace: "c1",
rtl: "c2",
ltr: "c3",
decorative: "c4",
},
space: "c5",
}
};
```

2. Create a theming client:

```ts
// theming.ts

import { create } from "react-design-tokens";

const tokens = {
variants: {
dark: {
colors: {
primary: {
base: "d1",
hover: "d2",
active: "d3",
disabled: "d4",
},
secondary: {
base: "d5",
hover: "d6",
active: "d7",
disabled: "d8",
},
neutral: {
text: {
base: "d9",
secondary: "d10",
tertiary: "d11",
},
background: {
base: "d12",
container: "d13",
elevated: "d14",
},
},
},
},
light: {
colors: {
primary: {
base: "l1",
hover: "l2",
active: "l3",
disabled: "l4",
},
secondary: {
base: "l5",
hover: "l6",
active: "l7",
disabled: "l8",
},
neutral: {
text: {
base: "l9",
secondary: "l10",
tertiary: "l11",
},
background: {
base: "l12",
container: "l13",
elevated: "l14",
},
},
},
},
},
common: {
typefaces: {
monospace: "c1",
rtl: "c2",
ltr: "c3",
decorative: "c4",
},
space: "c5",
}
};

export const { useTokens, VariantSelector, generateCSSVariablesAsInlineStyle } = create(tokens);
```

3. Use the theme variants:

```tsx
// App.tsx

import { VariantSelector } from "./theming";

const App = () => {
return (


{/* Components with dark variant tokens */}



{/* Components with light variant tokens */}



);
}

export default App;
```

4. You can now access the tokens down the tree using `useTokens` hook. Also you have access to the generated CSS variables in your CSS.

The CSS variables generated for this variants map with default configuration set and the `dark` variant being selected is:

```
--colors-primary-base: d1;
--colors-primary-hover: d2;
--colors-primary-active: d3;
--colors-primary-disabled: d4;
--colors-secondary-base: d5;
--colors-secondary-hover: d6;
--colors-secondary-active: d7;
--colors-secondary-disabled: d8;
--colors-neutral-text-base: d9;
--colors-neutral-text-secondary: d10;
--colors-neutral-text-tertiary: d11;
--colors-neutral-background-base: d12;
--colors-neutral-background-container: d13;
--colors-neutral-background-elevated: d14;
--typefaces-monospace: c1;
--typefaces-rtl: c2;
--typefaces-ltr: c3;
--typefaces-decorative: c4;
--space: c5;
```

## Contributing

Read the [contributing guide](https://github.com/mimshins/react-design-tokens/blob/main/CONTRIBUTING.md) to learn about our development process, how to propose bug fixes and improvements, and how to build and test your changes.

Contributing to `react-design-tokens` is about more than just issues and pull requests! There are many other ways to support the project beyond contributing to the code base.

## License

This project is licensed under the terms of the [MIT license](https://github.com/mimshins/react-design-tokens/blob/main/LICENSE).