Skip to content

Commit

Permalink
Fixed runtime styles (#43)
Browse files Browse the repository at this point in the history
* fix: fixed runtime styles

* fix: fixes based on memo feedback

* test: added more tests
  • Loading branch information
0xcadams authored Dec 7, 2022
1 parent 2057272 commit 8fd4da4
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 56 deletions.
25 changes: 17 additions & 8 deletions src/internals/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,28 @@ export function createStitches(config = {}) {

const styles = _styles;

const styleSheets = utils.createStyleSheets({
styles,
config,
themes,
variants,
compoundVariants,
});
const styleSheets = {};

let attrsFn;

let Comp = forwardRef((props, ref) => {
const theme = useThemeInternal();
const styleSheet = styleSheets[theme.definition.__ID__];

const styleSheet = useMemo(() => {
const _styleSheet = styleSheets[theme.definition.__ID__];
if (_styleSheet) {
return _styleSheet;
}
styleSheets[theme.definition.__ID__] = utils.createStyleSheet({
styles,
config,
theme,
variants,
compoundVariants,
});
return styleSheets[theme.definition.__ID__];
}, [theme]);

const { width: windowWidth } = useWindowDimensions();

let variantStyles = [];
Expand Down
88 changes: 40 additions & 48 deletions src/internals/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,58 +175,50 @@ export function processStyles({ styles, theme, config }) {
}, {});
}

export function createStyleSheets({
themes,
export function createStyleSheet({
theme,
styles,
config,
variants,
compoundVariants,
}) {
const styleSheets = themes.reduce((styleSheetAcc, theme) => {
styleSheetAcc[theme.definition.__ID__] = StyleSheet.create({
base: styles
? processStyles({ styles, config, theme: theme.values })
: {},
// Variant styles
...Object.entries(variants).reduce(
(variantsAcc, [vartiantProp, variantValues]) => {
Object.entries(variantValues).forEach(
([variantName, variantStyles]) => {
// Eg. `color_primary` or `size_small`
const key = `${vartiantProp}_${variantName}`;

variantsAcc[key] = processStyles({
styles: variantStyles,
config,
theme: theme.values,
});
}
);
return variantsAcc;
},
{}
),
// Compound variant styles
...compoundVariants.reduce((compoundAcc, compoundVariant) => {
const { css, ...compounds } = compoundVariant;
const compoundEntries = Object.entries(compounds);

if (compoundEntries.length > 1) {
const key = getCompoundKey(compoundEntries);

compoundAcc[key] = processStyles({
styles: css || {},
config,
theme: theme.values,
});
}

return compoundAcc;
}, {}),
});

return styleSheetAcc;
}, {});
return StyleSheet.create({
base: styles ? processStyles({ styles, config, theme: theme.values }) : {},
// Variant styles
...Object.entries(variants).reduce(
(variantsAcc, [variantProp, variantValues]) => {
Object.entries(variantValues).forEach(
([variantName, variantStyles]) => {
// Eg. `color_primary` or `size_small`
const key = `${variantProp}_${variantName}`;

variantsAcc[key] = processStyles({
styles: variantStyles,
config,
theme: theme.values,
});
}
);
return variantsAcc;
},
{}
),
// Compound variant styles
...compoundVariants.reduce((compoundAcc, compoundVariant) => {
const { css, ...compounds } = compoundVariant;
const compoundEntries = Object.entries(compounds);

if (compoundEntries.length > 1) {
const key = getCompoundKey(compoundEntries);

compoundAcc[key] = processStyles({
styles: css || {},
config,
theme: theme.values,
});
}

return styleSheets;
return compoundAcc;
}, {}),
});
}
126 changes: 126 additions & 0 deletions src/tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,130 @@ describe('Basic', () => {
width: 100,
});
});

it('Functionality of styled() should not trigger recompute when a runtime theme is not used', () => {
const { styled, createTheme } = createStitches({
theme: {
sizes: { demoWidth: 100 },
},
});

const Comp = styled('View', {
backgroundColor: 'red',
height: 100,
width: '$demoWidth',
});

render(<Comp />);

createTheme({ sizes: { demoWidth: 10 } });

const { toJSON } = render(<Comp />);

const result = toJSON();

expect(result?.type).toEqual('View');
expect(result?.props.style[0]).toMatchObject({
backgroundColor: 'red',
height: 100,
width: 100,
});
});
});

describe('Runtime', () => {
it('Functionality of ThemeProvider', () => {
const { styled, createTheme, ThemeProvider } = createStitches({
theme: {
sizes: { demoWidth: 100 },
},
});

const Comp = styled('View', {
backgroundColor: 'red',
height: 100,
width: '$demoWidth',
});

const newTheme = createTheme({ sizes: { demoWidth: 30 } });

const { toJSON } = render(
<ThemeProvider theme={newTheme}>
<Comp />
</ThemeProvider>
);

const result = toJSON();

expect(result?.type).toEqual('View');
expect(result?.props.style[0]).toMatchObject({
backgroundColor: 'red',
height: 100,
width: 30,
});
});

it('Functionality of ThemeProvider should use new theme when a runtime theme is added', () => {
const { styled, createTheme, ThemeProvider } = createStitches({
theme: {
sizes: { demoWidth: 100 },
},
});

const Comp = styled('View', {
backgroundColor: 'red',
height: 100,
width: '$demoWidth',
});

const newTheme = createTheme({ sizes: { demoWidth: 10 } });

const { toJSON } = render(
<ThemeProvider theme={newTheme}>
<Comp />
</ThemeProvider>
);

const result = toJSON();

expect(result?.type).toEqual('View');
expect(result?.props.style[0]).toMatchObject({
backgroundColor: 'red',
height: 100,
width: 10,
});
});

it('Functionality of ThemeProvider should trigger recompute when a runtime theme is added', () => {
const { styled, createTheme, ThemeProvider } = createStitches({
theme: {
sizes: { demoWidth: 100 },
},
});

const Comp = styled('View', {
backgroundColor: 'red',
height: 100,
width: '$demoWidth',
});

render(<Comp />);

const newTheme = createTheme({ sizes: { demoWidth: 10 } });

const { toJSON } = render(
<ThemeProvider theme={newTheme}>
<Comp />
</ThemeProvider>
);

const result = toJSON();

expect(result?.type).toEqual('View');
expect(result?.props.style[0]).toMatchObject({
backgroundColor: 'red',
height: 100,
width: 10,
});
});
});

0 comments on commit 8fd4da4

Please sign in to comment.