Skip to content

Commit

Permalink
Updating docs on how to extend the tokens (microsoft#33229)
Browse files Browse the repository at this point in the history
  • Loading branch information
mltejera authored Nov 15, 2024
1 parent d766af9 commit e8a616e
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 12 deletions.
43 changes: 31 additions & 12 deletions apps/public-docsite-v9/src/Concepts/Theming.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -123,25 +123,44 @@ export const customLightTheme: Theme = {

### Extending theme with new tokens

Similarly to overriding existing tokens, you can add custom tokens as well.
It's often useful for an app to extend the base set of tokens from Fluent UI. This process will help consuming teams or libraries add more tokens, but sharing them is outside the scope of this doc.

Components which use custom tokens cannot be shared between applications. Keep in mind that any application which uses a component with custom tokens must also add the custom tokens to its own themes. Instead of adding custom tokens inside potentially reusable components, you should talk to design.
Warning that adding more tokens adds more CSS variables which can effect run time performance as each DOM Node carries all the tokens.

```tsx
import { webLightTheme, Theme } from '@fluentui/react-components';
import { makeStyles, themeToTokensObject, webLightTheme, FluentProvider, Theme } from '@fluentui/react-components';

export const customLightTheme: Theme & { customSpacingVerticalHuge: string } = {
...webLightTheme,
customSpacingVerticalHuge: '128px',
// You can pass your own custom tokens to a theme and pass that to the provider.
type CustomTheme = Theme & {
tokenA: string;
tokenB: string;
tokenC: string;
};
```
const customTheme: CustomTheme = { ...webLightTheme, tokenA: 'red', tokenB: 'blue', tokenC: 'green' };
function App() {
return <FluentProvider theme={customTheme}>{/* ... */}</FluentProvider>;
}

To use the tokens in styles, one is supposed to import `tokens`. Obviously that object would not contain any custom tokens. For that reason you can use `themeToTokensObject()` utility which will create the tokens object with the custom tokens.
// ...

⚠ Keep in mind that the object generated by the `themeToTokensObject()` will contain all the tokens and will not be tree-shakeable.
// You can construct a custom tokens object by yourself.
const customTokens: Record<keyof CustomTheme, string> = {
...tokens,
tokenA: `var(--tokenA)`,
tokenB: `var(--tokenB)`,
tokenC: `var(--tokenC)`,
};

```tsx
import { themeToTokensObject } from '@fluentui/react-components';
// You can alternatively use the themeToTokensObject function to construct the custom tokens object.
// Note: If you do it via the themeToTokensObject you might see a negative effect on tree-shaking since bundles won't know the shape of the output.
const alternativeCustomTokens = themeToTokensObject(customTheme);

export const customTokens = themeToTokensObject(customLightTheme);
// You can then use this custom tokens object inside your styles.
const useStyles = makeStyles({
base: {
color: customTokens.tokenA,
backgroundColor: customTokens.tokenB,
outlineColor: customTokens.tokenC,
},
});
```
43 changes: 43 additions & 0 deletions docs/react-v9/contributing/patterns/extending-tokens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
It's often useful for an app to extend the base set of tokens from Fluent UI.

⚠ Components in this repo should _not_ do this.

⚠ Warning that adding more tokens adds more CSS variables which can effect run time performance as each DOM Node carries all the tokens.

```tsx
import { makeStyles, themeToTokensObject, webLightTheme, FluentProvider, Theme } from '@fluentui/react-components';

// You can pass your own custom tokens to a theme and pass that to the provider.
type CustomTheme = Theme & {
tokenA: string;
tokenB: string;
tokenC: string;
};
const customTheme: CustomTheme = { ...webLightTheme, tokenA: 'red', tokenB: 'blue', tokenC: 'green' };
function App() {
return <FluentProvider theme={customTheme}>{/* ... */}</FluentProvider>;
}

// ...

// You can construct a custom tokens object by yourself.
const customTokens: Record<keyof CustomTheme, string> = {
...tokens,
tokenA: `var(--tokenA)`,
tokenB: `var(--tokenB)`,
tokenC: `var(--tokenC)`,
};

// You can alternatively use the themeToTokensObject function to construct the custom tokens object.
// Note: If you do it via the themeToTokensObject you might see a negative effect on tree-shaking since bundles won't know the shape of the output.
const alternativeCustomTokens = themeToTokensObject(customTheme);

// You can then use this custom tokens object inside your styles.
const useStyles = makeStyles({
base: {
color: customTokens.tokenA,
backgroundColor: customTokens.tokenB,
outlineColor: customTokens.tokenC,
},
});
```

0 comments on commit e8a616e

Please sign in to comment.