Skip to content

Commit

Permalink
feat: resolve #94
Browse files Browse the repository at this point in the history
  • Loading branch information
mym0404 committed Apr 26, 2024
1 parent 6fe4345 commit 092f5f2
Show file tree
Hide file tree
Showing 16 changed files with 117 additions and 45 deletions.
36 changes: 25 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
# React Native Styled System
<p align="center">
<a href="https://mj-studio-library.github.io/react-native-naver-map/">
<img width="160px" src="https://raw.githubusercontent.com/mym0404/image-archive/master/202404261501218.webp"><br/>
</a>
<h1 align="center">React Native Styled System</h1>
<p align="center">
<a href="https://www.npmjs.com/package/@react-native-styled-system/core"><img src="https://img.shields.io/npm/dm/@react-native-styled-system/core.svg?style=flat-square" alt="NPM downloads"></a>
<a href="https://www.npmjs.com/package/@react-native-styled-system/core"><img src="https://img.shields.io/npm/v/@react-native-styled-system/core.svg?style=flat-square" alt="NPM version"></a>
<a href="/LICENSE"><img src="https://img.shields.io/npm/l/@react-native-styled-system/core.svg?style=flat-square" alt="License"></a>
<h3 align="center">Bring styled-system to React Native</h3>
</p>
</p>

[Documentation](https://mj-studio-library.github.io/react-native-styled-system/)
---

- [Documentation](https://mj-studio-library.github.io/react-native-styled-system/)

![ogimage](https://github.com/mj-studio-library/react-native-styled-system/assets/33388801/13d03f17-cc7a-45a8-8f63-24b75dade0ff)


`React Native Styled System` is a React Native implementation
of the `styled-system` package commonly used on the web.

## Highlights

- ⚡️ All styles are cached. So it doesn't cause any rerender if result is consistent.
- ⭐️ Allows arguments such as `m, px, py, bg, flex, flexDirection, position` to be passed directly to Props according to the grammar of `styled-system`.
- 🎨 Users can define the design system by directly defining and delivering themes.
- ❤️ TypeScript can be fully used through the Type Generation process using CLI.
- 🚀 Logical or responsive values such as `safeAreaTop` and `sidePadding` can be injected into the theme and used as token values.
- 💬 Text Typography
- 🎉 Integrate Dark Theme easily.

## Why we need styled-system

Let me show this code.
Expand Down Expand Up @@ -60,14 +82,6 @@ We introduce **React Native Styled System** 🎉
>
> Styles such as `justifySelf` that are not yet supported in React Native obviously cannot be added in the future.
## Supported features

- Allows arguments such as `m, px, py, bg, flex, flexDirection, position` to be passed directly to Props according to the grammar of `styled-system`.
- Users can define the design system by directly defining and delivering themes.
- TypeScript can be fully used through the Type Generation process using CLI.
- Logical or responsive values such as `safeAreaTop` and `sidePadding` can be injected into the theme and used as token values.
- Integrate Dark Theme easily.

## Contributing

Feel like contributing? That's awesome! We have a
Expand Down
17 changes: 9 additions & 8 deletions doc/docs/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ Styles such as `justifySelf` that are not yet supported in React Native obviousl
:::


## Supported features

- Allows arguments such as `m, px, py, bg, flex, flexDirection, position` to be passed directly to Props according to the grammar of `styled-system`.
- Users can define the design system by directly defining and delivering themes.
- TypeScript can be fully used through the Type Generation process using CLI.
- Logical or responsive values such as `safeAreaTop` and `sidePadding` can be injected into the theme and used as token values.
- Text Typography
- Integrate Dark Theme easily.
## Highlights

- ⚡️ All styles are cached. So it doesn't cause any rerender if result is consistent.
- ⭐️ Allows arguments such as `m, px, py, bg, flex, flexDirection, position` to be passed directly to Props according to the grammar of `styled-system`.
- 🎨 Users can define the design system by directly defining and delivering themes.
- ❤️ TypeScript can be fully used through the Type Generation process using CLI.
- 🚀 Logical or responsive values such as `safeAreaTop` and `sidePadding` can be injected into the theme and used as token values.
- 💬 Text Typography
- 🎉 Integrate Dark Theme easily.
4 changes: 2 additions & 2 deletions doc/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Config } from '@docusaurus/types';
import { themes as prismThemes } from 'prism-react-renderer';

const title = 'React Native Styled System';
const description = 'styled-system mimic for React Native';
const description = 'styled-system for React Native';
const websiteUrl = 'https://mj-studio-library.github.io/react-native-styled-system/';
const repoOrg = 'mj-studio-library';
const repoName = 'react-native-styled-system';
Expand Down Expand Up @@ -63,7 +63,7 @@ const config: Config = {
title: title,
logo: {
alt: 'My Site Logo',
src: 'img/logo.svg',
src: 'img/logo96.png',
},
items: [
{
Expand Down
6 changes: 3 additions & 3 deletions doc/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ export default function Home(): JSX.Element {
<Layout title={`${siteConfig.title}`} description={'Mimic styled-system for React Native'}>
<main style={{ flex: 1, justifyContent: 'center', display: 'flex', flexDirection: 'column' }}>
<div className={clsx(styles.heroBanner, 'container')} style={{ paddingBottom: '120px' }}>
<img src={'img/logo.svg'} width={64} height={64} alt={'logo'} />
<img src={'img/logo.png'} width={256} height={256} alt={'logo'} />
<Heading as={'h1'} className={'hero__title'}>
{siteConfig.title}
</Heading>
<p className={'hero__subtitle'}>{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link className={'button button--secondary button--lg'} to={'/docs/intro'}>
{'Getting Started ⏱️'}
{'Getting Started'}
</Link>
</div>
<img
Expand All @@ -35,7 +35,7 @@ export default function Home(): JSX.Element {
/>
<div style={{ marginTop: 24 }}>
<code style={{ borderWidth: 1, padding: 5, whiteSpace: 'pre-wrap' }}>
{'npm install @react-native-styled-system/core'}
{'yarn add @react-native-styled-system/core'}
</code>
</div>
</div>
Expand Down
Binary file modified doc/static/img/favicon.ico
Binary file not shown.
Binary file added doc/static/img/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 0 additions & 11 deletions doc/static/img/logo.svg

This file was deleted.

Binary file removed doc/static/img/logo48.png
Binary file not shown.
Binary file added doc/static/img/logo96.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified doc/static/img/ogimage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@commitlint/config-conventional": "^19.1.0",
"@mj-studio/eslint-config-react": "^1.0.4",
"@types/jest": "^29.5.12",
"@types/object-hash": "^3",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.57.0",
"husky": "^9.0.11",
Expand All @@ -36,5 +37,8 @@
},
"workspaces": [
"packages/*"
]
],
"dependencies": {
"object-hash": "^3.0.0"
}
}
25 changes: 24 additions & 1 deletion packages/core/src/hook/useSx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ function expectResult(
if (filteredPropsExpectation) {
expect(filteredProps).toEqual(filteredPropsExpectation);
}

return [getStyle(), filteredProps];
}

const emptyTheme = emptyThemedDict;
Expand Down Expand Up @@ -140,7 +142,6 @@ describe('space parsing', () => {
it('px suffix string, return parsed pixel number value', () => {
expectResult(emptyTheme, { m: '15px' }, { expectation: { margin: 15 } });
expectResult(emptyTheme, { m: '-1.5px' }, { expectation: { margin: -1.5 } });
expectResult(emptyTheme, { m: '-0px' }, { expectation: { margin: -0 } });
expectResult(emptyTheme, { m: '0px' }, { expectation: { margin: 0 } });
expectResult(emptyTheme, { m: '-1px' }, { expectation: { margin: -1 } });
});
Expand Down Expand Up @@ -354,3 +355,25 @@ describe('transform', () => {
});
});
});

describe('cache', () => {
it('same style result will be cached', () => {
const [style1] = expectResult(
emptyTheme,
{ bg: 'red', mt: 2 },
{
expectation: { marginTop: 2, backgroundColor: 'red' },
},
);

const [style2] = expectResult(
emptyTheme,
{ mt: 2, sx: { bg: 'red' } },
{
expectation: { marginTop: 2, backgroundColor: 'red' },
},
);

expect(style1 === style2).toBe(true);
});
});
11 changes: 7 additions & 4 deletions packages/core/src/hook/useSx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { ThemedDict } from '../@types/ThemedDict';
import { useStableCallback } from '../internal/useStableCallback';
import { mutateShortcutPropToOriginalKeys } from '../internal/util/mutateShortcutPropToOriginalKeys';
import { printWarning } from '../internal/util/printWarning';
import { getCachedStyle } from '../internal/util/StyleHash';
import { StyledSystemContext } from '../provider/StyledSystemProvider';
import type { ThemedStyleType } from '../util/propsToThemedStyle';
import { propsToThemedStyle } from '../util/propsToThemedStyle';
Expand Down Expand Up @@ -75,12 +76,14 @@ export const useSx = <S extends ViewStyle = ViewStyle, P extends Props = Props>(
if (is.function(transform)) {
const transformedSx = transform(StyleSheet.flatten(composedStyle));

return StyleSheet.compose(
composedStyle,
propsToThemedStyle({ theme, sx: transformedSx, styleType }) as S,
return getCachedStyle(
StyleSheet.compose(
composedStyle,
propsToThemedStyle({ theme, sx: transformedSx, styleType }) as S,
),
);
} else {
return composedStyle;
return getCachedStyle(composedStyle);
}
});

Expand Down
11 changes: 7 additions & 4 deletions packages/core/src/hook/useSxStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { StyleProp, TextStyle } from 'react-native';
import type { TextSxProps } from '../@types/SxProps';
import type { ThemedDict } from '../@types/ThemedDict';
import { printWarning } from '../internal/util/printWarning';
import { getCachedStyle } from '../internal/util/StyleHash';
import { StyledSystemContext } from '../provider/StyledSystemProvider';
import { propsToThemedStyle } from '../util/propsToThemedStyle';

Expand All @@ -24,9 +25,11 @@ export const useSxStyle = ({ theme: optionTheme }: UseSxStyleOptions = defaultOp
return {};
}

return propsToThemedStyle({
theme,
sx,
});
return getCachedStyle(
propsToThemedStyle({
theme,
sx,
}),
);
};
};
19 changes: 19 additions & 0 deletions packages/core/src/internal/util/StyleHash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { type StyleProp, type TextStyle } from 'react-native';
import hash from 'object-hash';

const _CACHE: Record<string, any> = {};

export function getCachedStyle(style?: StyleProp<TextStyle>) {
if (!style) {
return style;
}

const key = hash(style);
if (key in _CACHE) {
return _CACHE[key];
} else {
_CACHE[key] = style;

return style;
}
}
16 changes: 16 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3386,11 +3386,13 @@ __metadata:
"@commitlint/config-conventional": "npm:^19.1.0"
"@mj-studio/eslint-config-react": "npm:^1.0.4"
"@types/jest": "npm:^29.5.12"
"@types/object-hash": "npm:^3"
cz-conventional-changelog: "npm:^3.3.0"
eslint: "npm:^8.57.0"
husky: "npm:^9.0.11"
jest: "npm:^29.7.0"
lerna: "npm:^8.1.2"
object-hash: "npm:^3.0.0"
prettier: "npm:^3.2.5"
react-native: "npm:^0.73.6"
ts-jest: "npm:^29.1.2"
Expand Down Expand Up @@ -4059,6 +4061,13 @@ __metadata:
languageName: node
linkType: hard

"@types/object-hash@npm:^3":
version: 3.0.6
resolution: "@types/object-hash@npm:3.0.6"
checksum: 10c0/a5450cafdbc33c840be2c36fb1ace96cce7aa580177cf68dbdbda80f18938207692d74c76403321c99f43460ac31981c4af7fe8b49eca1570f8e9a4c01eaf33d
languageName: node
linkType: hard

"@types/ora@npm:^3.2.0":
version: 3.2.0
resolution: "@types/ora@npm:3.2.0"
Expand Down Expand Up @@ -11752,6 +11761,13 @@ __metadata:
languageName: node
linkType: hard

"object-hash@npm:^3.0.0":
version: 3.0.0
resolution: "object-hash@npm:3.0.0"
checksum: 10c0/a06844537107b960c1c8b96cd2ac8592a265186bfa0f6ccafe0d34eabdb526f6fa81da1f37c43df7ed13b12a4ae3457a16071603bcd39d8beddb5f08c37b0f47
languageName: node
linkType: hard

"object-inspect@npm:^1.13.1":
version: 1.13.1
resolution: "object-inspect@npm:1.13.1"
Expand Down

0 comments on commit 092f5f2

Please sign in to comment.