@seed-design/lynx-react 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +20 -0
- package/lib/components/Field/Field.d.ts +47 -0
- package/lib/components/Field/Field.d.ts.map +1 -0
- package/lib/components/Field/Field.jsx +121 -0
- package/lib/components/Field/Field.namespace.d.ts +2 -0
- package/lib/components/Field/Field.namespace.d.ts.map +1 -0
- package/lib/components/Field/Field.namespace.js +16 -0
- package/lib/components/Field/context.d.ts +19 -0
- package/lib/components/Field/context.d.ts.map +1 -0
- package/lib/components/Field/context.js +10 -0
- package/lib/components/Field/index.d.ts +3 -0
- package/lib/components/Field/index.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.d.ts +42 -0
- package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.jsx +140 -0
- package/lib/components/KeyboardAvoidingScrollView/context.d.ts +17 -0
- package/lib/components/KeyboardAvoidingScrollView/context.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/context.js +12 -0
- package/lib/components/KeyboardAvoidingScrollView/engine.d.ts +50 -0
- package/lib/components/KeyboardAvoidingScrollView/engine.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/engine.js +259 -0
- package/lib/components/KeyboardAvoidingScrollView/geometry.d.ts +50 -0
- package/lib/components/KeyboardAvoidingScrollView/geometry.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/geometry.js +90 -0
- package/lib/components/KeyboardAvoidingScrollView/index.d.ts +2 -0
- package/lib/components/KeyboardAvoidingScrollView/index.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.d.ts +11 -0
- package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.js +43 -0
- package/lib/components/KeyboardAvoidingScrollView/native-driver.d.ts +34 -0
- package/lib/components/KeyboardAvoidingScrollView/native-driver.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/native-driver.js +133 -0
- package/lib/components/TextField/TextField.d.ts +113 -0
- package/lib/components/TextField/TextField.d.ts.map +1 -0
- package/lib/components/TextField/TextField.jsx +418 -0
- package/lib/components/TextField/TextField.namespace.d.ts +2 -0
- package/lib/components/TextField/TextField.namespace.d.ts.map +1 -0
- package/lib/components/TextField/TextField.namespace.js +14 -0
- package/lib/components/TextField/context.d.ts +22 -0
- package/lib/components/TextField/context.d.ts.map +1 -0
- package/lib/components/TextField/context.js +7 -0
- package/lib/components/TextField/index.d.ts +4 -0
- package/lib/components/TextField/index.d.ts.map +1 -0
- package/lib/components/TextField/useTextFieldWithGraphemes.d.ts +24 -0
- package/lib/components/TextField/useTextFieldWithGraphemes.d.ts.map +1 -0
- package/lib/components/TextField/useTextFieldWithGraphemes.js +47 -0
- package/lib/components/index.d.ts +3 -0
- package/lib/components/index.d.ts.map +1 -1
- package/lib/index.js +7 -1
- package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_grapheme_data.js +8 -0
- package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_incb_data.js +14 -0
- package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/core.js +68 -0
- package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/grapheme.js +175 -0
- package/lib/utils/create-slot-recipe-context.d.ts.map +1 -1
- package/lib/utils/create-slot-recipe-context.jsx +7 -0
- package/package.json +10 -5
- package/src/components/Field/Field.namespace.ts +19 -0
- package/src/components/Field/Field.test.tsx +81 -0
- package/src/components/Field/Field.tsx +252 -0
- package/src/components/Field/context.ts +26 -0
- package/src/components/Field/index.ts +21 -0
- package/src/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.test.tsx +267 -0
- package/src/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.tsx +299 -0
- package/src/components/KeyboardAvoidingScrollView/context.ts +24 -0
- package/src/components/KeyboardAvoidingScrollView/engine.test.ts +451 -0
- package/src/components/KeyboardAvoidingScrollView/engine.ts +417 -0
- package/src/components/KeyboardAvoidingScrollView/geometry.test.ts +315 -0
- package/src/components/KeyboardAvoidingScrollView/geometry.ts +194 -0
- package/src/components/KeyboardAvoidingScrollView/index.ts +5 -0
- package/src/components/KeyboardAvoidingScrollView/keyboard-event-source.test.ts +122 -0
- package/src/components/KeyboardAvoidingScrollView/keyboard-event-source.ts +75 -0
- package/src/components/KeyboardAvoidingScrollView/native-driver.test.ts +223 -0
- package/src/components/KeyboardAvoidingScrollView/native-driver.ts +248 -0
- package/src/components/TextField/TextField.namespace.ts +16 -0
- package/src/components/TextField/TextField.test.tsx +924 -0
- package/src/components/TextField/TextField.tsx +912 -0
- package/src/components/TextField/context.ts +33 -0
- package/src/components/TextField/index.ts +23 -0
- package/src/components/TextField/useTextFieldWithGraphemes.test.tsx +80 -0
- package/src/components/TextField/useTextFieldWithGraphemes.ts +78 -0
- package/src/components/index.ts +3 -0
- package/src/utils/create-slot-recipe-context.test.tsx +51 -0
- package/src/utils/create-slot-recipe-context.tsx +23 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from "@lynx-js/react";
|
|
2
|
+
import type { NodesRef } from "@lynx-js/types";
|
|
3
|
+
|
|
4
|
+
/** iOS와 Android의 32비트 `maxlength` setter에서 사용하는 무제한 센티널. */
|
|
5
|
+
export const NATIVE_TEXT_MAX_LENGTH_UNLIMITED = 2_147_483_647;
|
|
6
|
+
|
|
7
|
+
export interface TextFieldContextValue {
|
|
8
|
+
rootRef: React.RefObject<NodesRef | null>;
|
|
9
|
+
value: string;
|
|
10
|
+
/** @internal controlled 입력의 native value 조정 여부를 판별한다. */
|
|
11
|
+
controlled: boolean;
|
|
12
|
+
nativeInsertionMaxLength?: number;
|
|
13
|
+
disabled: boolean;
|
|
14
|
+
invalid: boolean;
|
|
15
|
+
readOnly: boolean;
|
|
16
|
+
required: boolean;
|
|
17
|
+
name?: string;
|
|
18
|
+
focused: boolean;
|
|
19
|
+
setValue: (value: string) => void;
|
|
20
|
+
setFocused: (focused: boolean) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const TextFieldContext = React.createContext<TextFieldContextValue | null>(null);
|
|
24
|
+
|
|
25
|
+
export function useTextFieldContext(): TextFieldContextValue {
|
|
26
|
+
const context = React.useContext(TextFieldContext);
|
|
27
|
+
|
|
28
|
+
if (!context) {
|
|
29
|
+
throw new Error("TextField compound components must be rendered inside <TextField.Root>.");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return context;
|
|
33
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export {
|
|
2
|
+
TextFieldPrefixIcon,
|
|
3
|
+
TextFieldPrefixText,
|
|
4
|
+
TextFieldRoot,
|
|
5
|
+
TextFieldSuffixIcon,
|
|
6
|
+
TextFieldSuffixText,
|
|
7
|
+
TextFieldInput,
|
|
8
|
+
TextFieldTextarea,
|
|
9
|
+
type TextFieldPrefixIconProps,
|
|
10
|
+
type TextFieldPrefixTextProps,
|
|
11
|
+
type TextFieldRootProps,
|
|
12
|
+
type TextFieldSuffixIconProps,
|
|
13
|
+
type TextFieldSuffixTextProps,
|
|
14
|
+
type TextFieldInputProps,
|
|
15
|
+
type TextFieldTextareaProps,
|
|
16
|
+
} from "./TextField";
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
useTextFieldWithGraphemes,
|
|
20
|
+
type UseTextFieldWithGraphemesParams,
|
|
21
|
+
} from "./useTextFieldWithGraphemes";
|
|
22
|
+
|
|
23
|
+
export * as TextField from "./TextField.namespace";
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { act, renderHook } from "@lynx-js/react/testing-library";
|
|
2
|
+
import { describe, expect, it, vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { NATIVE_TEXT_MAX_LENGTH_UNLIMITED } from "./context";
|
|
5
|
+
import { useTextFieldWithGraphemes } from "./useTextFieldWithGraphemes";
|
|
6
|
+
|
|
7
|
+
describe("useTextFieldWithGraphemes", () => {
|
|
8
|
+
it("counts extended grapheme clusters", () => {
|
|
9
|
+
const { result } = renderHook(() =>
|
|
10
|
+
useTextFieldWithGraphemes({ defaultValue: "👨👩👧👦🏳️🌈é" }),
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
expect(result.current.graphemes).toEqual(["👨👩👧👦", "🏳️🌈", "é"]);
|
|
14
|
+
expect(result.current.counterProps).toEqual({ current: 3, max: 0 });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("reports the original and grapheme-sliced values", () => {
|
|
18
|
+
const onValueChange = vi.fn();
|
|
19
|
+
const { result } = renderHook(() =>
|
|
20
|
+
useTextFieldWithGraphemes({ maxGraphemeCount: 2, onValueChange }),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
act(() => {
|
|
24
|
+
result.current.textFieldRootProps.onValueChange("A👨👩👧👦B");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
expect(onValueChange).toHaveBeenCalledWith({
|
|
28
|
+
value: "A👨👩👧👦B",
|
|
29
|
+
graphemes: ["A", "👨👩👧👦", "B"],
|
|
30
|
+
slicedValue: "A👨👩👧👦",
|
|
31
|
+
slicedGraphemes: ["A", "👨👩👧👦"],
|
|
32
|
+
});
|
|
33
|
+
expect(result.current.counterProps).toEqual({ current: 3, max: 2 });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("keeps a controlled value fixed", () => {
|
|
37
|
+
const onValueChange = vi.fn();
|
|
38
|
+
const { result } = renderHook(() =>
|
|
39
|
+
useTextFieldWithGraphemes({ value: "고정", onValueChange }),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
act(() => {
|
|
43
|
+
result.current.textFieldRootProps.onValueChange("변경");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(result.current.textFieldRootProps.value).toBe("고정");
|
|
47
|
+
expect(onValueChange).toHaveBeenCalledOnce();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("leaves native insertion maxlength unmanaged without a grapheme limit", () => {
|
|
51
|
+
const { result } = renderHook(() => useTextFieldWithGraphemes({ defaultValue: "제한 없음" }));
|
|
52
|
+
|
|
53
|
+
expect(result.current.textFieldRootProps.nativeInsertionMaxLength).toBeUndefined();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("provides a UTF-16 native insertion cap only at the grapheme limit", () => {
|
|
57
|
+
const family = "👨👩👧👦";
|
|
58
|
+
const { result, rerender } = renderHook(
|
|
59
|
+
({ value }: { value: string }) => useTextFieldWithGraphemes({ value, maxGraphemeCount: 2 }),
|
|
60
|
+
{ initialProps: { value: family } },
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
expect(result.current.textFieldRootProps.nativeInsertionMaxLength).toBe(
|
|
64
|
+
NATIVE_TEXT_MAX_LENGTH_UNLIMITED,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const valueAtLimit = `${family}A`;
|
|
68
|
+
rerender({ value: valueAtLimit });
|
|
69
|
+
|
|
70
|
+
expect(result.current.graphemes).toEqual([family, "A"]);
|
|
71
|
+
expect(result.current.textFieldRootProps.nativeInsertionMaxLength).toBe(valueAtLimit.length);
|
|
72
|
+
expect(result.current.textFieldRootProps.nativeInsertionMaxLength).toBeGreaterThan(2);
|
|
73
|
+
|
|
74
|
+
rerender({ value: "A" });
|
|
75
|
+
|
|
76
|
+
expect(result.current.textFieldRootProps.nativeInsertionMaxLength).toBe(
|
|
77
|
+
NATIVE_TEXT_MAX_LENGTH_UNLIMITED,
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as React from "@lynx-js/react";
|
|
2
|
+
import { splitGraphemes } from "unicode-segmenter/grapheme";
|
|
3
|
+
|
|
4
|
+
import { NATIVE_TEXT_MAX_LENGTH_UNLIMITED } from "./context";
|
|
5
|
+
|
|
6
|
+
export interface UseTextFieldWithGraphemesParams {
|
|
7
|
+
maxGraphemeCount?: number;
|
|
8
|
+
value?: string;
|
|
9
|
+
defaultValue?: string;
|
|
10
|
+
onValueChange?: (values: {
|
|
11
|
+
value: string;
|
|
12
|
+
graphemes: string[];
|
|
13
|
+
slicedValue: string;
|
|
14
|
+
slicedGraphemes: string[];
|
|
15
|
+
}) => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let cachedValue = "";
|
|
19
|
+
let cachedGraphemes: string[] = [];
|
|
20
|
+
|
|
21
|
+
function getGraphemes(value: string): string[] {
|
|
22
|
+
if (value === cachedValue) return cachedGraphemes;
|
|
23
|
+
|
|
24
|
+
cachedValue = value;
|
|
25
|
+
cachedGraphemes = Array.from(splitGraphemes(value));
|
|
26
|
+
return cachedGraphemes;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function useTextFieldWithGraphemes({
|
|
30
|
+
maxGraphemeCount,
|
|
31
|
+
value: controlledValue,
|
|
32
|
+
defaultValue = "",
|
|
33
|
+
onValueChange,
|
|
34
|
+
}: UseTextFieldWithGraphemesParams) {
|
|
35
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
|
|
36
|
+
const isControlled = controlledValue !== undefined;
|
|
37
|
+
const value = isControlled ? controlledValue : uncontrolledValue;
|
|
38
|
+
const graphemes = React.useMemo(() => getGraphemes(value), [value]);
|
|
39
|
+
|
|
40
|
+
const handleValueChange = React.useCallback(
|
|
41
|
+
(nextValue: string) => {
|
|
42
|
+
"background only";
|
|
43
|
+
|
|
44
|
+
const nextGraphemes = getGraphemes(nextValue);
|
|
45
|
+
const slicedGraphemes =
|
|
46
|
+
maxGraphemeCount === undefined ? nextGraphemes : nextGraphemes.slice(0, maxGraphemeCount);
|
|
47
|
+
|
|
48
|
+
if (!isControlled) {
|
|
49
|
+
setUncontrolledValue(nextValue);
|
|
50
|
+
}
|
|
51
|
+
onValueChange?.({
|
|
52
|
+
value: nextValue,
|
|
53
|
+
graphemes: nextGraphemes,
|
|
54
|
+
slicedValue: slicedGraphemes.join(""),
|
|
55
|
+
slicedGraphemes,
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
[isControlled, maxGraphemeCount, onValueChange],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
textFieldRootProps: {
|
|
63
|
+
value,
|
|
64
|
+
onValueChange: handleValueChange,
|
|
65
|
+
nativeInsertionMaxLength:
|
|
66
|
+
maxGraphemeCount === undefined
|
|
67
|
+
? undefined
|
|
68
|
+
: graphemes.length >= maxGraphemeCount
|
|
69
|
+
? value.length
|
|
70
|
+
: NATIVE_TEXT_MAX_LENGTH_UNLIMITED,
|
|
71
|
+
},
|
|
72
|
+
counterProps: {
|
|
73
|
+
current: graphemes.length,
|
|
74
|
+
max: maxGraphemeCount ?? 0,
|
|
75
|
+
},
|
|
76
|
+
graphemes,
|
|
77
|
+
};
|
|
78
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -4,10 +4,13 @@ export * from "./Badge";
|
|
|
4
4
|
export * from "./Box";
|
|
5
5
|
export * from "./BottomSheet";
|
|
6
6
|
export * from "./Checkbox";
|
|
7
|
+
export * from "./Field";
|
|
7
8
|
export * from "./Icon";
|
|
9
|
+
export * from "./KeyboardAvoidingScrollView";
|
|
8
10
|
export * from "./ProgressCircle";
|
|
9
11
|
export * from "./RadioGroup";
|
|
10
12
|
export * from "./Stack";
|
|
11
13
|
export * from "./Switch";
|
|
12
14
|
export * from "./TagGroup";
|
|
13
15
|
export * from "./Text";
|
|
16
|
+
export * from "./TextField";
|
|
@@ -29,6 +29,7 @@ const mockSlotRecipe = Object.assign(
|
|
|
29
29
|
type MockProps = {
|
|
30
30
|
children?: unknown;
|
|
31
31
|
className?: string;
|
|
32
|
+
active?: boolean;
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
type MockReceived = { props?: MockProps };
|
|
@@ -93,4 +94,54 @@ describe("createSlotRecipeContext", () => {
|
|
|
93
94
|
expect(rootReceived.props?.className).toBe("root-a extra");
|
|
94
95
|
expect(childReceived.props?.className).toBe("label-a child-extra");
|
|
95
96
|
});
|
|
97
|
+
|
|
98
|
+
it("restores root default props overwritten with undefined", () => {
|
|
99
|
+
const { Mock: Root, received } = createMock("Root");
|
|
100
|
+
const { withRootProvider } = createSlotRecipeContext(mockSlotRecipe);
|
|
101
|
+
const StyledRoot = withRootProvider<MockVariantProps & MockProps>(Root, {
|
|
102
|
+
defaultProps: { active: true },
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
render(<StyledRoot active={undefined} />);
|
|
106
|
+
|
|
107
|
+
expect(received.props?.active).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("restores provider default props overwritten with undefined", () => {
|
|
111
|
+
const { Mock: Root, received } = createMock("Root");
|
|
112
|
+
const { withProvider } = createSlotRecipeContext(mockSlotRecipe);
|
|
113
|
+
const StyledRoot = withProvider<{ tag: "mock" }, MockVariantProps & MockProps>(Root, "root", {
|
|
114
|
+
defaultProps: { active: true },
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
render(<StyledRoot active={undefined} />);
|
|
118
|
+
|
|
119
|
+
expect(received.props?.active).toBe(true);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("restores context default props overwritten with undefined and preserves false", () => {
|
|
123
|
+
const { Mock: Root } = createMock("Root");
|
|
124
|
+
const { Mock: Child, received } = createMock("Child");
|
|
125
|
+
const { withRootProvider, withContext } = createSlotRecipeContext(mockSlotRecipe);
|
|
126
|
+
const StyledRoot = withRootProvider<MockVariantProps & MockProps>(Root);
|
|
127
|
+
const StyledChild = withContext<{ tag: "mock" }, MockProps>(Child, "label", {
|
|
128
|
+
defaultProps: { active: true },
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const { rerender } = render(
|
|
132
|
+
<StyledRoot>
|
|
133
|
+
<StyledChild active={undefined} />
|
|
134
|
+
</StyledRoot>,
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
expect(received.props?.active).toBe(true);
|
|
138
|
+
|
|
139
|
+
rerender(
|
|
140
|
+
<StyledRoot>
|
|
141
|
+
<StyledChild active={false} />
|
|
142
|
+
</StyledRoot>,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
expect(received.props?.active).toBe(false);
|
|
146
|
+
});
|
|
96
147
|
});
|
|
@@ -24,6 +24,20 @@ function assertNotIntrinsicComponent(Component: ElementType<any>, caller: string
|
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function restoreDefaultProps<P>(
|
|
28
|
+
props: Record<string, unknown>,
|
|
29
|
+
defaultProps: Partial<P> | undefined,
|
|
30
|
+
) {
|
|
31
|
+
if (!defaultProps) return;
|
|
32
|
+
|
|
33
|
+
// Explicit `undefined` should not override component-level defaults.
|
|
34
|
+
for (const key of Object.keys(defaultProps)) {
|
|
35
|
+
if (props[key] === undefined) {
|
|
36
|
+
props[key] = defaultProps[key as keyof P];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
27
41
|
export function createSlotRecipeContext<
|
|
28
42
|
Props extends Record<string, string | boolean | undefined>,
|
|
29
43
|
Classnames extends Record<string, string>,
|
|
@@ -93,6 +107,9 @@ export function createSlotRecipeContext<
|
|
|
93
107
|
const StyledComponent = (innerProps: any) => {
|
|
94
108
|
const props = { ...(defaultProps ?? {}), ...useProps(), ...innerProps } as Props &
|
|
95
109
|
Record<string, unknown>;
|
|
110
|
+
|
|
111
|
+
restoreDefaultProps(props, defaultProps);
|
|
112
|
+
|
|
96
113
|
const [variantProps, otherProps] = recipe.splitVariantProps(props);
|
|
97
114
|
const classNames = recipe(variantProps);
|
|
98
115
|
|
|
@@ -123,6 +140,9 @@ export function createSlotRecipeContext<
|
|
|
123
140
|
|
|
124
141
|
const StyledComponent = forwardRef<any, any>((innerProps, ref) => {
|
|
125
142
|
const props: any = { ...(defaultProps ?? {}), ...useProps(), ...innerProps };
|
|
143
|
+
|
|
144
|
+
restoreDefaultProps(props, defaultProps);
|
|
145
|
+
|
|
126
146
|
const [variantProps, otherProps] = recipe.splitVariantProps(props as Props);
|
|
127
147
|
const classNames = recipe(variantProps);
|
|
128
148
|
const slotClassName: string | undefined = classNames[slot];
|
|
@@ -158,6 +178,9 @@ export function createSlotRecipeContext<
|
|
|
158
178
|
|
|
159
179
|
const StyledComponent = forwardRef<any, any>((innerProps, ref) => {
|
|
160
180
|
const props: any = { ...(defaultProps ?? {}), ...innerProps };
|
|
181
|
+
|
|
182
|
+
restoreDefaultProps(props, defaultProps);
|
|
183
|
+
|
|
161
184
|
const classNames = useClassNames();
|
|
162
185
|
const slotClassName: string | undefined = slot ? classNames[slot] : undefined;
|
|
163
186
|
const userClassName: string | undefined = props["className"];
|