From 574667e1cb1244bf50a23166dde06a7d2db8db20 Mon Sep 17 00:00:00 2001 From: georgewrmarshall Date: Tue, 21 Jun 2022 15:39:29 -0700 Subject: [PATCH 1/8] Adding shadow tokens --- .storybook/preview.js | 2 + docs/Shadows.mdx | 79 ++++ docs/Shadows.stories.tsx | 206 +++++++++ docs/components/Text/Text.tsx | 7 +- jest.config.js | 6 +- src/css/design-tokens.css | 38 +- src/figma/tokens.json | 136 ++++++ src/js/colors/colors.test.ts | 452 -------------------- src/js/colors/colors.ts | 1 + src/js/index.ts | 1 + src/js/themes/darkTheme/colors.test.ts | 30 ++ src/js/themes/darkTheme/colors.ts | 5 + src/js/themes/darkTheme/darkTheme.test.ts | 12 + src/js/themes/darkTheme/darkTheme.ts | 2 + src/js/themes/darkTheme/shadows.test.ts | 86 ++++ src/js/themes/darkTheme/shadows.ts | 43 ++ src/js/themes/lightTheme/colors.test.ts | 30 ++ src/js/themes/lightTheme/colors.ts | 5 + src/js/themes/lightTheme/lightTheme.test.ts | 12 + src/js/themes/lightTheme/lightTheme.ts | 2 + src/js/themes/lightTheme/shadows.test.ts | 86 ++++ src/js/themes/lightTheme/shadows.ts | 43 ++ src/js/themes/types.ts | 36 ++ 23 files changed, 846 insertions(+), 474 deletions(-) create mode 100644 docs/Shadows.mdx create mode 100644 docs/Shadows.stories.tsx delete mode 100644 src/js/colors/colors.test.ts create mode 100644 src/js/themes/darkTheme/shadows.test.ts create mode 100644 src/js/themes/darkTheme/shadows.ts create mode 100644 src/js/themes/lightTheme/shadows.test.ts create mode 100644 src/js/themes/lightTheme/shadows.ts diff --git a/.storybook/preview.js b/.storybook/preview.js index 40f87c5e..aa2ffa9e 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,3 +1,5 @@ +import '../src/css/design-tokens.css'; + export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { diff --git a/docs/Shadows.mdx b/docs/Shadows.mdx new file mode 100644 index 00000000..6b2208eb --- /dev/null +++ b/docs/Shadows.mdx @@ -0,0 +1,79 @@ +import { Meta, Canvas, Story } from '@storybook/addon-docs'; +import LinkTo from '@storybook/addon-links/react'; + + + +# Shadows + +Shadows convey elevation of elements on a surface + +## Size + +There are 4 different sizes of shadow in MetaMask. + + + + + +| Size | JS | CSS | +| ------ | ----------------- | ----------------------- | +| **XS** | `shadows.size.xs` | `var(--shadow-size-xs)` | +| **SM** | `shadows.size.sm` | `var(--shadow-size-sm)` | +| **MD** | `shadows.size.md` | `var(--shadow-size-md)` | +| **LG** | `shadows.size.lg` | `var(--shadow-size-lg)` | + +## 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 + + + + + +| Color | JS | CSS | +| ----------- | ----------------------- | ----------------------------- | +| **neutral** | `colors.shadow.default` | `var(--color-shadow-default)` | +| **primary** | `colors.primary.shadow` | `var(--color-primary-shadow)` | +| **danger** | `colors.error.shadow` | `var(--color-error-shadow)` | + +## Usage + +Using both size and color tokens, different shadows can be applied to components. + + + + + +| Component | JS | CSS | +| ------------------------ | ------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| **Card** | `cardShadow: {...shadows.size.xs }` | `box-shadow: var(--shadow-size-xs) var(--color-shadow-default);` | +| **Dropdown** | `dropdownShadow: { ...shadows.size.sm }` | `box-shadow: var(--shadow-size-sm) var(--color-shadow-default);` | +| **Toast** | `toastShadow: { ...shadows.size.md }` | `box-shadow: var(--shadow-size-md) var(--color-shadow-default);` | +| **Modal** | `modalShadow: { ...shadows.size.lg }` | `box-shadow: var(--shadow-size-lg) var(--color-shadow-default);` | +| **Button Primary Hover** | `buttonPrimaryHover: { ...shadows.size.sm, shadowColor: colors.primary.shadow}` | `box-shadow: var(--shadow-size-sm) var(--color-primary-shadow);` | +| **Button Danger Hover** | `buttonDangerHover: { ...shadows.size.sm, shadowColor: colors.primary.shadow}` | `box-shadow: var(--shadow-size-sm) var(--color-error-shadow);` | + +**NOTE: The CSS-in-JS `shadows.size` objects for React Native contain all the correct tokens for neutral shadows. For primary and error/danger shadows change the `shadowColor` key** + +Example shape of the `xs` shadow size object from `shadows` + +``` +size: { + xs: { + shadowColor: colors.light.shadow.default, + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 1, + shadowRadius: 4, + }, + ... +} + +``` + +## References + +- [Figma Light Theme Colors Library(Shadows Page)](https://www.figma.com/file/kdFzEC7xzSNw7cXteqgzDW/%5BColor%5D-Light-Theme?node-id=753%3A719)(internal use only) +- [Figma Dark Theme Colors Library(Shadows Page)](https://www.figma.com/file/rLKsoqpjyoKauYnFDcBIbO/%5BColor%5D-Dark-Theme?node-id=522%3A1022)(internal use only) diff --git a/docs/Shadows.stories.tsx b/docs/Shadows.stories.tsx new file mode 100644 index 00000000..930ee701 --- /dev/null +++ b/docs/Shadows.stories.tsx @@ -0,0 +1,206 @@ +import React from 'react'; +import { Text } from './components'; + +import README from './Shadows.mdx'; + +export default { + title: 'Shadows/Shadows', + parameters: { + docs: { + page: README, + }, + }, +}; + +interface ShadowSwatchProps { + children: any; + style?: object; +} + +const ShadowSwatch = ({ children, style }: ShadowSwatchProps) => ( +
+ {children} +
+); + +export const Size = () => { + return ( +
+ + + XS + + + + + SM + + + + + MD + + + + + LG + + +
+ ); +}; + +export const Color = () => { + return ( +
+ + + Neutral + + + + + Primary + + + + + Danger + + +
+ ); +}; + +export const Usage = () => { + return ( +
+
+ + + Card + + + + + Dropdown + + + + + Toast + + + + + Modal + + +
+
+ + + Button Primary Hover + + + + + Button Danger Hover + + +
+
+ ); +}; diff --git a/docs/components/Text/Text.tsx b/docs/components/Text/Text.tsx index 49eca278..74cedf1d 100644 --- a/docs/components/Text/Text.tsx +++ b/docs/components/Text/Text.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { fontFamilies } from '../../../src/js/typography/fontFamilies'; interface Props { /** @@ -24,5 +25,9 @@ export const Text = ({ as, }: TextProps) => { const Component = as || 'span'; - return {children}; + return ( + + {children} + + ); }; diff --git a/jest.config.js b/jest.config.js index c0390703..3d7ced0c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,11 @@ module.exports = { collectCoverage: true, // Ensures that we collect coverage from all source files, not just tested // ones. - collectCoverageFrom: ['./src/**/*.ts', '!./src/**/*index.ts'], + collectCoverageFrom: [ + './src/**/*.ts', + '!./src/**/*index.ts', + '!./src/js/colors/colors.ts', + ], coverageReporters: ['text', 'html'], coverageThreshold: { global: { diff --git a/src/css/design-tokens.css b/src/css/design-tokens.css index 2bad19b9..eb7053da 100644 --- a/src/css/design-tokens.css +++ b/src/css/design-tokens.css @@ -97,31 +97,26 @@ --letter-spacing-0: 0; --letter-spacing-1: 2.5%; /* typography scale small screen */ - --typography-s-display-md-font-family: var(--font-family-euclid-circular-b); --typography-s-display-md-font-size: var(--font-size-7); --typography-s-display-md-line-height: var(--line-height-4); --typography-s-display-md-font-weight: var(--font-weight-medium); --typography-s-display-md-letter-spacing: var(--letter-spacing-0); - --typography-s-heading-lg-font-family: var(--font-family-euclid-circular-b); --typography-s-heading-lg-font-size: var(--font-size-6); --typography-s-heading-lg-line-height: var(--line-height-5); --typography-s-heading-lg-font-weight: var(--font-weight-bold); --typography-s-heading-lg-letter-spacing: var(--letter-spacing-0); - --typography-s-heading-md-font-family: var(--font-family-euclid-circular-b); --typography-s-heading-md-font-size: var(--font-size-5); --typography-s-heading-md-line-height: var(--line-height-5); --typography-s-heading-md-font-weight: var(--font-weight-bold); --typography-s-heading-md-letter-spacing: var(--letter-spacing-0); - --typography-s-heading-sm-font-family: var(--font-family-euclid-circular-b); --typography-s-heading-sm-font-size: var(--font-size-4); --typography-s-heading-sm-line-height: var(--line-height-6); --typography-s-heading-sm-font-weight: var(--font-weight-regular); --typography-s-heading-sm-letter-spacing: var(--letter-spacing-0); - --typography-s-heading-sm-regular-font-family: var( --font-family-euclid-circular-b ); @@ -129,31 +124,26 @@ --typography-s-heading-sm-regular-line-height: var(--line-height-6); --typography-s-heading-sm-regular-font-weight: var(--font-weight-regular); --typography-s-heading-sm-regular-letter-spacing: var(--letter-spacing-0); - --typography-s-body-md-bold-font-family: var(--font-family-euclid-circular-b); --typography-s-body-md-bold-font-size: var(--font-size-3); --typography-s-body-md-bold-line-height: var(--line-height-6); --typography-s-body-md-bold-font-weight: var(--font-weight-bold); --typography-s-body-md-bold-letter-spacing: var(--letter-spacing-0); - --typography-s-body-md-font-family: var(--font-family-euclid-circular-b); --typography-s-body-md-font-size: var(--font-size-3); --typography-s-body-md-line-height: var(--line-height-6); --typography-s-body-md-font-weight: var(--font-weight-regular); --typography-s-body-md-letter-spacing: var(--letter-spacing-0); - --typography-s-body-sm-bold-font-family: var(--font-family-euclid-circular-b); --typography-s-body-sm-bold-font-size: var(--font-size-2); --typography-s-body-sm-bold-line-height: var(--line-height-8); --typography-s-body-sm-bold-font-weight: var(--font-weight-bold); --typography-s-body-sm-bold-letter-spacing: var(--letter-spacing-0); - --typography-s-body-sm-font-family: var(--font-family-euclid-circular-b); --typography-s-body-sm-font-size: var(--font-size-2); --typography-s-body-sm-line-height: var(--line-height-8); --typography-s-body-sm-font-weight: var(--font-weight-regular); --typography-s-body-sm-letter-spacing: var(--letter-spacing-0); - --typography-s-body-xs-font-family: var(--font-family-euclid-circular-b); --typography-s-body-xs-font-size: var(--font-size-1); --typography-s-body-xs-line-height: var(--line-height-7); @@ -161,31 +151,26 @@ --typography-s-body-xs-letter-spacing: var(--letter-spacing-0); /* typography scale large screen */ - --typography-l-display-md-font-family: var(--font-family-euclid-circular-b); --typography-l-display-md-font-size: var(--font-size-8); --typography-l-display-md-line-height: var(--line-height-2); --typography-l-display-md-font-weight: var(--font-weight-medium); --typography-l-display-md-letter-spacing: var(--letter-spacing-0); - --typography-l-heading-lg-font-family: var(--font-family-euclid-circular-b); --typography-l-heading-lg-font-size: var(--font-size-7); --typography-l-heading-lg-line-height: var(--line-height-4); --typography-l-heading-lg-font-weight: var(--font-weight-bold); --typography-l-heading-lg-letter-spacing: var(--letter-spacing-0); - --typography-l-heading-md-font-family: var(--font-family-euclid-circular-b); --typography-l-heading-md-font-size: var(--font-size-6); --typography-l-heading-md-line-height: var(--line-height-5); --typography-l-heading-md-font-weight: var(--font-weight-bold); --typography-l-heading-md-letter-spacing: var(--letter-spacing-0); - --typography-l-heading-sm-font-family: var(--font-family-euclid-circular-b); --typography-l-heading-sm-font-size: var(--font-size-5); --typography-l-heading-sm-line-height: var(--line-height-5); --typography-l-heading-sm-font-weight: var(--font-weight-bold); --typography-l-heading-sm-letter-spacing: var(--letter-spacing-0); - --typography-l-heading-sm-regular-font-family: var( --font-family-euclid-circular-b ); @@ -193,36 +178,36 @@ --typography-l-heading-sm-regular-line-height: var(--line-height-5); --typography-l-heading-sm-regular-font-weight: var(--font-weight-bold); --typography-l-heading-sm-regular-letter-spacing: var(--letter-spacing-0); - --typography-l-body-md-bold-font-family: var(--font-family-euclid-circular-b); --typography-l-body-md-bold-font-size: var(--font-size-4); --typography-l-body-md-bold-line-height: var(--line-height-6); --typography-l-body-md-bold-font-weight: var(--font-weight-bold); --typography-l-body-md-bold-letter-spacing: var(--letter-spacing-0); - --typography-l-body-md-font-family: var(--font-family-euclid-circular-b); --typography-l-body-md-font-size: var(--font-size-4); --typography-l-body-md-line-height: var(--line-height-6); --typography-l-body-md-font-weight: var(--font-weight-regular); --typography-l-body-md-letter-spacing: var(--letter-spacing-0); - --typography-l-body-sm-bold-font-family: var(--font-family-euclid-circular-b); --typography-l-body-sm-bold-font-size: var(--font-size-3); --typography-l-body-sm-bold-line-height: var(--line-height-6); --typography-l-body-sm-bold-font-weight: var(--font-weight-bold); --typography-l-body-sm-bold-letter-spacing: var(--letter-spacing-0); - --typography-l-body-sm-font-family: var(--font-family-euclid-circular-b); --typography-l-body-sm-font-size: var(--font-size-3); --typography-l-body-sm-line-height: var(--line-height-6); --typography-l-body-sm-font-weight: var(--font-weight-regular); --typography-l-body-sm-letter-spacing: var(--letter-spacing-0); - --typography-l-body-xs-font-family: var(--font-family-euclid-circular-b); --typography-l-body-xs-font-size: var(--font-size-2); --typography-l-body-xs-line-height: var(--line-height-7); --typography-l-body-xs-font-weight: var(--font-weight-regular); --typography-l-body-xs-letter-spacing: var(--letter-spacing-0); + /* shadow */ + --shadow-size-xs: 0 2px 4px 0; + --shadow-size-sm: 0 2px 8px 0; + --shadow-size-md: 0 2px 16px 0; + --shadow-size-lg: 0 2px 40px 0; } /* @@ -245,11 +230,13 @@ --color-overlay-default: #00000099; --color-overlay-alternative: #000000cc; --color-overlay-inverse: var(--brand-colors-white-white010); + --color-shadow-default: #0000001a; --color-primary-default: var(--brand-colors-blue-blue500); --color-primary-alternative: var(--brand-colors-blue-blue600); --color-primary-muted: #037dd619; --color-primary-inverse: var(--brand-colors-white-white010); --color-primary-disabled: #037dd680; + --color-primary-shadow: #037dd633; --color-secondary-default: var(--brand-colors-orange-orange500); --color-secondary-alternative: var(--brand-colors-orange-orange600); --color-secondary-muted: #f66a0a19; @@ -260,6 +247,7 @@ --color-error-muted: #d73a4919; --color-error-inverse: var(--brand-colors-white-white010); --color-error-disabled: #d73a4980; + --color-error-shadow: #d73a4966; --color-warning-default: var(--brand-colors-orange-orange500); --color-warning-alternative: var(--brand-colors-yellow-yellow600); --color-warning-muted: #ffd33d19; @@ -275,6 +263,13 @@ --color-info-muted: #037dd619; --color-info-inverse: var(--brand-colors-white-white010); --color-info-disabled: #037dd680; + + /* Components */ + /* button */ + --component-button-primary-shadow: var(--shadow-size-sm) + var(--color-primary-shadow); + --component-button-danger-shadow: var(--shadow-size-sm) + var(--color-error-shadow); } /** @@ -295,12 +290,14 @@ --color-border-muted: var(--brand-colors-grey-grey700); --color-overlay-default: #00000099; --color-overlay-alternative: #000000cc; + --color-shadow-default: #00000080; --color-overlay-inverse: var(--brand-colors-white-white010); --color-primary-default: var(--brand-colors-blue-blue400); --color-primary-alternative: var(--brand-colors-blue-blue300); --color-primary-muted: #1098fc26; --color-primary-inverse: var(--brand-colors-white-white010); --color-primary-disabled: #1098fc80; + --color-primary-shadow: #037dd633; --color-secondary-default: var(--brand-colors-orange-orange400); --color-secondary-alternative: var(--brand-colors-orange-orange300); --color-secondary-muted: #f8883b26; @@ -311,6 +308,7 @@ --color-error-muted: #d73a4926; --color-error-inverse: var(--brand-colors-white-white010); --color-error-disabled: #d73a4980; + --color-error-shadow: #d73a4966; --color-warning-default: var(--brand-colors-yellow-yellow500); --color-warning-alternative: var(--brand-colors-yellow-yellow400); --color-warning-muted: #ffd33d26; diff --git a/src/figma/tokens.json b/src/figma/tokens.json index 9512cc77..ef71d96d 100644 --- a/src/figma/tokens.json +++ b/src/figma/tokens.json @@ -935,6 +935,74 @@ "type": "color" } } + }, + "shadows": { + "xs": { + "value": { + "color": "#0000001a", + "type": "dropShadow", + "x": 0, + "y": 2, + "blur": 4, + "spread": 0 + }, + "type": "boxShadow" + }, + "sm": { + "value": { + "color": "#0000001a", + "type": "dropShadow", + "x": 0, + "y": 2, + "blur": 8, + "spread": 0 + }, + "type": "boxShadow" + }, + "md": { + "value": { + "color": "#0000001a", + "type": "dropShadow", + "x": 0, + "y": 2, + "blur": 16, + "spread": 0 + }, + "type": "boxShadow" + }, + "lg": { + "value": { + "color": "#0000001a", + "type": "dropShadow", + "x": 0, + "y": 8, + "blur": 40, + "spread": 0 + }, + "type": "boxShadow" + }, + "primary": { + "value": { + "color": "#037dd633", + "type": "dropShadow", + "x": 0, + "y": 7, + "blur": 42, + "spread": 0 + }, + "type": "boxShadow" + }, + "error": { + "value": { + "color": "#d73a4966", + "type": "dropShadow", + "x": 0, + "y": 7, + "blur": 42, + "spread": 0 + }, + "type": "boxShadow" + } } }, "dark": { @@ -1176,6 +1244,74 @@ "type": "color" } } + }, + "shadows": { + "xs": { + "value": { + "color": "#00000066", + "type": "dropShadow", + "x": 0, + "y": 2, + "blur": 4, + "spread": 0 + }, + "type": "boxShadow" + }, + "sm": { + "value": { + "color": "#00000066", + "type": "dropShadow", + "x": 0, + "y": 2, + "blur": 8, + "spread": 0 + }, + "type": "boxShadow" + }, + "md": { + "value": { + "color": "#00000066", + "type": "dropShadow", + "x": 0, + "y": 2, + "blur": 16, + "spread": 0 + }, + "type": "boxShadow" + }, + "lg": { + "value": { + "color": "#00000066", + "type": "dropShadow", + "x": 0, + "y": 8, + "blur": 40, + "spread": 0 + }, + "type": "boxShadow" + }, + "primary": { + "value": { + "color": "#1098FC66", + "type": "dropShadow", + "x": 0, + "y": 7, + "blur": 42, + "spread": 0 + }, + "type": "boxShadow" + }, + "error": { + "value": { + "color": "#D73A4966", + "type": "dropShadow", + "x": 0, + "y": 7, + "blur": 42, + "spread": 0 + }, + "type": "boxShadow" + } } }, "$themes": [] diff --git a/src/js/colors/colors.test.ts b/src/js/colors/colors.test.ts deleted file mode 100644 index 467951c6..00000000 --- a/src/js/colors/colors.test.ts +++ /dev/null @@ -1,452 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */ -import { colors as importableColors } from '.'; - -const designTokens = require('../../figma/tokens.json'); - -describe('Light Theme Colors', () => { - it('js tokens for background.default matches figma tokens background.default', () => { - expect(importableColors.light.background.default).toStrictEqual( - designTokens.light.colors.background.default.value, - ); - }); - - it('js tokens for background.alternative matches figma tokens background.alternative', () => { - expect(importableColors.light.background.alternative).toStrictEqual( - designTokens.light.colors.background.alternative.value, - ); - }); - - it('js tokens for text.default matches figma tokens text.default', () => { - expect(importableColors.light.text.default).toStrictEqual( - designTokens.light.colors.text.default.value, - ); - }); - - it('js tokens for text.alternative matches figma tokens text.alternative', () => { - expect(importableColors.light.text.alternative).toStrictEqual( - designTokens.light.colors.text.alternative.value, - ); - }); - - it('js tokens for text.muted matches figma tokens text.muted', () => { - expect(importableColors.light.text.muted).toStrictEqual( - designTokens.light.colors.text.muted.value, - ); - }); - - it('js tokens for icon.default matches figma tokens icon.default', () => { - expect(importableColors.light.icon.default).toStrictEqual( - designTokens.light.colors.icon.default.value, - ); - }); - - it('js tokens for icon.alternative matches figma tokens icon.alternative', () => { - expect(importableColors.light.icon.alternative).toStrictEqual( - designTokens.light.colors.icon.alternative.value, - ); - }); - - it('js tokens for icon.muted matches figma tokens icon.muted', () => { - expect(importableColors.light.icon.muted).toStrictEqual( - designTokens.light.colors.icon.muted.value, - ); - }); - - it('js tokens for border.default matches figma tokens border.default', () => { - expect(importableColors.light.border.default).toStrictEqual( - designTokens.light.colors.border.default.value, - ); - }); - - it('js tokens for border.muted matches figma tokens border.muted', () => { - expect(importableColors.light.border.muted).toStrictEqual( - designTokens.light.colors.border.muted.value, - ); - }); - - it('js tokens for overlay.default matches figma tokens overlay.default', () => { - expect(importableColors.light.overlay.default).toStrictEqual( - designTokens.light.colors.overlay.default.value, - ); - }); - - it('js tokens for overlay.alternative matches figma tokens overlay.alternative', () => { - expect(importableColors.light.overlay.alternative).toStrictEqual( - designTokens.light.colors.overlay.alternative.value, - ); - }); - - it('js tokens for overlay.inverse matches figma tokens overlay.inverse', () => { - expect(importableColors.light.overlay.inverse).toStrictEqual( - designTokens.light.colors.overlay.inverse.value, - ); - }); - - it('js tokens for primary.default matches figma tokens primary.default', () => { - expect(importableColors.light.primary.default).toStrictEqual( - designTokens.light.colors.primary.default.value, - ); - }); - - it('js tokens for primary.alternative matches figma tokens primary.alternative', () => { - expect(importableColors.light.primary.alternative).toStrictEqual( - designTokens.light.colors.primary.alternative.value, - ); - }); - - it('js tokens for primary.muted matches figma tokens primary.muted', () => { - expect(importableColors.light.primary.muted).toStrictEqual( - designTokens.light.colors.primary.muted.value, - ); - }); - - it('js tokens for primary.inverse matches figma tokens primary.inverse', () => { - expect(importableColors.light.primary.inverse).toStrictEqual( - designTokens.light.colors.primary.inverse.value, - ); - }); - - it('js tokens for secondary.default matches figma tokens secondary.default', () => { - expect(importableColors.light.secondary.default).toStrictEqual( - designTokens.light.colors.secondary.default.value, - ); - }); - - it('js tokens for secondary.alternative matches figma tokens secondary.alternative', () => { - expect(importableColors.light.secondary.alternative).toStrictEqual( - designTokens.light.colors.secondary.alternative.value, - ); - }); - - it('js tokens for secondary.muted matches figma tokens secondary.muted', () => { - expect(importableColors.light.secondary.muted).toStrictEqual( - designTokens.light.colors.secondary.muted.value, - ); - }); - - it('js tokens for secondary.inverse matches figma tokens secondary.inverse', () => { - expect(importableColors.light.secondary.inverse).toStrictEqual( - designTokens.light.colors.secondary.inverse.value, - ); - }); - - it('js tokens for error.default matches figma tokens error.default', () => { - expect(importableColors.light.error.default).toStrictEqual( - designTokens.light.colors.error.default.value, - ); - }); - - it('js tokens for error.alternative matches figma tokens error.alternative', () => { - expect(importableColors.light.error.alternative).toStrictEqual( - designTokens.light.colors.error.alternative.value, - ); - }); - - it('js tokens for error.muted matches figma tokens error.muted', () => { - expect(importableColors.light.error.muted).toStrictEqual( - designTokens.light.colors.error.muted.value, - ); - }); - - it('js tokens for error.inverse matches figma tokens error.inverse', () => { - expect(importableColors.light.error.inverse).toStrictEqual( - designTokens.light.colors.error.inverse.value, - ); - }); - - it('js tokens for warning.default matches figma tokens warning.default', () => { - expect(importableColors.light.warning.default).toStrictEqual( - designTokens.light.colors.warning.default.value, - ); - }); - - it('js tokens for warning.alternative matches figma tokens warning.alternative', () => { - expect(importableColors.light.warning.alternative).toStrictEqual( - designTokens.light.colors.warning.alternative.value, - ); - }); - - it('js tokens for warning.muted matches figma tokens warning.muted', () => { - expect(importableColors.light.warning.muted).toStrictEqual( - designTokens.light.colors.warning.muted.value, - ); - }); - - it('js tokens for warning.inverse matches figma tokens warning.inverse', () => { - expect(importableColors.light.warning.inverse).toStrictEqual( - designTokens.light.colors.warning.inverse.value, - ); - }); - - it('js tokens for success.default matches figma tokens success.default', () => { - expect(importableColors.light.success.default).toStrictEqual( - designTokens.light.colors.success.default.value, - ); - }); - - it('js tokens for success.alternative matches figma tokens success.alternative', () => { - expect(importableColors.light.success.alternative).toStrictEqual( - designTokens.light.colors.success.alternative.value, - ); - }); - - it('js tokens for success.muted matches figma tokens success.muted', () => { - expect(importableColors.light.success.muted).toStrictEqual( - designTokens.light.colors.success.muted.value, - ); - }); - - it('js tokens for success.inverse matches figma tokens success.inverse', () => { - expect(importableColors.light.success.inverse).toStrictEqual( - designTokens.light.colors.success.inverse.value, - ); - }); - - it('js tokens for info.default matches figma tokens info.default', () => { - expect(importableColors.light.info.default).toStrictEqual( - designTokens.light.colors.info.default.value, - ); - }); - - it('js tokens for info.alternative matches figma tokens info.alternative', () => { - expect(importableColors.light.info.alternative).toStrictEqual( - designTokens.light.colors.info.alternative.value, - ); - }); - - it('js tokens for info.muted matches figma tokens info.muted', () => { - expect(importableColors.light.info.muted).toStrictEqual( - designTokens.light.colors.info.muted.value, - ); - }); - - it('js tokens for info.inverse matches figma tokens info.inverse', () => { - expect(importableColors.light.info.inverse).toStrictEqual( - designTokens.light.colors.info.inverse.value, - ); - }); -}); - -describe('Dark Theme Colors', () => { - it('js tokens for background.default matches figma tokens background.default', () => { - expect(importableColors.dark.background.default).toStrictEqual( - designTokens.dark.colors.background.default.value, - ); - }); - - it('js tokens for background.alternative matches figma tokens background.alternative', () => { - expect(importableColors.dark.background.alternative).toStrictEqual( - designTokens.dark.colors.background.alternative.value, - ); - }); - - it('js tokens for text.default matches figma tokens text.default', () => { - expect(importableColors.dark.text.default).toStrictEqual( - designTokens.dark.colors.text.default.value, - ); - }); - - it('js tokens for text.alternative matches figma tokens text.alternative', () => { - expect(importableColors.dark.text.alternative).toStrictEqual( - designTokens.dark.colors.text.alternative.value, - ); - }); - - it('js tokens for text.muted matches figma tokens text.muted', () => { - expect(importableColors.dark.text.muted).toStrictEqual( - designTokens.dark.colors.text.muted.value, - ); - }); - - it('js tokens for icon.default matches figma tokens icon.default', () => { - expect(importableColors.dark.icon.default).toStrictEqual( - designTokens.dark.colors.icon.default.value, - ); - }); - - it('js tokens for icon.alternative matches figma tokens icon.alternative', () => { - expect(importableColors.dark.icon.alternative).toStrictEqual( - designTokens.dark.colors.icon.alternative.value, - ); - }); - - it('js tokens for icon.muted matches figma tokens icon.muted', () => { - expect(importableColors.dark.icon.muted).toStrictEqual( - designTokens.dark.colors.icon.muted.value, - ); - }); - - it('js tokens for border.default matches figma tokens border.default', () => { - expect(importableColors.dark.border.default).toStrictEqual( - designTokens.dark.colors.border.default.value, - ); - }); - - it('js tokens for border.muted matches figma tokens border.muted', () => { - expect(importableColors.dark.border.muted).toStrictEqual( - designTokens.dark.colors.border.muted.value, - ); - }); - - it('js tokens for overlay.default matches figma tokens overlay.default', () => { - expect(importableColors.dark.overlay.default).toStrictEqual( - designTokens.dark.colors.overlay.default.value, - ); - }); - - it('js tokens for overlay.alternative matches figma tokens overlay.alternative', () => { - expect(importableColors.dark.overlay.alternative).toStrictEqual( - designTokens.dark.colors.overlay.alternative.value, - ); - }); - - it('js tokens for overlay.inverse matches figma tokens overlay.inverse', () => { - expect(importableColors.dark.overlay.inverse).toStrictEqual( - designTokens.dark.colors.overlay.inverse.value, - ); - }); - - it('js tokens for primary.default matches figma tokens primary.default', () => { - expect(importableColors.dark.primary.default).toStrictEqual( - designTokens.dark.colors.primary.default.value, - ); - }); - - it('js tokens for primary.alternative matches figma tokens primary.alternative', () => { - expect(importableColors.dark.primary.alternative).toStrictEqual( - designTokens.dark.colors.primary.alternative.value, - ); - }); - - it('js tokens for primary.muted matches figma tokens primary.muted', () => { - expect(importableColors.dark.primary.muted).toStrictEqual( - designTokens.dark.colors.primary.muted.value, - ); - }); - - it('js tokens for primary.inverse matches figma tokens primary.inverse', () => { - expect(importableColors.dark.primary.inverse).toStrictEqual( - designTokens.dark.colors.primary.inverse.value, - ); - }); - - it('js tokens for secondary.default matches figma tokens secondary.default', () => { - expect(importableColors.dark.secondary.default).toStrictEqual( - designTokens.dark.colors.secondary.default.value, - ); - }); - - it('js tokens for secondary.alternative matches figma tokens secondary.alternative', () => { - expect(importableColors.dark.secondary.alternative).toStrictEqual( - designTokens.dark.colors.secondary.alternative.value, - ); - }); - - it('js tokens for secondary.muted matches figma tokens secondary.muted', () => { - expect(importableColors.dark.secondary.muted).toStrictEqual( - designTokens.dark.colors.secondary.muted.value, - ); - }); - - it('js tokens for secondary.inverse matches figma tokens secondary.inverse', () => { - expect(importableColors.dark.secondary.inverse).toStrictEqual( - designTokens.dark.colors.secondary.inverse.value, - ); - }); - - it('js tokens for error.default matches figma tokens error.default', () => { - expect(importableColors.dark.error.default).toStrictEqual( - designTokens.dark.colors.error.default.value, - ); - }); - - it('js tokens for error.alternative matches figma tokens error.alternative', () => { - expect(importableColors.dark.error.alternative).toStrictEqual( - designTokens.dark.colors.error.alternative.value, - ); - }); - - it('js tokens for error.muted matches figma tokens error.muted', () => { - expect(importableColors.dark.error.muted).toStrictEqual( - designTokens.dark.colors.error.muted.value, - ); - }); - - it('js tokens for error.inverse matches figma tokens error.inverse', () => { - expect(importableColors.dark.error.inverse).toStrictEqual( - designTokens.dark.colors.error.inverse.value, - ); - }); - - it('js tokens for warning.default matches figma tokens warning.default', () => { - expect(importableColors.dark.warning.default).toStrictEqual( - designTokens.dark.colors.warning.default.value, - ); - }); - - it('js tokens for warning.alternative matches figma tokens warning.alternative', () => { - expect(importableColors.dark.warning.alternative).toStrictEqual( - designTokens.dark.colors.warning.alternative.value, - ); - }); - - it('js tokens for warning.muted matches figma tokens warning.muted', () => { - expect(importableColors.dark.warning.muted).toStrictEqual( - designTokens.dark.colors.warning.muted.value, - ); - }); - - it('js tokens for warning.inverse matches figma tokens warning.inverse', () => { - expect(importableColors.dark.warning.inverse).toStrictEqual( - designTokens.dark.colors.warning.inverse.value, - ); - }); - - it('js tokens for success.default matches figma tokens success.default', () => { - expect(importableColors.dark.success.default).toStrictEqual( - designTokens.dark.colors.success.default.value, - ); - }); - - it('js tokens for success.alternative matches figma tokens success.alternative', () => { - expect(importableColors.dark.success.alternative).toStrictEqual( - designTokens.dark.colors.success.alternative.value, - ); - }); - - it('js tokens for success.muted matches figma tokens success.muted', () => { - expect(importableColors.dark.success.muted).toStrictEqual( - designTokens.dark.colors.success.muted.value, - ); - }); - - it('js tokens for success.inverse matches figma tokens success.inverse', () => { - expect(importableColors.dark.success.inverse).toStrictEqual( - designTokens.dark.colors.success.inverse.value, - ); - }); - - it('js tokens for info.default matches figma tokens info.default', () => { - expect(importableColors.dark.info.default).toStrictEqual( - designTokens.dark.colors.info.default.value, - ); - }); - - it('js tokens for info.alternative matches figma tokens info.alternative', () => { - expect(importableColors.dark.info.alternative).toStrictEqual( - designTokens.dark.colors.info.alternative.value, - ); - }); - - it('js tokens for info.muted matches figma tokens info.muted', () => { - expect(importableColors.dark.info.muted).toStrictEqual( - designTokens.dark.colors.info.muted.value, - ); - }); - - it('js tokens for info.inverse matches figma tokens info.inverse', () => { - expect(importableColors.dark.info.inverse).toStrictEqual( - designTokens.dark.colors.info.inverse.value, - ); - }); -}); diff --git a/src/js/colors/colors.ts b/src/js/colors/colors.ts index 4ce9be11..296c475b 100644 --- a/src/js/colors/colors.ts +++ b/src/js/colors/colors.ts @@ -2,6 +2,7 @@ import { lightTheme, darkTheme } from '../themes'; /** * This object is DEPRECATED in favour of the theme objects + * jest ignores this file when testing coverage */ export const colors = { diff --git a/src/js/index.ts b/src/js/index.ts index 5fa681c3..cccb7b0f 100644 --- a/src/js/index.ts +++ b/src/js/index.ts @@ -5,3 +5,4 @@ export { darkTheme } from './themes'; // DEPRECATED in favor of importing theme objects above export { colors } from './colors'; export { typography } from './typography'; +export { shadows } from './shadows'; diff --git a/src/js/themes/darkTheme/colors.test.ts b/src/js/themes/darkTheme/colors.test.ts index c4802be5..bd9c3c10 100644 --- a/src/js/themes/darkTheme/colors.test.ts +++ b/src/js/themes/darkTheme/colors.test.ts @@ -82,6 +82,24 @@ describe('Dark Theme Colors', () => { ); }); + it('js tokens for shadow.default matches figma tokens dark.shadows.xs.value.color', () => { + expect(importableColors.shadow.default).toStrictEqual( + designTokens.dark.shadows.xs.value.color, + ); + + expect(importableColors.shadow.default).toStrictEqual( + designTokens.dark.shadows.sm.value.color, + ); + + expect(importableColors.shadow.default).toStrictEqual( + designTokens.dark.shadows.md.value.color, + ); + + expect(importableColors.shadow.default).toStrictEqual( + designTokens.dark.shadows.lg.value.color, + ); + }); + it('js tokens for primary.default matches figma tokens primary.default', () => { expect(importableColors.primary.default).toStrictEqual( designTokens.dark.colors.primary.default.value, @@ -106,6 +124,12 @@ describe('Dark Theme Colors', () => { ); }); + it('js tokens for primary.shadow matches figma tokens shadows.primary', () => { + expect(importableColors.primary.shadow).toStrictEqual( + designTokens.dark.shadows.primary.value.color, + ); + }); + it('js tokens for secondary.default matches figma tokens secondary.default', () => { expect(importableColors.secondary.default).toStrictEqual( designTokens.dark.colors.secondary.default.value, @@ -154,6 +178,12 @@ describe('Dark Theme Colors', () => { ); }); + it('js tokens for error.shadow matches figma tokens shadows.error', () => { + expect(importableColors.error.shadow).toStrictEqual( + designTokens.dark.shadows.error.value.color, + ); + }); + it('js tokens for warning.default matches figma tokens warning.default', () => { expect(importableColors.warning.default).toStrictEqual( designTokens.dark.colors.warning.default.value, diff --git a/src/js/themes/darkTheme/colors.ts b/src/js/themes/darkTheme/colors.ts index aa73a5b9..659d1693 100644 --- a/src/js/themes/darkTheme/colors.ts +++ b/src/js/themes/darkTheme/colors.ts @@ -28,12 +28,16 @@ export const colors: ThemeColors = { inverse: '#FCFCFC', alternative: '#000000CC', }, + shadow: { + default: '#00000066', + }, primary: { default: '#1098FC', alternative: '#43AEFC', muted: '#1098FC26', inverse: '#FCFCFC', disabled: '#1098FC80', + shadow: '#1098FC66', }, secondary: { default: '#F8883B', @@ -48,6 +52,7 @@ export const colors: ThemeColors = { muted: '#D73A4926', inverse: '#FCFCFC', disabled: '#D73A4980', + shadow: '#D73A4966', }, warning: { default: '#FFD33D', diff --git a/src/js/themes/darkTheme/darkTheme.test.ts b/src/js/themes/darkTheme/darkTheme.test.ts index 36ef1a57..07122c0f 100644 --- a/src/js/themes/darkTheme/darkTheme.test.ts +++ b/src/js/themes/darkTheme/darkTheme.test.ts @@ -15,4 +15,16 @@ describe('dark Theme', () => { designTokens.global.fontFamilies['euclid-circular-b'].value, ); }); + + it('shadow tokens are exported from darkTheme by checking first shadow size object', () => { + expect(darkTheme.shadows.size.xs).toStrictEqual({ + shadowColor: designTokens.dark.shadows.xs.value.color, + shadowOffset: { + width: designTokens.dark.shadows.xs.value.x, + height: designTokens.dark.shadows.xs.value.y, + }, + shadowOpacity: 1, + shadowRadius: designTokens.dark.shadows.xs.value.blur, + }); + }); }); diff --git a/src/js/themes/darkTheme/darkTheme.ts b/src/js/themes/darkTheme/darkTheme.ts index cd2f29a1..5084cbab 100644 --- a/src/js/themes/darkTheme/darkTheme.ts +++ b/src/js/themes/darkTheme/darkTheme.ts @@ -1,8 +1,10 @@ import { Theme } from '../types'; import { typography } from '../../typography'; import { colors } from './colors'; +import { shadows } from './shadows'; export const darkTheme: Theme = { colors, typography, + shadows, }; diff --git a/src/js/themes/darkTheme/shadows.test.ts b/src/js/themes/darkTheme/shadows.test.ts new file mode 100644 index 00000000..ec0cfda8 --- /dev/null +++ b/src/js/themes/darkTheme/shadows.test.ts @@ -0,0 +1,86 @@ +/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */ +import { shadows } from './shadows'; + +const designTokens = require('../../../figma/tokens.json'); + +describe('Shadows', () => { + it('js tokens shadows.size.xs matches figma tokens shadows.xs', () => { + expect(shadows.size.xs.shadowColor).toStrictEqual( + designTokens.dark.shadows.xs.value.color, + ); + + expect(shadows.size.xs.shadowOffset.width).toStrictEqual( + designTokens.dark.shadows.xs.value.x, + ); + + expect(shadows.size.xs.shadowOffset.height).toStrictEqual( + designTokens.dark.shadows.xs.value.y, + ); + + expect(shadows.size.xs.shadowOpacity).toStrictEqual(1); + + expect(shadows.size.xs.shadowRadius).toStrictEqual( + designTokens.dark.shadows.xs.value.blur, + ); + }); + + it('js tokens shadows.size.sm matches figma tokens shadows.sm', () => { + expect(shadows.size.sm.shadowColor).toStrictEqual( + designTokens.dark.shadows.sm.value.color, + ); + + expect(shadows.size.sm.shadowOffset.width).toStrictEqual( + designTokens.dark.shadows.sm.value.x, + ); + + expect(shadows.size.sm.shadowOffset.height).toStrictEqual( + designTokens.dark.shadows.sm.value.y, + ); + + expect(shadows.size.sm.shadowOpacity).toStrictEqual(1); + + expect(shadows.size.sm.shadowRadius).toStrictEqual( + designTokens.dark.shadows.sm.value.blur, + ); + }); + + it('js tokens shadows.size.md matches figma tokens shadows.md', () => { + expect(shadows.size.md.shadowColor).toStrictEqual( + designTokens.dark.shadows.md.value.color, + ); + + expect(shadows.size.md.shadowOffset.width).toStrictEqual( + designTokens.dark.shadows.md.value.x, + ); + + expect(shadows.size.md.shadowOffset.height).toStrictEqual( + designTokens.dark.shadows.md.value.y, + ); + + expect(shadows.size.md.shadowOpacity).toStrictEqual(1); + + expect(shadows.size.md.shadowRadius).toStrictEqual( + designTokens.dark.shadows.md.value.blur, + ); + }); + + it('js tokens shadows.size.lg matches figma tokens shadows.lg', () => { + expect(shadows.size.lg.shadowColor).toStrictEqual( + designTokens.dark.shadows.lg.value.color, + ); + + expect(shadows.size.lg.shadowOffset.width).toStrictEqual( + designTokens.dark.shadows.lg.value.x, + ); + + expect(shadows.size.lg.shadowOffset.height).toStrictEqual( + designTokens.dark.shadows.lg.value.y, + ); + + expect(shadows.size.lg.shadowOpacity).toStrictEqual(1); + + expect(shadows.size.lg.shadowRadius).toStrictEqual( + designTokens.dark.shadows.lg.value.blur, + ); + }); +}); diff --git a/src/js/themes/darkTheme/shadows.ts b/src/js/themes/darkTheme/shadows.ts new file mode 100644 index 00000000..341b36b8 --- /dev/null +++ b/src/js/themes/darkTheme/shadows.ts @@ -0,0 +1,43 @@ +import { ThemeShadows } from '../types'; +import { colors } from './colors'; + +export const shadows: ThemeShadows = { + size: { + xs: { + shadowColor: colors.shadow.default, + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 1, + shadowRadius: 4, + }, + sm: { + shadowColor: colors.shadow.default, + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 1, + shadowRadius: 8, + }, + md: { + shadowColor: colors.shadow.default, + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 1, + shadowRadius: 16, + }, + lg: { + shadowColor: colors.shadow.default, + shadowOffset: { + width: 0, + height: 8, + }, + shadowOpacity: 1, + shadowRadius: 40, + }, + }, +}; diff --git a/src/js/themes/lightTheme/colors.test.ts b/src/js/themes/lightTheme/colors.test.ts index 65bad480..f6eba244 100644 --- a/src/js/themes/lightTheme/colors.test.ts +++ b/src/js/themes/lightTheme/colors.test.ts @@ -82,6 +82,24 @@ describe('Light Theme Colors', () => { ); }); + it('js tokens for shadow.default matches figma tokens light.shadows.xs.value.color', () => { + expect(importableColors.shadow.default).toStrictEqual( + designTokens.light.shadows.xs.value.color, + ); + + expect(importableColors.shadow.default).toStrictEqual( + designTokens.light.shadows.sm.value.color, + ); + + expect(importableColors.shadow.default).toStrictEqual( + designTokens.light.shadows.md.value.color, + ); + + expect(importableColors.shadow.default).toStrictEqual( + designTokens.light.shadows.lg.value.color, + ); + }); + it('js tokens for primary.default matches figma tokens primary.default', () => { expect(importableColors.primary.default).toStrictEqual( designTokens.light.colors.primary.default.value, @@ -106,6 +124,12 @@ describe('Light Theme Colors', () => { ); }); + it('js tokens for primary.shadow matches figma tokens shadows.primary', () => { + expect(importableColors.primary.shadow).toStrictEqual( + designTokens.light.shadows.primary.value.color, + ); + }); + it('js tokens for secondary.default matches figma tokens secondary.default', () => { expect(importableColors.secondary.default).toStrictEqual( designTokens.light.colors.secondary.default.value, @@ -154,6 +178,12 @@ describe('Light Theme Colors', () => { ); }); + it('js tokens for error.shadow matches figma tokens shadows.error', () => { + expect(importableColors.error.shadow).toStrictEqual( + designTokens.light.shadows.error.value.color, + ); + }); + it('js tokens for warning.default matches figma tokens warning.default', () => { expect(importableColors.warning.default).toStrictEqual( designTokens.light.colors.warning.default.value, diff --git a/src/js/themes/lightTheme/colors.ts b/src/js/themes/lightTheme/colors.ts index f67427c9..b66b7496 100644 --- a/src/js/themes/lightTheme/colors.ts +++ b/src/js/themes/lightTheme/colors.ts @@ -28,12 +28,16 @@ export const colors: ThemeColors = { inverse: '#FCFCFC', alternative: '#000000CC', }, + shadow: { + default: '#0000001a', + }, primary: { default: '#037DD6', alternative: '#0260A4', muted: '#037DD619', inverse: '#FCFCFC', disabled: '#037DD680', + shadow: '#037dd633', }, secondary: { default: '#F66A0A', @@ -48,6 +52,7 @@ export const colors: ThemeColors = { muted: '#D73A4919', inverse: '#FCFCFC', disabled: '#D73A4980', + shadow: '#d73a4966', }, warning: { default: '#F66A0A', diff --git a/src/js/themes/lightTheme/lightTheme.test.ts b/src/js/themes/lightTheme/lightTheme.test.ts index 3bb72b98..207ecd5e 100644 --- a/src/js/themes/lightTheme/lightTheme.test.ts +++ b/src/js/themes/lightTheme/lightTheme.test.ts @@ -15,4 +15,16 @@ describe('Light Theme', () => { designTokens.global.fontFamilies['euclid-circular-b'].value, ); }); + + it('shadow tokens are exported from lightTheme by checking first shadow size object', () => { + expect(lightTheme.shadows.size.xs).toStrictEqual({ + shadowColor: designTokens.light.shadows.xs.value.color, + shadowOffset: { + width: designTokens.light.shadows.xs.value.x, + height: designTokens.light.shadows.xs.value.y, + }, + shadowOpacity: 1, + shadowRadius: designTokens.light.shadows.xs.value.blur, + }); + }); }); diff --git a/src/js/themes/lightTheme/lightTheme.ts b/src/js/themes/lightTheme/lightTheme.ts index b5fc19c1..f1ec1231 100644 --- a/src/js/themes/lightTheme/lightTheme.ts +++ b/src/js/themes/lightTheme/lightTheme.ts @@ -1,8 +1,10 @@ import { Theme } from '../types'; import { typography } from '../../typography'; +import { shadows } from './shadows'; import { colors } from './colors'; export const lightTheme: Theme = { colors, typography, + shadows, }; diff --git a/src/js/themes/lightTheme/shadows.test.ts b/src/js/themes/lightTheme/shadows.test.ts new file mode 100644 index 00000000..e2f65cd0 --- /dev/null +++ b/src/js/themes/lightTheme/shadows.test.ts @@ -0,0 +1,86 @@ +/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */ +import { shadows } from './shadows'; + +const designTokens = require('../../../figma/tokens.json'); + +describe('Shadows', () => { + it('js tokens shadows.size.xs matches figma tokens shadows.xs', () => { + expect(shadows.size.xs.shadowColor).toStrictEqual( + designTokens.light.shadows.xs.value.color, + ); + + expect(shadows.size.xs.shadowOffset.width).toStrictEqual( + designTokens.light.shadows.xs.value.x, + ); + + expect(shadows.size.xs.shadowOffset.height).toStrictEqual( + designTokens.light.shadows.xs.value.y, + ); + + expect(shadows.size.xs.shadowOpacity).toStrictEqual(1); + + expect(shadows.size.xs.shadowRadius).toStrictEqual( + designTokens.light.shadows.xs.value.blur, + ); + }); + + it('js tokens shadows.size.sm matches figma tokens shadows.sm', () => { + expect(shadows.size.sm.shadowColor).toStrictEqual( + designTokens.light.shadows.sm.value.color, + ); + + expect(shadows.size.sm.shadowOffset.width).toStrictEqual( + designTokens.light.shadows.sm.value.x, + ); + + expect(shadows.size.sm.shadowOffset.height).toStrictEqual( + designTokens.light.shadows.sm.value.y, + ); + + expect(shadows.size.sm.shadowOpacity).toStrictEqual(1); + + expect(shadows.size.sm.shadowRadius).toStrictEqual( + designTokens.light.shadows.sm.value.blur, + ); + }); + + it('js tokens shadows.size.md matches figma tokens shadows.md', () => { + expect(shadows.size.md.shadowColor).toStrictEqual( + designTokens.light.shadows.md.value.color, + ); + + expect(shadows.size.md.shadowOffset.width).toStrictEqual( + designTokens.light.shadows.md.value.x, + ); + + expect(shadows.size.md.shadowOffset.height).toStrictEqual( + designTokens.light.shadows.md.value.y, + ); + + expect(shadows.size.md.shadowOpacity).toStrictEqual(1); + + expect(shadows.size.md.shadowRadius).toStrictEqual( + designTokens.light.shadows.md.value.blur, + ); + }); + + it('js tokens shadows.size.lg matches figma tokens shadows.lg', () => { + expect(shadows.size.lg.shadowColor).toStrictEqual( + designTokens.light.shadows.lg.value.color, + ); + + expect(shadows.size.lg.shadowOffset.width).toStrictEqual( + designTokens.light.shadows.lg.value.x, + ); + + expect(shadows.size.lg.shadowOffset.height).toStrictEqual( + designTokens.light.shadows.lg.value.y, + ); + + expect(shadows.size.lg.shadowOpacity).toStrictEqual(1); + + expect(shadows.size.lg.shadowRadius).toStrictEqual( + designTokens.light.shadows.lg.value.blur, + ); + }); +}); diff --git a/src/js/themes/lightTheme/shadows.ts b/src/js/themes/lightTheme/shadows.ts new file mode 100644 index 00000000..341b36b8 --- /dev/null +++ b/src/js/themes/lightTheme/shadows.ts @@ -0,0 +1,43 @@ +import { ThemeShadows } from '../types'; +import { colors } from './colors'; + +export const shadows: ThemeShadows = { + size: { + xs: { + shadowColor: colors.shadow.default, + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 1, + shadowRadius: 4, + }, + sm: { + shadowColor: colors.shadow.default, + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 1, + shadowRadius: 8, + }, + md: { + shadowColor: colors.shadow.default, + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 1, + shadowRadius: 16, + }, + lg: { + shadowColor: colors.shadow.default, + shadowOffset: { + width: 0, + height: 8, + }, + shadowOpacity: 1, + shadowRadius: 40, + }, + }, +}; diff --git a/src/js/themes/types.ts b/src/js/themes/types.ts index d4f12902..1edad9b0 100644 --- a/src/js/themes/types.ts +++ b/src/js/themes/types.ts @@ -1,5 +1,26 @@ import { ThemeTypography } from '../typography'; +interface ShadowShape { + shadowColor: string; + shadowOffset: { + width: number; + height: number; + }; + shadowOpacity: number; + shadowRadius: number; +} + +interface ShadowSizes { + xs: ShadowShape; + sm: ShadowShape; + md: ShadowShape; + lg: ShadowShape; +} + +export interface ThemeShadows { + size: ShadowSizes; +} + export interface ThemeColors { background: { /** @@ -63,6 +84,12 @@ export interface ThemeColors { */ alternative: string; }; + shadow: { + /** + * {string} shadow.default - For neutral shadows + */ + default: string; + }; primary: { /** * {string} primary.default - For primary user action related elements @@ -84,6 +111,10 @@ export interface ThemeColors { * {string} primary.disabled - [Deprecated] Should be used for */ disabled: string; + /** + * {string} primary.shadow - For primary button hover + */ + shadow: string; }; secondary: { /** @@ -128,6 +159,10 @@ export interface ThemeColors { * {string} error.disabled - [Deprecated] Should be used for disabled state */ disabled: string; + /** + * {string} error.shadow - For error danger/critical button hover + */ + shadow: string; }; warning: { /** @@ -200,4 +235,5 @@ export interface ThemeColors { export interface Theme { colors: ThemeColors; typography: ThemeTypography; + shadows: ThemeShadows; } From 415cd4f61c5b8aca2a0f83aea229d4bc9dfe13a7 Mon Sep 17 00:00:00 2001 From: georgewrmarshall Date: Tue, 21 Jun 2022 16:05:57 -0700 Subject: [PATCH 2/8] Removing wrong shadow object from index --- src/js/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/js/index.ts b/src/js/index.ts index cccb7b0f..5fa681c3 100644 --- a/src/js/index.ts +++ b/src/js/index.ts @@ -5,4 +5,3 @@ export { darkTheme } from './themes'; // DEPRECATED in favor of importing theme objects above export { colors } from './colors'; export { typography } from './typography'; -export { shadows } from './shadows'; From c2597fd1bf758bde53dddec8df77b569ff0e96e7 Mon Sep 17 00:00:00 2001 From: georgewrmarshall Date: Wed, 22 Jun 2022 16:26:11 -0700 Subject: [PATCH 3/8] Making it uppercase --- src/js/themes/lightTheme/colors.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/themes/lightTheme/colors.ts b/src/js/themes/lightTheme/colors.ts index b66b7496..403388aa 100644 --- a/src/js/themes/lightTheme/colors.ts +++ b/src/js/themes/lightTheme/colors.ts @@ -29,7 +29,7 @@ export const colors: ThemeColors = { alternative: '#000000CC', }, shadow: { - default: '#0000001a', + default: '#0000001A', }, primary: { default: '#037DD6', @@ -37,7 +37,7 @@ export const colors: ThemeColors = { muted: '#037DD619', inverse: '#FCFCFC', disabled: '#037DD680', - shadow: '#037dd633', + shadow: '#037DD633', }, secondary: { default: '#F66A0A', @@ -52,7 +52,7 @@ export const colors: ThemeColors = { muted: '#D73A4919', inverse: '#FCFCFC', disabled: '#D73A4980', - shadow: '#d73a4966', + shadow: '#D73A4966', }, warning: { default: '#F66A0A', From e29bded7b7699416fefc7a678f28f8e478567f79 Mon Sep 17 00:00:00 2001 From: georgewrmarshall Date: Wed, 22 Jun 2022 16:31:28 -0700 Subject: [PATCH 4/8] Changing hex values to uppercase --- src/figma/tokens.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/figma/tokens.json b/src/figma/tokens.json index ef71d96d..90a546c5 100644 --- a/src/figma/tokens.json +++ b/src/figma/tokens.json @@ -939,7 +939,7 @@ "shadows": { "xs": { "value": { - "color": "#0000001a", + "color": "#0000001A", "type": "dropShadow", "x": 0, "y": 2, @@ -950,7 +950,7 @@ }, "sm": { "value": { - "color": "#0000001a", + "color": "#0000001A", "type": "dropShadow", "x": 0, "y": 2, @@ -961,7 +961,7 @@ }, "md": { "value": { - "color": "#0000001a", + "color": "#0000001A", "type": "dropShadow", "x": 0, "y": 2, @@ -972,7 +972,7 @@ }, "lg": { "value": { - "color": "#0000001a", + "color": "#0000001A", "type": "dropShadow", "x": 0, "y": 8, @@ -983,7 +983,7 @@ }, "primary": { "value": { - "color": "#037dd633", + "color": "#037DD633", "type": "dropShadow", "x": 0, "y": 7, @@ -994,7 +994,7 @@ }, "error": { "value": { - "color": "#d73a4966", + "color": "#D73A4966", "type": "dropShadow", "x": 0, "y": 7, From c55bf5a671de6c4ce3780c7d3ce0ccfac02431d0 Mon Sep 17 00:00:00 2001 From: georgewrmarshall Date: Thu, 23 Jun 2022 16:32:10 -0700 Subject: [PATCH 5/8] Adding story with controls and updating docs --- docs/Shadows.mdx | 6 ++- docs/Shadows.stories.tsx | 92 +++++++++++++++++++++++++++------------- 2 files changed, 67 insertions(+), 31 deletions(-) diff --git a/docs/Shadows.mdx b/docs/Shadows.mdx index 6b2208eb..415c420b 100644 --- a/docs/Shadows.mdx +++ b/docs/Shadows.mdx @@ -7,6 +7,10 @@ import LinkTo from '@storybook/addon-links/react'; Shadows convey elevation of elements on a surface + + + + ## Size There are 4 different sizes of shadow in MetaMask. @@ -36,7 +40,7 @@ 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)` | -## Usage +## Example usage Using both size and color tokens, different shadows can be applied to components. diff --git a/docs/Shadows.stories.tsx b/docs/Shadows.stories.tsx index 930ee701..9dee22ae 100644 --- a/docs/Shadows.stories.tsx +++ b/docs/Shadows.stories.tsx @@ -1,4 +1,7 @@ import React from 'react'; +import { lightTheme } from '../src/js'; +import { useArgs } from '@storybook/api'; + import { Text } from './components'; import README from './Shadows.mdx'; @@ -10,23 +13,48 @@ export default { page: README, }, }, + argTypes: { + size: { + control: 'select', + options: ['xs', 'sm', 'md', 'lg'], // Object.keys(lightTheme.shadow.size) + }, + color: { + control: 'select', + options: ['default', 'primary', 'error'], + }, + }, + args: { + color: 'default', + size: 'xs', + }, }; interface ShadowSwatchProps { children: any; style?: object; + size?: 'xs' | 'sm' | 'md' | 'lg'; + color?: 'default' | 'primary' | 'error'; } -const ShadowSwatch = ({ children, style }: ShadowSwatchProps) => ( +const ShadowSwatch = ({ + children, + style, + size = 'xs', + color = 'default', +}: ShadowSwatchProps) => (
@@ -34,7 +62,25 @@ const ShadowSwatch = ({ children, style }: ShadowSwatchProps) => (
); -export const Size = () => { +export const Shadow = (args) => { + return ( +
+ + + Shadow + + +
+ ); +}; + +export const Size = (args) => { return (
{ gridTemplateColumns: 'repeat(auto-fill, 200px)', }} > - + XS - + SM - + MD - + LG @@ -79,7 +113,7 @@ export const Size = () => { ); }; -export const Color = () => { +export const Color = (args) => { return (
{ gridTemplateColumns: 'repeat(auto-fill, 200px)', }} > - + - Neutral + Default { - Danger + Error/Danger
@@ -197,7 +229,7 @@ export const Usage = () => { }} > - Button Danger Hover + Button Error/Danger Hover
From 526d5383a8b4926b6ce9dc2601d5457ed51af9e2 Mon Sep 17 00:00:00 2001 From: georgewrmarshall Date: Thu, 23 Jun 2022 16:38:38 -0700 Subject: [PATCH 6/8] Removing unused imports --- docs/Shadows.stories.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/Shadows.stories.tsx b/docs/Shadows.stories.tsx index 9dee22ae..ae8bc2c8 100644 --- a/docs/Shadows.stories.tsx +++ b/docs/Shadows.stories.tsx @@ -1,6 +1,4 @@ import React from 'react'; -import { lightTheme } from '../src/js'; -import { useArgs } from '@storybook/api'; import { Text } from './components'; From e2538d7eaeb88d2a21b4ede926b0fe067804514f Mon Sep 17 00:00:00 2001 From: georgewrmarshall Date: Thu, 23 Jun 2022 16:39:40 -0700 Subject: [PATCH 7/8] Using design tokens for size options --- docs/Shadows.stories.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Shadows.stories.tsx b/docs/Shadows.stories.tsx index ae8bc2c8..0da8046c 100644 --- a/docs/Shadows.stories.tsx +++ b/docs/Shadows.stories.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { lightTheme } from '../src/js'; import { Text } from './components'; @@ -14,7 +15,7 @@ export default { argTypes: { size: { control: 'select', - options: ['xs', 'sm', 'md', 'lg'], // Object.keys(lightTheme.shadow.size) + options: Object.keys(lightTheme.shadows.size), }, color: { control: 'select', From e26f734c2a262905dd5e0fd1ba95193195b1f668 Mon Sep 17 00:00:00 2001 From: georgewrmarshall Date: Thu, 23 Jun 2022 16:47:10 -0700 Subject: [PATCH 8/8] Updating Usage to ExampleUsage to match title --- docs/Shadows.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Shadows.stories.tsx b/docs/Shadows.stories.tsx index 0da8046c..3864828f 100644 --- a/docs/Shadows.stories.tsx +++ b/docs/Shadows.stories.tsx @@ -154,7 +154,7 @@ export const Color = (args) => { ); }; -export const Usage = () => { +export const ExampleUsage = () => { return (