@simplysm/solid 13.0.72 → 13.0.74

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.
Files changed (210) hide show
  1. package/README.md +209 -202
  2. package/dist/components/data/calendar/Calendar.d.ts.map +1 -1
  3. package/dist/components/data/calendar/Calendar.js +3 -11
  4. package/dist/components/data/calendar/Calendar.js.map +2 -2
  5. package/dist/components/data/sheet/DataSheet.js +10 -10
  6. package/dist/components/data/sheet/DataSheet.js.map +2 -2
  7. package/dist/components/data/sheet/DataSheetConfigDialog.d.ts.map +1 -1
  8. package/dist/components/data/sheet/DataSheetConfigDialog.js +27 -9
  9. package/dist/components/data/sheet/DataSheetConfigDialog.js.map +2 -2
  10. package/dist/components/disclosure/Dialog.d.ts +1 -1
  11. package/dist/components/disclosure/Dialog.d.ts.map +1 -1
  12. package/dist/components/disclosure/Dialog.js +5 -5
  13. package/dist/components/disclosure/Dialog.js.map +2 -2
  14. package/dist/components/disclosure/dialogZIndex.d.ts +1 -1
  15. package/dist/components/features/crud-detail/CrudDetail.js +23 -23
  16. package/dist/components/features/crud-detail/CrudDetail.js.map +2 -2
  17. package/dist/components/features/crud-sheet/CrudSheet.js +49 -49
  18. package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
  19. package/dist/components/features/crud-sheet/types.d.ts +4 -4
  20. package/dist/components/features/crud-sheet/types.d.ts.map +1 -1
  21. package/dist/components/features/data-select-button/DataSelectButton.d.ts +25 -7
  22. package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -1
  23. package/dist/components/features/data-select-button/DataSelectButton.js +27 -12
  24. package/dist/components/features/data-select-button/DataSelectButton.js.map +2 -2
  25. package/dist/components/features/permission-table/PermissionTable.js +4 -4
  26. package/dist/components/features/permission-table/PermissionTable.js.map +2 -2
  27. package/dist/components/features/shared-data/SharedDataSelect.d.ts +22 -10
  28. package/dist/components/features/shared-data/SharedDataSelect.d.ts.map +1 -1
  29. package/dist/components/features/shared-data/SharedDataSelect.js +113 -29
  30. package/dist/components/features/shared-data/SharedDataSelect.js.map +2 -2
  31. package/dist/components/features/shared-data/SharedDataSelectButton.d.ts +3 -3
  32. package/dist/components/features/shared-data/SharedDataSelectButton.d.ts.map +1 -1
  33. package/dist/components/features/shared-data/SharedDataSelectButton.js.map +1 -1
  34. package/dist/components/features/shared-data/SharedDataSelectList.js +5 -4
  35. package/dist/components/features/shared-data/SharedDataSelectList.js.map +2 -2
  36. package/dist/components/feedback/notification/NotificationBanner.js +3 -3
  37. package/dist/components/feedback/notification/NotificationBanner.js.map +2 -2
  38. package/dist/components/feedback/notification/NotificationBell.d.ts.map +1 -1
  39. package/dist/components/feedback/notification/NotificationBell.js +12 -5
  40. package/dist/components/feedback/notification/NotificationBell.js.map +2 -2
  41. package/dist/components/feedback/notification/NotificationProvider.d.ts.map +1 -1
  42. package/dist/components/feedback/notification/NotificationProvider.js +3 -1
  43. package/dist/components/feedback/notification/NotificationProvider.js.map +2 -2
  44. package/dist/components/form-control/ThemeToggle.d.ts.map +1 -1
  45. package/dist/components/form-control/ThemeToggle.js +9 -6
  46. package/dist/components/form-control/ThemeToggle.js.map +2 -2
  47. package/dist/components/form-control/checkbox/Checkbox.d.ts.map +1 -1
  48. package/dist/components/form-control/checkbox/Checkbox.js +3 -1
  49. package/dist/components/form-control/checkbox/Checkbox.js.map +2 -2
  50. package/dist/components/form-control/checkbox/CheckboxGroup.js +1 -1
  51. package/dist/components/form-control/checkbox/CheckboxGroup.js.map +2 -2
  52. package/dist/components/form-control/checkbox/Radio.d.ts.map +1 -1
  53. package/dist/components/form-control/checkbox/Radio.js +3 -1
  54. package/dist/components/form-control/checkbox/Radio.js.map +2 -2
  55. package/dist/components/form-control/checkbox/RadioGroup.js +1 -1
  56. package/dist/components/form-control/checkbox/RadioGroup.js.map +2 -2
  57. package/dist/components/form-control/color-picker/ColorPicker.d.ts.map +1 -1
  58. package/dist/components/form-control/color-picker/ColorPicker.js +3 -1
  59. package/dist/components/form-control/color-picker/ColorPicker.js.map +2 -2
  60. package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
  61. package/dist/components/form-control/combobox/Combobox.js +9 -5
  62. package/dist/components/form-control/combobox/Combobox.js.map +2 -2
  63. package/dist/components/form-control/date-range-picker/DateRangePicker.js +9 -9
  64. package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
  65. package/dist/components/form-control/editor/EditorToolbar.js +3 -3
  66. package/dist/components/form-control/editor/EditorToolbar.js.map +2 -2
  67. package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
  68. package/dist/components/form-control/field/DatePicker.js +9 -3
  69. package/dist/components/form-control/field/DatePicker.js.map +2 -2
  70. package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
  71. package/dist/components/form-control/field/DateTimePicker.js +9 -3
  72. package/dist/components/form-control/field/DateTimePicker.js.map +2 -2
  73. package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
  74. package/dist/components/form-control/field/NumberInput.js +9 -3
  75. package/dist/components/form-control/field/NumberInput.js.map +2 -2
  76. package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
  77. package/dist/components/form-control/field/TextInput.js +10 -4
  78. package/dist/components/form-control/field/TextInput.js.map +2 -2
  79. package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
  80. package/dist/components/form-control/field/Textarea.js +9 -3
  81. package/dist/components/form-control/field/Textarea.js.map +2 -2
  82. package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
  83. package/dist/components/form-control/field/TimePicker.js +9 -3
  84. package/dist/components/form-control/field/TimePicker.js.map +2 -2
  85. package/dist/components/form-control/numpad/Numpad.d.ts.map +1 -1
  86. package/dist/components/form-control/numpad/Numpad.js +5 -1
  87. package/dist/components/form-control/numpad/Numpad.js.map +2 -2
  88. package/dist/components/form-control/select/Select.js +7 -7
  89. package/dist/components/form-control/select/Select.js.map +2 -2
  90. package/dist/components/form-control/state-preset/StatePreset.d.ts.map +1 -1
  91. package/dist/components/form-control/state-preset/StatePreset.js +42 -20
  92. package/dist/components/form-control/state-preset/StatePreset.js.map +2 -2
  93. package/dist/components/layout/sidebar/SidebarContainer.js +3 -3
  94. package/dist/components/layout/sidebar/SidebarContainer.js.map +2 -2
  95. package/dist/components/layout/sidebar/SidebarMenu.d.ts.map +1 -1
  96. package/dist/components/layout/sidebar/SidebarMenu.js +5 -2
  97. package/dist/components/layout/sidebar/SidebarMenu.js.map +2 -2
  98. package/dist/components/layout/topbar/Topbar.js +3 -4
  99. package/dist/components/layout/topbar/Topbar.js.map +2 -2
  100. package/dist/components/layout/topbar/TopbarMenu.js +3 -3
  101. package/dist/components/layout/topbar/TopbarMenu.js.map +2 -2
  102. package/dist/hooks/createSelectionGroup.d.ts +2 -2
  103. package/dist/hooks/createSelectionGroup.d.ts.map +1 -1
  104. package/dist/hooks/createSelectionGroup.js +5 -2
  105. package/dist/hooks/createSelectionGroup.js.map +2 -2
  106. package/dist/providers/i18n/I18nContext.d.ts +0 -4
  107. package/dist/providers/i18n/I18nContext.d.ts.map +1 -1
  108. package/dist/providers/i18n/I18nContext.js +1 -5
  109. package/dist/providers/i18n/I18nContext.js.map +2 -2
  110. package/dist/providers/i18n/locales/en.d.ts +38 -0
  111. package/dist/providers/i18n/locales/en.d.ts.map +1 -1
  112. package/dist/providers/i18n/locales/en.js +39 -1
  113. package/dist/providers/i18n/locales/en.js.map +1 -1
  114. package/dist/providers/i18n/locales/ko.d.ts +38 -0
  115. package/dist/providers/i18n/locales/ko.d.ts.map +1 -1
  116. package/dist/providers/i18n/locales/ko.js +39 -1
  117. package/dist/providers/i18n/locales/ko.js.map +1 -1
  118. package/package.json +6 -6
  119. package/src/components/data/calendar/Calendar.tsx +3 -4
  120. package/src/components/data/sheet/DataSheet.tsx +11 -11
  121. package/src/components/data/sheet/DataSheetConfigDialog.tsx +12 -10
  122. package/src/components/data/sheet/types.ts +1 -1
  123. package/src/components/disclosure/Dialog.tsx +10 -10
  124. package/src/components/disclosure/dialogZIndex.ts +1 -1
  125. package/src/components/features/crud-detail/CrudDetail.tsx +25 -25
  126. package/src/components/features/crud-sheet/CrudSheet.tsx +53 -53
  127. package/src/components/features/crud-sheet/types.ts +4 -4
  128. package/src/components/features/data-select-button/DataSelectButton.tsx +51 -21
  129. package/src/components/features/permission-table/PermissionTable.tsx +3 -3
  130. package/src/components/features/shared-data/SharedDataSelect.tsx +172 -33
  131. package/src/components/features/shared-data/SharedDataSelectButton.tsx +3 -2
  132. package/src/components/features/shared-data/SharedDataSelectList.tsx +4 -4
  133. package/src/components/feedback/notification/NotificationBanner.tsx +3 -3
  134. package/src/components/feedback/notification/NotificationBell.tsx +6 -4
  135. package/src/components/feedback/notification/NotificationProvider.tsx +3 -1
  136. package/src/components/form-control/ThemeToggle.tsx +10 -6
  137. package/src/components/form-control/checkbox/Checkbox.tsx +4 -1
  138. package/src/components/form-control/checkbox/CheckboxGroup.tsx +1 -1
  139. package/src/components/form-control/checkbox/Radio.tsx +4 -1
  140. package/src/components/form-control/checkbox/RadioGroup.tsx +1 -1
  141. package/src/components/form-control/color-picker/ColorPicker.tsx +4 -1
  142. package/src/components/form-control/combobox/Combobox.tsx +6 -3
  143. package/src/components/form-control/date-range-picker/DateRangePicker.tsx +8 -8
  144. package/src/components/form-control/editor/EditorToolbar.tsx +23 -23
  145. package/src/components/form-control/field/DatePicker.tsx +6 -3
  146. package/src/components/form-control/field/DateTimePicker.tsx +6 -3
  147. package/src/components/form-control/field/NumberInput.tsx +6 -3
  148. package/src/components/form-control/field/TextInput.tsx +7 -4
  149. package/src/components/form-control/field/Textarea.tsx +6 -3
  150. package/src/components/form-control/field/TimePicker.tsx +6 -3
  151. package/src/components/form-control/numpad/Numpad.tsx +3 -1
  152. package/src/components/form-control/select/Select.tsx +7 -7
  153. package/src/components/form-control/state-preset/StatePreset.tsx +14 -12
  154. package/src/components/layout/sidebar/SidebarContainer.tsx +3 -3
  155. package/src/components/layout/sidebar/SidebarMenu.tsx +3 -1
  156. package/src/components/layout/topbar/Topbar.tsx +3 -3
  157. package/src/components/layout/topbar/TopbarMenu.tsx +3 -3
  158. package/src/hooks/createSelectionGroup.tsx +8 -4
  159. package/src/providers/i18n/I18nContext.tsx +0 -7
  160. package/src/providers/i18n/locales/en.ts +38 -0
  161. package/src/providers/i18n/locales/ko.ts +38 -0
  162. package/tailwind.config.ts +2 -2
  163. package/tests/components/data/kanban/Kanban.selection.spec.tsx +34 -24
  164. package/tests/components/disclosure/Dialog.spec.tsx +28 -28
  165. package/tests/components/disclosure/DialogProvider.spec.tsx +51 -25
  166. package/tests/components/features/address/AddressSearch.spec.tsx +12 -4
  167. package/tests/components/features/crud-detail/CrudDetail.spec.tsx +1 -0
  168. package/tests/components/features/crud-sheet/CrudSheet.spec.tsx +30 -6
  169. package/tests/components/features/data-select-button/DataSelectButton.spec.tsx +77 -56
  170. package/tests/components/features/permission-table/PermissionTable.spec.tsx +12 -8
  171. package/tests/components/features/shared-data/SharedDataSelect.spec.tsx +172 -0
  172. package/tests/components/features/shared-data/SharedDataSelectList.spec.tsx +14 -2
  173. package/tests/components/feedback/notification/LiveRegion.spec.tsx +20 -9
  174. package/tests/components/feedback/notification/NotificationBanner.spec.tsx +64 -46
  175. package/tests/components/feedback/notification/NotificationBell.spec.tsx +70 -51
  176. package/tests/components/feedback/notification/NotificationContext.spec.tsx +105 -78
  177. package/tests/components/form-control/checkbox/Checkbox.spec.tsx +25 -20
  178. package/tests/components/form-control/checkbox/CheckboxGroup.spec.tsx +53 -30
  179. package/tests/components/form-control/checkbox/Radio.spec.tsx +25 -20
  180. package/tests/components/form-control/checkbox/RadioGroup.spec.tsx +53 -30
  181. package/tests/components/form-control/color-picker/ColorPicker.spec.tsx +24 -15
  182. package/tests/components/form-control/combobox/Combobox.spec.tsx +92 -59
  183. package/tests/components/form-control/date-range-picker/DateRangePicker.spec.tsx +2 -2
  184. package/tests/components/form-control/field/DatePicker.spec.tsx +50 -44
  185. package/tests/components/form-control/field/DateTimePicker.spec.tsx +51 -45
  186. package/tests/components/form-control/field/NumberInput.spec.tsx +53 -47
  187. package/tests/components/form-control/field/TextInput.spec.tsx +50 -44
  188. package/tests/components/form-control/field/Textarea.spec.tsx +35 -29
  189. package/tests/components/form-control/field/TimePicker.spec.tsx +43 -37
  190. package/tests/components/form-control/numpad/Numpad.spec.tsx +175 -25
  191. package/tests/components/form-control/select/Select.spec.tsx +5 -0
  192. package/tests/components/form-control/select/SelectItem.spec.tsx +1 -0
  193. package/tests/components/layout/sidebar/Sidebar.spec.tsx +79 -35
  194. package/tests/components/layout/sidebar/SidebarContainer.spec.tsx +1 -0
  195. package/tests/components/layout/sidebar/SidebarMenu.spec.tsx +28 -17
  196. package/tests/components/layout/topbar/TopbarActions.spec.tsx +41 -23
  197. package/tests/components/layout/topbar/createTopbarActions.spec.tsx +1 -0
  198. package/tests/hooks/usePrint.spec.tsx +1 -1
  199. package/tests/hooks/useRouterLink.spec.tsx +2 -0
  200. package/tests/hooks/useSyncConfig.spec.tsx +1 -0
  201. package/tests/providers/ErrorLoggerProvider.spec.tsx +1 -0
  202. package/tests/providers/PwaUpdateProvider.spec.tsx +16 -6
  203. package/tests/providers/ServiceClientContext.spec.tsx +40 -25
  204. package/tests/providers/i18n/I18nContext.spec.tsx +3 -4
  205. package/tests/providers/shared-data/SharedDataProvider.spec.tsx +2 -0
  206. package/dist/hooks/usePrint.d.ts +0 -3
  207. package/dist/hooks/usePrint.d.ts.map +0 -1
  208. package/dist/hooks/usePrint.js +0 -5
  209. package/dist/hooks/usePrint.js.map +0 -6
  210. package/src/hooks/usePrint.ts +0 -2
@@ -1,29 +1,34 @@
1
1
  import { render, fireEvent } from "@solidjs/testing-library";
2
- import { describe, it, expect, vi } from "vitest";
2
+ import { describe, it, expect, vi, beforeEach } from "vitest";
3
3
  import { createSignal } from "solid-js";
4
4
  import { Radio } from "../../../../src/components/form-control/checkbox/Radio";
5
+ import { I18nProvider } from "../../../../src/providers/i18n/I18nContext";
6
+ import { ConfigProvider } from "../../../../src/providers/ConfigContext";
5
7
 
6
8
  describe("Radio component", () => {
9
+ beforeEach(() => {
10
+ localStorage.setItem("test.i18n-locale", JSON.stringify("en"));
11
+ });
7
12
  describe("basic rendering", () => {
8
13
  it("renders with radio role", () => {
9
- const { getByRole } = render(() => <Radio />);
14
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio /></I18nProvider></ConfigProvider>);
10
15
  expect(getByRole("radio")).toBeTruthy();
11
16
  });
12
17
 
13
18
  it("renders children as label", () => {
14
- const { getByText } = render(() => <Radio>옵션 A</Radio>);
19
+ const { getByText } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio>옵션 A</Radio></I18nProvider></ConfigProvider>);
15
20
  expect(getByText("옵션 A")).toBeTruthy();
16
21
  });
17
22
 
18
23
  it("defaults to unchecked", () => {
19
- const { getByRole } = render(() => <Radio />);
24
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio /></I18nProvider></ConfigProvider>);
20
25
  expect(getByRole("radio").getAttribute("aria-checked")).toBe("false");
21
26
  });
22
27
  });
23
28
 
24
29
  describe("click behavior", () => {
25
30
  it("selects on click", () => {
26
- const { getByRole } = render(() => <Radio />);
31
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio /></I18nProvider></ConfigProvider>);
27
32
  const radio = getByRole("radio");
28
33
 
29
34
  fireEvent.click(radio);
@@ -31,7 +36,7 @@ describe("Radio component", () => {
31
36
  });
32
37
 
33
38
  it("does not deselect when already selected", () => {
34
- const { getByRole } = render(() => <Radio value={true} />);
39
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio value={true} /></I18nProvider></ConfigProvider>);
35
40
  const radio = getByRole("radio");
36
41
 
37
42
  fireEvent.click(radio);
@@ -39,7 +44,7 @@ describe("Radio component", () => {
39
44
  });
40
45
 
41
46
  it("does not change when disabled", () => {
42
- const { getByRole } = render(() => <Radio disabled />);
47
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio disabled /></I18nProvider></ConfigProvider>);
43
48
  const radio = getByRole("radio");
44
49
 
45
50
  fireEvent.click(radio);
@@ -49,7 +54,7 @@ describe("Radio component", () => {
49
54
 
50
55
  describe("keyboard behavior", () => {
51
56
  it("selects with Space key", () => {
52
- const { getByRole } = render(() => <Radio />);
57
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio /></I18nProvider></ConfigProvider>);
53
58
  const radio = getByRole("radio");
54
59
 
55
60
  fireEvent.keyDown(radio, { key: " " });
@@ -59,13 +64,13 @@ describe("Radio component", () => {
59
64
 
60
65
  describe("controlled pattern", () => {
61
66
  it("reflects value prop as checked state", () => {
62
- const { getByRole } = render(() => <Radio value={true} />);
67
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio value={true} /></I18nProvider></ConfigProvider>);
63
68
  expect(getByRole("radio").getAttribute("aria-checked")).toBe("true");
64
69
  });
65
70
 
66
71
  it("calls onValueChange on click", () => {
67
72
  const handleChange = vi.fn();
68
- const { getByRole } = render(() => <Radio value={false} onValueChange={handleChange} />);
73
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio value={false} onValueChange={handleChange} /></I18nProvider></ConfigProvider>);
69
74
 
70
75
  fireEvent.click(getByRole("radio"));
71
76
  expect(handleChange).toHaveBeenCalledWith(true);
@@ -73,7 +78,7 @@ describe("Radio component", () => {
73
78
 
74
79
  it("updates when external state changes", () => {
75
80
  const [value, setValue] = createSignal(false);
76
- const { getByRole } = render(() => <Radio value={value()} onValueChange={setValue} />);
81
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio value={value()} onValueChange={setValue} /></I18nProvider></ConfigProvider>);
77
82
 
78
83
  expect(getByRole("radio").getAttribute("aria-checked")).toBe("false");
79
84
 
@@ -84,20 +89,20 @@ describe("Radio component", () => {
84
89
 
85
90
  describe("style variants", () => {
86
91
  it("indicator is circular", () => {
87
- const { getByRole } = render(() => <Radio />);
92
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio /></I18nProvider></ConfigProvider>);
88
93
  const indicator = getByRole("radio").querySelector("div") as HTMLElement;
89
94
  expect(indicator.classList.contains("rounded-full")).toBe(true);
90
95
  });
91
96
 
92
97
  it("applies different styles per size", () => {
93
- const { getByRole: getDefault } = render(() => <Radio />);
94
- const { getByRole: getSm } = render(() => <Radio size="sm" />);
98
+ const { getByRole: getDefault } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio /></I18nProvider></ConfigProvider>);
99
+ const { getByRole: getSm } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio size="sm" /></I18nProvider></ConfigProvider>);
95
100
 
96
101
  expect(getDefault("radio").className).not.toBe(getSm("radio").className);
97
102
  });
98
103
 
99
104
  it("applies disabled style", () => {
100
- const { getByRole } = render(() => <Radio disabled />);
105
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio disabled /></I18nProvider></ConfigProvider>);
101
106
  expect(getByRole("radio").classList.contains("opacity-30")).toBe(true);
102
107
  });
103
108
  });
@@ -105,32 +110,32 @@ describe("Radio component", () => {
105
110
  describe("class merging", () => {
106
111
  it("merges custom classes", () => {
107
112
  // eslint-disable-next-line tailwindcss/no-custom-classname
108
- const { getByRole } = render(() => <Radio class="my-custom-class" />);
113
+ const { getByRole } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio class="my-custom-class" /></I18nProvider></ConfigProvider>);
109
114
  expect(getByRole("radio").classList.contains("my-custom-class")).toBe(true);
110
115
  });
111
116
  });
112
117
 
113
118
  describe("validation", () => {
114
119
  it("sets error message when required and not selected", () => {
115
- const { container } = render(() => <Radio required value={false} />);
120
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio required value={false} /></I18nProvider></ConfigProvider>);
116
121
  const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
117
122
  expect(hiddenInput.validationMessage).toBe("This is a required selection");
118
123
  });
119
124
 
120
125
  it("is valid when required and selected", () => {
121
- const { container } = render(() => <Radio required value={true} />);
126
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio required value={true} /></I18nProvider></ConfigProvider>);
122
127
  const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
123
128
  expect(hiddenInput.validity.valid).toBe(true);
124
129
  });
125
130
 
126
131
  it("sets error message returned by validate function", () => {
127
- const { container } = render(() => <Radio value={true} validate={() => "커스텀 에러"} />);
132
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio value={true} validate={() => "커스텀 에러"} /></I18nProvider></ConfigProvider>);
128
133
  const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
129
134
  expect(hiddenInput.validationMessage).toBe("커스텀 에러");
130
135
  });
131
136
 
132
137
  it("is valid when validate function returns undefined", () => {
133
- const { container } = render(() => <Radio value={true} validate={() => undefined} />);
138
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><Radio value={true} validate={() => undefined} /></I18nProvider></ConfigProvider>);
134
139
  const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
135
140
  expect(hiddenInput.validity.valid).toBe(true);
136
141
  });
@@ -1,25 +1,34 @@
1
1
  import { render, fireEvent } from "@solidjs/testing-library";
2
- import { describe, it, expect, vi } from "vitest";
2
+ import { describe, it, expect, vi, beforeEach } from "vitest";
3
3
  import { createSignal } from "solid-js";
4
4
  import { RadioGroup } from "../../../../src/components/form-control/checkbox/RadioGroup";
5
+ import { I18nProvider } from "../../../../src/providers/i18n/I18nContext";
6
+ import { ConfigProvider } from "../../../../src/providers/ConfigContext";
5
7
 
6
8
  describe("RadioGroup component", () => {
9
+ beforeEach(() => {
10
+ localStorage.setItem("test.i18n-locale", JSON.stringify("en"));
11
+ });
7
12
  describe("basic rendering", () => {
8
13
  it("renders the container", () => {
9
14
  const { container } = render(() => (
10
- <RadioGroup>
11
- <RadioGroup.Item value="a">A</RadioGroup.Item>
12
- </RadioGroup>
15
+ <ConfigProvider clientName="test"><I18nProvider>
16
+ <RadioGroup>
17
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
18
+ </RadioGroup>
19
+ </I18nProvider></ConfigProvider>
13
20
  ));
14
21
  expect(container.querySelector("div")).toBeTruthy();
15
22
  });
16
23
 
17
24
  it("renders items as radios", () => {
18
25
  const { getAllByRole } = render(() => (
19
- <RadioGroup>
20
- <RadioGroup.Item value="a">A</RadioGroup.Item>
21
- <RadioGroup.Item value="b">B</RadioGroup.Item>
22
- </RadioGroup>
26
+ <ConfigProvider clientName="test"><I18nProvider>
27
+ <RadioGroup>
28
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
29
+ <RadioGroup.Item value="b">B</RadioGroup.Item>
30
+ </RadioGroup>
31
+ </I18nProvider></ConfigProvider>
23
32
  ));
24
33
  expect(getAllByRole("radio").length).toBe(2);
25
34
  });
@@ -28,10 +37,12 @@ describe("RadioGroup component", () => {
28
37
  describe("controlled pattern", () => {
29
38
  it("reflects value prop as selected state", () => {
30
39
  const { getAllByRole } = render(() => (
31
- <RadioGroup value="a">
32
- <RadioGroup.Item value="a">A</RadioGroup.Item>
33
- <RadioGroup.Item value="b">B</RadioGroup.Item>
34
- </RadioGroup>
40
+ <ConfigProvider clientName="test"><I18nProvider>
41
+ <RadioGroup value="a">
42
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
43
+ <RadioGroup.Item value="b">B</RadioGroup.Item>
44
+ </RadioGroup>
45
+ </I18nProvider></ConfigProvider>
35
46
  ));
36
47
  const radios = getAllByRole("radio");
37
48
  expect(radios[0].getAttribute("aria-checked")).toBe("true");
@@ -41,9 +52,11 @@ describe("RadioGroup component", () => {
41
52
  it("calls onValueChange on selection", () => {
42
53
  const handleChange = vi.fn();
43
54
  const { getAllByRole } = render(() => (
44
- <RadioGroup value={undefined} onValueChange={handleChange}>
45
- <RadioGroup.Item value="a">A</RadioGroup.Item>
46
- </RadioGroup>
55
+ <ConfigProvider clientName="test"><I18nProvider>
56
+ <RadioGroup value={undefined} onValueChange={handleChange}>
57
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
58
+ </RadioGroup>
59
+ </I18nProvider></ConfigProvider>
47
60
  ));
48
61
  fireEvent.click(getAllByRole("radio")[0]);
49
62
  expect(handleChange).toHaveBeenCalledWith("a");
@@ -52,9 +65,11 @@ describe("RadioGroup component", () => {
52
65
  it("updates when external state changes", () => {
53
66
  const [value, setValue] = createSignal<string | undefined>(undefined);
54
67
  const { getAllByRole } = render(() => (
55
- <RadioGroup value={value()} onValueChange={setValue}>
56
- <RadioGroup.Item value="a">A</RadioGroup.Item>
57
- </RadioGroup>
68
+ <ConfigProvider clientName="test"><I18nProvider>
69
+ <RadioGroup value={value()} onValueChange={setValue}>
70
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
71
+ </RadioGroup>
72
+ </I18nProvider></ConfigProvider>
58
73
  ));
59
74
  expect(getAllByRole("radio")[0].getAttribute("aria-checked")).toBe("false");
60
75
  setValue("a");
@@ -71,36 +86,44 @@ describe("RadioGroup component", () => {
71
86
 
72
87
  it("sets error message when required and no item selected", () => {
73
88
  const { container } = render(() => (
74
- <RadioGroup required value={undefined}>
75
- <RadioGroup.Item value="a">A</RadioGroup.Item>
76
- </RadioGroup>
89
+ <ConfigProvider clientName="test"><I18nProvider>
90
+ <RadioGroup required value={undefined}>
91
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
92
+ </RadioGroup>
93
+ </I18nProvider></ConfigProvider>
77
94
  ));
78
95
  expect(getGroupHiddenInput(container).validationMessage).toBe("Please select an item");
79
96
  });
80
97
 
81
98
  it("is valid when required and item is selected", () => {
82
99
  const { container } = render(() => (
83
- <RadioGroup required value="a">
84
- <RadioGroup.Item value="a">A</RadioGroup.Item>
85
- </RadioGroup>
100
+ <ConfigProvider clientName="test"><I18nProvider>
101
+ <RadioGroup required value="a">
102
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
103
+ </RadioGroup>
104
+ </I18nProvider></ConfigProvider>
86
105
  ));
87
106
  expect(getGroupHiddenInput(container).validity.valid).toBe(true);
88
107
  });
89
108
 
90
109
  it("sets error message returned by validate function", () => {
91
110
  const { container } = render(() => (
92
- <RadioGroup value="a" validate={() => "커스텀 에러"}>
93
- <RadioGroup.Item value="a">A</RadioGroup.Item>
94
- </RadioGroup>
111
+ <ConfigProvider clientName="test"><I18nProvider>
112
+ <RadioGroup value="a" validate={() => "커스텀 에러"}>
113
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
114
+ </RadioGroup>
115
+ </I18nProvider></ConfigProvider>
95
116
  ));
96
117
  expect(getGroupHiddenInput(container).validationMessage).toBe("커스텀 에러");
97
118
  });
98
119
 
99
120
  it("is valid when validate function returns undefined", () => {
100
121
  const { container } = render(() => (
101
- <RadioGroup value="a" validate={() => undefined}>
102
- <RadioGroup.Item value="a">A</RadioGroup.Item>
103
- </RadioGroup>
122
+ <ConfigProvider clientName="test"><I18nProvider>
123
+ <RadioGroup value="a" validate={() => undefined}>
124
+ <RadioGroup.Item value="a">A</RadioGroup.Item>
125
+ </RadioGroup>
126
+ </I18nProvider></ConfigProvider>
104
127
  ));
105
128
  expect(getGroupHiddenInput(container).validity.valid).toBe(true);
106
129
  });
@@ -1,19 +1,24 @@
1
1
  import { render, fireEvent } from "@solidjs/testing-library";
2
- import { describe, it, expect, vi } from "vitest";
2
+ import { describe, it, expect, vi, beforeEach } from "vitest";
3
3
  import { createSignal } from "solid-js";
4
4
  import { ColorPicker } from "../../../../src/components/form-control/color-picker/ColorPicker";
5
+ import { I18nProvider } from "../../../../src/providers/i18n/I18nContext";
6
+ import { ConfigProvider } from "../../../../src/providers/ConfigContext";
5
7
 
6
8
  describe("ColorPicker component", () => {
9
+ beforeEach(() => {
10
+ localStorage.setItem("test.i18n-locale", JSON.stringify("en"));
11
+ });
7
12
  describe("basic rendering", () => {
8
13
  it("renders input type=color", () => {
9
- const { container } = render(() => <ColorPicker />);
14
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><ColorPicker /></I18nProvider></ConfigProvider>);
10
15
  const input = container.querySelector("input") as HTMLInputElement;
11
16
  expect(input).toBeTruthy();
12
17
  expect(input.type).toBe("color");
13
18
  });
14
19
 
15
20
  it("defaults to #000000", () => {
16
- const { container } = render(() => <ColorPicker />);
21
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><ColorPicker /></I18nProvider></ConfigProvider>);
17
22
  const input = container.querySelector("input") as HTMLInputElement;
18
23
  expect(input.value).toBe("#000000");
19
24
  });
@@ -23,7 +28,9 @@ describe("ColorPicker component", () => {
23
28
  it("calls onValueChange on color change", () => {
24
29
  const handleChange = vi.fn();
25
30
  const { container } = render(() => (
26
- <ColorPicker value="#000000" onValueChange={handleChange} />
31
+ <ConfigProvider clientName="test"><I18nProvider>
32
+ <ColorPicker value="#000000" onValueChange={handleChange} />
33
+ </I18nProvider></ConfigProvider>
27
34
  ));
28
35
  const input = container.querySelector("input") as HTMLInputElement;
29
36
 
@@ -34,7 +41,7 @@ describe("ColorPicker component", () => {
34
41
 
35
42
  it("updates input value when external state changes", () => {
36
43
  const [value, setValue] = createSignal("#ff0000");
37
- const { container } = render(() => <ColorPicker value={value()} onValueChange={setValue} />);
44
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><ColorPicker value={value()} onValueChange={setValue} /></I18nProvider></ConfigProvider>);
38
45
  const input = container.querySelector("input") as HTMLInputElement;
39
46
 
40
47
  expect(input.value).toBe("#ff0000");
@@ -46,13 +53,13 @@ describe("ColorPicker component", () => {
46
53
 
47
54
  describe("disabled state", () => {
48
55
  it("disables input when disabled=true", () => {
49
- const { container } = render(() => <ColorPicker disabled />);
56
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><ColorPicker disabled /></I18nProvider></ConfigProvider>);
50
57
  const input = container.querySelector("input") as HTMLInputElement;
51
58
  expect(input.disabled).toBe(true);
52
59
  });
53
60
 
54
61
  it("applies disabled style", () => {
55
- const { container } = render(() => <ColorPicker disabled />);
62
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><ColorPicker disabled /></I18nProvider></ConfigProvider>);
56
63
  const input = container.querySelector("input") as HTMLInputElement;
57
64
  expect(input.classList.contains("cursor-default")).toBe(true);
58
65
  });
@@ -61,7 +68,7 @@ describe("ColorPicker component", () => {
61
68
  describe("class merging", () => {
62
69
  it("merges custom classes", () => {
63
70
  // eslint-disable-next-line tailwindcss/no-custom-classname
64
- const { container } = render(() => <ColorPicker class="my-custom-class" />);
71
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><ColorPicker class="my-custom-class" /></I18nProvider></ConfigProvider>);
65
72
  const input = container.querySelector("input") as HTMLInputElement;
66
73
  expect(input.classList.contains("my-custom-class")).toBe(true);
67
74
  });
@@ -69,23 +76,25 @@ describe("ColorPicker component", () => {
69
76
 
70
77
  describe("validation", () => {
71
78
  it("sets error message when required and value is empty", () => {
72
- const { container } = render(() => <ColorPicker required value={undefined} />);
79
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><ColorPicker required value={undefined} /></I18nProvider></ConfigProvider>);
73
80
  const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
74
- expect(hiddenInput.validationMessage).toBe("This field is required");
81
+ expect(hiddenInput.validationMessage).toBe("This is a required field");
75
82
  });
76
83
 
77
84
  it("is valid when required and value exists", () => {
78
- const { container } = render(() => <ColorPicker required value="#ff0000" />);
85
+ const { container } = render(() => <ConfigProvider clientName="test"><I18nProvider><ColorPicker required value="#ff0000" /></I18nProvider></ConfigProvider>);
79
86
  const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
80
87
  expect(hiddenInput.validity.valid).toBe(true);
81
88
  });
82
89
 
83
90
  it("sets error message returned by validate function", () => {
84
91
  const { container } = render(() => (
85
- <ColorPicker
86
- validate={(v) => (v === "#000000" ? "검정색은 사용할 수 없습니다" : undefined)}
87
- value="#000000"
88
- />
92
+ <ConfigProvider clientName="test"><I18nProvider>
93
+ <ColorPicker
94
+ validate={(v) => (v === "#000000" ? "검정색은 사용할 수 없습니다" : undefined)}
95
+ value="#000000"
96
+ />
97
+ </I18nProvider></ConfigProvider>
89
98
  ));
90
99
  const hiddenInput = container.querySelector("input[aria-hidden='true']") as HTMLInputElement;
91
100
  expect(hiddenInput.validationMessage).toBe("검정색은 사용할 수 없습니다");