@simplysm/solid 13.0.70 → 13.0.71
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/README.md +1 -1
- package/dist/components/disclosure/Dropdown.d.ts +6 -4
- package/dist/components/disclosure/Dropdown.d.ts.map +1 -1
- package/dist/components/disclosure/Dropdown.js +24 -8
- package/dist/components/disclosure/Dropdown.js.map +2 -2
- package/dist/components/disclosure/dialogZIndex.d.ts +2 -0
- package/dist/components/disclosure/dialogZIndex.d.ts.map +1 -1
- package/dist/components/disclosure/dialogZIndex.js +4 -0
- package/dist/components/disclosure/dialogZIndex.js.map +1 -1
- package/dist/components/features/crud-detail/CrudDetail.d.ts.map +1 -1
- package/dist/components/features/crud-detail/CrudDetail.js +16 -7
- package/dist/components/features/crud-detail/CrudDetail.js.map +2 -2
- package/dist/components/features/crud-sheet/CrudSheet.d.ts.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheet.js +14 -5
- package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
- package/dist/components/features/crudRegistry.d.ts +16 -0
- package/dist/components/features/crudRegistry.d.ts.map +1 -0
- package/dist/components/features/crudRegistry.js +37 -0
- package/dist/components/features/crudRegistry.js.map +6 -0
- package/dist/components/features/permission-table/PermissionTable.d.ts.map +1 -1
- package/dist/components/features/permission-table/PermissionTable.js +71 -86
- package/dist/components/features/permission-table/PermissionTable.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelect.js +2 -4
- package/dist/components/features/shared-data/SharedDataSelect.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelectList.d.ts +2 -4
- package/dist/components/features/shared-data/SharedDataSelectList.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelectList.js +11 -46
- package/dist/components/features/shared-data/SharedDataSelectList.js.map +2 -2
- package/dist/components/form-control/select/Select.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.js +1 -1
- package/dist/components/form-control/select/Select.js.map +1 -1
- package/dist/helpers/createAppStructure.d.ts.map +1 -1
- package/dist/helpers/createAppStructure.js +3 -2
- package/dist/helpers/createAppStructure.js.map +1 -1
- package/dist/helpers/createHmrSafeContext.d.ts +3 -0
- package/dist/helpers/createHmrSafeContext.d.ts.map +1 -0
- package/dist/helpers/createHmrSafeContext.js +10 -0
- package/dist/helpers/createHmrSafeContext.js.map +6 -0
- package/dist/hooks/createSelectionGroup.d.ts.map +1 -1
- package/dist/hooks/createSelectionGroup.js +3 -2
- package/dist/hooks/createSelectionGroup.js.map +2 -2
- package/package.json +6 -5
- package/src/components/disclosure/Dropdown.tsx +31 -17
- package/src/components/disclosure/dialogZIndex.ts +5 -0
- package/src/components/features/crud-detail/CrudDetail.tsx +16 -5
- package/src/components/features/crud-sheet/CrudSheet.tsx +13 -3
- package/src/components/features/crudRegistry.ts +60 -0
- package/src/components/features/permission-table/PermissionTable.tsx +49 -46
- package/src/components/features/shared-data/SharedDataSelect.tsx +2 -2
- package/src/components/features/shared-data/SharedDataSelectList.tsx +11 -36
- package/src/components/form-control/select/Select.tsx +1 -5
- package/src/helpers/createAppStructure.ts +3 -2
- package/src/helpers/createHmrSafeContext.ts +8 -0
- package/src/hooks/createSelectionGroup.tsx +4 -2
- package/tests/components/data/List.spec.tsx +52 -52
- package/tests/components/data/Pagination.spec.tsx +43 -43
- package/tests/components/data/Table.spec.tsx +4 -4
- package/tests/components/data/kanban/Kanban.selection.spec.tsx +21 -21
- package/tests/components/data/sheet/DataSheet.spec.tsx +50 -50
- package/tests/components/disclosure/Collapse.spec.tsx +24 -24
- package/tests/components/disclosure/Dialog.spec.tsx +33 -33
- package/tests/components/disclosure/DialogProvider.spec.tsx +9 -9
- package/tests/components/disclosure/Dropdown.spec.tsx +134 -14
- package/tests/components/disclosure/Tabs.spec.tsx +21 -21
- package/tests/components/disclosure/dialogZIndex.spec.ts +45 -0
- package/tests/components/display/Alert.spec.tsx +4 -4
- package/tests/components/display/Barcode.spec.tsx +7 -7
- package/tests/components/display/Card.spec.tsx +3 -3
- package/tests/components/display/Link.spec.tsx +5 -5
- package/tests/components/display/Tag.spec.tsx +4 -4
- package/tests/components/features/address/AddressSearch.spec.tsx +3 -3
- package/tests/components/features/crudRegistry.spec.ts +119 -0
- package/tests/components/features/data-select-button/DataSelectButton.spec.tsx +8 -8
- package/tests/components/features/permission-table/PermissionTable.spec.tsx +43 -43
- package/tests/components/features/shared-data/SharedDataSelectList.spec.tsx +2 -17
- package/tests/components/feedback/busy/BusyContainer.spec.tsx +7 -7
- package/tests/components/feedback/notification/NotificationBell.spec.tsx +9 -9
- package/tests/components/feedback/print/Print.spec.tsx +4 -4
- package/tests/components/form-control/Button.spec.tsx +18 -18
- package/tests/components/form-control/checkbox/Checkbox.spec.tsx +20 -20
- package/tests/components/form-control/checkbox/CheckboxGroup.spec.tsx +12 -12
- package/tests/components/form-control/checkbox/Radio.spec.tsx +21 -21
- package/tests/components/form-control/checkbox/RadioGroup.spec.tsx +12 -12
- package/tests/components/form-control/color-picker/ColorPicker.spec.tsx +10 -10
- package/tests/components/form-control/combobox/Combobox.spec.tsx +16 -16
- package/tests/components/form-control/combobox/ComboboxItem.spec.tsx +7 -7
- package/tests/components/form-control/date-range-picker/DateRangePicker.spec.tsx +24 -24
- package/tests/components/form-control/field/DatePicker.spec.tsx +50 -50
- package/tests/components/form-control/field/DateTimePicker.spec.tsx +47 -47
- package/tests/components/form-control/field/NumberInput.spec.tsx +54 -54
- package/tests/components/form-control/field/TextInput.spec.tsx +49 -49
- package/tests/components/form-control/field/Textarea.spec.tsx +33 -33
- package/tests/components/form-control/field/TimePicker.spec.tsx +42 -42
- package/tests/components/form-control/numpad/Numpad.spec.tsx +40 -40
- package/tests/components/form-control/select/Select.spec.tsx +9 -9
- package/tests/components/form-control/select/SelectItem.spec.tsx +10 -10
- package/tests/helpers/createAppStructure.spec.tsx +57 -57
- package/tests/helpers/mergeStyles.spec.ts +31 -31
|
@@ -3,26 +3,26 @@ import { describe, it, expect, vi } from "vitest";
|
|
|
3
3
|
import { createSignal } from "solid-js";
|
|
4
4
|
import { Checkbox } from "../../../../src/components/form-control/checkbox/Checkbox";
|
|
5
5
|
|
|
6
|
-
describe("Checkbox
|
|
6
|
+
describe("Checkbox component", () => {
|
|
7
7
|
describe("basic rendering", () => {
|
|
8
|
-
it("checkbox role
|
|
8
|
+
it("renders with checkbox role", () => {
|
|
9
9
|
const { getByRole } = render(() => <Checkbox />);
|
|
10
10
|
expect(getByRole("checkbox")).toBeTruthy();
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
it("children
|
|
13
|
+
it("renders children as label", () => {
|
|
14
14
|
const { getByText } = render(() => <Checkbox>동의합니다</Checkbox>);
|
|
15
15
|
expect(getByText("동의합니다")).toBeTruthy();
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
it("
|
|
18
|
+
it("defaults to unchecked", () => {
|
|
19
19
|
const { getByRole } = render(() => <Checkbox />);
|
|
20
20
|
expect(getByRole("checkbox").getAttribute("aria-checked")).toBe("false");
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
describe("click behavior", () => {
|
|
25
|
-
it("
|
|
25
|
+
it("toggles checked state on click", () => {
|
|
26
26
|
const { getByRole } = render(() => <Checkbox />);
|
|
27
27
|
const checkbox = getByRole("checkbox");
|
|
28
28
|
|
|
@@ -33,7 +33,7 @@ describe("Checkbox 컴포넌트", () => {
|
|
|
33
33
|
expect(checkbox.getAttribute("aria-checked")).toBe("false");
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
it("
|
|
36
|
+
it("does not change when disabled", () => {
|
|
37
37
|
const { getByRole } = render(() => <Checkbox disabled />);
|
|
38
38
|
const checkbox = getByRole("checkbox");
|
|
39
39
|
|
|
@@ -42,8 +42,8 @@ describe("Checkbox 컴포넌트", () => {
|
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
describe("
|
|
46
|
-
it("Space
|
|
45
|
+
describe("keyboard behavior", () => {
|
|
46
|
+
it("toggles with Space key", () => {
|
|
47
47
|
const { getByRole } = render(() => <Checkbox />);
|
|
48
48
|
const checkbox = getByRole("checkbox");
|
|
49
49
|
|
|
@@ -55,13 +55,13 @@ describe("Checkbox 컴포넌트", () => {
|
|
|
55
55
|
});
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
describe("controlled
|
|
59
|
-
it("value prop
|
|
58
|
+
describe("controlled pattern", () => {
|
|
59
|
+
it("reflects value prop as checked state", () => {
|
|
60
60
|
const { getByRole } = render(() => <Checkbox value={true} />);
|
|
61
61
|
expect(getByRole("checkbox").getAttribute("aria-checked")).toBe("true");
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
it("onValueChange
|
|
64
|
+
it("calls onValueChange on click", () => {
|
|
65
65
|
const handleChange = vi.fn();
|
|
66
66
|
const { getByRole } = render(() => <Checkbox value={false} onValueChange={handleChange} />);
|
|
67
67
|
|
|
@@ -69,7 +69,7 @@ describe("Checkbox 컴포넌트", () => {
|
|
|
69
69
|
expect(handleChange).toHaveBeenCalledWith(true);
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
-
it("
|
|
72
|
+
it("updates when external state changes", () => {
|
|
73
73
|
const [value, setValue] = createSignal(false);
|
|
74
74
|
const { getByRole } = render(() => <Checkbox value={value()} onValueChange={setValue} />);
|
|
75
75
|
|
|
@@ -80,22 +80,22 @@ describe("Checkbox 컴포넌트", () => {
|
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
describe("
|
|
84
|
-
it("
|
|
83
|
+
describe("style variants", () => {
|
|
84
|
+
it("applies different styles per size", () => {
|
|
85
85
|
const { getByRole: getDefault } = render(() => <Checkbox />);
|
|
86
86
|
const { getByRole: getSm } = render(() => <Checkbox size="sm" />);
|
|
87
87
|
|
|
88
88
|
expect(getDefault("checkbox").className).not.toBe(getSm("checkbox").className);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
it("
|
|
91
|
+
it("applies different styles when inset", () => {
|
|
92
92
|
const { getByRole: getDefault } = render(() => <Checkbox />);
|
|
93
93
|
const { getByRole: getInset } = render(() => <Checkbox inset />);
|
|
94
94
|
|
|
95
95
|
expect(getDefault("checkbox").className).not.toBe(getInset("checkbox").className);
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
-
it("disabled
|
|
98
|
+
it("applies disabled style", () => {
|
|
99
99
|
const { getByRole } = render(() => <Checkbox disabled />);
|
|
100
100
|
expect(getByRole("checkbox").classList.contains("opacity-30")).toBe(true);
|
|
101
101
|
});
|
|
@@ -110,25 +110,25 @@ describe("Checkbox 컴포넌트", () => {
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
describe("validation", () => {
|
|
113
|
-
it("
|
|
113
|
+
it("sets error message when required and unchecked", () => {
|
|
114
114
|
const { container } = render(() => <Checkbox required value={false} />);
|
|
115
115
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
116
116
|
expect(hiddenInput.validationMessage).toBe("This is a required selection");
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
it("required
|
|
119
|
+
it("is valid when required and checked", () => {
|
|
120
120
|
const { container } = render(() => <Checkbox required value={true} />);
|
|
121
121
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
122
122
|
expect(hiddenInput.validity.valid).toBe(true);
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
it("
|
|
125
|
+
it("sets error message returned by validate function", () => {
|
|
126
126
|
const { container } = render(() => <Checkbox value={true} validate={() => "커스텀 에러"} />);
|
|
127
127
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
128
128
|
expect(hiddenInput.validationMessage).toBe("커스텀 에러");
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
it("validate
|
|
131
|
+
it("is valid when validate function returns undefined", () => {
|
|
132
132
|
const { container } = render(() => <Checkbox value={true} validate={() => undefined} />);
|
|
133
133
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
134
134
|
expect(hiddenInput.validity.valid).toBe(true);
|
|
@@ -3,9 +3,9 @@ import { describe, it, expect, vi } from "vitest";
|
|
|
3
3
|
import { createSignal } from "solid-js";
|
|
4
4
|
import { CheckboxGroup } from "../../../../src/components/form-control/checkbox/CheckboxGroup";
|
|
5
5
|
|
|
6
|
-
describe("CheckboxGroup
|
|
6
|
+
describe("CheckboxGroup component", () => {
|
|
7
7
|
describe("basic rendering", () => {
|
|
8
|
-
it("
|
|
8
|
+
it("renders the container", () => {
|
|
9
9
|
const { container } = render(() => (
|
|
10
10
|
<CheckboxGroup>
|
|
11
11
|
<CheckboxGroup.Item value="a">A</CheckboxGroup.Item>
|
|
@@ -14,7 +14,7 @@ describe("CheckboxGroup 컴포넌트", () => {
|
|
|
14
14
|
expect(container.querySelector("div")).toBeTruthy();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it("
|
|
17
|
+
it("renders items as checkboxes", () => {
|
|
18
18
|
const { getAllByRole } = render(() => (
|
|
19
19
|
<CheckboxGroup>
|
|
20
20
|
<CheckboxGroup.Item value="a">A</CheckboxGroup.Item>
|
|
@@ -25,8 +25,8 @@ describe("CheckboxGroup 컴포넌트", () => {
|
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
describe("controlled
|
|
29
|
-
it("value prop
|
|
28
|
+
describe("controlled pattern", () => {
|
|
29
|
+
it("reflects value prop as selected state", () => {
|
|
30
30
|
const { getAllByRole } = render(() => (
|
|
31
31
|
<CheckboxGroup value={["a"]}>
|
|
32
32
|
<CheckboxGroup.Item value="a">A</CheckboxGroup.Item>
|
|
@@ -38,7 +38,7 @@ describe("CheckboxGroup 컴포넌트", () => {
|
|
|
38
38
|
expect(checkboxes[1].getAttribute("aria-checked")).toBe("false");
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
it("onValueChange
|
|
41
|
+
it("calls onValueChange on toggle", () => {
|
|
42
42
|
const handleChange = vi.fn();
|
|
43
43
|
const { getAllByRole } = render(() => (
|
|
44
44
|
<CheckboxGroup value={[]} onValueChange={handleChange}>
|
|
@@ -49,7 +49,7 @@ describe("CheckboxGroup 컴포넌트", () => {
|
|
|
49
49
|
expect(handleChange).toHaveBeenCalledWith(["a"]);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
it("
|
|
52
|
+
it("updates when external state changes", () => {
|
|
53
53
|
const [value, setValue] = createSignal<string[]>([]);
|
|
54
54
|
const { getAllByRole } = render(() => (
|
|
55
55
|
<CheckboxGroup value={value()} onValueChange={setValue}>
|
|
@@ -63,13 +63,13 @@ describe("CheckboxGroup 컴포넌트", () => {
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
describe("validation", () => {
|
|
66
|
-
//
|
|
66
|
+
// The group's hidden input is positioned after the children's hidden inputs
|
|
67
67
|
const getGroupHiddenInput = (container: HTMLElement) => {
|
|
68
68
|
const inputs = container.querySelectorAll("input[aria-hidden='true']");
|
|
69
69
|
return inputs[inputs.length - 1] as HTMLInputElement;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
-
it("
|
|
72
|
+
it("sets error message when required and no item selected", () => {
|
|
73
73
|
const { container } = render(() => (
|
|
74
74
|
<CheckboxGroup required value={[]}>
|
|
75
75
|
<CheckboxGroup.Item value="a">A</CheckboxGroup.Item>
|
|
@@ -78,7 +78,7 @@ describe("CheckboxGroup 컴포넌트", () => {
|
|
|
78
78
|
expect(getGroupHiddenInput(container).validationMessage).toBe("Please select an item");
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
it("required
|
|
81
|
+
it("is valid when required and item is selected", () => {
|
|
82
82
|
const { container } = render(() => (
|
|
83
83
|
<CheckboxGroup required value={["a"]}>
|
|
84
84
|
<CheckboxGroup.Item value="a">A</CheckboxGroup.Item>
|
|
@@ -87,7 +87,7 @@ describe("CheckboxGroup 컴포넌트", () => {
|
|
|
87
87
|
expect(getGroupHiddenInput(container).validity.valid).toBe(true);
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
it("
|
|
90
|
+
it("sets error message returned by validate function", () => {
|
|
91
91
|
const { container } = render(() => (
|
|
92
92
|
<CheckboxGroup value={["a"]} validate={() => "커스텀 에러"}>
|
|
93
93
|
<CheckboxGroup.Item value="a">A</CheckboxGroup.Item>
|
|
@@ -96,7 +96,7 @@ describe("CheckboxGroup 컴포넌트", () => {
|
|
|
96
96
|
expect(getGroupHiddenInput(container).validationMessage).toBe("커스텀 에러");
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
it("validate
|
|
99
|
+
it("is valid when validate function returns undefined", () => {
|
|
100
100
|
const { container } = render(() => (
|
|
101
101
|
<CheckboxGroup value={["a"]} validate={() => undefined}>
|
|
102
102
|
<CheckboxGroup.Item value="a">A</CheckboxGroup.Item>
|
|
@@ -3,26 +3,26 @@ import { describe, it, expect, vi } from "vitest";
|
|
|
3
3
|
import { createSignal } from "solid-js";
|
|
4
4
|
import { Radio } from "../../../../src/components/form-control/checkbox/Radio";
|
|
5
5
|
|
|
6
|
-
describe("Radio
|
|
6
|
+
describe("Radio component", () => {
|
|
7
7
|
describe("basic rendering", () => {
|
|
8
|
-
it("radio role
|
|
8
|
+
it("renders with radio role", () => {
|
|
9
9
|
const { getByRole } = render(() => <Radio />);
|
|
10
10
|
expect(getByRole("radio")).toBeTruthy();
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
it("children
|
|
13
|
+
it("renders children as label", () => {
|
|
14
14
|
const { getByText } = render(() => <Radio>옵션 A</Radio>);
|
|
15
15
|
expect(getByText("옵션 A")).toBeTruthy();
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
it("
|
|
18
|
+
it("defaults to unchecked", () => {
|
|
19
19
|
const { getByRole } = render(() => <Radio />);
|
|
20
20
|
expect(getByRole("radio").getAttribute("aria-checked")).toBe("false");
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
describe("click behavior", () => {
|
|
25
|
-
it("
|
|
25
|
+
it("selects on click", () => {
|
|
26
26
|
const { getByRole } = render(() => <Radio />);
|
|
27
27
|
const radio = getByRole("radio");
|
|
28
28
|
|
|
@@ -30,7 +30,7 @@ describe("Radio 컴포넌트", () => {
|
|
|
30
30
|
expect(radio.getAttribute("aria-checked")).toBe("true");
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
it("
|
|
33
|
+
it("does not deselect when already selected", () => {
|
|
34
34
|
const { getByRole } = render(() => <Radio value={true} />);
|
|
35
35
|
const radio = getByRole("radio");
|
|
36
36
|
|
|
@@ -38,7 +38,7 @@ describe("Radio 컴포넌트", () => {
|
|
|
38
38
|
expect(radio.getAttribute("aria-checked")).toBe("true");
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
it("
|
|
41
|
+
it("does not change when disabled", () => {
|
|
42
42
|
const { getByRole } = render(() => <Radio disabled />);
|
|
43
43
|
const radio = getByRole("radio");
|
|
44
44
|
|
|
@@ -47,8 +47,8 @@ describe("Radio 컴포넌트", () => {
|
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
describe("
|
|
51
|
-
it("Space
|
|
50
|
+
describe("keyboard behavior", () => {
|
|
51
|
+
it("selects with Space key", () => {
|
|
52
52
|
const { getByRole } = render(() => <Radio />);
|
|
53
53
|
const radio = getByRole("radio");
|
|
54
54
|
|
|
@@ -57,13 +57,13 @@ describe("Radio 컴포넌트", () => {
|
|
|
57
57
|
});
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
describe("controlled
|
|
61
|
-
it("value prop
|
|
60
|
+
describe("controlled pattern", () => {
|
|
61
|
+
it("reflects value prop as checked state", () => {
|
|
62
62
|
const { getByRole } = render(() => <Radio value={true} />);
|
|
63
63
|
expect(getByRole("radio").getAttribute("aria-checked")).toBe("true");
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
it("onValueChange
|
|
66
|
+
it("calls onValueChange on click", () => {
|
|
67
67
|
const handleChange = vi.fn();
|
|
68
68
|
const { getByRole } = render(() => <Radio value={false} onValueChange={handleChange} />);
|
|
69
69
|
|
|
@@ -71,7 +71,7 @@ describe("Radio 컴포넌트", () => {
|
|
|
71
71
|
expect(handleChange).toHaveBeenCalledWith(true);
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
it("
|
|
74
|
+
it("updates when external state changes", () => {
|
|
75
75
|
const [value, setValue] = createSignal(false);
|
|
76
76
|
const { getByRole } = render(() => <Radio value={value()} onValueChange={setValue} />);
|
|
77
77
|
|
|
@@ -82,21 +82,21 @@ describe("Radio 컴포넌트", () => {
|
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
describe("
|
|
86
|
-
it("
|
|
85
|
+
describe("style variants", () => {
|
|
86
|
+
it("indicator is circular", () => {
|
|
87
87
|
const { getByRole } = render(() => <Radio />);
|
|
88
88
|
const indicator = getByRole("radio").querySelector("div") as HTMLElement;
|
|
89
89
|
expect(indicator.classList.contains("rounded-full")).toBe(true);
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
it("
|
|
92
|
+
it("applies different styles per size", () => {
|
|
93
93
|
const { getByRole: getDefault } = render(() => <Radio />);
|
|
94
94
|
const { getByRole: getSm } = render(() => <Radio size="sm" />);
|
|
95
95
|
|
|
96
96
|
expect(getDefault("radio").className).not.toBe(getSm("radio").className);
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
it("disabled
|
|
99
|
+
it("applies disabled style", () => {
|
|
100
100
|
const { getByRole } = render(() => <Radio disabled />);
|
|
101
101
|
expect(getByRole("radio").classList.contains("opacity-30")).toBe(true);
|
|
102
102
|
});
|
|
@@ -111,25 +111,25 @@ describe("Radio 컴포넌트", () => {
|
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
describe("validation", () => {
|
|
114
|
-
it("
|
|
114
|
+
it("sets error message when required and not selected", () => {
|
|
115
115
|
const { container } = render(() => <Radio required value={false} />);
|
|
116
116
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
117
117
|
expect(hiddenInput.validationMessage).toBe("This is a required selection");
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
-
it("required
|
|
120
|
+
it("is valid when required and selected", () => {
|
|
121
121
|
const { container } = render(() => <Radio required value={true} />);
|
|
122
122
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
123
123
|
expect(hiddenInput.validity.valid).toBe(true);
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
-
it("
|
|
126
|
+
it("sets error message returned by validate function", () => {
|
|
127
127
|
const { container } = render(() => <Radio value={true} validate={() => "커스텀 에러"} />);
|
|
128
128
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
129
129
|
expect(hiddenInput.validationMessage).toBe("커스텀 에러");
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
-
it("validate
|
|
132
|
+
it("is valid when validate function returns undefined", () => {
|
|
133
133
|
const { container } = render(() => <Radio value={true} validate={() => undefined} />);
|
|
134
134
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
135
135
|
expect(hiddenInput.validity.valid).toBe(true);
|
|
@@ -3,9 +3,9 @@ import { describe, it, expect, vi } from "vitest";
|
|
|
3
3
|
import { createSignal } from "solid-js";
|
|
4
4
|
import { RadioGroup } from "../../../../src/components/form-control/checkbox/RadioGroup";
|
|
5
5
|
|
|
6
|
-
describe("RadioGroup
|
|
6
|
+
describe("RadioGroup component", () => {
|
|
7
7
|
describe("basic rendering", () => {
|
|
8
|
-
it("
|
|
8
|
+
it("renders the container", () => {
|
|
9
9
|
const { container } = render(() => (
|
|
10
10
|
<RadioGroup>
|
|
11
11
|
<RadioGroup.Item value="a">A</RadioGroup.Item>
|
|
@@ -14,7 +14,7 @@ describe("RadioGroup 컴포넌트", () => {
|
|
|
14
14
|
expect(container.querySelector("div")).toBeTruthy();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it("
|
|
17
|
+
it("renders items as radios", () => {
|
|
18
18
|
const { getAllByRole } = render(() => (
|
|
19
19
|
<RadioGroup>
|
|
20
20
|
<RadioGroup.Item value="a">A</RadioGroup.Item>
|
|
@@ -25,8 +25,8 @@ describe("RadioGroup 컴포넌트", () => {
|
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
describe("controlled
|
|
29
|
-
it("value prop
|
|
28
|
+
describe("controlled pattern", () => {
|
|
29
|
+
it("reflects value prop as selected state", () => {
|
|
30
30
|
const { getAllByRole } = render(() => (
|
|
31
31
|
<RadioGroup value="a">
|
|
32
32
|
<RadioGroup.Item value="a">A</RadioGroup.Item>
|
|
@@ -38,7 +38,7 @@ describe("RadioGroup 컴포넌트", () => {
|
|
|
38
38
|
expect(radios[1].getAttribute("aria-checked")).toBe("false");
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
it("onValueChange
|
|
41
|
+
it("calls onValueChange on selection", () => {
|
|
42
42
|
const handleChange = vi.fn();
|
|
43
43
|
const { getAllByRole } = render(() => (
|
|
44
44
|
<RadioGroup value={undefined} onValueChange={handleChange}>
|
|
@@ -49,7 +49,7 @@ describe("RadioGroup 컴포넌트", () => {
|
|
|
49
49
|
expect(handleChange).toHaveBeenCalledWith("a");
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
it("
|
|
52
|
+
it("updates when external state changes", () => {
|
|
53
53
|
const [value, setValue] = createSignal<string | undefined>(undefined);
|
|
54
54
|
const { getAllByRole } = render(() => (
|
|
55
55
|
<RadioGroup value={value()} onValueChange={setValue}>
|
|
@@ -63,13 +63,13 @@ describe("RadioGroup 컴포넌트", () => {
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
describe("validation", () => {
|
|
66
|
-
//
|
|
66
|
+
// The group's hidden input is positioned after the children's hidden inputs
|
|
67
67
|
const getGroupHiddenInput = (container: HTMLElement) => {
|
|
68
68
|
const inputs = container.querySelectorAll("input[aria-hidden='true']");
|
|
69
69
|
return inputs[inputs.length - 1] as HTMLInputElement;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
-
it("
|
|
72
|
+
it("sets error message when required and no item selected", () => {
|
|
73
73
|
const { container } = render(() => (
|
|
74
74
|
<RadioGroup required value={undefined}>
|
|
75
75
|
<RadioGroup.Item value="a">A</RadioGroup.Item>
|
|
@@ -78,7 +78,7 @@ describe("RadioGroup 컴포넌트", () => {
|
|
|
78
78
|
expect(getGroupHiddenInput(container).validationMessage).toBe("Please select an item");
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
it("required
|
|
81
|
+
it("is valid when required and item is selected", () => {
|
|
82
82
|
const { container } = render(() => (
|
|
83
83
|
<RadioGroup required value="a">
|
|
84
84
|
<RadioGroup.Item value="a">A</RadioGroup.Item>
|
|
@@ -87,7 +87,7 @@ describe("RadioGroup 컴포넌트", () => {
|
|
|
87
87
|
expect(getGroupHiddenInput(container).validity.valid).toBe(true);
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
it("
|
|
90
|
+
it("sets error message returned by validate function", () => {
|
|
91
91
|
const { container } = render(() => (
|
|
92
92
|
<RadioGroup value="a" validate={() => "커스텀 에러"}>
|
|
93
93
|
<RadioGroup.Item value="a">A</RadioGroup.Item>
|
|
@@ -96,7 +96,7 @@ describe("RadioGroup 컴포넌트", () => {
|
|
|
96
96
|
expect(getGroupHiddenInput(container).validationMessage).toBe("커스텀 에러");
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
it("validate
|
|
99
|
+
it("is valid when validate function returns undefined", () => {
|
|
100
100
|
const { container } = render(() => (
|
|
101
101
|
<RadioGroup value="a" validate={() => undefined}>
|
|
102
102
|
<RadioGroup.Item value="a">A</RadioGroup.Item>
|
|
@@ -3,24 +3,24 @@ import { describe, it, expect, vi } from "vitest";
|
|
|
3
3
|
import { createSignal } from "solid-js";
|
|
4
4
|
import { ColorPicker } from "../../../../src/components/form-control/color-picker/ColorPicker";
|
|
5
5
|
|
|
6
|
-
describe("ColorPicker
|
|
6
|
+
describe("ColorPicker component", () => {
|
|
7
7
|
describe("basic rendering", () => {
|
|
8
|
-
it("input type=color
|
|
8
|
+
it("renders input type=color", () => {
|
|
9
9
|
const { container } = render(() => <ColorPicker />);
|
|
10
10
|
const input = container.querySelector("input") as HTMLInputElement;
|
|
11
11
|
expect(input).toBeTruthy();
|
|
12
12
|
expect(input.type).toBe("color");
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
it("
|
|
15
|
+
it("defaults to #000000", () => {
|
|
16
16
|
const { container } = render(() => <ColorPicker />);
|
|
17
17
|
const input = container.querySelector("input") as HTMLInputElement;
|
|
18
18
|
expect(input.value).toBe("#000000");
|
|
19
19
|
});
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
describe("controlled
|
|
23
|
-
it("onValueChange
|
|
22
|
+
describe("controlled pattern", () => {
|
|
23
|
+
it("calls onValueChange on color change", () => {
|
|
24
24
|
const handleChange = vi.fn();
|
|
25
25
|
const { container } = render(() => (
|
|
26
26
|
<ColorPicker value="#000000" onValueChange={handleChange} />
|
|
@@ -32,7 +32,7 @@ describe("ColorPicker 컴포넌트", () => {
|
|
|
32
32
|
expect(handleChange).toHaveBeenCalledWith("#ff5500");
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
it("
|
|
35
|
+
it("updates input value when external state changes", () => {
|
|
36
36
|
const [value, setValue] = createSignal("#ff0000");
|
|
37
37
|
const { container } = render(() => <ColorPicker value={value()} onValueChange={setValue} />);
|
|
38
38
|
const input = container.querySelector("input") as HTMLInputElement;
|
|
@@ -45,13 +45,13 @@ describe("ColorPicker 컴포넌트", () => {
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
describe("disabled state", () => {
|
|
48
|
-
it("disabled=true
|
|
48
|
+
it("disables input when disabled=true", () => {
|
|
49
49
|
const { container } = render(() => <ColorPicker disabled />);
|
|
50
50
|
const input = container.querySelector("input") as HTMLInputElement;
|
|
51
51
|
expect(input.disabled).toBe(true);
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
it("disabled
|
|
54
|
+
it("applies disabled style", () => {
|
|
55
55
|
const { container } = render(() => <ColorPicker disabled />);
|
|
56
56
|
const input = container.querySelector("input") as HTMLInputElement;
|
|
57
57
|
expect(input.classList.contains("cursor-default")).toBe(true);
|
|
@@ -74,13 +74,13 @@ describe("ColorPicker 컴포넌트", () => {
|
|
|
74
74
|
expect(hiddenInput.validationMessage).toBe("This field is required");
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
-
it("required
|
|
77
|
+
it("is valid when required and value exists", () => {
|
|
78
78
|
const { container } = render(() => <ColorPicker required value="#ff0000" />);
|
|
79
79
|
const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
|
|
80
80
|
expect(hiddenInput.validity.valid).toBe(true);
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
it("
|
|
83
|
+
it("sets error message returned by validate function", () => {
|
|
84
84
|
const { container } = render(() => (
|
|
85
85
|
<ColorPicker
|
|
86
86
|
validate={(v) => (v === "#000000" ? "검정색은 사용할 수 없습니다" : undefined)}
|