diff --git a/packages/common/src/merge.ts b/packages/common/src/merge.ts index c4b36c98ee..dce8e1347c 100644 --- a/packages/common/src/merge.ts +++ b/packages/common/src/merge.ts @@ -1,5 +1,7 @@ -const merge = (target, source) => { - const newTarget = { ...target }; +type UnknownObject = Record; + +const merge = (target: TargetType, source: SourceType): TargetType & SourceType => { + const newTarget: UnknownObject = { ...target }; Object.keys(source).forEach(key => { newTarget[key] = source[key]; @@ -9,11 +11,11 @@ const merge = (target, source) => { typeof source[key] === 'object' && !Array.isArray(source[key]) ) { - newTarget[key] = merge(target[key] || {}, newTarget[key]); + newTarget[key] = merge(target[key] as UnknownObject || {}, newTarget[key] as UnknownObject); } }); - return newTarget; + return newTarget as TargetType & SourceType; }; export default merge; diff --git a/packages/yoga/src/Theme/index.js b/packages/yoga/src/Theme/index.ts similarity index 75% rename from packages/yoga/src/Theme/index.js rename to packages/yoga/src/Theme/index.ts index 6f1d66be3e..37dc896e9e 100644 --- a/packages/yoga/src/Theme/index.js +++ b/packages/yoga/src/Theme/index.ts @@ -1,8 +1,8 @@ import { ThemeProvider, FontLoader } from './Provider'; -import yogaTheme, { v3theme } from './theme'; +import yogaTheme, { v3theme, type Theme } from './theme'; import theme from './helpers/themeReader'; import createTheme from './helpers/themeGenerator'; -export { ThemeProvider, FontLoader, yogaTheme, theme, createTheme, v3theme }; +export { ThemeProvider, FontLoader, yogaTheme, theme, createTheme, v3theme, Theme }; export default ThemeProvider; diff --git a/packages/yoga/src/Theme/theme/index.js b/packages/yoga/src/Theme/theme/index.js deleted file mode 100644 index c5c6fec42e..0000000000 --- a/packages/yoga/src/Theme/theme/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import theme from './theme'; - -export { v3theme } from './v3theme'; - -export default theme; diff --git a/packages/yoga/src/Theme/theme/index.ts b/packages/yoga/src/Theme/theme/index.ts new file mode 100644 index 0000000000..a0efd4b1be --- /dev/null +++ b/packages/yoga/src/Theme/theme/index.ts @@ -0,0 +1,7 @@ +import theme, { type Theme } from './theme'; + +export { v3theme } from './v3theme'; + +export { Theme }; + +export default theme; diff --git a/packages/yoga/src/Theme/theme/theme.js b/packages/yoga/src/Theme/theme/theme.ts similarity index 51% rename from packages/yoga/src/Theme/theme/theme.js rename to packages/yoga/src/Theme/theme/theme.ts index 15e9b0ac29..ff35cbc3b9 100644 --- a/packages/yoga/src/Theme/theme/theme.js +++ b/packages/yoga/src/Theme/theme/theme.ts @@ -1,9 +1,21 @@ /* eslint-disable prefer-destructuring */ import { merge } from '@gympass/yoga-common'; +import yogaTokens from '@gympass/yoga-tokens'; import componentThemes from './componentThemes'; -const getComponentThemes = tokens => { - const { colors, baseFont, baseFontSize } = tokens; +type themeTypes = ReturnType; + +export type Theme = ReturnType; + +const getComponentThemes = (theme: themeTypes) => { + type ComponentThemesType = typeof componentThemes; + type OutputObject = { + [K in keyof ComponentThemesType as `${Lowercase}`]: ReturnType< + ComponentThemesType[K] + >; + }; + + const { colors, baseFont, baseFontSize } = theme; const components = Object.entries(componentThemes).reduce( (componentsStyles, [names, themed]) => { const name = names.toLowerCase(); @@ -11,7 +23,7 @@ const getComponentThemes = tokens => { return { ...componentsStyles, [name]: themed({ - ...tokens, + ...theme, colors, baseFont, baseFontSize, @@ -19,12 +31,12 @@ const getComponentThemes = tokens => { }; }, {}, - ); + ) as OutputObject; return { components }; }; -const theme = tokens => { +const theme = (tokens: typeof yogaTokens) => { const baseFont = tokens.fonts.rubik; const baseFontSize = tokens.fontSizes.medium; @@ -33,10 +45,22 @@ const theme = tokens => { primary: tokens.colors.vibin, secondary: tokens.colors.stamina, feedback: { - success: [tokens.colors.success, tokens.colors.hope], - informative: [tokens.colors.neutral, tokens.colors.relax], - attention: [tokens.colors.attention, tokens.colors.verve], - neutral: [tokens.colors.light, tokens.colors.medium], + success: Object.assign([tokens.colors.success, tokens.colors.hope], { + light: tokens.colors.success, + dark: tokens.colors.hope, + }), + informative: Object.assign([tokens.colors.neutral, tokens.colors.relax], { + light: tokens.colors.neutral, + dark: tokens.colors.relax, + }), + attention: Object.assign([tokens.colors.attention, tokens.colors.verve], { + light: tokens.colors.attention, + dark: tokens.colors.verve, + }), + neutral: Object.assign([tokens.colors.light, tokens.colors.medium], { + light: tokens.colors.light, + dark: tokens.colors.medium, + }), }, text: { primary: tokens.colors.stamina, @@ -50,18 +74,6 @@ const theme = tokens => { }, }; - [colors.feedback.success.light, colors.feedback.success.dark] = - colors.feedback.success; - - [colors.feedback.informative.light, colors.feedback.informative.dark] = - colors.feedback.informative; - - [colors.feedback.attention.light, colors.feedback.attention.dark] = - colors.feedback.attention; - - [colors.feedback.neutral.light, colors.feedback.neutral.dark] = - colors.feedback.neutral; - return { ...tokens, colors, @@ -71,7 +83,7 @@ const theme = tokens => { }; }; -const composeTheme = (tokens, customTheming = {}) => { +const composeTheme = (tokens: typeof yogaTokens, customTheming = {}) => { const baseTheme = theme(tokens); const customTheme = merge(baseTheme, customTheming); const componentTheming = getComponentThemes(customTheme); diff --git a/packages/yoga/src/index.ts b/packages/yoga/src/index.ts index cfbaab95d1..9d5110a278 100644 --- a/packages/yoga/src/index.ts +++ b/packages/yoga/src/index.ts @@ -4,6 +4,7 @@ import ThemeProvider, { theme, createTheme, v3theme, + type Theme, } from './Theme'; import Accordion from './Accordion'; import Button from './Button'; @@ -92,4 +93,5 @@ export { Popover, Spinner, NavigationMenu, + Theme, };