@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
@@ -81,6 +81,7 @@ describe("Select component", () => {
81
81
  fireEvent.click(selectItem);
82
82
 
83
83
  // Value changed
84
+
84
85
  expect(value()).toBe("apple");
85
86
  // aria-expanded becomes false (close triggered)
86
87
  expect(getByRole("combobox").getAttribute("aria-expanded")).toBe("false");
@@ -150,9 +151,11 @@ describe("Select component", () => {
150
151
 
151
152
  const selectItems = document.querySelectorAll("[data-select-item]");
152
153
  fireEvent.click(selectItems[0]);
154
+
153
155
  expect(value()).toEqual(["apple"]);
154
156
 
155
157
  fireEvent.click(selectItems[1]);
158
+
156
159
  expect(value()).toEqual(["apple", "banana"]);
157
160
  });
158
161
 
@@ -490,6 +493,7 @@ describe("Select component", () => {
490
493
  const selectAllBtn = document.querySelector("[data-select-all]") as HTMLElement;
491
494
  fireEvent.click(selectAllBtn);
492
495
 
496
+
493
497
  expect(value()).toEqual(["apple", "banana", "cherry"]);
494
498
  });
495
499
 
@@ -518,6 +522,7 @@ describe("Select component", () => {
518
522
  const deselectAllBtn = document.querySelector("[data-deselect-all]") as HTMLElement;
519
523
  fireEvent.click(deselectAllBtn);
520
524
 
525
+
521
526
  expect(value()).toEqual([]);
522
527
  });
523
528
 
@@ -9,6 +9,7 @@ import {
9
9
 
10
10
  // Test provider
11
11
  function TestProvider(props: { children: JSX.Element; value: SelectContextValue }) {
12
+
12
13
  return <SelectContext.Provider value={props.value}>{props.children}</SelectContext.Provider>;
13
14
  }
14
15
 
@@ -16,16 +16,20 @@ vi.mock("@solidjs/router", () => ({
16
16
  }));
17
17
 
18
18
  import { Sidebar, useSidebarContext } from "../../../../src";
19
+ import { I18nProvider } from "../../../../src/providers/i18n/I18nContext";
20
+ import { ConfigProvider } from "../../../../src/providers/ConfigContext";
19
21
 
20
22
  // ToggleCapture helper - Extract setToggle from Context for external control
21
23
  const ToggleCapture: Component<{ onCapture: (setToggle: Setter<boolean>) => void }> = (props) => {
22
24
  const { setToggle } = useSidebarContext();
25
+
23
26
  props.onCapture(setToggle);
24
27
  return null;
25
28
  };
26
29
 
27
30
  describe("Sidebar component", () => {
28
31
  beforeEach(() => {
32
+ localStorage.setItem("test.i18n-locale", JSON.stringify("en"));
29
33
  mockCreateMediaQuery.mockReturnValue(() => true); // Desktop mode
30
34
  });
31
35
 
@@ -36,11 +40,15 @@ describe("Sidebar component", () => {
36
40
  describe("basic rendering", () => {
37
41
  it("displays children inside sidebar", () => {
38
42
  const { getByText } = render(() => (
39
- <Sidebar.Container>
40
- <Sidebar>
41
- <span>Sidebar content</span>
42
- </Sidebar>
43
- </Sidebar.Container>
43
+ <ConfigProvider clientName="test">
44
+ <I18nProvider>
45
+ <Sidebar.Container>
46
+ <Sidebar>
47
+ <span>Sidebar content</span>
48
+ </Sidebar>
49
+ </Sidebar.Container>
50
+ </I18nProvider>
51
+ </ConfigProvider>
44
52
  ));
45
53
 
46
54
  expect(getByText("Sidebar content")).toBeTruthy();
@@ -48,9 +56,13 @@ describe("Sidebar component", () => {
48
56
 
49
57
  it("renders as aside element", () => {
50
58
  const { container } = render(() => (
51
- <Sidebar.Container>
52
- <Sidebar>Content</Sidebar>
53
- </Sidebar.Container>
59
+ <ConfigProvider clientName="test">
60
+ <I18nProvider>
61
+ <Sidebar.Container>
62
+ <Sidebar>Content</Sidebar>
63
+ </Sidebar.Container>
64
+ </I18nProvider>
65
+ </ConfigProvider>
54
66
  ));
55
67
 
56
68
  expect(container.querySelector("aside")).toBeTruthy();
@@ -62,9 +74,13 @@ describe("Sidebar component", () => {
62
74
  mockCreateMediaQuery.mockReturnValue(() => true); // Desktop
63
75
 
64
76
  const { container } = render(() => (
65
- <Sidebar.Container>
66
- <Sidebar>Content</Sidebar>
67
- </Sidebar.Container>
77
+ <ConfigProvider clientName="test">
78
+ <I18nProvider>
79
+ <Sidebar.Container>
80
+ <Sidebar>Content</Sidebar>
81
+ </Sidebar.Container>
82
+ </I18nProvider>
83
+ </ConfigProvider>
68
84
  ));
69
85
 
70
86
  // toggle=false (initial) → open on desktop
@@ -77,10 +93,14 @@ describe("Sidebar component", () => {
77
93
  let setToggle!: Setter<boolean>;
78
94
 
79
95
  const { container } = render(() => (
80
- <Sidebar.Container>
81
- <ToggleCapture onCapture={(fn) => (setToggle = fn)} />
82
- <Sidebar>Content</Sidebar>
83
- </Sidebar.Container>
96
+ <ConfigProvider clientName="test">
97
+ <I18nProvider>
98
+ <Sidebar.Container>
99
+ <ToggleCapture onCapture={(fn) => (setToggle = fn)} />
100
+ <Sidebar>Content</Sidebar>
101
+ </Sidebar.Container>
102
+ </I18nProvider>
103
+ </ConfigProvider>
84
104
  ));
85
105
 
86
106
  setToggle(true); // Switch to closed
@@ -92,9 +112,13 @@ describe("Sidebar component", () => {
92
112
  mockCreateMediaQuery.mockReturnValue(() => false); // Mobile
93
113
 
94
114
  const { container } = render(() => (
95
- <Sidebar.Container>
96
- <Sidebar>Content</Sidebar>
97
- </Sidebar.Container>
115
+ <ConfigProvider clientName="test">
116
+ <I18nProvider>
117
+ <Sidebar.Container>
118
+ <Sidebar>Content</Sidebar>
119
+ </Sidebar.Container>
120
+ </I18nProvider>
121
+ </ConfigProvider>
98
122
  ));
99
123
 
100
124
  // toggle=false (initial) → closed on mobile
@@ -107,10 +131,14 @@ describe("Sidebar component", () => {
107
131
  let setToggle!: Setter<boolean>;
108
132
 
109
133
  const { container } = render(() => (
110
- <Sidebar.Container>
111
- <ToggleCapture onCapture={(fn) => (setToggle = fn)} />
112
- <Sidebar>Content</Sidebar>
113
- </Sidebar.Container>
134
+ <ConfigProvider clientName="test">
135
+ <I18nProvider>
136
+ <Sidebar.Container>
137
+ <ToggleCapture onCapture={(fn) => (setToggle = fn)} />
138
+ <Sidebar>Content</Sidebar>
139
+ </Sidebar.Container>
140
+ </I18nProvider>
141
+ </ConfigProvider>
114
142
  ));
115
143
 
116
144
  setToggle(true); // Switch to open
@@ -124,9 +152,13 @@ describe("Sidebar component", () => {
124
152
  mockCreateMediaQuery.mockReturnValue(() => true); // Desktop
125
153
 
126
154
  const { container } = render(() => (
127
- <Sidebar.Container>
128
- <Sidebar>Content</Sidebar>
129
- </Sidebar.Container>
155
+ <ConfigProvider clientName="test">
156
+ <I18nProvider>
157
+ <Sidebar.Container>
158
+ <Sidebar>Content</Sidebar>
159
+ </Sidebar.Container>
160
+ </I18nProvider>
161
+ </ConfigProvider>
130
162
  ));
131
163
 
132
164
  // toggle=false (initial) → open on desktop
@@ -138,9 +170,13 @@ describe("Sidebar component", () => {
138
170
  mockCreateMediaQuery.mockReturnValue(() => false); // Mobile
139
171
 
140
172
  const { container } = render(() => (
141
- <Sidebar.Container>
142
- <Sidebar>Content</Sidebar>
143
- </Sidebar.Container>
173
+ <ConfigProvider clientName="test">
174
+ <I18nProvider>
175
+ <Sidebar.Container>
176
+ <Sidebar>Content</Sidebar>
177
+ </Sidebar.Container>
178
+ </I18nProvider>
179
+ </ConfigProvider>
144
180
  ));
145
181
 
146
182
  // toggle=false (initial) → closed on mobile
@@ -152,9 +188,13 @@ describe("Sidebar component", () => {
152
188
  mockCreateMediaQuery.mockReturnValue(() => false); // Mobile
153
189
 
154
190
  const { container } = render(() => (
155
- <Sidebar.Container>
156
- <Sidebar>Content</Sidebar>
157
- </Sidebar.Container>
191
+ <ConfigProvider clientName="test">
192
+ <I18nProvider>
193
+ <Sidebar.Container>
194
+ <Sidebar>Content</Sidebar>
195
+ </Sidebar.Container>
196
+ </I18nProvider>
197
+ </ConfigProvider>
158
198
  ));
159
199
 
160
200
  // toggle=false (initial) → closed on mobile
@@ -166,10 +206,14 @@ describe("Sidebar component", () => {
166
206
  describe("style merging", () => {
167
207
  it("merges custom classes", () => {
168
208
  const { container } = render(() => (
169
- <Sidebar.Container>
170
- {/* eslint-disable-next-line tailwindcss/no-custom-classname */}
171
- <Sidebar class="my-custom-class">Content</Sidebar>
172
- </Sidebar.Container>
209
+ <ConfigProvider clientName="test">
210
+ <I18nProvider>
211
+ <Sidebar.Container>
212
+ {/* eslint-disable-next-line tailwindcss/no-custom-classname */}
213
+ <Sidebar class="my-custom-class">Content</Sidebar>
214
+ </Sidebar.Container>
215
+ </I18nProvider>
216
+ </ConfigProvider>
173
217
  ));
174
218
 
175
219
  const sidebar = container.querySelector("aside");
@@ -22,6 +22,7 @@ import { ConfigProvider } from "../../../../src/providers/ConfigContext";
22
22
  // ToggleCapture helper - Extract setToggle from Context for external control
23
23
  const ToggleCapture: Component<{ onCapture: (setToggle: Setter<boolean>) => void }> = (props) => {
24
24
  const { setToggle } = useSidebarContext();
25
+
25
26
  props.onCapture(setToggle);
26
27
  return null;
27
28
  };
@@ -2,6 +2,8 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
2
  import { render, fireEvent } from "@solidjs/testing-library";
3
3
  import { Router } from "@solidjs/router";
4
4
  import { Sidebar, type AppMenu } from "../../../../src";
5
+ import { I18nProvider } from "../../../../src/providers/i18n/I18nContext";
6
+ import { ConfigProvider } from "../../../../src/providers/ConfigContext";
5
7
 
6
8
  // Mock pathname signal
7
9
  import { createSignal } from "solid-js";
@@ -27,6 +29,7 @@ const mockWindowOpen = vi.fn();
27
29
 
28
30
  describe("SidebarMenu", () => {
29
31
  beforeEach(() => {
32
+ localStorage.setItem("test.i18n-locale", JSON.stringify("en"));
30
33
  vi.clearAllMocks();
31
34
  setMockPathname("/"); // Initialize pathname
32
35
  vi.spyOn(window, "open").mockImplementation(mockWindowOpen);
@@ -43,14 +46,18 @@ describe("SidebarMenu", () => {
43
46
 
44
47
  const renderWithRouter = (menus: AppMenu[]) => {
45
48
  return render(() => (
46
- <Router base="" root={(props) => props.children}>
47
- {[
48
- {
49
- path: "*",
50
- component: () => <Sidebar.Menu menus={menus} />,
51
- },
52
- ]}
53
- </Router>
49
+ <ConfigProvider clientName="test">
50
+ <I18nProvider>
51
+ <Router base="" root={(props) => props.children}>
52
+ {[
53
+ {
54
+ path: "*",
55
+ component: () => <Sidebar.Menu menus={menus} />,
56
+ },
57
+ ]}
58
+ </Router>
59
+ </I18nProvider>
60
+ </ConfigProvider>
54
61
  ));
55
62
  };
56
63
 
@@ -202,15 +209,19 @@ describe("SidebarMenu", () => {
202
209
  const menus: AppMenu[] = [{ title: "Home", href: "/" }];
203
210
 
204
211
  const { container } = render(() => (
205
- <Router base="" root={(props) => props.children}>
206
- {[
207
- {
208
- path: "*",
209
- // eslint-disable-next-line tailwindcss/no-custom-classname
210
- component: () => <Sidebar.Menu menus={menus} class="my-custom-class" />,
211
- },
212
- ]}
213
- </Router>
212
+ <ConfigProvider clientName="test">
213
+ <I18nProvider>
214
+ <Router base="" root={(props) => props.children}>
215
+ {[
216
+ {
217
+ path: "*",
218
+ // eslint-disable-next-line tailwindcss/no-custom-classname
219
+ component: () => <Sidebar.Menu menus={menus} class="my-custom-class" />,
220
+ },
221
+ ]}
222
+ </Router>
223
+ </I18nProvider>
224
+ </ConfigProvider>
214
225
  ));
215
226
 
216
227
  expect(container.querySelector(".my-custom-class")).toBeTruthy();
@@ -1,9 +1,15 @@
1
1
  import { render, cleanup } from "@solidjs/testing-library";
2
- import { describe, it, expect, afterEach } from "vitest";
2
+ import { describe, it, expect, afterEach, beforeEach } from "vitest";
3
3
  import { createSignal, Show } from "solid-js";
4
4
  import { Topbar, createTopbarActions } from "../../../../src";
5
+ import { I18nProvider } from "../../../../src/providers/i18n/I18nContext";
6
+ import { ConfigProvider } from "../../../../src/providers/ConfigContext";
5
7
 
6
8
  describe("Topbar.Actions component", () => {
9
+ beforeEach(() => {
10
+ localStorage.setItem("test.i18n-locale", JSON.stringify("en"));
11
+ });
12
+
7
13
  afterEach(() => {
8
14
  cleanup();
9
15
  });
@@ -15,13 +21,17 @@ describe("Topbar.Actions component", () => {
15
21
  }
16
22
 
17
23
  const { getByText } = render(() => (
18
- <Topbar.Container>
19
- <Topbar>
20
- <span>Title</span>
21
- <Topbar.Actions />
22
- </Topbar>
23
- <PageWithActions />
24
- </Topbar.Container>
24
+ <ConfigProvider clientName="test">
25
+ <I18nProvider>
26
+ <Topbar.Container>
27
+ <Topbar>
28
+ <span>Title</span>
29
+ <Topbar.Actions />
30
+ </Topbar>
31
+ <PageWithActions />
32
+ </Topbar.Container>
33
+ </I18nProvider>
34
+ </ConfigProvider>
25
35
  ));
26
36
 
27
37
  expect(getByText("Save")).toBeTruthy();
@@ -29,13 +39,17 @@ describe("Topbar.Actions component", () => {
29
39
 
30
40
  it("renders nothing when actions are not provided", () => {
31
41
  const { container } = render(() => (
32
- <Topbar.Container>
33
- <Topbar>
34
- <span>Title</span>
35
- <Topbar.Actions />
36
- </Topbar>
37
- <div>Content</div>
38
- </Topbar.Container>
42
+ <ConfigProvider clientName="test">
43
+ <I18nProvider>
44
+ <Topbar.Container>
45
+ <Topbar>
46
+ <span>Title</span>
47
+ <Topbar.Actions />
48
+ </Topbar>
49
+ <div>Content</div>
50
+ </Topbar.Container>
51
+ </I18nProvider>
52
+ </ConfigProvider>
39
53
  ));
40
54
 
41
55
  const actionsSlot = container.querySelector("[data-topbar-actions]");
@@ -56,14 +70,18 @@ describe("Topbar.Actions component", () => {
56
70
  const [page, setPage] = createSignal<"a" | "b">("a");
57
71
 
58
72
  const { getByText, queryByText } = render(() => (
59
- <Topbar.Container>
60
- <Topbar>
61
- <Topbar.Actions />
62
- </Topbar>
63
- <Show when={page() === "a"} fallback={<PageB />}>
64
- <PageA />
65
- </Show>
66
- </Topbar.Container>
73
+ <ConfigProvider clientName="test">
74
+ <I18nProvider>
75
+ <Topbar.Container>
76
+ <Topbar>
77
+ <Topbar.Actions />
78
+ </Topbar>
79
+ <Show when={page() === "a"} fallback={<PageB />}>
80
+ <PageA />
81
+ </Show>
82
+ </Topbar.Container>
83
+ </I18nProvider>
84
+ </ConfigProvider>
67
85
  ));
68
86
 
69
87
  expect(getByText("Save")).toBeTruthy();
@@ -6,6 +6,7 @@ import { Topbar, createTopbarActions, useTopbarActionsAccessor } from "../../../
6
6
  // Helper: Extract actions accessor from TopbarContext
7
7
  function ActionsReader(props: { onCapture: (actions: Accessor<JSX.Element | undefined>) => void }) {
8
8
  const actions = useTopbarActionsAccessor();
9
+
9
10
  props.onCapture(actions);
10
11
  return null;
11
12
  }
@@ -3,7 +3,7 @@ import { describe, it, expect, vi } from "vitest";
3
3
  import { onMount } from "solid-js";
4
4
  import { BusyProvider } from "../../src/components/feedback/busy/BusyProvider";
5
5
  import { PrintProvider } from "../../src/components/feedback/print/PrintProvider";
6
- import { usePrint } from "../../src/hooks/usePrint";
6
+ import { usePrint } from "../../src/components/feedback/print/PrintContext";
7
7
  import { Print } from "../../src/components/feedback/print/Print";
8
8
  import { usePrintInstance } from "../../src/components/feedback/print/PrintInstanceContext";
9
9
 
@@ -33,12 +33,14 @@ describe("useRouterLink", () => {
33
33
  onHandlerCreated?: (handler: (e: MouseEvent) => void) => void;
34
34
  }) => {
35
35
  const navigate = useRouterLink();
36
+
36
37
  const handler = navigate({
37
38
  href: props.href,
38
39
  state: props.state,
39
40
  window: props.windowOptions,
40
41
  });
41
42
  props.onHandlerCreated?.(handler);
43
+
42
44
 
43
45
  return (
44
46
  <button data-testid="test-button" onClick={handler}>
@@ -10,6 +10,7 @@ import {
10
10
 
11
11
  /** Helper to configure adapter within SyncStorageProvider and render children */
12
12
  function ConfigureStorage(props: { storage: StorageAdapter; children: any }) {
13
+
13
14
  useSyncStorage()!.configure(() => props.storage);
14
15
  return <>{props.children}</>;
15
16
  }
@@ -6,6 +6,7 @@ import { useLogger } from "../../src/hooks/useLogger";
6
6
 
7
7
  /** Helper to configure adapter within LoggerProvider and render children */
8
8
  function ConfigureLogger(props: { adapter: LogAdapter; children: any }) {
9
+
9
10
  useLogger().configure(() => props.adapter);
10
11
  return <>{props.children}</>;
11
12
  }
@@ -1,20 +1,30 @@
1
- import { describe, it, expect, afterEach } from "vitest";
1
+ import { describe, it, expect, afterEach, beforeEach } from "vitest";
2
2
  import { render, cleanup } from "@solidjs/testing-library";
3
3
  import { PwaUpdateProvider } from "../../src/providers/PwaUpdateProvider";
4
4
  import { NotificationProvider } from "../../src/components/feedback/notification/NotificationProvider";
5
+ import { I18nProvider } from "../../src/providers/i18n/I18nContext";
6
+ import { ConfigProvider } from "../../src/providers/ConfigContext";
5
7
 
6
8
  describe("PwaUpdateProvider", () => {
9
+ beforeEach(() => {
10
+ localStorage.setItem("test.i18n-locale", JSON.stringify("en"));
11
+ });
12
+
7
13
  afterEach(() => {
8
14
  cleanup();
9
15
  });
10
16
 
11
17
  it("renders children correctly", () => {
12
18
  const { getByText } = render(() => (
13
- <NotificationProvider>
14
- <PwaUpdateProvider>
15
- <div>child content</div>
16
- </PwaUpdateProvider>
17
- </NotificationProvider>
19
+ <ConfigProvider clientName="test">
20
+ <I18nProvider>
21
+ <NotificationProvider>
22
+ <PwaUpdateProvider>
23
+ <div>child content</div>
24
+ </PwaUpdateProvider>
25
+ </NotificationProvider>
26
+ </I18nProvider>
27
+ </ConfigProvider>
18
28
  ));
19
29
 
20
30
  expect(getByText("child content")).toBeDefined();
@@ -1,4 +1,4 @@
1
- import { describe, it, expect } from "vitest";
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
2
  import { createRoot } from "solid-js";
3
3
  import { render } from "@solidjs/testing-library";
4
4
  import {
@@ -8,8 +8,13 @@ import {
8
8
  import { ServiceClientProvider } from "../../src/providers/ServiceClientProvider";
9
9
  import { NotificationProvider } from "../../src/components/feedback/notification/NotificationProvider";
10
10
  import { ConfigContext } from "../../src/providers/ConfigContext";
11
+ import { I18nProvider } from "../../src/providers/i18n/I18nContext";
11
12
 
12
13
  describe("ServiceClientContext", () => {
14
+ beforeEach(() => {
15
+ localStorage.setItem("testApp.i18n-locale", JSON.stringify("en"));
16
+ });
17
+
13
18
  describe("useServiceClient", () => {
14
19
  it("throws error when used without Provider", () => {
15
20
  createRoot((dispose) => {
@@ -23,19 +28,25 @@ describe("ServiceClientContext", () => {
23
28
  });
24
29
 
25
30
  describe("ServiceClientProvider", () => {
31
+ beforeEach(() => {
32
+ localStorage.setItem("testApp.i18n-locale", JSON.stringify("en"));
33
+ });
34
+
26
35
  it("useServiceClient works correctly inside Provider", () => {
27
36
  let serviceClient: ServiceClientContextValue;
28
37
 
29
38
  render(() => (
30
39
  <ConfigContext.Provider value={{ clientName: "testApp" }}>
31
- <NotificationProvider>
32
- <ServiceClientProvider>
33
- {(() => {
34
- serviceClient = useServiceClient();
35
- return null;
36
- })()}
37
- </ServiceClientProvider>
38
- </NotificationProvider>
40
+ <I18nProvider>
41
+ <NotificationProvider>
42
+ <ServiceClientProvider>
43
+ {(() => {
44
+ serviceClient = useServiceClient();
45
+ return null;
46
+ })()}
47
+ </ServiceClientProvider>
48
+ </NotificationProvider>
49
+ </I18nProvider>
39
50
  </ConfigContext.Provider>
40
51
  ));
41
52
 
@@ -51,14 +62,16 @@ describe("ServiceClientProvider", () => {
51
62
 
52
63
  render(() => (
53
64
  <ConfigContext.Provider value={{ clientName: "testApp" }}>
54
- <NotificationProvider>
55
- <ServiceClientProvider>
56
- {(() => {
57
- serviceClient = useServiceClient();
58
- return null;
59
- })()}
60
- </ServiceClientProvider>
61
- </NotificationProvider>
65
+ <I18nProvider>
66
+ <NotificationProvider>
67
+ <ServiceClientProvider>
68
+ {(() => {
69
+ serviceClient = useServiceClient();
70
+ return null;
71
+ })()}
72
+ </ServiceClientProvider>
73
+ </NotificationProvider>
74
+ </I18nProvider>
62
75
  </ConfigContext.Provider>
63
76
  ));
64
77
 
@@ -72,14 +85,16 @@ describe("ServiceClientProvider", () => {
72
85
 
73
86
  render(() => (
74
87
  <ConfigContext.Provider value={{ clientName: "testApp" }}>
75
- <NotificationProvider>
76
- <ServiceClientProvider>
77
- {(() => {
78
- serviceClient = useServiceClient();
79
- return null;
80
- })()}
81
- </ServiceClientProvider>
82
- </NotificationProvider>
88
+ <I18nProvider>
89
+ <NotificationProvider>
90
+ <ServiceClientProvider>
91
+ {(() => {
92
+ serviceClient = useServiceClient();
93
+ return null;
94
+ })()}
95
+ </ServiceClientProvider>
96
+ </NotificationProvider>
97
+ </I18nProvider>
83
98
  </ConfigContext.Provider>
84
99
  ));
85
100
 
@@ -1,5 +1,5 @@
1
1
  import { render, cleanup } from "@solidjs/testing-library";
2
- import { useI18n, useI18nOptional, I18nProvider } from "../../../src/providers/i18n/I18nContext";
2
+ import { useI18n, I18nProvider } from "../../../src/providers/i18n/I18nContext";
3
3
  import { ConfigProvider } from "../../../src/providers/ConfigContext";
4
4
  import { describe, it, expect, beforeEach, afterEach } from "vitest";
5
5
 
@@ -103,8 +103,7 @@ describe("I18nProvider", () => {
103
103
  expect(result).toBe("日");
104
104
  });
105
105
 
106
- it("should work without provider (optional hook)", () => {
107
- const i18n = useI18nOptional();
108
- expect(i18n).toBeUndefined();
106
+ it("should throw when used without provider", () => {
107
+ expect(() => useI18n()).toThrow("useI18n can only be used inside I18nProvider");
109
108
  });
110
109
  });
@@ -71,12 +71,14 @@ function ConfigureSharedData(props: {
71
71
  children: any;
72
72
  }) {
73
73
  const shared = useTestSharedData();
74
+
74
75
  shared.configure(() => props.definitions);
75
76
  return <>{props.children}</>;
76
77
  }
77
78
 
78
79
  function TestConsumer(props: { onData?: (shared: any) => void }) {
79
80
  const shared = useTestSharedData();
81
+
80
82
  props.onData?.(shared);
81
83
 
82
84
  return (
@@ -1,3 +0,0 @@
1
- export { usePrint } from "../components/feedback/print/PrintContext";
2
- export type { PrintOptions, PrintContextValue } from "../components/feedback/print/PrintContext";
3
- //# sourceMappingURL=usePrint.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usePrint.d.ts","sourceRoot":"","sources":["..\\..\\src\\hooks\\usePrint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAC;AACrE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC"}