-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding CSS and JS token display in storybook #594
Changes from 4 commits
76df8db
ee701ca
68504fb
5abc7de
a6a6567
ab1c530
86cde74
7fea178
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,11 @@ | ||
import React from 'react'; | ||
import React, { useEffect, useState } from 'react'; | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import tokens from '../src/figma/tokens.json'; | ||
import { ColorSwatchGroup } from './components'; | ||
import { Color } from './utils/getThemeColorsFromStylesheet'; | ||
|
||
import { ColorSwatchGroup, ColorSwatch } from './components'; | ||
|
||
import README from './BrandColors.mdx'; | ||
|
||
const meta: Meta<typeof ColorSwatchGroup> = { | ||
|
@@ -18,7 +22,64 @@ export default meta; | |
|
||
type Story = StoryObj<typeof ColorSwatchGroup>; | ||
|
||
export const DefaultStory: Story = { | ||
export const Figma: Story = { | ||
render: () => <ColorSwatchGroup swatchData={tokens.global.brandColors} />, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Renaming stories to align with their format |
||
name: 'Default', | ||
}; | ||
|
||
export const CSS: Story = { | ||
render: () => { | ||
const [brandColors, setBrandColors] = useState<Color>({}); | ||
|
||
useEffect(() => { | ||
// Getting all CSS variables that start with '--brand-colors' from all stylesheets | ||
const cssVars = Array.from(document.styleSheets) | ||
georgewrmarshall marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.flatMap((styleSheet) => { | ||
try { | ||
return Array.from(styleSheet.cssRules); | ||
} catch (err) { | ||
return []; | ||
} | ||
}) | ||
.filter((cssRule) => cssRule.type === CSSRule.STYLE_RULE) | ||
.flatMap((cssRule) => Array.from((cssRule as CSSStyleRule).style)) | ||
.filter((varName) => varName.startsWith('--brand-colors')); | ||
|
||
const brandColors: Color = {}; | ||
|
||
// Looping through each CSS variable and getting its value | ||
cssVars.forEach((varName) => { | ||
const name = varName.split('-').slice(2).join('-'); | ||
const color = getComputedStyle(document.documentElement) | ||
.getPropertyValue(varName) | ||
.trim(); | ||
brandColors[name] = { | ||
color: color, | ||
name: `var(${varName})`, | ||
}; | ||
}); | ||
|
||
// Updating the state with the new brandColors | ||
setBrandColors(brandColors); | ||
}, []); | ||
|
||
// Rendering the color swatches | ||
return ( | ||
<div | ||
style={{ | ||
display: 'grid', | ||
gap: '16px', | ||
gridTemplateColumns: 'repeat(auto-fill, 300px)', | ||
}} | ||
> | ||
{/* Mapping through each brand color and rendering a ColorSwatch component for it */} | ||
{Object.values(brandColors).map(({ color, name }) => ( | ||
<ColorSwatch key={name} color={color} name={name} /> | ||
))} | ||
</div> | ||
); | ||
}, | ||
}; | ||
|
||
export const JS: Story = { | ||
render: () => <h1>Coming soon</h1>, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,13 +16,13 @@ For most use cases, these function-based color tokens should be your first choic | |
|
||
The light theme colors are designed to be used in the styles for MetaMask UI when the light theme is active | ||
|
||
<Canvas of={ThemeColorStories.LightThemeColors} /> | ||
<Canvas of={ThemeColorStories.FigmaLightTheme} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updating story name references in MDX so they still render as intended |
||
|
||
## Dark theme colors | ||
|
||
The dark theme colors are designed for MetaMask UI when the dark theme is active. They have the same names as the light theme colors but different values. If you are using the light theme colors for their intended purpose, your UI will automatically be compatible with the dark theme. | ||
|
||
<Canvas of={ThemeColorStories.DarkThemeColors} /> | ||
<Canvas of={ThemeColorStories.FigmaDarkTheme} /> | ||
|
||
## Best practices | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
import React from 'react'; | ||
|
||
import tokens from '../src/figma/tokens.json'; | ||
import { ColorSwatchGroup } from './components'; | ||
import { lightTheme, darkTheme } from '../src'; | ||
|
||
import getThemeColorsFromStylesheet from './utils/getThemeColorsFromStylesheet'; | ||
import { ColorSwatchGroup, ColorSwatch } from './components'; | ||
import README from './ThemeColors.mdx'; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Imports all the different token data for each format |
||
export default { | ||
|
@@ -13,8 +17,8 @@ export default { | |
}, | ||
}; | ||
|
||
export const LightThemeColors = { | ||
render: () => <ColorSwatchGroup {...LightThemeColors.args} />, | ||
export const FigmaLightTheme = { | ||
render: () => <ColorSwatchGroup {...FigmaLightTheme.args} />, | ||
args: { | ||
swatchData: tokens.light.colors, | ||
borderColor: tokens.light.colors.border.muted.value, | ||
|
@@ -23,7 +27,7 @@ export const LightThemeColors = { | |
}, | ||
}; | ||
|
||
export const DarkThemeColors = { | ||
export const FigmaDarkTheme = { | ||
render: () => ( | ||
<div | ||
style={{ | ||
|
@@ -32,7 +36,7 @@ export const DarkThemeColors = { | |
padding: '1rem', | ||
}} | ||
> | ||
<ColorSwatchGroup {...DarkThemeColors.args} /> | ||
<ColorSwatchGroup {...FigmaDarkTheme.args} /> | ||
</div> | ||
), | ||
args: { | ||
|
@@ -50,3 +54,139 @@ export const DarkThemeColors = { | |
}, | ||
}, | ||
}; | ||
|
||
export const CSSLightTheme = { | ||
render: () => { | ||
const lightThemeColors = getThemeColorsFromStylesheet(); | ||
|
||
return ( | ||
<div | ||
style={{ | ||
display: 'grid', | ||
gap: '16px', | ||
gridTemplateColumns: 'repeat(auto-fill, 300px)', | ||
}} | ||
> | ||
{Object.entries(lightThemeColors).map( | ||
([name, { color, name: colorName }]) => ( | ||
<ColorSwatch key={name} color={color} name={colorName} /> | ||
), | ||
)} | ||
</div> | ||
); | ||
}, | ||
}; | ||
|
||
export const CSSDarkTheme = { | ||
render: () => { | ||
const darkThemeColors = getThemeColorsFromStylesheet(); | ||
return ( | ||
<div | ||
style={{ | ||
backgroundColor: 'var(--color-background-default)', | ||
margin: '-1rem', | ||
padding: '1rem', | ||
}} | ||
> | ||
<div | ||
style={{ | ||
display: 'grid', | ||
gap: '16px', | ||
gridTemplateColumns: 'repeat(auto-fill, 300px)', | ||
}} | ||
> | ||
{Object.entries(darkThemeColors).map( | ||
([name, { color, name: colorName }]) => ( | ||
<ColorSwatch | ||
key={name} | ||
color={color} | ||
name={colorName} | ||
borderColor="var(--color-border-muted)" | ||
textBackgroundColor="var(--color-background-default)" | ||
textColor="var(--color-text-default)" | ||
/> | ||
), | ||
)} | ||
</div> | ||
</div> | ||
); | ||
}, | ||
backgrounds: { | ||
default: 'dark', | ||
values: [{ name: 'dark', value: 'var(--color-background-default)' }], | ||
}, | ||
decorators: [ | ||
// eslint-disable-next-line no-unused-vars | ||
(StoryFn) => { | ||
// Check if document object is available | ||
if (typeof document !== 'undefined') { | ||
// Add the data-theme attribute to the root element | ||
// eslint-disable-next-line no-undef | ||
document.documentElement.setAttribute('data-theme', 'dark'); | ||
} | ||
// Render the story | ||
return <StoryFn />; | ||
}, | ||
], | ||
}; | ||
|
||
export const JSLightTheme = { | ||
render: () => ( | ||
<div | ||
style={{ | ||
display: 'grid', | ||
gap: '16px', | ||
gridTemplateColumns: 'repeat(auto-fill, 300px)', | ||
}} | ||
> | ||
{Object.entries(lightTheme.colors).flatMap(([category, colorObj]) => | ||
Object.entries(colorObj).map(([name, color]) => ( | ||
<ColorSwatch | ||
key={`${category}-${name}`} | ||
color={color} | ||
name={`color.${category}.${name}`} | ||
/> | ||
)), | ||
)} | ||
</div> | ||
), | ||
}; | ||
|
||
export const JSDarkTheme = { | ||
render: () => ( | ||
<div | ||
style={{ | ||
backgroundColor: darkTheme.colors.background.default, | ||
margin: '-1rem', | ||
padding: '1rem', | ||
}} | ||
> | ||
<div | ||
style={{ | ||
display: 'grid', | ||
gap: '16px', | ||
gridTemplateColumns: 'repeat(auto-fill, 300px)', | ||
}} | ||
> | ||
{Object.entries(darkTheme.colors).flatMap(([category, colorObj]) => | ||
Object.entries(colorObj).map(([name, color]) => ( | ||
<ColorSwatch | ||
key={`${category}-${name}`} | ||
color={color} | ||
name={`color.${category}.${name}`} | ||
borderColor={darkTheme.colors.border.muted} | ||
textBackgroundColor={darkTheme.colors.background.default} | ||
textColor={darkTheme.colors.text.default} | ||
/> | ||
)), | ||
)} | ||
</div> | ||
</div> | ||
), | ||
parameters: { | ||
backgrounds: { | ||
default: 'dark', | ||
values: [{ name: 'dark', value: darkTheme.colors.background.default }], | ||
}, | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { ColorSwatch } from './ColorSwatch'; | ||
|
||
const meta: Meta<typeof ColorSwatch> = { | ||
title: 'Documentation Components/ColorSwatch', | ||
component: ColorSwatch, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof ColorSwatch>; | ||
|
||
export const Default: Story = { | ||
render: () => ( | ||
<ColorSwatch | ||
color="#007bff" | ||
borderColor="#ced4da" | ||
textBackgroundColor="#f8f9fa" | ||
textColor="#212529" | ||
name="Primary Default" | ||
/> | ||
), | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,7 @@ export const ColorSwatch: FunctionComponent<ColorSwatchProps> = ({ | |
backgroundColor: textBackgroundColor, | ||
padding: 8, | ||
borderRadius: '0 0 8px 8px', | ||
color: textColor, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. including text color so we can adjust the display of swatches for dark mode |
||
}} | ||
> | ||
<strong style={{ display: 'block', marginBottom: '8px' }}> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { ColorSwatchGroup } from './ColorSwatchGroup'; | ||
|
||
const meta: Meta<typeof ColorSwatchGroup> = { | ||
title: 'Documentation Components/ColorSwatchGroup', | ||
component: ColorSwatchGroup, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof ColorSwatchGroup>; | ||
|
||
export const Default: Story = { | ||
render: () => ( | ||
<ColorSwatchGroup | ||
swatchData={{ | ||
white: { | ||
white000: { | ||
value: '#FFFFFF', | ||
description: '(HEX: #FFFFFF)', | ||
type: 'color', | ||
}, | ||
white010: { | ||
value: '#FCFCFC', | ||
description: '(HEX: #FCFCFC)', | ||
type: 'color', | ||
}, | ||
}, | ||
}} | ||
borderColor="#ced4da" | ||
textBackgroundColor="#f8f9fa" | ||
textColor="#212529" | ||
name="Color Swatch Group" | ||
/> | ||
), | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ import { ComponentStory, ComponentMeta } from '@storybook/react'; | |
import { Text } from '.'; | ||
|
||
export default { | ||
title: 'Doc components/Text', | ||
title: 'Documentation Components/Text', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just updating "Doc" to "Documentation" as it's bumped to 2 lines anyway |
||
argTypes: { | ||
children: { | ||
control: 'text', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updating reference to brand color story in MDX docs so it still renders