diff --git a/README.md b/README.md index d2be3ec9..c15c48e7 100644 --- a/README.md +++ b/README.md @@ -103,10 +103,10 @@ Follow these steps to below to get the library up and running locally. ### Setup -- Install [Node.js](https://nodejs.org) version 12 +- Install [Node.js](https://nodejs.org) version 16 - If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you. - Install [Yarn v1](https://yarnpkg.com/en/docs/install) -- Run `yarn setup` to install dependencies and run any requried post-install scripts +- Run `yarn setup` to install dependencies and run any required post-install scripts - **Warning:** Do not use the `yarn` / `yarn install` command directly. Use `yarn setup` instead. The normal install command will skip required post-install scripts, leaving your development environment in an invalid state. ### Documentation @@ -117,9 +117,9 @@ We use storybook for documentation. To get storybook up and running use: yarn storybook ``` -### Figma Tokens +### Tokens Studio for Figma (formerly known as Figma Tokens) -The primary data for the generation of tokens is based on the json generated from a figma plugin called [Figma Tokens](https://github.com/six7/figma-tokens). This keeps our code in sync with our figma libraries. Currently the token formats are manually generated we are hoping to automate this process in future. +The primary data for the generation of tokens is based on the json generated from a figma plugin called [Tokens Studio for Figma (formerly known as Figma Tokens)](https://github.com/six7/figma-tokens). This keeps our code in sync with our figma libraries. Currently the token formats are manually generated we are hoping to automate this process in future. ### Testing and Linting diff --git a/docs/BrandColors.mdx b/docs/BrandColors.mdx index 2580bb25..eb64f52a 100644 --- a/docs/BrandColors.mdx +++ b/docs/BrandColors.mdx @@ -1,17 +1,68 @@ -import { Meta, Canvas, Story } from '@storybook/addon-docs'; -import LinkTo from '@storybook/addon-links/react'; +import { Canvas } from '@storybook/blocks'; +import * as BrandColorStories from './BrandColors.stories'; - +# Brand colors (first tier) -# Brand Colors (first tier) +Brand colors form the foundation of our color system. They use literal color names (like red, green, etc.) and a numeric scale (where 000 is light and 900 is dark) by default. These colors are essential to maintaining visual consistency across our products and are primarily used as a reference for the [theme colors](/docs/colors-theme-colors--docs). -Brand specific colors used in the first tier of design token abstraction. They **should not** be used in the code directly but referenced by [**Theme Colors**](/docs/colors-themecolors--light-theme-colors) used in second tier tokens. Most brand color progressions were generated using [0to255](https://0to255.com/037dd6) +While these colors are fundamental to our design system, they **should not** be used directly in most cases. Instead, they should be referenced via [theme colors](/docs/colors-theme-colors--docs), which form the second tier of our design tokens. - - - +However, in rare cases where a color needs to remain constant across themes (e.g., white always being white, regardless of light or dark mode), the corresponding brand color can be used. Always ensure there isn't an existing theme token that could be used instead. + +_The majority of our brand color progressions were generated using the [0to255](https://0to255.com/037dd6) tool, which helps ensure smooth and consistent color transitions._ + +- [**Brand colors**](#brand-colors) +- [**Best practices**](#best-practices) +- [**References**](#references) + +## Brand colors + + + +## Best Practices + +### ✅ **DO**: Use brand colors when the color should remain the same across all themes + +```jsx +fill: brandColors.white.white000; +fill: var(--brand-colors-white-white000); +``` + +### ❌ **DON'T**: Use brand colors without checking for an existing theme token first + +```jsx +background-color: brandColors.blue.blue500; // Brand color instead of theme.color.primary.default +background-color: var(--brand-colors-blue-blue500); // Brand color instead of var(--color-primary-default) +``` + +### ✅ **DO**: Store non-token colors in a global file + +If you need to use colors that are not included in the design tokens, store these colors in a global file in your project. This makes it easier to keep track of these colors and update them as needed. Always consider this as a last resort, and strive to use design tokens wherever possible. + +```jsx +// colors.js +export const customColors = { + myCustomColor: '#abc123', +}; + +// colors.css +--custom-colors-my-custom-color: #abc123; + +// component.js +import { customColors } from './colors.js'; + +background-color: customColors.myCustomColor; +background-color: var(--custom-colors-my-custom-color); +``` + +### ❌ **DON'T**: Use non-token colors directly in your components + +```jsx +// Avoid +background-color: #abc123; // Custom color not in design tokens or global file +``` ## References -- [Tool used to generate colors](http://www.0to255.com/037DD6) -- [Figma Brand Colors Library](https://www.figma.com/file/cBAUPFMnbv6tHR1J8KvBI2/Brand-Colors?node-id=0%3A1)(internal use only) +- [0to255](http://www.0to255.com/037DD6): The tool we used to generate our color progressions. +- [Figma Brand Colors Library](https://www.figma.com/file/cBAUPFMnbv6tHR1J8KvBI2/Brand-Colors?node-id=0%3A1): Our internal Figma library for brand colors. Please note that this is for internal use only. diff --git a/docs/BrandColors.stories.tsx b/docs/BrandColors.stories.tsx index 324203f6..7c5a8ee2 100644 --- a/docs/BrandColors.stories.tsx +++ b/docs/BrandColors.stories.tsx @@ -1,27 +1,24 @@ -import { ComponentStory, ComponentMeta } from '@storybook/react'; +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; import tokens from '../src/figma/tokens.json'; - import { ColorSwatchGroup } from './components'; - import README from './BrandColors.mdx'; -export default { - title: 'Colors/BrandColors', +const meta: Meta = { + title: 'Colors/Brand Colors', + component: ColorSwatchGroup, parameters: { docs: { page: README, }, }, -} as ComponentMeta; +}; -const Template: ComponentStory = (args) => ( - -); +export default meta; -export const DefaultStory = Template.bind({}); +type Story = StoryObj; -DefaultStory.args = { - swatchData: tokens.global.brandColors, +export const DefaultStory: Story = { + render: () => , + name: 'Default', }; - -DefaultStory.storyName = 'Default'; diff --git a/docs/IntroductionColor.stories.mdx b/docs/IntroductionColor.stories.mdx index 0ebba576..f2c797ba 100644 --- a/docs/IntroductionColor.stories.mdx +++ b/docs/IntroductionColor.stories.mdx @@ -7,11 +7,7 @@ import { lightTheme } from '../src/index.ts'; # Color -Color is used to express style and communicate meaning. - -## Token Tiers - -We follow a 3 tiered system for color design tokens. +Color is used to express style and communicate meaning. We follow a 3 tiered system for color design tokens.
-

-### **Brand colors** (first tier) +## Brand colors (first tier) -These colors **SHOULD NOT** be used in your component styles directly. They are used as a reference for the [Theme Colors](/docs/colors-themecolors--light-theme-colors). Brand colors are used to keep track of all colors used in our app. See [Brand Colors](/docs/colors-brandcolors--default-story) +Brand colors are the foundation of our color system. They are primarily used as a reference for the [theme colors](/docs/colors-theme-colors--docs) and **should not** be used directly in most component styles. -### **Theme Colors** (second tier) +However, in rare cases where a color needs to remain constant across themes (e.g., white always being white, regardless of light or dark mode), the corresponding brand color can be used. Always ensure there isn't an existing theme token that could be used instead. -These colors are color agnostic, semantically neutral and theme compatible design tokens that you can use in your code and styles. Please refer to the description of each token for it's intended purpose. See [Theme Colors](/docs/colors-themecolors--light-theme-colors) +For more details, refer to the [brand colors](/docs/colors-brand-colors--docs) section. -### **Component colors** (third tier) +## Theme colors (second tier) -Another level of abstraction is component colors that you can use at a component specific level. We do not currently provide any component tier colors but that may change in future. +Theme colors are design tokens that are named based on their function rather than their actual color values. This makes them adaptable to different themes and ensures consistency and accessibility across your project. For most use cases, these function-based theme color tokens should be your first choice. -## Takeaways +For more details, refer to the [theme colors](/docs/colors-theme-colors--docs) section -- Do not use static HEX values in your code. Use the [Theme Colors](/docs/colors-themecolors--light-theme-colors). If one does not exist for your use case [create an issue](https://github.com/MetaMask/design-tokens/issues/new) and tag it with a `color` label. -- Make sure the design token you are using is for it's intended purpose. Please refer to the description of each token. +## Component colors (third tier) -### Next 👉 [Theme Colors](/docs/colors-themecolors--light-theme-colors) +Component colors provide another level of abstraction for component-specific colors. We currently do not provide any component tier colors, but this may change in the future -
+## Next steps + +Learn more about our [brand colors](/docs/colors-brand-colors--docs) or [theme colors](/docs/colors-theme-colors--docs) section ## References diff --git a/docs/Shadows.mdx b/docs/Shadows.mdx index 18c79533..531a007a 100644 --- a/docs/Shadows.mdx +++ b/docs/Shadows.mdx @@ -1,23 +1,19 @@ import { Meta, Canvas, Story } from '@storybook/addon-docs'; -import LinkTo from '@storybook/addon-links/react'; +import * as ShadowStories from './Shadows.stories'; # Shadows -Shadows convey elevation of elements on a surface +Shadows in design are used to create depth and hierarchy. They can be used to differentiate between different elements, and to highlight interactive elements. - - - + ## Size -There are 4 different sizes of shadow in MetaMask. +Shadows come in four different sizes: XS, SM, MD, and LG. The size of the shadow can be used to indicate the relative importance or prominence of an element. - - - + | Size | JS | CSS | | ------ | ----------------- | ----------------------- | @@ -28,11 +24,9 @@ There are 4 different sizes of shadow in MetaMask. ## Color -As well as the neutral colors for shadow 2 other colors exist that are used for the primary and error/danger button hover states +Shadows can have three different colors: default (neutral), primary, and error/danger. The color of the shadow can be used to indicate the state or functionality of an element. - - - + | Color | JS | CSS | | ----------- | ----------------------- | ----------------------------- | @@ -40,13 +34,11 @@ As well as the neutral colors for shadow 2 other colors exist that are used for | **primary** | `colors.primary.shadow` | `var(--color-primary-shadow)` | | **danger** | `colors.error.shadow` | `var(--color-error-shadow)` | -## Example usage +## Usage -Using both size and color tokens, different shadows can be applied to components. +Shadows can be applied to various components to create depth and hierarchy. Here are some examples of how shadows can be used in different components: - - - + | Component | JS | CSS | | ------------------------ | ------------------------------------------------------------------------------- | ---------------------------------------------------------------- | diff --git a/docs/Shadows.stories.tsx b/docs/Shadows.stories.tsx index 3864828f..1d8e00c2 100644 --- a/docs/Shadows.stories.tsx +++ b/docs/Shadows.stories.tsx @@ -1,33 +1,8 @@ import React from 'react'; import { lightTheme } from '../src/js'; - import { Text } from './components'; - import README from './Shadows.mdx'; -export default { - title: 'Shadows/Shadows', - parameters: { - docs: { - page: README, - }, - }, - argTypes: { - size: { - control: 'select', - options: Object.keys(lightTheme.shadows.size), - }, - color: { - control: 'select', - options: ['default', 'primary', 'error'], - }, - }, - args: { - color: 'default', - size: 'xs', - }, -}; - interface ShadowSwatchProps { children: any; style?: object; @@ -61,8 +36,29 @@ const ShadowSwatch = ({ ); -export const Shadow = (args) => { - return ( +export default { + title: 'Shadows/Shadows', + component: ShadowSwatch, + parameters: { + docs: { + page: README, + }, + }, + argTypes: { + size: { + control: 'select', + options: Object.keys(lightTheme.shadows.size), + }, + color: { + control: 'select', + options: ['default', 'primary', 'error'], + }, + }, +}; + +export const DefaultStory = { + name: 'Default', + render: (args) => (
{
- ); + ), + args: { + color: 'default', + size: 'xs', + }, }; -export const Size = (args) => { - return ( +export const Size = { + render: (args) => (
{
- ); + ), + args: { + color: 'default', + size: 'xs', + }, }; -export const Color = (args) => { - return ( +export const Color = { + render: (args) => (
{
- ); + ), + args: { + color: 'default', + size: 'xs', + }, }; -export const ExampleUsage = () => { - return ( +export const ExampleUsage = { + render: () => (
{
- ); + ), }; diff --git a/docs/ThemeColors.mdx b/docs/ThemeColors.mdx index b476ee17..5da45b2e 100644 --- a/docs/ThemeColors.mdx +++ b/docs/ThemeColors.mdx @@ -1,31 +1,76 @@ -import { Meta, Canvas, Story } from '@storybook/addon-docs'; +import { Canvas } from '@storybook/addon-docs/blocks'; +import * as ThemeColorStories from './ThemeColors.stories'; -import tokens from '../src/figma/tokens.json'; +# Theme Colors (second tier) - +Theme colors are design tokens that are named based on their function rather than their actual color values. This makes them adaptable to different themes and ensures consistency and accessibility across your project. -# Theme Colors (second tier) +For most use cases, these function-based color tokens should be your first choice. They are derived from the first-tier [**brand colors**](/docs/colors-brand-colors--docs) and are applied to high-level applications within the UI. + +- [**Light theme colors**](#light-theme-colors) +- [**Dark theme colors**](#dark-theme-colors) +- [**Best practices**](#best-practices) +- [**References**](#references) + +## Light theme colors + +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 + +### ✅ **DO**: Use theme colors in your components + +```jsx +// Good +background-color: theme.colors.background.default; +background-color: var(--color-background-default); +``` + +### ❌ **DON'T**: Use static color values or brand colors in your components + +See when to use [brand colors](/docs/colors-brand-colors--docs#best-practices) + +```jsx +// Avoid +background-color: #ffffff; // Static color value +background-color: brandColors.white.white000; // Brand color +background-color: var(--brand-colors-white-white000); // Brand color +``` -Theme colors take the first tier [**Brand Colors**](/docs/colors-brandcolors--default-story) and start applying them to high-level applications within the UI. They are considered second tier tokens and can be used in the code directly. Theme colors should be used liberally throughout the codebase and create theme compatibility in your components. +### ✅ **DO**: Store non-token colors in a global file -- [Light Theme Colors](#light-theme-colors) -- [Dark Theme Colors](#dark-theme-colors) +If you need to use colors that are not included in the design tokens, store these colors in a global file in your project. This makes it easier to keep track of these colors and update them as needed. Always consider this as a last resort, and strive to use design tokens wherever possible. -## Light Theme Colors +```jsx +// colors.js +export const customColors = { + myCustomColor: '#abc123', +}; -Light theme colors to be used in the styles for MetaMask UI. +// colors.css +--custom-colors-my-custom-color: #abc123; - - - +// component.js +import { customColors } from './colors.js'; -## Dark Theme Colors +background-color: customColors.myCustomColor; +background-color: var(--custom-colors-my-custom-color); +``` -Dark theme colors for MetaMask UI. They have the same name as Light Theme Colors but different values. If you are using the Light Theme Colors for their intended purpose your UI will be dark theme compatible. +### ❌ **DON'T**: Use non-token colors directly in your components - - - +```jsx +// Avoid +background-color: #abc123; // Custom color not in design tokens or global file +``` ## References diff --git a/docs/ThemeColors.stories.tsx b/docs/ThemeColors.stories.tsx index d8e7c096..6e94fc8b 100644 --- a/docs/ThemeColors.stories.tsx +++ b/docs/ThemeColors.stories.tsx @@ -1,58 +1,30 @@ import React from 'react'; -import { StoryFn, Meta } from '@storybook/react'; - +import tokens from '../src/figma/tokens.json'; import { ColorSwatchGroup } from './components'; import README from './ThemeColors.mdx'; -import tokens from '../src/figma/tokens.json'; - export default { - title: 'Colors/ThemeColors', + title: 'Colors/Theme Colors', component: ColorSwatchGroup, parameters: { docs: { page: README, }, }, -} as Meta; - -const Template: StoryFn = (args) => { - return ( - <> - - - ); -}; - -export const LightThemeColors = Template.bind({}); - -LightThemeColors.args = { - swatchData: tokens.light.colors, - borderColor: tokens.light.colors.border.muted.value, - textBackgroundColor: tokens.light.colors.background.default.value, - textColor: tokens.light.colors.text.default.value, }; -export const DarkThemeColors = Template.bind({}); - -DarkThemeColors.args = { - swatchData: tokens.dark.colors, - borderColor: tokens.dark.colors.border.muted.value, - textBackgroundColor: tokens.dark.colors.background.default.value, - textColor: tokens.dark.colors.text.default.value, -}; - -DarkThemeColors.parameters = { - backgrounds: { - default: 'dark', - values: [ - { name: 'dark', value: tokens.dark.colors.background.default.value }, - ], +export const LightThemeColors = { + render: () => , + args: { + swatchData: tokens.light.colors, + borderColor: tokens.light.colors.border.muted.value, + textBackgroundColor: tokens.light.colors.background.default.value, + textColor: tokens.light.colors.text.default.value, }, }; -DarkThemeColors.decorators = [ - (Story) => ( +export const DarkThemeColors = { + render: () => (
- +
), -]; + args: { + swatchData: tokens.dark.colors, + borderColor: tokens.dark.colors.border.muted.value, + textBackgroundColor: tokens.dark.colors.background.default.value, + textColor: tokens.dark.colors.text.default.value, + }, + parameters: { + backgrounds: { + default: 'dark', + values: [ + { name: 'dark', value: tokens.dark.colors.background.default.value }, + ], + }, + }, +}; diff --git a/docs/Typography.mdx b/docs/Typography.mdx index 5f9040a6..74a39f3f 100644 --- a/docs/Typography.mdx +++ b/docs/Typography.mdx @@ -1,7 +1,5 @@ import { Meta, Canvas, Story } from '@storybook/addon-docs'; -import tokens from '../src/figma/tokens.json'; - # Typography diff --git a/docs/Typography.stories.tsx b/docs/Typography.stories.tsx index 433842e3..f57fd7ef 100644 --- a/docs/Typography.stories.tsx +++ b/docs/Typography.stories.tsx @@ -1,4 +1,5 @@ -import { ComponentStory, ComponentMeta } from '@storybook/react'; +import React from 'react'; +import { StoryFn, Meta } from '@storybook/react'; import { typography } from '../src/js/typography'; import { fontSizes } from '../src/js/typography/fontSizes'; @@ -18,9 +19,9 @@ export default { page: README, }, }, -} as ComponentMeta; +} as Meta; -export const FontFamily: ComponentStory = (...args) => { +export const FontFamily: StoryFn = (...args) => { const styles = { displayMD: { fontFamily: fontFamilies.euclidCircularB, @@ -39,7 +40,7 @@ export const FontFamily: ComponentStory = (...args) => { ); }; -export const SmallScreen: ComponentStory = (...args) => { +export const SmallScreen: StoryFn = (...args) => { const smallScreenFontSizeBase = 16; const styles = { displayMD: { @@ -208,7 +209,7 @@ export const SmallScreen: ComponentStory = (...args) => { ); }; -export const LargeScreen: ComponentStory = (...args) => { +export const LargeScreen: StoryFn = (...args) => { const largeScreenFontSizeBase = 16; const styles = { displayMD: { @@ -377,7 +378,7 @@ export const LargeScreen: ComponentStory = (...args) => { ); }; -export const FontWeight: ComponentStory = (...args) => { +export const FontWeight: StoryFn = (...args) => { const styles = { regular: { fontFamily: fontFamilies.euclidCircularB, @@ -413,7 +414,7 @@ export const FontWeight: ComponentStory = (...args) => { ); }; -export const SmallScreenCSS: ComponentStory = (...args) => { +export const SmallScreenCSS: StoryFn = (...args) => { const fontBase = 16; const styles = { DisplayMD: { @@ -541,7 +542,7 @@ export const SmallScreenCSS: ComponentStory = (...args) => { ); }; -export const LargeScreenCSS: ComponentStory = (...args) => { +export const LargeScreenCSS: StoryFn = (...args) => { const fontBase = 16; const styles = { diff --git a/docs/components/ColorSwatchGroup/ColorSwatchGroup.tsx b/docs/components/ColorSwatchGroup/ColorSwatchGroup.tsx index 07feeef9..3d45823f 100644 --- a/docs/components/ColorSwatchGroup/ColorSwatchGroup.tsx +++ b/docs/components/ColorSwatchGroup/ColorSwatchGroup.tsx @@ -43,6 +43,7 @@ interface ColorSwatchGroupProps { */ name?: string; } + export const ColorSwatchGroup: FunctionComponent = ({ swatchData, borderColor,