diff --git a/docs/BrandColors.mdx b/docs/BrandColors.mdx index eb64f52a..4641a38a 100644 --- a/docs/BrandColors.mdx +++ b/docs/BrandColors.mdx @@ -17,7 +17,7 @@ _The majority of our brand color progressions were generated using the [0to255]( ## Brand colors - + ## Best Practices diff --git a/docs/BrandColors.stories.tsx b/docs/BrandColors.stories.tsx index 63aeeb6d..4c0c415a 100644 --- a/docs/BrandColors.stories.tsx +++ b/docs/BrandColors.stories.tsx @@ -2,6 +2,7 @@ import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import tokens from '../src/figma/tokens.json'; import { brandColor } from '../src/js'; +import getCSSVariablesFromStylesheet from './utils/getCSSVariablesFromStylesheet'; import { ColorSwatchGroup, ColorSwatch } from './components'; import README from './BrandColors.mdx'; @@ -19,9 +20,28 @@ export default meta; type Story = StoryObj; -export const DefaultStory: Story = { +export const Figma: Story = { render: () => , - name: 'Default', +}; + +export const CSS: Story = { + render: () => { + const cssBrandColors = getCSSVariablesFromStylesheet('--brand-colors'); + return ( +
+ {/* Mapping through each brand color and rendering a ColorSwatch component for it */} + {Object.values(cssBrandColors).map(({ color, name }) => ( + + ))} +
+ ); + }, }; export const JS: Story = { diff --git a/docs/ThemeColors.mdx b/docs/ThemeColors.mdx index 5da45b2e..e42830f2 100644 --- a/docs/ThemeColors.mdx +++ b/docs/ThemeColors.mdx @@ -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 - + ## 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. - + ## Best practices diff --git a/docs/ThemeColors.stories.tsx b/docs/ThemeColors.stories.tsx index 6e94fc8b..200da606 100644 --- a/docs/ThemeColors.stories.tsx +++ b/docs/ThemeColors.stories.tsx @@ -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 getCSSVariablesFromStylesheet from './utils/getCSSVariablesFromStylesheet'; + +import { ColorSwatchGroup, ColorSwatch } from './components'; + import README from './ThemeColors.mdx'; export default { @@ -13,8 +17,8 @@ export default { }, }; -export const LightThemeColors = { - render: () => , +export const FigmaLightTheme = { + render: () => , 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: () => (
- +
), args: { @@ -50,3 +54,136 @@ export const DarkThemeColors = { }, }, }; + +export const CSSLightTheme = { + render: () => { + const lightThemeColors = getCSSVariablesFromStylesheet('--color-'); + return ( +
+ {Object.entries(lightThemeColors).map( + ([name, { color, name: colorName }]) => ( + + ), + )} +
+ ); + }, +}; + +export const CSSDarkTheme = { + render: () => { + const darkThemeColors = getCSSVariablesFromStylesheet('--color-'); + return ( +
+
+ {Object.entries(darkThemeColors).map( + ([name, { color, name: colorName }]) => ( + + ), + )} +
+
+ ); + }, + backgrounds: { + default: 'dark', + values: [{ name: 'dark', value: 'var(--color-background-default)' }], + }, + decorators: [ + (StoryFn) => { + // Check if document object is available + if (typeof document !== 'undefined') { + // Add the data-theme attribute to the root element + document.documentElement.setAttribute('data-theme', 'dark'); + } + // Render the story + return ; + }, + ], +}; + +export const JSLightTheme = { + render: () => ( +
+ {Object.entries(lightTheme.colors).flatMap(([category, colorObj]) => + Object.entries(colorObj).map(([name, color]) => ( + + )), + )} +
+ ), +}; + +export const JSDarkTheme = { + render: () => ( +
+
+ {Object.entries(darkTheme.colors).flatMap(([category, colorObj]) => + Object.entries(colorObj).map(([name, color]) => ( + + )), + )} +
+
+ ), + parameters: { + backgrounds: { + default: 'dark', + values: [{ name: 'dark', value: darkTheme.colors.background.default }], + }, + }, +}; diff --git a/docs/components/ColorSwatch/ColorSwatch.stories.tsx b/docs/components/ColorSwatch/ColorSwatch.stories.tsx new file mode 100644 index 00000000..67a50c65 --- /dev/null +++ b/docs/components/ColorSwatch/ColorSwatch.stories.tsx @@ -0,0 +1,23 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ColorSwatch } from './ColorSwatch'; + +const meta: Meta = { + title: 'Documentation Components/ColorSwatch', + component: ColorSwatch, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + render: () => ( + + ), +}; diff --git a/docs/components/ColorSwatch/ColorSwatch.tsx b/docs/components/ColorSwatch/ColorSwatch.tsx index ac1f52fb..a190a368 100644 --- a/docs/components/ColorSwatch/ColorSwatch.tsx +++ b/docs/components/ColorSwatch/ColorSwatch.tsx @@ -49,6 +49,7 @@ export const ColorSwatch: FunctionComponent = ({ backgroundColor: textBackgroundColor, padding: 8, borderRadius: '0 0 8px 8px', + color: textColor, }} > diff --git a/docs/components/ColorSwatchGroup/ColorSwatchGroup.stories.tsx b/docs/components/ColorSwatchGroup/ColorSwatchGroup.stories.tsx new file mode 100644 index 00000000..ea714957 --- /dev/null +++ b/docs/components/ColorSwatchGroup/ColorSwatchGroup.stories.tsx @@ -0,0 +1,36 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ColorSwatchGroup } from './ColorSwatchGroup'; + +const meta: Meta = { + title: 'Documentation Components/ColorSwatchGroup', + component: ColorSwatchGroup, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + render: () => ( + + ), +}; diff --git a/docs/components/Text/Text.stories.tsx b/docs/components/Text/Text.stories.tsx index e0dd6cbb..b4ae5cd6 100644 --- a/docs/components/Text/Text.stories.tsx +++ b/docs/components/Text/Text.stories.tsx @@ -3,7 +3,7 @@ import { ComponentStory, ComponentMeta } from '@storybook/react'; import { Text } from '.'; export default { - title: 'Doc components/Text', + title: 'Documentation Components/Text', argTypes: { children: { control: 'text', diff --git a/docs/components/Text/Text.tsx b/docs/components/Text/Text.tsx index 74cedf1d..022306f0 100644 --- a/docs/components/Text/Text.tsx +++ b/docs/components/Text/Text.tsx @@ -5,7 +5,7 @@ interface Props { /** * The children or content of the Text component */ - children?: React.ReactChild; + children?: React.ReactNode; /** * Polymorphic prop to change the html root element of the component */ @@ -14,6 +14,10 @@ interface Props { * The style prop of the Text component */ style?: object; + /** + * The color prop of the Text component + */ + color?: string; } type TextProps = Props & @@ -23,10 +27,17 @@ export const Text = ({ style, children, as, + color, }: TextProps) => { const Component = as || 'span'; return ( - + {children} ); diff --git a/docs/utils/getCSSVariablesFromStylesheet.ts b/docs/utils/getCSSVariablesFromStylesheet.ts new file mode 100644 index 00000000..e404569f --- /dev/null +++ b/docs/utils/getCSSVariablesFromStylesheet.ts @@ -0,0 +1,49 @@ +// Define a type for the color object +export interface Color { + [key: string]: { + color: string; + name: string; + }; +} + +/** + * Retrieves CSS variables from the stylesheet. + * + * @param varPrefix - The prefix of the CSS variables to retrieve. + * @returns An object containing the retrieved CSS variables. + */ +function getCSSVariablesFromStylesheet(varPrefix: string): Color { + const cssVariables: Color = {}; + + Array.from(document.styleSheets) + .flatMap((styleSheet) => { + try { + return Array.from(styleSheet.cssRules); + } catch (err) { + return []; + } + }) + .filter((cssRule) => cssRule.type === CSSRule.STYLE_RULE) + .filter( + (cssRule: CSSRule) => (cssRule as CSSStyleRule).selectorText === ':root', + ) + .flatMap( + (cssRule: CSSRule) => + Array.from((cssRule as CSSStyleRule).style) as string[], + ) + .filter((varName) => varName.startsWith(varPrefix)) + .forEach((varName) => { + const name = varName.split('-').slice(2).join('-'); + const color = getComputedStyle(document.documentElement) + .getPropertyValue(varName) + .trim(); + cssVariables[name] = { + color, + name: `var(${varName})`, + }; + }); + + return cssVariables; +} + +export default getCSSVariablesFromStylesheet; diff --git a/src/js/brandColor/brandColor.ts b/src/js/brandColor/brandColor.ts index 1608011c..a50f3ef0 100644 --- a/src/js/brandColor/brandColor.ts +++ b/src/js/brandColor/brandColor.ts @@ -37,7 +37,7 @@ export const brandColor: BrandColor = { orange300: '#faa66c', orange400: '#f8883b', orange500: '#f66a0a', - orange600: '#c65507', + orange600: '#bf5208', orange700: '#954005', orange800: '#632b04', orange900: '#321602', @@ -48,7 +48,7 @@ export const brandColor: BrandColor = { green300: '#86e29b', green400: '#5dd879', green500: '#28a745', - green600: '#1e7e34', + green600: '#1c8234', green700: '#145523', green800: '#0a2c12', green900: '#041007',