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..3c87ce47
--- /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 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 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/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
index 467951c6..a60dfcec 100644
--- a/src/js/colors/colors.test.ts
+++ b/src/js/colors/colors.test.ts
@@ -76,6 +76,24 @@ describe('Light Theme Colors', () => {
);
});
+ it('js tokens for shadow.default matches figma tokens light.shadows.xs.value.color', () => {
+ expect(importableColors.light.shadow.default).toStrictEqual(
+ designTokens.light.shadows.xs.value.color,
+ );
+
+ expect(importableColors.light.shadow.default).toStrictEqual(
+ designTokens.light.shadows.sm.value.color,
+ );
+
+ expect(importableColors.light.shadow.default).toStrictEqual(
+ designTokens.light.shadows.md.value.color,
+ );
+
+ expect(importableColors.light.shadow.default).toStrictEqual(
+ designTokens.light.shadows.lg.value.color,
+ );
+ });
+
it('js tokens for overlay.inverse matches figma tokens overlay.inverse', () => {
expect(importableColors.light.overlay.inverse).toStrictEqual(
designTokens.light.colors.overlay.inverse.value,
@@ -106,6 +124,12 @@ describe('Light Theme Colors', () => {
);
});
+ it('js tokens for primary.shadow matches figma tokens shadows.primary', () => {
+ expect(importableColors.light.primary.shadow).toStrictEqual(
+ designTokens.light.shadows.primary.value.color,
+ );
+ });
+
it('js tokens for secondary.default matches figma tokens secondary.default', () => {
expect(importableColors.light.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.light.error.shadow).toStrictEqual(
+ designTokens.light.shadows.error.value.color,
+ );
+ });
+
it('js tokens for warning.default matches figma tokens warning.default', () => {
expect(importableColors.light.warning.default).toStrictEqual(
designTokens.light.colors.warning.default.value,
@@ -306,6 +336,24 @@ describe('Dark Theme Colors', () => {
);
});
+ it('js tokens for shadow.default matches figma tokens dark.shadows.xs.value.color', () => {
+ expect(importableColors.dark.shadow.default).toStrictEqual(
+ designTokens.dark.shadows.xs.value.color,
+ );
+
+ expect(importableColors.dark.shadow.default).toStrictEqual(
+ designTokens.dark.shadows.sm.value.color,
+ );
+
+ expect(importableColors.dark.shadow.default).toStrictEqual(
+ designTokens.dark.shadows.md.value.color,
+ );
+
+ expect(importableColors.dark.shadow.default).toStrictEqual(
+ designTokens.dark.shadows.lg.value.color,
+ );
+ });
+
it('js tokens for primary.default matches figma tokens primary.default', () => {
expect(importableColors.dark.primary.default).toStrictEqual(
designTokens.dark.colors.primary.default.value,
@@ -330,6 +378,12 @@ describe('Dark Theme Colors', () => {
);
});
+ it('js tokens for primary.shadow matches figma tokens shadows.primary', () => {
+ expect(importableColors.dark.primary.shadow).toStrictEqual(
+ designTokens.dark.shadows.primary.value.color,
+ );
+ });
+
it('js tokens for secondary.default matches figma tokens secondary.default', () => {
expect(importableColors.dark.secondary.default).toStrictEqual(
designTokens.dark.colors.secondary.default.value,
@@ -378,6 +432,12 @@ describe('Dark Theme Colors', () => {
);
});
+ it('js tokens for error.shadow matches figma tokens shadows.error', () => {
+ expect(importableColors.dark.error.shadow).toStrictEqual(
+ designTokens.dark.shadows.error.value.color,
+ );
+ });
+
it('js tokens for warning.default matches figma tokens warning.default', () => {
expect(importableColors.dark.warning.default).toStrictEqual(
designTokens.dark.colors.warning.default.value,
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.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.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;
}