Skip to content

Commit

Permalink
Merge pull request #14 from MOCHI-inc-JAPAN/upmain
Browse files Browse the repository at this point in the history
Upmain
  • Loading branch information
tkow authored Dec 9, 2022
2 parents 613fd2a + b40cb92 commit bec0751
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 63 deletions.
56 changes: 56 additions & 0 deletions example/src/PerfTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useMemo } from 'react';
import { Stack } from './components';
import { styled } from './styles';

let measured = false;

export default function PerfTest() {
const start = useMemo(() => new Date(), []);

return (
<Wrapper
onLayout={() => {
if (!measured) {
measured = true;
console.log(
`Time taken: ${new Date().getTime() - start.getTime()} ms`
);
}
}}
>
<Content>
<Stack axis="y" space="4">
{Array.from({ length: 1000 }).map((_, i) => (
<Box key={i}>
<BoxText>{i + 1}</BoxText>
</Box>
))}
</Stack>
</Content>
</Wrapper>
);
}

const Wrapper = styled('SafeAreaView', {
flex: 1,
backgroundColor: '$background',
});

const Content = styled('ScrollView', {
flex: 1,
}).attrs((p) => ({
contentContainerStyle: {
padding: p.theme.space[2],
},
}));

const Box = styled('View', {
minHeight: 100,
backgroundColor: '$primaryMuted',
flexCenter: 'row',
borderRadius: '$md',
});

const BoxText = styled('Text', {
color: '$primaryText',
});
9 changes: 9 additions & 0 deletions example/src/type-test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { styled, css } from './styles';

const View = styled('View', {});

const csstest = css({
fontSize: 16,
});

export const Test = <View css={csstest} />;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stitches-native",
"description": "The modern CSS-in-JS library for React Native",
"version": "0.3.1",
"version": "0.4.0",
"license": "MIT",
"author": "Teemu Taskula",
"repository": "https://github.com/Temzasse/stitches-native",
Expand Down
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 @@ -192,58 +192,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,
});
});
});
7 changes: 1 addition & 6 deletions src/types/stitches.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,7 @@ export default interface Stitches<
: unknown;
};
}
): StyledComponent.CssComponent<
StyledComponent.StyledComponentType<Composers>,
StyledComponent.StyledComponentProps<Composers>,
Media,
CSS
>;
): CSS;
}; // TODO: `variants` inside `css` break TS...
styled: {
<
Expand Down

0 comments on commit bec0751

Please sign in to comment.