Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: default variant not being applied when setting variant property name #152

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/composeRestyleFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<keyof TProps, true>,
Expand Down Expand Up @@ -62,6 +64,7 @@ const composeRestyleFunctions = <
buildStyle,
properties,
propertiesMap,
variantProp: variantProp ? variantProp.property : 'variant',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default should be coming from here, so I don't think defaulting here to variant, too, is necessary.

Suggested change
variantProp: variantProp ? variantProp.property : 'variant',
variantProp: variantProp ? variantProp.property : undefined,

Or possibly even variantProp: variantProp?.property, if that works.

};
};

Expand Down
18 changes: 14 additions & 4 deletions src/hooks/useRestyle.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
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';
import useTheme from './useTheme';

const filterRestyleProps = <
TRestyleProps,
TProps extends Record<string, unknown> & TRestyleProps
TProps extends Record<string, unknown> & TRestyleProps,
Theme extends BaseTheme
>(
componentProps: TProps,
omitPropertiesMap: Record<keyof TProps, boolean>,
variant: RestyleFunctionContainer<TProps, Theme>['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]) {
Expand Down Expand Up @@ -59,6 +67,7 @@ const useRestyle = <
) => RNStyle;
properties: (keyof TProps)[];
propertiesMap: Record<keyof TProps, boolean>;
variantProp: RestyleFunctionContainer<TProps, Theme>['property'];
},
props: TProps,
) => {
Expand All @@ -68,6 +77,7 @@ const useRestyle = <
const {cleanProps, restyleProps, serializedRestyleProps} = filterRestyleProps(
props,
composedRestyleFunction.propertiesMap,
composedRestyleFunction.variantProp,
);

const calculatedStyle = useMemo(() => {
Expand Down
102 changes: 100 additions & 2 deletions src/test/createRestyleComponent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ const Component = createRestyleComponent<
const cardVariant = createVariant<ThemeWithVariant, 'cardVariants'>({
themeKey: 'cardVariants',
});
const cardVariantRenamed = createVariant({
themeKey: 'cardVariants',
property: 'size',
});
const ComponentWithVariant = createRestyleComponent<
BackgroundColorProps<ThemeWithVariant> &
SpacingProps<ThemeWithVariant> &
Expand All @@ -82,6 +86,14 @@ const ComponentWithVariant = createRestyleComponent<
ViewProps,
ThemeWithVariant
>([backgroundColor, spacing, opacity, cardVariant]);
const ComponentWithRenamedVariant = createRestyleComponent<
BackgroundColorProps<ThemeWithVariant> &
SpacingProps<ThemeWithVariant> &
OpacityProps<ThemeWithVariant> &
VariantProps<ThemeWithVariant, 'cardVariants', 'size'> &
ViewProps,
ThemeWithVariant
>([backgroundColor, spacing, opacity, cardVariantRenamed]);

describe('createRestyleComponent', () => {
describe('creates a component that', () => {
Expand Down Expand Up @@ -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(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithVariant />
</ThemeProvider>,
);
expect(root.findByType(View).props.style).toStrictEqual([
{
alignItems: 'flex-start',
backgroundColor: '#FFB6C1',
},
]);
});

it('passes styles from specified default variant', () => {
const {root} = render(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithVariant variant="regular" />
</ThemeProvider>,
);
expect(root.findByType(View).props.style).toStrictEqual([
{
alignItems: 'center',
backgroundColor: '#E0FFFF',
},
]);
});

it('passes styles from default variant with style prop', () => {
const {root} = render(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithVariant margin="s" />
Expand All @@ -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(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithVariant variant="regular" margin="s" />
Expand All @@ -198,5 +238,63 @@ describe('createRestyleComponent', () => {
},
]);
});

it('passes styles from renamed default variant', () => {
const {root} = render(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithRenamedVariant />
</ThemeProvider>,
);
expect(root.findByType(View).props.style).toStrictEqual([
{
alignItems: 'flex-start',
backgroundColor: '#FFB6C1',
},
]);
});

it('passes styles from specified renamed variant', () => {
const {root} = render(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithRenamedVariant size="regular" />
</ThemeProvider>,
);
expect(root.findByType(View).props.style).toStrictEqual([
{
alignItems: 'center',
backgroundColor: '#E0FFFF',
},
]);
});

it('passes styles from renamed default variant with style prop', () => {
const {root} = render(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithRenamedVariant margin="s" />
</ThemeProvider>,
);
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(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithRenamedVariant size="regular" margin="s" />
</ThemeProvider>,
);
expect(root.findByType(View).props.style).toStrictEqual([
{
alignItems: 'center',
backgroundColor: '#E0FFFF',
margin: 8,
},
]);
});
});
});