diff --git a/README.md b/README.md index f721fea1..20560c0b 100644 --- a/README.md +++ b/README.md @@ -415,6 +415,10 @@ const theme = createTheme({ tablet: 768, }, cardVariants: { + defaults: { + // We can define defaults for the variant here. + // This will be applied after the defaults passed to createVariant and before the variant defined below. + }, regular: { // We can refer to other values in the theme here, and use responsive props padding: { diff --git a/src/createVariant.ts b/src/createVariant.ts index ab8ef615..666719b6 100644 --- a/src/createVariant.ts +++ b/src/createVariant.ts @@ -50,9 +50,14 @@ function createVariant< const expandedProps = styleFunction.func(props, {theme, dimensions})[ property ]; - if (!expandedProps && !defaults) return {}; + + const variantDefaults = theme[themeKey].defaults as Partial< + AllProps + >; + + if (!expandedProps && !defaults && !variantDefaults) return {}; return allRestyleFunctions.buildStyle( - {...defaults, ...expandedProps}, + {...defaults, ...variantDefaults, ...expandedProps}, { theme, dimensions, @@ -71,6 +76,8 @@ export type VariantProps< Theme extends BaseTheme, K extends keyof Theme, Property extends keyof any = 'variant' -> = {[key in Property]?: ResponsiveValue}; +> = { + [key in Property]?: ResponsiveValue, Theme>; +}; export default createVariant; diff --git a/src/test/createVariant.test.ts b/src/test/createVariant.test.ts index 49aef770..4a18823d 100644 --- a/src/test/createVariant.test.ts +++ b/src/test/createVariant.test.ts @@ -33,6 +33,22 @@ const theme = { color: 'white', }, }, + boxVariants: { + defaults: { + fontSize: { + phone: 12, + tablet: 24, + }, + backgroundColor: { + phone: 'black', + tablet: 'white', + }, + }, + primary: { + width: 50, + height: 50, + }, + }, }; const dimensions = { width: 375, @@ -62,6 +78,65 @@ describe('createVariant', () => { }); }); + it('accepts defaults from the theme', () => { + const variant = createVariant({ + themeKey: 'boxVariants', + }); + expect(variant.func({}, {theme, dimensions})).toStrictEqual({ + fontSize: 12, + backgroundColor: '#111111', + }); + }); + + it('accepts defaults from the theme and correctly overrides variant defaults', () => { + const variant = createVariant({ + themeKey: 'boxVariants', + defaults: { + fontSize: 10, + opacity: 0.5, + }, + }); + + expect(variant.func({}, {theme, dimensions})).toStrictEqual({ + backgroundColor: '#111111', + fontSize: 12, + opacity: 0.5, + }); + }); + + it('correctly uses the breakpoints for defaults within the theme', () => { + const variant = createVariant({ + themeKey: 'boxVariants', + defaults: { + fontSize: 10, + opacity: 0.5, + }, + }); + + expect(variant.func({}, {theme, dimensions})).toStrictEqual({ + backgroundColor: '#111111', + fontSize: 12, + opacity: 0.5, + }); + + expect( + variant.func( + {}, + { + theme, + dimensions: { + width: 376, + height: 667, + }, + }, + ), + ).toStrictEqual({ + backgroundColor: '#EEEEEE', + fontSize: 24, + opacity: 0.5, + }); + }); + it('correctly overrides default values', () => { const variant = createVariant({ themeKey: 'textVariants',