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..415c420b --- /dev/null +++ b/docs/Shadows.mdx @@ -0,0 +1,83 @@ +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)` | + +## Example 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..3864828f --- /dev/null +++ b/docs/Shadows.stories.tsx @@ -0,0 +1,237 @@ +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; + size?: 'xs' | 'sm' | 'md' | 'lg'; + color?: 'default' | 'primary' | 'error'; +} + +const ShadowSwatch = ({ + children, + style, + size = 'xs', + color = 'default', +}: ShadowSwatchProps) => ( +
+ {children} +
+); + +export const Shadow = (args) => { + return ( +
+ + + Shadow + + +
+ ); +}; + +export const Size = (args) => { + return ( +
+ + + XS + + + + + SM + + + + + MD + + + + + LG + + +
+ ); +}; + +export const Color = (args) => { + return ( +
+ + + Default + + + + + Primary + + + + + Error/Danger + + +
+ ); +}; + +export const ExampleUsage = () => { + return ( +
+
+ + + Card + + + + + Dropdown + + + + + Toast + + + + + Modal + + +
+
+ + + Button Primary Hover + + + + + Button Error/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..90a546c5 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/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..403388aa 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; }