Skip to content

Commit

Permalink
feat: [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
mym0404 committed Mar 20, 2024
1 parent 442af9f commit 78c8b6d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 11 deletions.
21 changes: 20 additions & 1 deletion src/hook/useSx.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import type { StyleProp } from 'react-native';
import { StyleSheet } from 'react-native';
import { is } from '@mj-studio/js-util';
import { renderHook } from '@testing-library/react-hooks';

import type { SxProps, TextSxProps } from '../@types/SxProps';
import type { ThemedDict } from '../@types/ThemedDict';
import { emptyThemedDict } from '../@types/ThemedDict';
import type { ThemedStyleType } from '../util/propsToThemedStyle';

import type { StyleTransform } from './useSx';
import { useSx } from './useSx';

export function expectResult(
Expand All @@ -17,17 +19,19 @@ export function expectResult(
expectation,
filteredPropsExpectation,
styleType,
transform,
}: {
expectation: object;
filteredPropsExpectation?: object;
styleType?: ThemedStyleType;
transform?: StyleTransform;
},
) {
const {
result: {
current: { getStyle, filteredProps },
},
} = renderHook(() => useSx(props, { theme, styleType }));
} = renderHook(() => useSx(props, { theme, styleType, transform }));

if (expectation) {
expect(StyleSheet.flatten(getStyle(props.getStyleSx))).toEqual(expectation);
Expand Down Expand Up @@ -314,3 +318,18 @@ describe('TextStyle', () => {
);
});
});

describe('transform', () => {
it('property should be transform', () => {
expectResult(
baseTheme,
{ mt: 2, mb: 2 },
{
expectation: { marginTop: 8, marginBottom: 8, marginHorizontal: 16 },
transform: ({ marginTop, marginBottom }) => ({
mx: (is.number(marginTop) ? marginTop : 0) + (is.number(marginBottom) ? marginBottom : 0),
}),
},
);
});
});
41 changes: 31 additions & 10 deletions src/hook/useSx.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import { useContext, useMemo } from 'react';
import type { StyleProp } from 'react-native';
import type { StyleProp, TextStyle } from 'react-native';
import { StyleSheet } from 'react-native';
import { is } from '@mj-studio/js-util';

import type { SxProps, SxPropsKeys } from '../@types/SxProps';
import type { SxProps, SxPropsKeys, TextSxProps } from '../@types/SxProps';
import { _textStylePropList, _viewStylePropList } from '../@types/SxProps';
import type { ThemedDict } from '../@types/ThemedDict';
import { useStableCallback } from '../internal/useStableCallback';
import { printWarning } from '../internal/util/printWarning';
import { StyledSystemContext } from '../provider/StyledSystemProvider';
import type { InferStyleType, InferSxPropsType, ThemedStyleType } from '../util/propsToThemedStyle';
import { propsToThemedStyle } from '../util/propsToThemedStyle';

type Props = { style?: StyleProp<any> } & SxProps;
type Props = { style?: StyleProp<any> } & TextSxProps;

export type StyleTransform = (style: TextStyle) => TextSxProps;
export type UseSxOptions = {
theme?: ThemedDict;
styleType?: ThemedStyleType;
transform?: StyleTransform;
};
const defaultUseSxOptions: UseSxOptions = { styleType: 'ViewStyle' };
export const useSx = <P extends Props>(
props?: P | null,
{
theme: optionTheme,
styleType = defaultUseSxOptions.styleType,
transform = defaultUseSxOptions.transform,
}: UseSxOptions = defaultUseSxOptions,
) => {
const styledSystemContext = useContext(StyledSystemContext);
Expand All @@ -36,20 +41,36 @@ export const useSx = <P extends Props>(
return;
}

const theme = optionTheme ?? styledSystemContext?.theme;

if (!theme) {
printWarning('theme not found from useSx, undefined will be returned.');

return;
}

// todo handle default style
// causion: priority should be ordered correctly.
const mergedSx: SxProps = { ...sx, ...props, ...props?.sx };

const ret = propsToThemedStyle({
theme: optionTheme ?? styledSystemContext?.theme,
const computedStyle = propsToThemedStyle({
theme,
sx: mergedSx,
styleType,
});

if (!ret) {
return props?.style;
} else if (props?.style) {
return StyleSheet.compose(ret, props.style);
const composedStyle = !computedStyle
? props?.style
: props?.style
? StyleSheet.compose(computedStyle, props.style)
: computedStyle;

if (is.function(transform)) {
if (!computedStyle && !props?.style) {
return transform({});

Check failure on line 70 in src/hook/useSx.ts

View workflow job for this annotation

GitHub Actions / ESLint & Typescript & Test

Type 'TextSxProps' is not assignable to type 'StyleProp<InferStyleType<ThemedStyleType | undefined>>'.
}
} else {
return ret;
return composedStyle;
}
},
);
Expand Down

0 comments on commit 78c8b6d

Please sign in to comment.