From 32b2530b54e190afb7d84bc8a6da12f17d37fb88 Mon Sep 17 00:00:00 2001 From: mym0404 Date: Sun, 17 Mar 2024 00:54:16 +0900 Subject: [PATCH] feat(usesxtokens): useSxToken -> useSxTokens BREAKING CHANGE: useSxToken is changed to useSxTokens --- doc/docs/advanced/get-token-value.mdx | 12 +++--- .../current/advanced/get-token-value.mdx | 14 ++++--- src/hook/useSxToken.ts | 35 ---------------- ...useSxToken.test.ts => useSxTokens.test.ts} | 16 +++---- src/hook/useSxTokens.ts | 42 +++++++++++++++++++ 5 files changed, 65 insertions(+), 54 deletions(-) delete mode 100644 src/hook/useSxToken.ts rename src/hook/{useSxToken.test.ts => useSxTokens.test.ts} (68%) create mode 100644 src/hook/useSxTokens.ts diff --git a/doc/docs/advanced/get-token-value.mdx b/doc/docs/advanced/get-token-value.mdx index ac27879f..3e7fc26a 100644 --- a/doc/docs/advanced/get-token-value.mdx +++ b/doc/docs/advanced/get-token-value.mdx @@ -2,9 +2,9 @@ sidebar_position: 1 --- -# Get token value with useSxToken +# Get token value with useSxTokens -To get individual token values for a theme, you can use the `useSxToken` hook. +To get individual token values for a theme, you can use the `useSxTokens` hook. This is useful when it is cumbersome to get the style by passing `SxProps` to the `useSx` hook or when individual token values are needed. @@ -17,14 +17,16 @@ const MyView = ( disabled?: boolean; readonly?: boolean; }) => { - const backgroundColor = useSxToken('colors', readonly || disabled ? 'gray500' : 'gray200'); + const [backgroundColor, error] = useSxTokens('colors', [readonly || disabled ? 'gray500' : 'gray200', 'red500']); g - return + return } ``` :::info To operate properly, you must use it in the Context inside `StyledSystemProvider` or pass the theme object as an option. -Additionally, `undefined` is returned when attempting to reference a key that does not exist. +Otherwise, `undefined` is returned for every position in the returned array. + +Additionally, `undefined` is returned at that index when attempting to reference a key that does not exist. ::: \ No newline at end of file diff --git a/doc/i18n/ko/docusaurus-plugin-content-docs/current/advanced/get-token-value.mdx b/doc/i18n/ko/docusaurus-plugin-content-docs/current/advanced/get-token-value.mdx index 4ad5f37c..6ed73fdf 100644 --- a/doc/i18n/ko/docusaurus-plugin-content-docs/current/advanced/get-token-value.mdx +++ b/doc/i18n/ko/docusaurus-plugin-content-docs/current/advanced/get-token-value.mdx @@ -2,9 +2,9 @@ sidebar_position: 1 --- -# useSxToken를 이용해 토큰값 얻기 +# useSxTokens를 이용해 토큰값 얻기 -테마의 개별적인 토큰 값을 얻으려면 `useSxToken` 훅을 사용할 수 있습니다. +테마의 개별적인 토큰 값을 얻으려면 `useSxTokens` 훅을 사용할 수 있습니다. 이는 `SxProps`를 `useSx` 훅에 전달해 style을 얻기 번거롭거나 개별적인 토큰 값이 필요할 때 유용합니다. @@ -17,14 +17,16 @@ const MyView = ( disabled?: boolean; readonly?: boolean; }) => { - const backgroundColor = useSxToken('colors', readonly || disabled ? 'gray500' : 'gray200'); - - return + const [backgroundColor, error] = useSxTokens('colors', [readonly || disabled ? 'gray500' : 'gray200', 'red500']); +g + return } ``` :::info `StyledSystemProvider`내부의 Context에서 사용하거나 옵션으로 테마 객체를 전달해야 정상적으로 동작합니다. -또한, 존재하지 않는 키를 참조하려고 할 시에도 `undefined`가 반환됩니다. +그렇지 않다면 반환 배열의 모든 자리에 `undefined`가 반환됩니다. + +또한, 존재하지 않는 키를 참조하려고 할 시에도 해당 인덱스의 자리에 `undefined`가 반환됩니다. ::: \ No newline at end of file diff --git a/src/hook/useSxToken.ts b/src/hook/useSxToken.ts deleted file mode 100644 index d96e2f18..00000000 --- a/src/hook/useSxToken.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { useContext } from 'react'; - -import type { ThemedDict } from '../@types/ThemedDict'; -import type { ThemedTypings } from '../@types/ThemedTypings'; -import { printWarning } from '../internal/util/printWarning'; -import { StyledSystemContext } from '../provider/StyledSystemProvider'; - -export type UseSxTokenOptions = { - theme?: ThemedDict; -}; -export const useSxToken = ( - tokenType: T, - tokenValue: Exclude, - { theme: optionTheme }: UseSxTokenOptions = {}, -): ThemedDict[T][keyof ThemedDict[T]] => { - const styledSystemContext = useContext(StyledSystemContext); - - const theme = optionTheme ?? styledSystemContext?.theme; - - if (!theme) { - printWarning('theme not found from useSxToken, undefined will be returned.'); - - return undefined as any; - } - - if (!(tokenValue in theme[tokenType])) { - printWarning( - `tokenValue ${String(tokenValue)} doesn't exist in tokenType ${tokenType} from useSxToken, undefined will be returned.`, - ); - - return undefined as any; - } - - return theme[tokenType][tokenValue]; -}; diff --git a/src/hook/useSxToken.test.ts b/src/hook/useSxTokens.test.ts similarity index 68% rename from src/hook/useSxToken.test.ts rename to src/hook/useSxTokens.test.ts index baf77679..773397da 100644 --- a/src/hook/useSxToken.test.ts +++ b/src/hook/useSxTokens.test.ts @@ -3,7 +3,7 @@ import { renderHook } from '@testing-library/react-hooks'; import type { ThemedDict } from '../@types/ThemedDict'; import type { ThemedTypings } from '../@types/ThemedTypings'; -import { useSxToken } from './useSxToken'; +import { useSxTokens } from './useSxTokens'; const theme: ThemedDict = { colors: { @@ -27,32 +27,32 @@ const theme: ThemedDict = { export function expectResult( theme: ThemedDict, tokenGroup: T, - tokenValue: Exclude, - expectation: any, + tokenValues: Array>, + expectation: any[], ) { const { result: { current }, - } = renderHook(() => useSxToken(tokenGroup, tokenValue, { theme })); + } = renderHook(() => useSxTokens(tokenGroup, tokenValues, { theme })); return expect(current).toEqual(expectation); } describe('valid case', () => { it('colors', () => { - expectResult(theme, 'colors', 'red', 'red'); + expectResult(theme, 'colors', ['red'], ['red']); }); it('radii', () => { - expectResult(theme, 'radii', 'sm' as any, 8); + expectResult(theme, 'radii', ['sm' as any], [8]); }); }); describe('edge case', () => { it('cannot find value if tokenValue is not in tokenType', () => { - expectResult(theme, 'radii', '' as any, undefined); + expectResult(theme, 'radii', ['' as any], [undefined]); }); it('cannot find value if theme is undefined', () => { - expectResult(undefined as any, 'radii', '' as any, undefined); + expectResult(undefined as any, 'radii', ['' as any], [undefined]); }); }); diff --git a/src/hook/useSxTokens.ts b/src/hook/useSxTokens.ts new file mode 100644 index 00000000..8320978c --- /dev/null +++ b/src/hook/useSxTokens.ts @@ -0,0 +1,42 @@ +import { useContext } from 'react'; +import { generateArray } from '@mj-studio/js-util'; + +import type { ThemedDict } from '../@types/ThemedDict'; +import type { ThemedTypings } from '../@types/ThemedTypings'; +import { printWarning } from '../internal/util/printWarning'; +import { StyledSystemContext } from '../provider/StyledSystemProvider'; + +export type UseSxTokensOptions = { + theme?: ThemedDict; +}; +export const useSxTokens = ( + tokenType: T, + tokenValues: Array>, + { theme: optionTheme }: UseSxTokensOptions = {}, +): Array => { + const styledSystemContext = useContext(StyledSystemContext); + + const theme = optionTheme ?? styledSystemContext?.theme; + + if (!theme) { + printWarning('theme not found from useSxTokens, undefineds will be returned.'); + + return generateArray(tokenValues.length).map(() => undefined) as any; + } + + const ret: Array = []; + + for (let i = 0; i < tokenValues.length; i++) { + const tokenValue = tokenValues[i]; + if (!(tokenValue in theme[tokenType])) { + printWarning( + `tokenValue ${String(tokenValue)} at index ${i} doesn't exist in tokenType ${tokenType} from useSxTokens, undefined will be returned.`, + ); + ret.push(undefined as any); + } else { + ret.push(theme[tokenType][tokenValue]); + } + } + + return ret; +};