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 #148

Merged
merged 5 commits into from
Apr 11, 2022
Merged
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
5 changes: 4 additions & 1 deletion src/hooks/useRestyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ const filterRestyleProps = <
TRestyleProps,
TProps extends Record<string, unknown> & TRestyleProps
>(
props: TProps,
componentProps: TProps,
omitPropertiesMap: Record<keyof TProps, boolean>,
) => {
const props = omitPropertiesMap.variant
? {variant: 'defaults', ...componentProps}
: componentProps;
return getKeys(props).reduce(
({cleanProps, restyleProps, serializedRestyleProps}, key) => {
if (omitPropertiesMap[key as keyof TProps]) {
Expand Down
109 changes: 96 additions & 13 deletions src/test/createRestyleComponent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@ import {
opacity,
} from '../restyleFunctions';
import {ThemeProvider} from '../context';
import createVariant, {VariantProps} from '../createVariant';

const theme = {
colors: {
coral: '#FFE6E4',
lightcyan: '#E0FFFF',
lightpink: '#FFB6C1',
},
spacing: {
s: 8,
},
spacing: {},
breakpoints: {
phone: 0,
tablet: 376,
Expand All @@ -27,24 +32,56 @@ const theme = {
almostOpaque: 0.9,
},
};
const themeWithVariant = {
...theme,
cardVariants: {
defaults: {
alignItems: 'flex-start',
backgroundColor: 'lightpink',
},
regular: {
alignItems: 'center',
backgroundColor: 'lightcyan',
},
},
};
type Theme = typeof theme;
type ThemeWithVariant = typeof themeWithVariant;

jest.mock('react-native/Libraries/Utilities/Dimensions', () => {
return {
get: () => ({
width: 375,
height: 667,
}),
addEventListener: jest.fn(),
};
jest.mock('react-native', () => {
return Object.setPrototypeOf(
{
Dimensions: {
get: () => ({
width: 375,
height: 667,
}),
addEventListener: jest.fn(() => ({remove: () => {}})),
removeEventListener: jest.fn(),
},
},
jest.requireActual('react-native'),
);
});

const Component = createRestyleComponent<
BackgroundColorProps<Theme> &
SpacingProps<Theme> &
OpacityProps<Theme> &
ViewProps,
Theme
>([backgroundColor, spacing, opacity]);
const cardVariant = createVariant<ThemeWithVariant, 'cardVariants'>({
themeKey: 'cardVariants',
});
const ComponentWithVariant = createRestyleComponent<
BackgroundColorProps<ThemeWithVariant> &
SpacingProps<ThemeWithVariant> &
OpacityProps<ThemeWithVariant> &
VariantProps<ThemeWithVariant, 'cardVariants'> &
ViewProps,
ThemeWithVariant
>([backgroundColor, spacing, opacity, cardVariant]);

describe('createRestyleComponent', () => {
describe('creates a component that', () => {
Expand All @@ -53,20 +90,32 @@ describe('createRestyleComponent', () => {
});

it('passes styles based on the given props', () => {
const {root} = render(<Component opacity={0.5} />);
const {root} = render(
<ThemeProvider theme={theme}>
<Component opacity={0.5} />
</ThemeProvider>,
);
expect(root.findByType(View).props.style).toStrictEqual([{opacity: 0.5}]);
});

it('appends style prop to the end', () => {
const {root} = render(<Component opacity={0.5} style={{width: 100}} />);
const {root} = render(
<ThemeProvider theme={theme}>
<Component opacity={0.5} style={{width: 100}} />
</ThemeProvider>,
);
expect(root.findByType(View).props.style).toStrictEqual([
{opacity: 0.5},
{width: 100},
]);
});

it('does not pass styling properties to the child', () => {
const {root} = render(<Component opacity={0.5} pointerEvents="auto" />);
const {root} = render(
<ThemeProvider theme={theme}>
<Component opacity={0.5} pointerEvents="auto" />
</ThemeProvider>,
);
expect(root.findByType(View).props).toStrictEqual({
style: [{opacity: 0.5}],
pointerEvents: 'auto',
Expand Down Expand Up @@ -107,13 +156,47 @@ describe('createRestyleComponent', () => {

it('forwards refs', () => {
const spy = jest.fn();
render(<Component ref={spy} testID="RENDERED_COMPONENT" />);
render(
<ThemeProvider theme={theme}>
<Component ref={spy} testID="RENDERED_COMPONENT" />
</ThemeProvider>,
);

expect(spy).toHaveBeenCalledWith(
expect.objectContaining({
props: expect.objectContaining({testID: 'RENDERED_COMPONENT'}),
}),
);
});

it('passes styles from default variant when no variant prop is defined', () => {
const {root} = render(
<ThemeProvider theme={themeWithVariant}>
<ComponentWithVariant margin="s" />
</ThemeProvider>,
);
expect(root.findByType(View).props.style).toStrictEqual([
{
alignItems: 'flex-start',
backgroundColor: '#FFB6C1',
margin: 8,
},
]);
});

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