diff --git a/src/composeRestyleFunctions.ts b/src/composeRestyleFunctions.ts index 6b3f817c..da159869 100644 --- a/src/composeRestyleFunctions.ts +++ b/src/composeRestyleFunctions.ts @@ -23,10 +23,12 @@ const composeRestyleFunctions = < }, [], ); - - const properties = flattenedRestyleFunctions.map(styleFunc => { - return styleFunc.property; - }); + const variantProp = flattenedRestyleFunctions.find( + item => item.variant === true, + ); + const properties = flattenedRestyleFunctions.map( + styleFunc => styleFunc.property, + ); const propertiesMap = properties.reduce( (acc, prop) => ({...acc, [prop]: true}), {} as Record, @@ -62,6 +64,7 @@ const composeRestyleFunctions = < buildStyle, properties, propertiesMap, + variantProp: variantProp ? variantProp.property : 'variant', }; }; diff --git a/src/hooks/useRestyle.ts b/src/hooks/useRestyle.ts index 420d1304..b453ba06 100644 --- a/src/hooks/useRestyle.ts +++ b/src/hooks/useRestyle.ts @@ -1,7 +1,12 @@ import {useMemo} from 'react'; import {StyleProp} from 'react-native'; -import {BaseTheme, RNStyle, Dimensions} from '../types'; +import { + BaseTheme, + RNStyle, + Dimensions, + RestyleFunctionContainer, +} from '../types'; import {getKeys} from '../typeHelpers'; import useDimensions from './useDimensions'; @@ -9,14 +14,17 @@ import useTheme from './useTheme'; const filterRestyleProps = < TRestyleProps, - TProps extends Record & TRestyleProps + TProps extends Record & TRestyleProps, + Theme extends BaseTheme >( componentProps: TProps, omitPropertiesMap: Record, + variant: RestyleFunctionContainer['property'], ) => { - const props = omitPropertiesMap.variant - ? {variant: 'defaults', ...componentProps} + const props = omitPropertiesMap[variant] + ? {[variant]: 'defaults', ...componentProps} : componentProps; + return getKeys(props).reduce( ({cleanProps, restyleProps, serializedRestyleProps}, key) => { if (omitPropertiesMap[key as keyof TProps]) { @@ -59,6 +67,7 @@ const useRestyle = < ) => RNStyle; properties: (keyof TProps)[]; propertiesMap: Record; + variantProp: RestyleFunctionContainer['property']; }, props: TProps, ) => { @@ -68,6 +77,7 @@ const useRestyle = < const {cleanProps, restyleProps, serializedRestyleProps} = filterRestyleProps( props, composedRestyleFunction.propertiesMap, + composedRestyleFunction.variantProp, ); const calculatedStyle = useMemo(() => { diff --git a/src/test/createRestyleComponent.test.tsx b/src/test/createRestyleComponent.test.tsx index c3a4af23..662e2d18 100644 --- a/src/test/createRestyleComponent.test.tsx +++ b/src/test/createRestyleComponent.test.tsx @@ -74,6 +74,10 @@ const Component = createRestyleComponent< const cardVariant = createVariant({ themeKey: 'cardVariants', }); +const cardVariantRenamed = createVariant({ + themeKey: 'cardVariants', + property: 'size', +}); const ComponentWithVariant = createRestyleComponent< BackgroundColorProps & SpacingProps & @@ -82,6 +86,14 @@ const ComponentWithVariant = createRestyleComponent< ViewProps, ThemeWithVariant >([backgroundColor, spacing, opacity, cardVariant]); +const ComponentWithRenamedVariant = createRestyleComponent< + BackgroundColorProps & + SpacingProps & + OpacityProps & + VariantProps & + ViewProps, + ThemeWithVariant +>([backgroundColor, spacing, opacity, cardVariantRenamed]); describe('createRestyleComponent', () => { describe('creates a component that', () => { @@ -169,7 +181,35 @@ describe('createRestyleComponent', () => { ); }); - it('passes styles from default variant when no variant prop is defined', () => { + it('passes styles from default variant', () => { + const {root} = render( + + + , + ); + expect(root.findByType(View).props.style).toStrictEqual([ + { + alignItems: 'flex-start', + backgroundColor: '#FFB6C1', + }, + ]); + }); + + it('passes styles from specified default variant', () => { + const {root} = render( + + + , + ); + expect(root.findByType(View).props.style).toStrictEqual([ + { + alignItems: 'center', + backgroundColor: '#E0FFFF', + }, + ]); + }); + + it('passes styles from default variant with style prop', () => { const {root} = render( @@ -184,7 +224,7 @@ describe('createRestyleComponent', () => { ]); }); - it('passes styles from the defined variant', () => { + it('passes styles from the specified variant with style prop', () => { const {root} = render( @@ -198,5 +238,63 @@ describe('createRestyleComponent', () => { }, ]); }); + + it('passes styles from renamed default variant', () => { + const {root} = render( + + + , + ); + expect(root.findByType(View).props.style).toStrictEqual([ + { + alignItems: 'flex-start', + backgroundColor: '#FFB6C1', + }, + ]); + }); + + it('passes styles from specified renamed variant', () => { + const {root} = render( + + + , + ); + expect(root.findByType(View).props.style).toStrictEqual([ + { + alignItems: 'center', + backgroundColor: '#E0FFFF', + }, + ]); + }); + + it('passes styles from renamed default variant with style prop', () => { + const {root} = render( + + + , + ); + expect(root.findByType(View).props.style).toStrictEqual([ + { + alignItems: 'flex-start', + backgroundColor: '#FFB6C1', + margin: 8, + }, + ]); + }); + + it('passes styles from specified renamed variant with style prop', () => { + const {root} = render( + + + , + ); + expect(root.findByType(View).props.style).toStrictEqual([ + { + alignItems: 'center', + backgroundColor: '#E0FFFF', + margin: 8, + }, + ]); + }); }); });