From 348b649e61298720d10c12749221a90ac8e350c2 Mon Sep 17 00:00:00 2001 From: Aaron Date: Fri, 26 Feb 2021 14:54:01 -0500 Subject: [PATCH 01/15] Add base serialization and theme provider --- packages/gamut-styles/src/index.ts | 7 -- .../src/theme/GamutThemeProvider.tsx | 22 +++++ packages/gamut-styles/src/theme/index.ts | 2 + packages/gamut-styles/src/theme/props.ts | 85 +++++++++++++++++++ packages/gamut-styles/src/theme/theme.tsx | 13 +++ .../src/theme/utils/createThemeVars.ts | 56 ++++++++++++ .../gamut-styles/src/variables/elements.ts | 3 + packages/gamut-styles/src/variables/index.ts | 1 + .../gamut-styles/src/variables/responsive.ts | 5 +- .../.storybook/addons/system/enhancers.ts | 3 +- .../.storybook/addons/system/propMeta.ts | 2 +- .../components/PropsTable/constants.ts | 2 +- .../.storybook/decorators/theme.tsx | 11 ++- 13 files changed, 195 insertions(+), 17 deletions(-) create mode 100644 packages/gamut-styles/src/theme/GamutThemeProvider.tsx create mode 100644 packages/gamut-styles/src/theme/index.ts create mode 100644 packages/gamut-styles/src/theme/props.ts create mode 100644 packages/gamut-styles/src/theme/theme.tsx create mode 100644 packages/gamut-styles/src/theme/utils/createThemeVars.ts create mode 100644 packages/gamut-styles/src/variables/elements.ts diff --git a/packages/gamut-styles/src/index.ts b/packages/gamut-styles/src/index.ts index 2798e9e46d2..b1049e0957c 100644 --- a/packages/gamut-styles/src/index.ts +++ b/packages/gamut-styles/src/index.ts @@ -1,13 +1,6 @@ import '@emotion/react'; -import { Theme as GamutTheme } from './theme'; - export * from './cache'; export * from './variables'; export * from './utilities'; -export * from './system'; export * from './theme'; - -declare module '@emotion/react' { - export interface Theme extends GamutTheme {} -} diff --git a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx new file mode 100644 index 00000000000..0f28bbef483 --- /dev/null +++ b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx @@ -0,0 +1,22 @@ +import { css, Global, ThemeProvider } from '@emotion/react'; +import React from 'react'; + +import { theme as rawTheme } from './theme'; +import { createThemeVars } from './utils/createThemeVars'; + +export const { theme, vars } = createThemeVars(rawTheme, ['elements']); + +export type ThemeShape = typeof theme; + +declare module '@emotion/react' { + export interface Theme extends ThemeShape {} +} + +export const GamutThemeProvider: React.FC = ({ children }) => { + return ( + + + {children} + + ); +}; diff --git a/packages/gamut-styles/src/theme/index.ts b/packages/gamut-styles/src/theme/index.ts new file mode 100644 index 00000000000..3675e9fecbb --- /dev/null +++ b/packages/gamut-styles/src/theme/index.ts @@ -0,0 +1,2 @@ +export * from './GamutThemeProvider'; +export * from './props'; diff --git a/packages/gamut-styles/src/theme/props.ts b/packages/gamut-styles/src/theme/props.ts new file mode 100644 index 00000000000..faedd19bc85 --- /dev/null +++ b/packages/gamut-styles/src/theme/props.ts @@ -0,0 +1,85 @@ +import { system } from '@codecademy/gamut-system'; +import { Theme } from '@emotion/react'; + +const { + variant, + properties, + typography, + grid, + flex, + layout, + positioning, + background, + color, + shadow, + spacing: space, + border, +} = system.withTheme().create({ + typography: { + fontSize: { + propName: 'fontSize', + scale: 'fontSize', + }, + fontFamily: { + propName: 'fontFamily', + scale: 'fontFamily', + }, + fontWeight: { + propName: 'fontWeight', + scale: 'fontWeight', + }, + lineHeight: { + propName: 'lineHeight', + scale: 'lineHeight', + }, + }, + spacing: { + margin: { + propName: 'margin', + scale: 'spacing', + }, + padding: { + propName: 'padding', + scale: 'spacing', + }, + }, + color: { + textColor: { + propName: 'textColor', + scale: 'colors', + }, + backgroundColor: { + propName: 'backgroundColor', + scale: 'colors', + }, + borderColor: { + propName: 'borderColor', + scale: 'colors', + }, + }, + grid: { + columnGap: { + propName: 'columnGap', + scale: 'spacing', + }, + rowGap: { + propName: 'rowGap', + scale: 'spacing', + }, + }, +}); + +export { + variant, + properties, + typography, + grid, + flex, + layout, + positioning, + background, + color, + shadow, + space, + border, +}; diff --git a/packages/gamut-styles/src/theme/theme.tsx b/packages/gamut-styles/src/theme/theme.tsx new file mode 100644 index 00000000000..e45bf549d78 --- /dev/null +++ b/packages/gamut-styles/src/theme/theme.tsx @@ -0,0 +1,13 @@ +import * as tokens from '../variables'; + +export const theme = { + boxShadows: tokens.boxShadows, + breakpoints: tokens.mediaQueries, + fontSize: tokens.fontSize, + fontFamily: tokens.fontFamily, + lineHeight: tokens.lineHeight, + fontWeight: tokens.fontWeight, + colors: tokens.colors, + spacing: tokens.spacing, + elements: tokens.elements, +} as const; diff --git a/packages/gamut-styles/src/theme/utils/createThemeVars.ts b/packages/gamut-styles/src/theme/utils/createThemeVars.ts new file mode 100644 index 00000000000..b2b7fa56adc --- /dev/null +++ b/packages/gamut-styles/src/theme/utils/createThemeVars.ts @@ -0,0 +1,56 @@ +import { AbstractTheme } from '@codecademy/gamut-system'; +import { get, omit } from 'lodash'; + +export const createThemeVars = < + T extends AbstractTheme, + K extends (keyof T)[], + Registered extends Pick, + MappedVars extends { + [Key in keyof Registered]: { + [Variable in keyof Registered[Key]]: any; + }; + }, + ReturnedTheme extends T & MappedVars +>( + theme: T, + keys: K +): { + vars: Record; + theme: ReturnedTheme; +} => { + const vars: Record> = {}; + const themeVars = {} as Record>; + + keys.forEach((key: string) => { + const varsToRegister = theme[key]; + themeVars[key] = {} as Record; + Object.keys(varsToRegister).forEach((variable: string) => { + const varName = `--${variable}`; + themeVars[key][variable] = `var(${varName})`; + const valuesToRegister = varsToRegister[variable]; + + switch (typeof valuesToRegister) { + case 'string': + // add static vars + vars[varName] = valuesToRegister; + break; + case 'object': + // Add vars that have responsive values + Object.assign(vars, { + [varName]: get(valuesToRegister, 'base'), + ...Object.keys(omit(valuesToRegister, 'base')).reduce( + (carry, key) => ({ + ...carry, + [get(theme.breakpoints, key)]: { + [varName]: valuesToRegister[key], + }, + }), + {} + ), + }); + } + }); + }); + + return { vars, theme: { ...theme, ...themeVars } as ReturnedTheme }; +}; diff --git a/packages/gamut-styles/src/variables/elements.ts b/packages/gamut-styles/src/variables/elements.ts new file mode 100644 index 00000000000..03f3cda38f9 --- /dev/null +++ b/packages/gamut-styles/src/variables/elements.ts @@ -0,0 +1,3 @@ +export const elements = { + headerHeight: { base: '4rem', md: '5rem' }, +} as const; diff --git a/packages/gamut-styles/src/variables/index.ts b/packages/gamut-styles/src/variables/index.ts index 9a0a0a121af..38b0689a25d 100644 --- a/packages/gamut-styles/src/variables/index.ts +++ b/packages/gamut-styles/src/variables/index.ts @@ -5,5 +5,6 @@ export * from './typography'; export * from './effects'; export * from './shadows'; export * from './timing'; +export * from './elements'; // Deprecated variables export * from './deprecated-colors'; diff --git a/packages/gamut-styles/src/variables/responsive.ts b/packages/gamut-styles/src/variables/responsive.ts index a6820dae1c3..1237a50e529 100644 --- a/packages/gamut-styles/src/variables/responsive.ts +++ b/packages/gamut-styles/src/variables/responsive.ts @@ -8,9 +8,8 @@ export const breakpoints: Record = { xl: '1440px', }; -const createMediaQuery = (size: MediaSize, direction: 'min' | 'max') => ` - @media only screen and (${direction}-width: ${breakpoints[size]}) -`; +const createMediaQuery = (size: MediaSize, direction: 'min' | 'max') => + `@media only screen and (${direction}-width: ${breakpoints[size]})`; export const mediaQueries = { xs: createMediaQuery('xs', 'min'), diff --git a/packages/styleguide/.storybook/addons/system/enhancers.ts b/packages/styleguide/.storybook/addons/system/enhancers.ts index 377b63fa5d6..4baf51c80d5 100644 --- a/packages/styleguide/.storybook/addons/system/enhancers.ts +++ b/packages/styleguide/.storybook/addons/system/enhancers.ts @@ -2,7 +2,8 @@ import { mapValues, isNumber, map } from 'lodash/fp'; import { ArgTypesEnhancer } from '@storybook/client-api'; import { kebabCase } from 'lodash'; import { ALL_PROPS, PROP_META, PROP_GROUPS } from './propMeta'; -import { Theme, theme } from '@codecademy/gamut-styles/src/theme'; +import { theme } from '@codecademy/gamut-styles/src/theme'; +import { Theme } from '@emotion/react'; export type SystemControls = 'text' | 'select' | 'radio' | 'inline-radio'; diff --git a/packages/styleguide/.storybook/addons/system/propMeta.ts b/packages/styleguide/.storybook/addons/system/propMeta.ts index 23550f9bc78..7cf7bd3fa51 100644 --- a/packages/styleguide/.storybook/addons/system/propMeta.ts +++ b/packages/styleguide/.storybook/addons/system/propMeta.ts @@ -1,4 +1,4 @@ -import * as system from '@codecademy/gamut-styles/src/system'; +import * as system from '@codecademy/gamut-styles/src/theme/props'; const { properties, variant, ...groups } = system; diff --git a/packages/styleguide/.storybook/components/PropsTable/constants.ts b/packages/styleguide/.storybook/components/PropsTable/constants.ts index 39d081e0692..17afc686d95 100644 --- a/packages/styleguide/.storybook/components/PropsTable/constants.ts +++ b/packages/styleguide/.storybook/components/PropsTable/constants.ts @@ -1,4 +1,4 @@ -import * as system from '@codecademy/gamut-styles/src/system'; +import * as system from '@codecademy/gamut-styles/src/theme/props'; const { properties: props, variant, ...groups } = system; diff --git a/packages/styleguide/.storybook/decorators/theme.tsx b/packages/styleguide/.storybook/decorators/theme.tsx index 1b6f5c52e6b..45f47961157 100644 --- a/packages/styleguide/.storybook/decorators/theme.tsx +++ b/packages/styleguide/.storybook/decorators/theme.tsx @@ -1,7 +1,10 @@ import React from 'react'; -import { CacheProvider, ThemeContext } from '@emotion/react'; +import { CacheProvider } from '@emotion/react'; -import { theme, createEmotionCache } from '@codecademy/gamut-styles'; +import { + GamutThemeProvider, + createEmotionCache, +} from '@codecademy/gamut-styles'; const cache = createEmotionCache(); @@ -12,10 +15,10 @@ const cache = createEmotionCache(); export const withEmotion = (Story: any) => { return process.env.NODE_ENV === 'test' ? ( - {Story()} + {Story()} ) : ( - {Story()} + {Story()} ); }; From af8d6c7f465a256620176c69bd2c9e3ee4d791e9 Mon Sep 17 00:00:00 2001 From: Aaron Date: Fri, 26 Feb 2021 15:22:02 -0500 Subject: [PATCH 02/15] Use our provider --- packages/gamut-tests/src/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/gamut-tests/src/index.tsx b/packages/gamut-tests/src/index.tsx index b9231786eac..93a3f754515 100644 --- a/packages/gamut-tests/src/index.tsx +++ b/packages/gamut-tests/src/index.tsx @@ -1,5 +1,4 @@ -import { theme } from '@codecademy/gamut-styles'; -import { ThemeProvider } from '@emotion/react'; +import { GamutThemeProvider } from '@codecademy/gamut-styles'; import { setupEnzyme as setupEnzymeBase, setupRtl as setupRtlBase, @@ -13,9 +12,9 @@ function withThemeProvider( WrappedComponent: React.ComponentType ) { const WithBoundaryComponent: React.FC = (props) => ( - + - + ); return WithBoundaryComponent; From db86d30b33c9236b36b61332ab153e492a9744ea Mon Sep 17 00:00:00 2001 From: Aaron Date: Fri, 26 Feb 2021 16:22:03 -0500 Subject: [PATCH 03/15] Whoops --- packages/gamut-styles/src/index.ts | 8 ++++++++ packages/gamut-styles/src/theme.tsx | 16 ---------------- 2 files changed, 8 insertions(+), 16 deletions(-) delete mode 100644 packages/gamut-styles/src/theme.tsx diff --git a/packages/gamut-styles/src/index.ts b/packages/gamut-styles/src/index.ts index b1049e0957c..8977610e1a1 100644 --- a/packages/gamut-styles/src/index.ts +++ b/packages/gamut-styles/src/index.ts @@ -4,3 +4,11 @@ export * from './cache'; export * from './variables'; export * from './utilities'; export * from './theme'; + +import { theme } from './theme'; + +export type ThemeShape = typeof theme; + +declare module '@emotion/react' { + export interface Theme extends ThemeShape {} +} diff --git a/packages/gamut-styles/src/theme.tsx b/packages/gamut-styles/src/theme.tsx deleted file mode 100644 index e474f8de94e..00000000000 --- a/packages/gamut-styles/src/theme.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as tokens from './variables'; - -export const theme = { - boxShadows: tokens.boxShadows, - breakpoints: tokens.mediaQueries, - fontSize: tokens.fontSize, - fontFamily: tokens.fontFamily, - lineHeight: tokens.lineHeight, - fontWeight: tokens.fontWeight, - colors: tokens.colors, - spacing: tokens.spacing, -} as const; - -export type ThemeShape = typeof theme; - -export interface Theme extends ThemeShape {} From 512e32cd9901c1df799d99035917f5fab97debc6 Mon Sep 17 00:00:00 2001 From: Aaron Date: Fri, 26 Feb 2021 16:23:05 -0500 Subject: [PATCH 04/15] Import order --- packages/gamut-styles/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/gamut-styles/src/index.ts b/packages/gamut-styles/src/index.ts index 8977610e1a1..2c9e0399080 100644 --- a/packages/gamut-styles/src/index.ts +++ b/packages/gamut-styles/src/index.ts @@ -1,12 +1,12 @@ import '@emotion/react'; +import { theme } from './theme'; + export * from './cache'; export * from './variables'; export * from './utilities'; export * from './theme'; -import { theme } from './theme'; - export type ThemeShape = typeof theme; declare module '@emotion/react' { From 19a61cb0980771ba65100f84354d43a37b293837 Mon Sep 17 00:00:00 2001 From: Aaron Date: Fri, 26 Feb 2021 16:29:35 -0500 Subject: [PATCH 05/15] Fix it again --- packages/gamut-styles/src/system.ts | 86 ------------------- .../src/theme/GamutThemeProvider.tsx | 6 -- 2 files changed, 92 deletions(-) delete mode 100644 packages/gamut-styles/src/system.ts diff --git a/packages/gamut-styles/src/system.ts b/packages/gamut-styles/src/system.ts deleted file mode 100644 index 4e58c6c11d5..00000000000 --- a/packages/gamut-styles/src/system.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { system } from '@codecademy/gamut-system'; - -import { Theme } from './theme'; - -const { - variant, - properties, - typography, - grid, - flex, - layout, - positioning, - background, - color, - shadow, - spacing: space, - border, -} = system.withTheme().create({ - typography: { - fontSize: { - propName: 'fontSize', - scale: 'fontSize', - }, - fontFamily: { - propName: 'fontFamily', - scale: 'fontFamily', - }, - fontWeight: { - propName: 'fontWeight', - scale: 'fontWeight', - }, - lineHeight: { - propName: 'lineHeight', - scale: 'lineHeight', - }, - }, - spacing: { - margin: { - propName: 'margin', - scale: 'spacing', - }, - padding: { - propName: 'padding', - scale: 'spacing', - }, - }, - color: { - textColor: { - propName: 'textColor', - scale: 'colors', - }, - backgroundColor: { - propName: 'backgroundColor', - scale: 'colors', - }, - borderColor: { - propName: 'borderColor', - scale: 'colors', - }, - }, - grid: { - columnGap: { - propName: 'columnGap', - scale: 'spacing', - }, - rowGap: { - propName: 'rowGap', - scale: 'spacing', - }, - }, -}); - -export { - variant, - properties, - typography, - grid, - flex, - layout, - positioning, - background, - color, - shadow, - space, - border, -}; diff --git a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx index 0f28bbef483..6fab179db23 100644 --- a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx +++ b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx @@ -6,12 +6,6 @@ import { createThemeVars } from './utils/createThemeVars'; export const { theme, vars } = createThemeVars(rawTheme, ['elements']); -export type ThemeShape = typeof theme; - -declare module '@emotion/react' { - export interface Theme extends ThemeShape {} -} - export const GamutThemeProvider: React.FC = ({ children }) => { return ( From c504a0378afb4d5d5c5dfb232e413d9eeb03dceb Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 1 Mar 2021 22:18:52 -0500 Subject: [PATCH 06/15] even simpler --- packages/gamut-styles/src/theme/utils/createThemeVars.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/gamut-styles/src/theme/utils/createThemeVars.ts b/packages/gamut-styles/src/theme/utils/createThemeVars.ts index d163526c2ec..c0bb3ba0363 100644 --- a/packages/gamut-styles/src/theme/utils/createThemeVars.ts +++ b/packages/gamut-styles/src/theme/utils/createThemeVars.ts @@ -24,15 +24,12 @@ export interface CreateThemeVars { export const createThemeVars: CreateThemeVars = (theme, keys) => { // Create an empty theme to merge with the base theme object - type UpdatedThemeKeys = ThemeWithVariables; - const updatedTheme = { ...theme } as UpdatedThemeKeys; - + const updatedTheme = { ...theme }; // Treat all CSS Variables as a plain emotion CSSObject to be added to. const vars: CSSObject = {}; keys.forEach((key) => { const varsToRegister = theme[key]; - updatedTheme[key] = {} as UpdatedThemeKeys[typeof key]; for (const variable in varsToRegister) { if (hasIn(varsToRegister, variable)) { From 4aeaedb36912c7ed47170378e6e31845f7c8bc78 Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 1 Mar 2021 22:42:56 -0500 Subject: [PATCH 07/15] Final Refactor --- .../src/theme/utils/createThemeVars.ts | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/gamut-styles/src/theme/utils/createThemeVars.ts b/packages/gamut-styles/src/theme/utils/createThemeVars.ts index c0bb3ba0363..148f7a98586 100644 --- a/packages/gamut-styles/src/theme/utils/createThemeVars.ts +++ b/packages/gamut-styles/src/theme/utils/createThemeVars.ts @@ -2,23 +2,32 @@ import { AbstractTheme } from '@codecademy/gamut-system'; import { CSSObject } from '@emotion/react'; import { get, hasIn, omit } from 'lodash'; -export type ThemeVariables = { - [Key in keyof Pick]: { [V in keyof T[Key]]: string }; +/** + * Returns an type of any object with { key: 'var(--key) } + */ +export type KeyAsVariable> = { + [V in keyof T]: `var(--${Extract})`; }; +/** + * Updates the theme type with the correct new values of css variable references + */ export type ThemeWithVariables< - T extends AbstractTheme, - K extends (keyof T)[] + Theme extends AbstractTheme, + VariableKeys extends (keyof Theme)[] > = { - [Key in keyof T]: Key extends keyof ThemeVariables - ? ThemeVariables[Key] - : T[Key]; + [Key in keyof Theme]: Key extends VariableKeys[number] + ? KeyAsVariable + : Theme[Key]; }; export interface CreateThemeVars { - (theme: T, keys: K): { + ( + theme: Theme, + keys: VariableKeys + ): { vars: CSSObject; - theme: ThemeWithVariables; + theme: ThemeWithVariables; }; } From 5b53899fd1c86c7e4adc3877ed791e5dba8c2f35 Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 1 Mar 2021 23:09:52 -0500 Subject: [PATCH 08/15] Don't update random system things --- .../src/theme/GamutThemeProvider.tsx | 4 +- .../src/theme/utils/createThemeVars.ts | 52 ++++++++++++------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx index 6fab179db23..1b613982983 100644 --- a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx +++ b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx @@ -4,12 +4,12 @@ import React from 'react'; import { theme as rawTheme } from './theme'; import { createThemeVars } from './utils/createThemeVars'; -export const { theme, vars } = createThemeVars(rawTheme, ['elements']); +export const { theme, cssVariables } = createThemeVars(rawTheme, ['elements']); export const GamutThemeProvider: React.FC = ({ children }) => { return ( - + {children} ); diff --git a/packages/gamut-styles/src/theme/utils/createThemeVars.ts b/packages/gamut-styles/src/theme/utils/createThemeVars.ts index 148f7a98586..b7909585b9d 100644 --- a/packages/gamut-styles/src/theme/utils/createThemeVars.ts +++ b/packages/gamut-styles/src/theme/utils/createThemeVars.ts @@ -1,6 +1,6 @@ import { AbstractTheme } from '@codecademy/gamut-system'; import { CSSObject } from '@emotion/react'; -import { get, hasIn, omit } from 'lodash'; +import { hasIn, merge } from 'lodash'; /** * Returns an type of any object with { key: 'var(--key) } @@ -22,20 +22,25 @@ export type ThemeWithVariables< }; export interface CreateThemeVars { - ( + , VariableKeys extends (keyof Theme)[]>( theme: Theme, keys: VariableKeys ): { - vars: CSSObject; + cssVariables: CSSObject; theme: ThemeWithVariables; }; } +const isBreakpoint = ( + key: string +): key is keyof Required['breakpoints'] => + Object.keys(['xs', 'sm', 'md', 'lg', 'xl']).includes(key); + export const createThemeVars: CreateThemeVars = (theme, keys) => { // Create an empty theme to merge with the base theme object const updatedTheme = { ...theme }; // Treat all CSS Variables as a plain emotion CSSObject to be added to. - const vars: CSSObject = {}; + const cssVariables: CSSObject = {}; keys.forEach((key) => { const varsToRegister = theme[key]; @@ -50,24 +55,31 @@ export const createThemeVars: CreateThemeVars = (theme, keys) => { // If the value is primitive just add it as is to the returned vars css object case 'number': case 'string': - vars[varName] = valuesToRegister; + cssVariables[varName] = valuesToRegister; break; // If the value is an object then attempt to parse it as a resposnive property case 'object': - Object.assign(vars, { - // Add the base as the default variable value - [varName]: get(valuesToRegister, 'base'), - // Add a variable override at each breakpoint specified - ...Object.keys(omit(valuesToRegister, 'base')).reduce( - (carry, key) => ({ - ...carry, - [get(theme.breakpoints, key)]: { - [varName]: valuesToRegister[key], - }, - }), - {} - ), - }); + const { base, ...media } = valuesToRegister; + + // If base key is defined add it to the root values + if (base) { + cssVariables[varName] = base; + } + + // If there are remaining breakpoints that override the root value add them to style object + const mediaQueries = Object.keys(media).filter(isBreakpoint); + if (mediaQueries) { + const valuesByMediaQuery: CSSObject = {}; + mediaQueries.forEach((key) => { + const breakpoint = theme.breakpoints[key]; + valuesByMediaQuery[breakpoint] = { + [varName]: valuesToRegister[key], + }; + }); + + // Merge to preserve all breakpoints + merge(cssVariables, valuesByMediaQuery); + } break; default: break; @@ -79,5 +91,5 @@ export const createThemeVars: CreateThemeVars = (theme, keys) => { } }); - return { vars, theme: updatedTheme }; + return { cssVariables, theme: updatedTheme }; }; From 6ff2c687f13bfbe1c2b4d501c41837eeda08ab3a Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 1 Mar 2021 23:59:34 -0500 Subject: [PATCH 09/15] Add this --- .../src/theme/GamutThemeProvider.tsx | 6 +- .../src/theme/utils/createThemeVars.ts | 95 -------------- .../src/theme/utils/createVariables.ts | 118 ++++++++++++++++++ 3 files changed, 122 insertions(+), 97 deletions(-) delete mode 100644 packages/gamut-styles/src/theme/utils/createThemeVars.ts create mode 100644 packages/gamut-styles/src/theme/utils/createVariables.ts diff --git a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx index 1b613982983..f49b6308894 100644 --- a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx +++ b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx @@ -2,9 +2,11 @@ import { css, Global, ThemeProvider } from '@emotion/react'; import React from 'react'; import { theme as rawTheme } from './theme'; -import { createThemeVars } from './utils/createThemeVars'; +import { createThemeVariables } from './utils/createVariables'; -export const { theme, cssVariables } = createThemeVars(rawTheme, ['elements']); +export const { theme, cssVariables } = createThemeVariables(rawTheme, [ + 'elements', +]); export const GamutThemeProvider: React.FC = ({ children }) => { return ( diff --git a/packages/gamut-styles/src/theme/utils/createThemeVars.ts b/packages/gamut-styles/src/theme/utils/createThemeVars.ts deleted file mode 100644 index b7909585b9d..00000000000 --- a/packages/gamut-styles/src/theme/utils/createThemeVars.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { AbstractTheme } from '@codecademy/gamut-system'; -import { CSSObject } from '@emotion/react'; -import { hasIn, merge } from 'lodash'; - -/** - * Returns an type of any object with { key: 'var(--key) } - */ -export type KeyAsVariable> = { - [V in keyof T]: `var(--${Extract})`; -}; - -/** - * Updates the theme type with the correct new values of css variable references - */ -export type ThemeWithVariables< - Theme extends AbstractTheme, - VariableKeys extends (keyof Theme)[] -> = { - [Key in keyof Theme]: Key extends VariableKeys[number] - ? KeyAsVariable - : Theme[Key]; -}; - -export interface CreateThemeVars { - , VariableKeys extends (keyof Theme)[]>( - theme: Theme, - keys: VariableKeys - ): { - cssVariables: CSSObject; - theme: ThemeWithVariables; - }; -} - -const isBreakpoint = ( - key: string -): key is keyof Required['breakpoints'] => - Object.keys(['xs', 'sm', 'md', 'lg', 'xl']).includes(key); - -export const createThemeVars: CreateThemeVars = (theme, keys) => { - // Create an empty theme to merge with the base theme object - const updatedTheme = { ...theme }; - // Treat all CSS Variables as a plain emotion CSSObject to be added to. - const cssVariables: CSSObject = {}; - - keys.forEach((key) => { - const varsToRegister = theme[key]; - - for (const variable in varsToRegister) { - if (hasIn(varsToRegister, variable)) { - const varName = `--${variable}`; - const valuesToRegister = varsToRegister[variable]; - - // For all variables in the theme scale add theme to the resulting CSS Object - switch (typeof valuesToRegister) { - // If the value is primitive just add it as is to the returned vars css object - case 'number': - case 'string': - cssVariables[varName] = valuesToRegister; - break; - // If the value is an object then attempt to parse it as a resposnive property - case 'object': - const { base, ...media } = valuesToRegister; - - // If base key is defined add it to the root values - if (base) { - cssVariables[varName] = base; - } - - // If there are remaining breakpoints that override the root value add them to style object - const mediaQueries = Object.keys(media).filter(isBreakpoint); - if (mediaQueries) { - const valuesByMediaQuery: CSSObject = {}; - mediaQueries.forEach((key) => { - const breakpoint = theme.breakpoints[key]; - valuesByMediaQuery[breakpoint] = { - [varName]: valuesToRegister[key], - }; - }); - - // Merge to preserve all breakpoints - merge(cssVariables, valuesByMediaQuery); - } - break; - default: - break; - } - - // Add variable reference as the theme key's value - updatedTheme[key][variable] = `var(${varName})`; - } - } - }); - - return { cssVariables, theme: updatedTheme }; -}; diff --git a/packages/gamut-styles/src/theme/utils/createVariables.ts b/packages/gamut-styles/src/theme/utils/createVariables.ts new file mode 100644 index 00000000000..c8dd337ee2d --- /dev/null +++ b/packages/gamut-styles/src/theme/utils/createVariables.ts @@ -0,0 +1,118 @@ +import { AbstractTheme } from '@codecademy/gamut-system'; +import { CSSObject } from '@emotion/react'; +import { hasIn, isObject, mapKeys, mapValues, merge } from 'lodash'; + +/** + * Returns an type of any object with { key: 'var(--key) } + */ +export type KeyAsVariable> = { + [V in keyof T]: `var(--${Extract})`; +}; + +/** + * Updates the theme type with the correct new values of css variable references + */ +export type ThemeWithVariables< + Theme extends AbstractTheme, + VariableKeys extends (keyof Theme)[] +> = { + [Key in keyof Theme]: Key extends VariableKeys[number] + ? KeyAsVariable + : Theme[Key]; +}; + +export interface CreateThemeVars { + , VariableKeys extends (keyof Theme)[]>( + theme: Theme, + keys: VariableKeys + ): { + cssVariables: CSSObject; + theme: ThemeWithVariables; + }; +} + +const isBreakpoint = ( + key: string +): key is keyof Required['breakpoints'] => + Object.keys(['xs', 'sm', 'md', 'lg', 'xl']).includes(key); + +export const createVariables = ( + tokens: Record +) => { + const cssVariables: CSSObject = {}; + + for (const variable in tokens) { + if (hasIn(tokens, variable)) { + const varName = `--${variable}`; + const valuesToRegister = tokens[variable]; + + // For all variables in the theme scale add theme to the resulting CSS Object + switch (typeof valuesToRegister) { + // If the value is primitive just add it as is to the returned vars css object + case 'number': + case 'string': + cssVariables[varName] = valuesToRegister; + break; + // If the value is an object then attempt to parse it as a resposnive property + case 'object': + const { base, ...otherSelectors } = valuesToRegister; + + // If base key is defined add it to the root values + if (base) { + cssVariables[varName] = base; + } + + // If there are remaining breakpoints that override the root value add them to style object + const selectors = Object.keys(otherSelectors); + if (selectors) { + const valuesByMediaQuery: CSSObject = {}; + selectors.forEach((key) => { + valuesByMediaQuery[key] = { + [varName]: valuesToRegister[key], + }; + }); + + // Merge to preserve all breakpoints + merge(cssVariables, valuesByMediaQuery); + } + break; + default: + break; + } + + // Add variable reference as the theme key's value + } + } + return cssVariables; +}; + +export const createThemeVariables: CreateThemeVars = (theme, keys) => { + // Create an empty theme to merge with the base theme object + const updatedTheme = { ...theme }; + // Treat all CSS Variables as a plain emotion CSSObject to be added to. + const cssVariables: CSSObject = {}; + + keys.forEach((key) => { + const tokensToSerialize = theme[key]; + // Update the theme object with the new tokens + for (const variable in tokensToSerialize) { + if (hasIn(tokensToSerialize, variable)) { + const variableReference = `var(--${variable}_`; + updatedTheme[key][variable] = variableReference; + } + } + + // Replace breakpoint aliases with the actual selector + const replacedBreakpointAliases = mapValues(tokensToSerialize, (val) => { + if (!isObject(val)) return val; + return mapKeys(val, (key) => + isBreakpoint(key) ? theme.breakpoints[key] : key + ); + }); + + // Create the variables and merge with the rest of the vars + merge(cssVariables, createVariables(replacedBreakpointAliases)); + }); + + return { cssVariables, theme: updatedTheme }; +}; From a98f6fa8941e0cd3bcff333fbc030ba36131f616 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 2 Mar 2021 00:01:06 -0500 Subject: [PATCH 10/15] What the heck --- .../src/theme/utils/createVariables.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/gamut-styles/src/theme/utils/createVariables.ts b/packages/gamut-styles/src/theme/utils/createVariables.ts index c8dd337ee2d..e7893d6422c 100644 --- a/packages/gamut-styles/src/theme/utils/createVariables.ts +++ b/packages/gamut-styles/src/theme/utils/createVariables.ts @@ -32,9 +32,10 @@ export interface CreateThemeVars { } const isBreakpoint = ( - key: string + key: string, + breakpoints: Required['breakpoints'] ): key is keyof Required['breakpoints'] => - Object.keys(['xs', 'sm', 'md', 'lg', 'xl']).includes(key); + Object.keys(breakpoints).includes(key); export const createVariables = ( tokens: Record @@ -103,12 +104,13 @@ export const createThemeVariables: CreateThemeVars = (theme, keys) => { } // Replace breakpoint aliases with the actual selector - const replacedBreakpointAliases = mapValues(tokensToSerialize, (val) => { - if (!isObject(val)) return val; - return mapKeys(val, (key) => - isBreakpoint(key) ? theme.breakpoints[key] : key - ); - }); + const replacedBreakpointAliases = mapValues(tokensToSerialize, (val) => + isObject(val) + ? mapKeys(val, (key) => + isBreakpoint(key, theme.breakpoints) ? theme.breakpoints[key] : key + ) + : val + ); // Create the variables and merge with the rest of the vars merge(cssVariables, createVariables(replacedBreakpointAliases)); From b54a3a9296feafb425f7f066b8f00d5cfd38850e Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 2 Mar 2021 00:04:36 -0500 Subject: [PATCH 11/15] Split to different files --- .../src/theme/GamutThemeProvider.tsx | 2 +- .../src/theme/utils/createThemeVariables.ts | 72 +++++++++++++++++++ .../src/theme/utils/createVariables.ts | 70 +----------------- 3 files changed, 74 insertions(+), 70 deletions(-) create mode 100644 packages/gamut-styles/src/theme/utils/createThemeVariables.ts diff --git a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx index f49b6308894..317f55136c6 100644 --- a/packages/gamut-styles/src/theme/GamutThemeProvider.tsx +++ b/packages/gamut-styles/src/theme/GamutThemeProvider.tsx @@ -2,7 +2,7 @@ import { css, Global, ThemeProvider } from '@emotion/react'; import React from 'react'; import { theme as rawTheme } from './theme'; -import { createThemeVariables } from './utils/createVariables'; +import { createThemeVariables } from './utils/createThemeVariables'; export const { theme, cssVariables } = createThemeVariables(rawTheme, [ 'elements', diff --git a/packages/gamut-styles/src/theme/utils/createThemeVariables.ts b/packages/gamut-styles/src/theme/utils/createThemeVariables.ts new file mode 100644 index 00000000000..eaae292fe18 --- /dev/null +++ b/packages/gamut-styles/src/theme/utils/createThemeVariables.ts @@ -0,0 +1,72 @@ +import { AbstractTheme } from '@codecademy/gamut-system'; +import { CSSObject } from '@emotion/react'; +import { hasIn, isObject, mapKeys, mapValues, merge } from 'lodash'; + +import { createVariables } from './createVariables'; + +/** + * Returns an type of any object with { key: 'var(--key) } + */ +export type KeyAsVariable> = { + [V in keyof T]: `var(--${Extract})`; +}; + +/** + * Updates the theme type with the correct new values of css variable references + */ +export type ThemeWithVariables< + Theme extends AbstractTheme, + VariableKeys extends (keyof Theme)[] +> = { + [Key in keyof Theme]: Key extends VariableKeys[number] + ? KeyAsVariable + : Theme[Key]; +}; + +export interface CreateThemeVars { + , VariableKeys extends (keyof Theme)[]>( + theme: Theme, + keys: VariableKeys + ): { + cssVariables: CSSObject; + theme: ThemeWithVariables; + }; +} + +const isBreakpoint = ( + key: string, + breakpoints: Required['breakpoints'] +): key is keyof Required['breakpoints'] => + Object.keys(breakpoints).includes(key); + +export const createThemeVariables: CreateThemeVars = (theme, keys) => { + // Create an empty theme to merge with the base theme object + const updatedTheme = { ...theme }; + // Treat all CSS Variables as a plain emotion CSSObject to be added to. + const cssVariables: CSSObject = {}; + + keys.forEach((key) => { + const tokensToSerialize = theme[key]; + // Update the theme object with the new tokens + for (const variable in tokensToSerialize) { + if (hasIn(tokensToSerialize, variable)) { + const variableReference = `var(--${variable}_`; + updatedTheme[key][variable] = variableReference; + } + } + + // Replace breakpoint aliases with the actual selector + const replacedBreakpointAliases = mapValues(tokensToSerialize, (val) => + isObject(val) + ? mapKeys(val, (key) => + isBreakpoint(key, theme.breakpoints) ? theme.breakpoints[key] : key + ) + : val + ); + + // Create the variables and merge with the rest of the vars + merge(cssVariables, createVariables(replacedBreakpointAliases)); + }); + + return { cssVariables, theme: updatedTheme }; +}; diff --git a/packages/gamut-styles/src/theme/utils/createVariables.ts b/packages/gamut-styles/src/theme/utils/createVariables.ts index e7893d6422c..94c4ff68593 100644 --- a/packages/gamut-styles/src/theme/utils/createVariables.ts +++ b/packages/gamut-styles/src/theme/utils/createVariables.ts @@ -1,41 +1,5 @@ -import { AbstractTheme } from '@codecademy/gamut-system'; import { CSSObject } from '@emotion/react'; -import { hasIn, isObject, mapKeys, mapValues, merge } from 'lodash'; - -/** - * Returns an type of any object with { key: 'var(--key) } - */ -export type KeyAsVariable> = { - [V in keyof T]: `var(--${Extract})`; -}; - -/** - * Updates the theme type with the correct new values of css variable references - */ -export type ThemeWithVariables< - Theme extends AbstractTheme, - VariableKeys extends (keyof Theme)[] -> = { - [Key in keyof Theme]: Key extends VariableKeys[number] - ? KeyAsVariable - : Theme[Key]; -}; - -export interface CreateThemeVars { - , VariableKeys extends (keyof Theme)[]>( - theme: Theme, - keys: VariableKeys - ): { - cssVariables: CSSObject; - theme: ThemeWithVariables; - }; -} - -const isBreakpoint = ( - key: string, - breakpoints: Required['breakpoints'] -): key is keyof Required['breakpoints'] => - Object.keys(breakpoints).includes(key); +import { hasIn, merge } from 'lodash'; export const createVariables = ( tokens: Record @@ -86,35 +50,3 @@ export const createVariables = ( } return cssVariables; }; - -export const createThemeVariables: CreateThemeVars = (theme, keys) => { - // Create an empty theme to merge with the base theme object - const updatedTheme = { ...theme }; - // Treat all CSS Variables as a plain emotion CSSObject to be added to. - const cssVariables: CSSObject = {}; - - keys.forEach((key) => { - const tokensToSerialize = theme[key]; - // Update the theme object with the new tokens - for (const variable in tokensToSerialize) { - if (hasIn(tokensToSerialize, variable)) { - const variableReference = `var(--${variable}_`; - updatedTheme[key][variable] = variableReference; - } - } - - // Replace breakpoint aliases with the actual selector - const replacedBreakpointAliases = mapValues(tokensToSerialize, (val) => - isObject(val) - ? mapKeys(val, (key) => - isBreakpoint(key, theme.breakpoints) ? theme.breakpoints[key] : key - ) - : val - ); - - // Create the variables and merge with the rest of the vars - merge(cssVariables, createVariables(replacedBreakpointAliases)); - }); - - return { cssVariables, theme: updatedTheme }; -}; From e1a95d794da5b204712a7bb80efa0de3b267c008 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 2 Mar 2021 00:06:19 -0500 Subject: [PATCH 12/15] Export variable creation --- packages/gamut-styles/src/theme/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/gamut-styles/src/theme/index.ts b/packages/gamut-styles/src/theme/index.ts index 3675e9fecbb..50783682a50 100644 --- a/packages/gamut-styles/src/theme/index.ts +++ b/packages/gamut-styles/src/theme/index.ts @@ -1,2 +1,3 @@ export * from './GamutThemeProvider'; export * from './props'; +export { createVariables } from './utils/createVariables'; From 29590a72e8939cf34ae3690b21a4797f62028511 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 2 Mar 2021 01:00:46 -0500 Subject: [PATCH 13/15] reorganize --- packages/gamut-styles/src/theme/index.ts | 1 + packages/gamut-styles/src/theme/props.ts | 12 ---------- .../src/theme/utils/createThemeVariables.ts | 23 +++++++++++-------- .../src/theme/utils/shouldForwardProp.ts | 13 +++++++++++ .../.storybook/addons/system/propMeta.ts | 2 +- 5 files changed, 28 insertions(+), 23 deletions(-) create mode 100644 packages/gamut-styles/src/theme/utils/shouldForwardProp.ts diff --git a/packages/gamut-styles/src/theme/index.ts b/packages/gamut-styles/src/theme/index.ts index 50783682a50..b7f36d5e460 100644 --- a/packages/gamut-styles/src/theme/index.ts +++ b/packages/gamut-styles/src/theme/index.ts @@ -1,3 +1,4 @@ export * from './GamutThemeProvider'; export * from './props'; export { createVariables } from './utils/createVariables'; +export * from './utils/shouldForwardProp'; diff --git a/packages/gamut-styles/src/theme/props.ts b/packages/gamut-styles/src/theme/props.ts index ed14ef14c22..faedd19bc85 100644 --- a/packages/gamut-styles/src/theme/props.ts +++ b/packages/gamut-styles/src/theme/props.ts @@ -1,5 +1,4 @@ import { system } from '@codecademy/gamut-system'; -import isPropValid from '@emotion/is-prop-valid'; import { Theme } from '@emotion/react'; const { @@ -70,16 +69,6 @@ const { }, }); -const allProps = Object.keys(properties).reduce( - (carry, prop: keyof typeof properties) => { - return [...carry, ...properties[prop].propNames]; - }, - [] -); - -const shouldForwardProp = (prop: string) => - isPropValid(prop) && !allProps.includes(prop); - export { variant, properties, @@ -93,5 +82,4 @@ export { shadow, space, border, - shouldForwardProp, }; diff --git a/packages/gamut-styles/src/theme/utils/createThemeVariables.ts b/packages/gamut-styles/src/theme/utils/createThemeVariables.ts index eaae292fe18..4575b472edd 100644 --- a/packages/gamut-styles/src/theme/utils/createThemeVariables.ts +++ b/packages/gamut-styles/src/theme/utils/createThemeVariables.ts @@ -46,23 +46,26 @@ export const createThemeVariables: CreateThemeVars = (theme, keys) => { const cssVariables: CSSObject = {}; keys.forEach((key) => { - const tokensToSerialize = theme[key]; + const tokensToSerialize = { ...theme[key] }; // Update the theme object with the new tokens for (const variable in tokensToSerialize) { if (hasIn(tokensToSerialize, variable)) { - const variableReference = `var(--${variable}_`; + const variableReference = `var(--${variable})`; updatedTheme[key][variable] = variableReference; } } - // Replace breakpoint aliases with the actual selector - const replacedBreakpointAliases = mapValues(tokensToSerialize, (val) => - isObject(val) - ? mapKeys(val, (key) => - isBreakpoint(key, theme.breakpoints) ? theme.breakpoints[key] : key - ) - : val - ); + const replacedBreakpointAliases = mapValues(tokensToSerialize, (val) => { + if (isObject(val)) { + return mapKeys(val, (val, key) => { + return isBreakpoint(key, theme.breakpoints) + ? theme.breakpoints[key] + : key; + }); + } + + return val; + }); // Create the variables and merge with the rest of the vars merge(cssVariables, createVariables(replacedBreakpointAliases)); diff --git a/packages/gamut-styles/src/theme/utils/shouldForwardProp.ts b/packages/gamut-styles/src/theme/utils/shouldForwardProp.ts new file mode 100644 index 00000000000..819ff5fc4e5 --- /dev/null +++ b/packages/gamut-styles/src/theme/utils/shouldForwardProp.ts @@ -0,0 +1,13 @@ +import isPropValid from '@emotion/is-prop-valid'; + +import { properties } from '../props'; + +const allProps = Object.keys(properties).reduce( + (carry, prop: keyof typeof properties) => { + return [...carry, ...properties[prop].propNames]; + }, + [] +); + +export const shouldForwardProp = (prop: string) => + isPropValid(prop) && !allProps.includes(prop); diff --git a/packages/styleguide/.storybook/addons/system/propMeta.ts b/packages/styleguide/.storybook/addons/system/propMeta.ts index 80a95f670bc..7cf7bd3fa51 100644 --- a/packages/styleguide/.storybook/addons/system/propMeta.ts +++ b/packages/styleguide/.storybook/addons/system/propMeta.ts @@ -1,6 +1,6 @@ import * as system from '@codecademy/gamut-styles/src/theme/props'; -const { shouldForwardProp, properties, variant, ...groups } = system; +const { properties, variant, ...groups } = system; export const PROP_GROUPS = groups; From 5f2f455e497784ab64bb98a3f9315a326e0c0b65 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 2 Mar 2021 09:52:20 -0500 Subject: [PATCH 14/15] Rename --- .../src/theme/utils/createVariables.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/gamut-styles/src/theme/utils/createVariables.ts b/packages/gamut-styles/src/theme/utils/createVariables.ts index 94c4ff68593..258f092c22a 100644 --- a/packages/gamut-styles/src/theme/utils/createVariables.ts +++ b/packages/gamut-styles/src/theme/utils/createVariables.ts @@ -20,7 +20,7 @@ export const createVariables = ( break; // If the value is an object then attempt to parse it as a resposnive property case 'object': - const { base, ...otherSelectors } = valuesToRegister; + const { base, ...rest } = valuesToRegister; // If base key is defined add it to the root values if (base) { @@ -28,17 +28,17 @@ export const createVariables = ( } // If there are remaining breakpoints that override the root value add them to style object - const selectors = Object.keys(otherSelectors); + const selectors = Object.keys(rest); if (selectors) { - const valuesByMediaQuery: CSSObject = {}; - selectors.forEach((key) => { - valuesByMediaQuery[key] = { - [varName]: valuesToRegister[key], + const overridesBySelector: CSSObject = {}; + selectors.forEach((selector) => { + overridesBySelector[selector] = { + [varName]: valuesToRegister[selector], }; }); // Merge to preserve all breakpoints - merge(cssVariables, valuesByMediaQuery); + merge(cssVariables, overridesBySelector); } break; default: From 4ac7094fdbf43cf639cbb415b28d2e827e82c136 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 2 Mar 2021 09:54:19 -0500 Subject: [PATCH 15/15] Less nesting --- .../src/theme/utils/createVariables.ts | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/packages/gamut-styles/src/theme/utils/createVariables.ts b/packages/gamut-styles/src/theme/utils/createVariables.ts index 258f092c22a..e4c85e143aa 100644 --- a/packages/gamut-styles/src/theme/utils/createVariables.ts +++ b/packages/gamut-styles/src/theme/utils/createVariables.ts @@ -7,45 +7,43 @@ export const createVariables = ( const cssVariables: CSSObject = {}; for (const variable in tokens) { - if (hasIn(tokens, variable)) { - const varName = `--${variable}`; - const valuesToRegister = tokens[variable]; + if (!hasIn(tokens, variable)) continue; - // For all variables in the theme scale add theme to the resulting CSS Object - switch (typeof valuesToRegister) { - // If the value is primitive just add it as is to the returned vars css object - case 'number': - case 'string': - cssVariables[varName] = valuesToRegister; - break; - // If the value is an object then attempt to parse it as a resposnive property - case 'object': - const { base, ...rest } = valuesToRegister; + const varName = `--${variable}`; + const valuesToRegister = tokens[variable]; - // If base key is defined add it to the root values - if (base) { - cssVariables[varName] = base; - } + // For all variables in the theme scale add theme to the resulting CSS Object + switch (typeof valuesToRegister) { + // If the value is primitive just add it as is to the returned vars css object + case 'number': + case 'string': + cssVariables[varName] = valuesToRegister; + break; + // If the value is an object then attempt to parse it as a resposnive property + case 'object': + const { base, ...rest } = valuesToRegister; - // If there are remaining breakpoints that override the root value add them to style object - const selectors = Object.keys(rest); - if (selectors) { - const overridesBySelector: CSSObject = {}; - selectors.forEach((selector) => { - overridesBySelector[selector] = { - [varName]: valuesToRegister[selector], - }; - }); + // If base key is defined add it to the root values + if (base) { + cssVariables[varName] = base; + } - // Merge to preserve all breakpoints - merge(cssVariables, overridesBySelector); - } - break; - default: - break; - } + // If there are remaining selectors / queries that override the root value add them to style object + const selectors = Object.keys(rest); + if (selectors) { + const overridesBySelector: CSSObject = {}; + selectors.forEach((selector) => { + overridesBySelector[selector] = { + [varName]: valuesToRegister[selector], + }; + }); - // Add variable reference as the theme key's value + // Merge with the base object. + merge(cssVariables, overridesBySelector); + } + break; + default: + break; } } return cssVariables;