@seed-design/lynx-react 0.2.0-alpha.3 → 0.3.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/lib/_virtual/_rolldown/runtime.js +13 -0
- package/lib/components/ActionButton/ActionButton.d.ts +26 -33
- package/lib/components/ActionButton/ActionButton.d.ts.map +1 -1
- package/lib/components/ActionButton/ActionButton.jsx +139 -120
- package/lib/components/ActionButton/index.d.ts +1 -1
- package/lib/components/AppBar/AppBar.d.ts +35 -0
- package/lib/components/AppBar/AppBar.d.ts.map +1 -0
- package/lib/components/AppBar/AppBar.jsx +132 -0
- package/lib/components/AppBar/AppBar.namespace.d.ts +2 -0
- package/lib/components/AppBar/AppBar.namespace.d.ts.map +1 -0
- package/lib/components/AppBar/AppBar.namespace.js +15 -0
- package/lib/components/AppBar/context.d.ts +13 -0
- package/lib/components/AppBar/context.d.ts.map +1 -0
- package/lib/components/AppBar/context.js +12 -0
- package/lib/components/AppBar/index.d.ts +3 -0
- package/lib/components/AppBar/index.d.ts.map +1 -0
- package/lib/components/AppBar/useAppBar.d.ts +15 -0
- package/lib/components/AppBar/useAppBar.d.ts.map +1 -0
- package/lib/components/AppBar/useAppBar.js +72 -0
- package/lib/components/Badge/Badge.d.ts +14 -0
- package/lib/components/Badge/Badge.d.ts.map +1 -0
- package/lib/components/Badge/Badge.jsx +15 -0
- package/lib/components/Badge/index.d.ts +2 -0
- package/lib/components/Badge/index.d.ts.map +1 -0
- package/lib/components/BottomSheet/BottomSheet.d.ts +22 -27
- package/lib/components/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/lib/components/BottomSheet/BottomSheet.jsx +127 -142
- package/lib/components/BottomSheet/BottomSheet.namespace.d.ts +1 -1
- package/lib/components/BottomSheet/BottomSheet.namespace.js +18 -1
- package/lib/components/BottomSheet/index.d.ts +2 -2
- package/lib/components/Box/Box.d.ts +20 -0
- package/lib/components/Box/Box.d.ts.map +1 -0
- package/lib/components/Box/Box.jsx +14 -0
- package/lib/components/Box/index.d.ts +2 -0
- package/lib/components/Box/index.d.ts.map +1 -0
- package/lib/components/Checkbox/Checkbox.d.ts +14 -31
- package/lib/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/lib/components/Checkbox/Checkbox.jsx +107 -98
- package/lib/components/Checkbox/Checkbox.namespace.d.ts +1 -1
- package/lib/components/Checkbox/Checkbox.namespace.js +12 -1
- package/lib/components/Checkbox/index.d.ts +2 -2
- package/lib/components/Icon/Icon.d.ts +37 -0
- package/lib/components/Icon/Icon.d.ts.map +1 -0
- package/lib/components/Icon/Icon.jsx +143 -0
- package/lib/components/Icon/index.d.ts +2 -0
- package/lib/components/Icon/index.d.ts.map +1 -0
- package/lib/components/ProgressCircle/ProgressCircle.d.ts +4 -8
- package/lib/components/ProgressCircle/ProgressCircle.d.ts.map +1 -1
- package/lib/components/ProgressCircle/ProgressCircle.jsx +255 -260
- package/lib/components/ProgressCircle/ProgressCircle.namespace.d.ts +1 -1
- package/lib/components/ProgressCircle/ProgressCircle.namespace.js +9 -1
- package/lib/components/ProgressCircle/index.d.ts +2 -2
- package/lib/components/RadioGroup/RadioGroup.d.ts +12 -29
- package/lib/components/RadioGroup/RadioGroup.d.ts.map +1 -1
- package/lib/components/RadioGroup/RadioGroup.jsx +134 -118
- package/lib/components/RadioGroup/RadioGroup.namespace.d.ts +1 -1
- package/lib/components/RadioGroup/RadioGroup.namespace.js +12 -1
- package/lib/components/RadioGroup/index.d.ts +2 -2
- package/lib/components/Stack/Stack.d.ts +33 -0
- package/lib/components/Stack/Stack.d.ts.map +1 -0
- package/lib/components/Stack/Stack.jsx +39 -0
- package/lib/components/Stack/index.d.ts +2 -0
- package/lib/components/Stack/index.d.ts.map +1 -0
- package/lib/components/Switch/Switch.d.ts +8 -14
- package/lib/components/Switch/Switch.d.ts.map +1 -1
- package/lib/components/Switch/Switch.jsx +82 -56
- package/lib/components/Switch/Switch.namespace.d.ts +1 -1
- package/lib/components/Switch/Switch.namespace.js +11 -1
- package/lib/components/Switch/index.d.ts +2 -2
- package/lib/components/TagGroup/TagGroup.d.ts +8 -14
- package/lib/components/TagGroup/TagGroup.d.ts.map +1 -1
- package/lib/components/TagGroup/TagGroup.jsx +42 -39
- package/lib/components/TagGroup/TagGroup.namespace.d.ts +1 -1
- package/lib/components/TagGroup/TagGroup.namespace.js +10 -1
- package/lib/components/TagGroup/index.d.ts +2 -2
- package/lib/components/Text/Text.d.ts +7 -0
- package/lib/components/Text/Text.d.ts.map +1 -0
- package/lib/components/Text/Text.jsx +28 -0
- package/lib/components/Text/index.d.ts +2 -0
- package/lib/components/Text/index.d.ts.map +1 -0
- package/lib/components/index.d.ts +13 -7
- package/lib/components/index.d.ts.map +1 -1
- package/lib/hooks/index.d.ts +5 -3
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/useControllableState.js +23 -23
- package/lib/hooks/useIconColor.d.ts +6 -3
- package/lib/hooks/useIconColor.d.ts.map +1 -1
- package/lib/hooks/useIconColor.js +34 -37
- package/lib/hooks/usePressTap.d.ts +11 -8
- package/lib/hooks/usePressTap.d.ts.map +1 -1
- package/lib/hooks/usePressTap.js +31 -31
- package/lib/hooks/useSafeArea.d.ts +19 -0
- package/lib/hooks/useSafeArea.d.ts.map +1 -0
- package/lib/hooks/useSafeArea.js +33 -0
- package/lib/hooks/useSeedClassName.d.ts +27 -0
- package/lib/hooks/useSeedClassName.d.ts.map +1 -0
- package/lib/hooks/useSeedClassName.js +32 -0
- package/lib/index.d.ts +4 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +30 -3
- package/lib/types.d.ts +51 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/utils/children.d.ts +3 -0
- package/lib/utils/children.d.ts.map +1 -0
- package/lib/utils/children.js +8 -0
- package/lib/utils/create-slot-recipe-context.d.ts +13 -12
- package/lib/utils/create-slot-recipe-context.d.ts.map +1 -1
- package/lib/utils/create-slot-recipe-context.jsx +88 -70
- package/lib/utils/get-seed-class-name.d.ts +9 -7
- package/lib/utils/get-seed-class-name.d.ts.map +1 -1
- package/lib/utils/get-seed-class-name.js +29 -37
- package/lib/utils/index.d.ts +4 -4
- package/lib/utils/resolve-recipe-token.js +45 -43
- package/lib/utils/split-multiple-variants-props.js +32 -32
- package/lib/utils/styled.d.ts +83 -0
- package/lib/utils/styled.d.ts.map +1 -0
- package/lib/utils/styled.js +144 -0
- package/package.json +10 -9
- package/src/components/ActionButton/ActionButton.test.tsx +167 -0
- package/src/components/ActionButton/ActionButton.tsx +210 -169
- package/src/components/AppBar/AppBar.namespace.ts +18 -0
- package/src/components/AppBar/AppBar.test.tsx +270 -0
- package/src/components/AppBar/AppBar.tsx +288 -0
- package/src/components/AppBar/context.ts +27 -0
- package/src/components/AppBar/index.ts +21 -0
- package/src/components/AppBar/useAppBar.ts +100 -0
- package/src/components/Badge/Badge.test.tsx +54 -0
- package/src/components/Badge/Badge.tsx +32 -0
- package/src/components/Badge/index.ts +1 -0
- package/src/components/BottomSheet/BottomSheet.test.tsx +219 -0
- package/src/components/BottomSheet/BottomSheet.tsx +120 -83
- package/src/components/Box/Box.test.tsx +85 -0
- package/src/components/Box/Box.tsx +39 -0
- package/src/components/Box/index.ts +1 -0
- package/src/components/Checkbox/Checkbox.tsx +106 -116
- package/src/components/Icon/Icon.tsx +265 -0
- package/src/components/Icon/index.ts +8 -0
- package/src/components/ProgressCircle/ProgressCircle.tsx +39 -25
- package/src/components/RadioGroup/RadioGroup.tsx +98 -117
- package/src/components/Stack/Stack.tsx +97 -0
- package/src/components/Stack/index.ts +1 -0
- package/src/components/Switch/Switch.tsx +59 -50
- package/src/components/TagGroup/TagGroup.tsx +27 -25
- package/src/components/Text/Text.tsx +64 -0
- package/src/components/Text/index.ts +1 -0
- package/src/components/index.ts +6 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/{__tests__/useControllableState.test.ts → useControllableState.test.ts} +1 -1
- package/src/hooks/{__tests__/useIconColor.test.ts → useIconColor.test.ts} +1 -1
- package/src/hooks/useIconColor.ts +22 -12
- package/src/hooks/{__tests__/usePressTap.test.ts → usePressTap.test.ts} +1 -1
- package/src/hooks/usePressTap.ts +14 -10
- package/src/hooks/useSafeArea.test.ts +83 -0
- package/src/hooks/useSafeArea.ts +56 -0
- package/src/hooks/useSeedClassName.ts +35 -0
- package/src/index.ts +1 -0
- package/src/types.ts +76 -0
- package/src/utils/children.ts +13 -0
- package/src/utils/create-slot-recipe-context.test.tsx +96 -0
- package/src/utils/create-slot-recipe-context.tsx +55 -15
- package/src/utils/get-seed-class-name.ts +10 -12
- package/src/utils/{__tests__/split-multiple-variants-props.test.ts → split-multiple-variants-props.test.ts} +1 -1
- package/src/utils/styled.ts +442 -0
- package/lib/components/ActionButton/index.js +0 -1
- package/lib/components/BottomSheet/index.js +0 -2
- package/lib/components/Checkbox/index.js +0 -2
- package/lib/components/ProgressCircle/index.js +0 -2
- package/lib/components/RadioGroup/index.js +0 -2
- package/lib/components/Switch/index.js +0 -2
- package/lib/components/TagGroup/index.js +0 -2
- package/lib/components/index.js +0 -7
- package/lib/hooks/index.js +0 -3
- package/lib/utils/index.js +0 -4
- package/src/components/ActionButton/__tests__/ActionButton.test.tsx +0 -35
- package/src/components/BottomSheet/__tests__/BottomSheet.test.tsx +0 -119
- package/src/components/__tests__/ProgressCircle.test.ts +0 -33
- package/src/components/__tests__/exports.test.ts +0 -38
- package/src/components/__tests__/switch.test.ts +0 -34
- package/src/utils/__tests__/create-slot-recipe-context.test.tsx +0 -228
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
|
|
6
|
-
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const componentsDir = join(currentDir, "..");
|
|
8
|
-
|
|
9
|
-
function readComponentFile(componentName: string, fileName: string): string {
|
|
10
|
-
return readFileSync(join(componentsDir, componentName, fileName), "utf8");
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
describe("components public exports", () => {
|
|
14
|
-
it("exposes compound components through namespace exports", () => {
|
|
15
|
-
for (const componentName of ["Switch", "Checkbox", "RadioGroup", "TagGroup"]) {
|
|
16
|
-
expect(readComponentFile(componentName, "index.ts")).toContain(
|
|
17
|
-
`export * as ${componentName} from "./${componentName}.namespace";`,
|
|
18
|
-
);
|
|
19
|
-
expect(readComponentFile(componentName, `${componentName}.namespace.ts`)).toContain(
|
|
20
|
-
" as Root",
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("keeps ProgressCircle namespace usage while exposing flat slots", () => {
|
|
26
|
-
const index = readComponentFile("ProgressCircle", "index.ts");
|
|
27
|
-
const implementation = readComponentFile("ProgressCircle", "ProgressCircle.tsx");
|
|
28
|
-
const namespace = readComponentFile("ProgressCircle", "ProgressCircle.namespace.ts");
|
|
29
|
-
|
|
30
|
-
expect(index).toContain('export * as ProgressCircle from "./ProgressCircle.namespace";');
|
|
31
|
-
expect(index).toContain("ProgressCircleRoot");
|
|
32
|
-
expect(index).toContain("ProgressCircleRange");
|
|
33
|
-
expect(namespace).toContain("ProgressCircleRoot as Root");
|
|
34
|
-
expect(namespace).toContain("ProgressCircleRange as Range");
|
|
35
|
-
expect(implementation).toContain("export const ProgressCircleRoot");
|
|
36
|
-
expect(implementation).toContain("export const ProgressCircleRange");
|
|
37
|
-
});
|
|
38
|
-
});
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { switchmark } from "@seed-design/lynx-css/recipes/switchmark";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { describe, expect, it } from "vitest";
|
|
6
|
-
|
|
7
|
-
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const lynxCssRecipesDir = join(currentDir, "..", "..", "..", "..", "lynx-css", "recipes");
|
|
9
|
-
const switchCss = readFileSync(join(lynxCssRecipesDir, "switch.css"), "utf8");
|
|
10
|
-
const switchmarkCss = readFileSync(join(lynxCssRecipesDir, "switchmark.css"), "utf8");
|
|
11
|
-
|
|
12
|
-
describe("Switch", () => {
|
|
13
|
-
it.each(["16", "24", "32"] as const)(
|
|
14
|
-
"includes selected thumb class for size %s",
|
|
15
|
-
(size) => {
|
|
16
|
-
const classNames = switchmark({
|
|
17
|
-
tone: "brand",
|
|
18
|
-
size,
|
|
19
|
-
checked: true,
|
|
20
|
-
disabled: false,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
expect(classNames.thumb.split(" ")).toContain(
|
|
24
|
-
`seed-switchmark__thumb--size_${size}-checked_true`,
|
|
25
|
-
);
|
|
26
|
-
},
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
it("aligns Lynx switch content with flex center instead of margin compensation", () => {
|
|
30
|
-
expect(switchCss).toContain("align-items: center");
|
|
31
|
-
expect(switchCss).not.toContain("--switchmark-margin-top");
|
|
32
|
-
expect(switchmarkCss).not.toContain("--switchmark-margin-top");
|
|
33
|
-
});
|
|
34
|
-
});
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { forwardRef } from "@lynx-js/react";
|
|
2
|
-
import { render, renderHook } from "@lynx-js/react/testing-library";
|
|
3
|
-
import { describe, expect, it } from "vitest";
|
|
4
|
-
|
|
5
|
-
import { createSlotRecipeContext } from "../create-slot-recipe-context";
|
|
6
|
-
|
|
7
|
-
type MockVariantProps = {
|
|
8
|
-
variant?: "a" | "b";
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
type MockClassnames = {
|
|
12
|
-
root: string;
|
|
13
|
-
label: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const mockSlotRecipe = Object.assign(
|
|
17
|
-
(props?: MockVariantProps): MockClassnames => ({
|
|
18
|
-
root: `root-${props?.variant ?? "a"}`,
|
|
19
|
-
label: `label-${props?.variant ?? "a"}`,
|
|
20
|
-
}),
|
|
21
|
-
{
|
|
22
|
-
splitVariantProps: <T extends MockVariantProps>(props: T) => {
|
|
23
|
-
const { variant, ...rest } = props;
|
|
24
|
-
return [{ variant }, rest] as [MockVariantProps, Omit<T, keyof MockVariantProps>];
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
type MockReceived = { props?: Record<string, unknown>; refValue?: unknown };
|
|
30
|
-
|
|
31
|
-
function createMock(name: string) {
|
|
32
|
-
const received: MockReceived = {};
|
|
33
|
-
const Mock = forwardRef<{ tag: "mock" }, Record<string, unknown>>((props, ref) => {
|
|
34
|
-
received.props = props;
|
|
35
|
-
received.refValue = ref;
|
|
36
|
-
const { children } = props as { children?: unknown };
|
|
37
|
-
return <>{children as never}</>;
|
|
38
|
-
});
|
|
39
|
-
Mock.displayName = name;
|
|
40
|
-
return { Mock, received };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
describe("createSlotRecipeContext", () => {
|
|
44
|
-
describe("useClassNames", () => {
|
|
45
|
-
it("throws when used outside a ClassNamesProvider", () => {
|
|
46
|
-
const { useClassNames } = createSlotRecipeContext(mockSlotRecipe);
|
|
47
|
-
|
|
48
|
-
expect(() => renderHook(() => useClassNames())).toThrow(
|
|
49
|
-
/useClassNames must be used within a ClassNamesProvider/,
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("returns the provided classnames inside ClassNamesProvider", () => {
|
|
54
|
-
const { useClassNames, ClassNamesProvider } = createSlotRecipeContext(mockSlotRecipe);
|
|
55
|
-
const value: MockClassnames = { root: "custom-root", label: "custom-label" };
|
|
56
|
-
|
|
57
|
-
const { result } = renderHook(() => useClassNames(), {
|
|
58
|
-
wrapper: ({ children }) => (
|
|
59
|
-
<ClassNamesProvider value={value}>{children}</ClassNamesProvider>
|
|
60
|
-
),
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
expect(result.current).toEqual(value);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe("useProps", () => {
|
|
68
|
-
it("returns null outside of PropsProvider", () => {
|
|
69
|
-
const { useProps } = createSlotRecipeContext(mockSlotRecipe);
|
|
70
|
-
const { result } = renderHook(() => useProps());
|
|
71
|
-
|
|
72
|
-
expect(result.current).toBeNull();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("returns the provided value inside PropsProvider", () => {
|
|
76
|
-
const { useProps, PropsProvider } = createSlotRecipeContext(mockSlotRecipe);
|
|
77
|
-
const { result } = renderHook(() => useProps(), {
|
|
78
|
-
wrapper: ({ children }) => (
|
|
79
|
-
<PropsProvider value={{ variant: "b" }}>{children}</PropsProvider>
|
|
80
|
-
),
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
expect(result.current).toEqual({ variant: "b" });
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
describe("withRootProvider", () => {
|
|
88
|
-
it("injects classnames into context without applying className on the root element", () => {
|
|
89
|
-
const { Mock: Root, received: rootReceived } = createMock("Root");
|
|
90
|
-
const { Mock: Child, received: childReceived } = createMock("Child");
|
|
91
|
-
const { withRootProvider, withContext } = createSlotRecipeContext(mockSlotRecipe);
|
|
92
|
-
|
|
93
|
-
const StyledRoot = withRootProvider<MockVariantProps>(Root);
|
|
94
|
-
const StyledLabel = withContext<{ tag: "mock" }, Record<string, unknown>>(Child, "label");
|
|
95
|
-
|
|
96
|
-
render(
|
|
97
|
-
<StyledRoot variant="b">
|
|
98
|
-
<StyledLabel />
|
|
99
|
-
</StyledRoot>,
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
expect(rootReceived.props).not.toHaveProperty("className");
|
|
103
|
-
expect(childReceived.props?.className).toBe("label-b");
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
describe("withProvider", () => {
|
|
108
|
-
it("applies slot className to the provider element and injects context", () => {
|
|
109
|
-
const { Mock: Root, received: rootReceived } = createMock("Root");
|
|
110
|
-
const { Mock: Child, received: childReceived } = createMock("Child");
|
|
111
|
-
const { withProvider, withContext } = createSlotRecipeContext(mockSlotRecipe);
|
|
112
|
-
|
|
113
|
-
const StyledRoot = withProvider<{ tag: "mock" }, MockVariantProps>(Root, "root");
|
|
114
|
-
const StyledLabel = withContext<{ tag: "mock" }, Record<string, unknown>>(Child, "label");
|
|
115
|
-
|
|
116
|
-
render(
|
|
117
|
-
<StyledRoot variant="a">
|
|
118
|
-
<StyledLabel />
|
|
119
|
-
</StyledRoot>,
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
expect(rootReceived.props?.className).toBe("root-a");
|
|
123
|
-
expect(childReceived.props?.className).toBe("label-a");
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("merges user-provided className with the slot className", () => {
|
|
127
|
-
const { Mock: Root, received: rootReceived } = createMock("Root");
|
|
128
|
-
const { withProvider } = createSlotRecipeContext(mockSlotRecipe);
|
|
129
|
-
type StyledProps = MockVariantProps & { className?: string };
|
|
130
|
-
const StyledRoot = withProvider<{ tag: "mock" }, StyledProps>(Root, "root");
|
|
131
|
-
|
|
132
|
-
render(<StyledRoot variant="a" className="extra" />);
|
|
133
|
-
|
|
134
|
-
expect(rootReceived.props?.className).toBe("root-a extra");
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("forwards the ref to the provider element", () => {
|
|
138
|
-
const { Mock: Root, received } = createMock("Root");
|
|
139
|
-
const { withProvider } = createSlotRecipeContext(mockSlotRecipe);
|
|
140
|
-
const StyledRoot = withProvider<{ tag: "mock" }, MockVariantProps>(Root, "root");
|
|
141
|
-
const refFn = (node: { tag: "mock" } | null) => {
|
|
142
|
-
received.refValue = node;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
render(<StyledRoot ref={refFn} variant="a" />);
|
|
146
|
-
|
|
147
|
-
expect(received.refValue).toBe(refFn);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it("prefers innerProps over PropsProvider and defaultProps", () => {
|
|
151
|
-
const { Mock: Root, received } = createMock("Root");
|
|
152
|
-
const { withProvider, PropsProvider } = createSlotRecipeContext(mockSlotRecipe);
|
|
153
|
-
const StyledRoot = withProvider<{ tag: "mock" }, MockVariantProps>(Root, "root", {
|
|
154
|
-
defaultProps: { variant: "a" },
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
render(
|
|
158
|
-
<PropsProvider value={{ variant: "a" }}>
|
|
159
|
-
<StyledRoot variant="b" />
|
|
160
|
-
</PropsProvider>,
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
expect(received.props?.className).toBe("root-b");
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
describe("withContext", () => {
|
|
168
|
-
it("reads slot className from ClassNamesProvider", () => {
|
|
169
|
-
const { Mock: Label, received } = createMock("Label");
|
|
170
|
-
const { ClassNamesProvider, withContext } = createSlotRecipeContext(mockSlotRecipe);
|
|
171
|
-
const StyledLabel = withContext<{ tag: "mock" }, Record<string, unknown>>(Label, "label");
|
|
172
|
-
const classNames: MockClassnames = { root: "r", label: "custom-label" };
|
|
173
|
-
|
|
174
|
-
render(
|
|
175
|
-
<ClassNamesProvider value={classNames}>
|
|
176
|
-
<StyledLabel />
|
|
177
|
-
</ClassNamesProvider>,
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
expect(received.props?.className).toBe("custom-label");
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it("merges user-provided className with slot className", () => {
|
|
184
|
-
const { Mock: Label, received } = createMock("Label");
|
|
185
|
-
const { ClassNamesProvider, withContext } = createSlotRecipeContext(mockSlotRecipe);
|
|
186
|
-
type StyledProps = { className?: string };
|
|
187
|
-
const StyledLabel = withContext<{ tag: "mock" }, StyledProps>(Label, "label");
|
|
188
|
-
|
|
189
|
-
render(
|
|
190
|
-
<ClassNamesProvider value={{ root: "r", label: "l" }}>
|
|
191
|
-
<StyledLabel className="extra" />
|
|
192
|
-
</ClassNamesProvider>,
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
expect(received.props?.className).toBe("l extra");
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it("passes through native props like data attributes", () => {
|
|
199
|
-
const { Mock: Label, received } = createMock("Label");
|
|
200
|
-
const { ClassNamesProvider, withContext } = createSlotRecipeContext(mockSlotRecipe);
|
|
201
|
-
type StyledProps = { "data-testid"?: string };
|
|
202
|
-
const StyledLabel = withContext<{ tag: "mock" }, StyledProps>(Label, "label");
|
|
203
|
-
|
|
204
|
-
render(
|
|
205
|
-
<ClassNamesProvider value={{ root: "r", label: "l" }}>
|
|
206
|
-
<StyledLabel data-testid="hello" />
|
|
207
|
-
</ClassNamesProvider>,
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
expect(received.props?.["data-testid"]).toBe("hello");
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it("renders without a slot className when slot argument is omitted", () => {
|
|
214
|
-
const { Mock: Label, received } = createMock("Label");
|
|
215
|
-
const { ClassNamesProvider, withContext } = createSlotRecipeContext(mockSlotRecipe);
|
|
216
|
-
const StyledLabel = withContext<{ tag: "mock" }, Record<string, unknown>>(Label);
|
|
217
|
-
|
|
218
|
-
render(
|
|
219
|
-
<ClassNamesProvider value={{ root: "r", label: "l" }}>
|
|
220
|
-
<StyledLabel />
|
|
221
|
-
</ClassNamesProvider>,
|
|
222
|
-
);
|
|
223
|
-
|
|
224
|
-
// clsx(undefined, undefined) → ""
|
|
225
|
-
expect(received.props?.className).toBe("");
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
});
|