@simplysm/solid 13.0.28 → 13.0.30

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 (379) hide show
  1. package/README.md +15 -9
  2. package/dist/components/data/Pagination.d.ts +4 -5
  3. package/dist/components/data/Pagination.d.ts.map +1 -1
  4. package/dist/components/data/Pagination.js +14 -14
  5. package/dist/components/data/Pagination.js.map +2 -2
  6. package/dist/components/data/Table.js +1 -1
  7. package/dist/components/data/calendar/Calendar.d.ts.map +1 -1
  8. package/dist/components/data/calendar/Calendar.js +1 -1
  9. package/dist/components/data/calendar/Calendar.js.map +1 -1
  10. package/dist/components/data/kanban/Kanban.d.ts +9 -9
  11. package/dist/components/data/kanban/Kanban.d.ts.map +1 -1
  12. package/dist/components/data/kanban/Kanban.js +6 -6
  13. package/dist/components/data/kanban/Kanban.js.map +2 -2
  14. package/dist/components/data/list/List.d.ts.map +1 -1
  15. package/dist/components/data/list/List.js.map +1 -1
  16. package/dist/components/data/list/ListItem.d.ts.map +1 -1
  17. package/dist/components/data/list/ListItem.js.map +1 -1
  18. package/dist/components/data/permission-table/PermissionTable.d.ts.map +1 -1
  19. package/dist/components/data/permission-table/PermissionTable.js.map +1 -1
  20. package/dist/components/data/sheet/DataSheet.d.ts.map +1 -1
  21. package/dist/components/data/sheet/DataSheet.js +102 -107
  22. package/dist/components/data/sheet/DataSheet.js.map +2 -2
  23. package/dist/components/data/sheet/DataSheet.styles.d.ts.map +1 -1
  24. package/dist/components/data/sheet/DataSheet.styles.js +24 -6
  25. package/dist/components/data/sheet/DataSheet.styles.js.map +1 -1
  26. package/dist/components/data/sheet/DataSheetColumn.d.ts.map +1 -1
  27. package/dist/components/data/sheet/DataSheetColumn.js.map +1 -1
  28. package/dist/components/data/sheet/DataSheetConfigDialog.d.ts.map +1 -1
  29. package/dist/components/data/sheet/DataSheetConfigDialog.js.map +1 -1
  30. package/dist/components/data/sheet/sheetUtils.d.ts.map +1 -1
  31. package/dist/components/data/sheet/sheetUtils.js.map +1 -1
  32. package/dist/components/data/sheet/types.d.ts +2 -2
  33. package/dist/components/data/sheet/types.d.ts.map +1 -1
  34. package/dist/components/disclosure/Collapse.d.ts.map +1 -1
  35. package/dist/components/disclosure/Collapse.js +0 -3
  36. package/dist/components/disclosure/Collapse.js.map +1 -1
  37. package/dist/components/disclosure/Dialog.d.ts +8 -8
  38. package/dist/components/disclosure/Dialog.d.ts.map +1 -1
  39. package/dist/components/disclosure/Dialog.js +64 -69
  40. package/dist/components/disclosure/Dialog.js.map +2 -2
  41. package/dist/components/disclosure/DialogContext.d.ts +4 -4
  42. package/dist/components/disclosure/DialogContext.d.ts.map +1 -1
  43. package/dist/components/disclosure/DialogContext.js.map +1 -1
  44. package/dist/components/disclosure/DialogProvider.d.ts.map +1 -1
  45. package/dist/components/disclosure/DialogProvider.js +8 -8
  46. package/dist/components/disclosure/DialogProvider.js.map +2 -2
  47. package/dist/components/disclosure/Dropdown.d.ts.map +1 -1
  48. package/dist/components/disclosure/Dropdown.js.map +1 -1
  49. package/dist/components/disclosure/Tabs.d.ts.map +1 -1
  50. package/dist/components/disclosure/Tabs.js.map +1 -1
  51. package/dist/components/display/Alert.d.ts.map +1 -1
  52. package/dist/components/display/Alert.js.map +1 -1
  53. package/dist/components/display/Card.d.ts +0 -1
  54. package/dist/components/display/Card.d.ts.map +1 -1
  55. package/dist/components/display/Card.js +1 -2
  56. package/dist/components/display/Card.js.map +1 -1
  57. package/dist/components/display/Echarts.d.ts +1 -1
  58. package/dist/components/display/Echarts.d.ts.map +1 -1
  59. package/dist/components/display/Echarts.js +2 -2
  60. package/dist/components/display/Echarts.js.map +2 -2
  61. package/dist/components/display/Link.d.ts +5 -0
  62. package/dist/components/display/Link.d.ts.map +1 -0
  63. package/dist/components/display/Link.js +26 -0
  64. package/dist/components/display/Link.js.map +6 -0
  65. package/dist/components/feedback/Progress.d.ts +3 -3
  66. package/dist/components/feedback/Progress.d.ts.map +1 -1
  67. package/dist/components/feedback/Progress.js +1 -1
  68. package/dist/components/feedback/Progress.js.map +2 -2
  69. package/dist/components/feedback/busy/BusyContainer.d.ts +13 -0
  70. package/dist/components/feedback/busy/BusyContainer.d.ts.map +1 -0
  71. package/dist/components/feedback/{loading/LoadingContainer.js → busy/BusyContainer.js} +20 -13
  72. package/dist/components/feedback/busy/BusyContainer.js.map +6 -0
  73. package/dist/components/feedback/busy/BusyContext.d.ts +11 -0
  74. package/dist/components/feedback/busy/BusyContext.d.ts.map +1 -0
  75. package/dist/components/feedback/busy/BusyContext.js +14 -0
  76. package/dist/components/feedback/busy/BusyContext.js.map +6 -0
  77. package/dist/components/feedback/busy/BusyProvider.d.ts +7 -0
  78. package/dist/components/feedback/busy/BusyProvider.d.ts.map +1 -0
  79. package/dist/components/feedback/{loading/LoadingProvider.js → busy/BusyProvider.js} +7 -7
  80. package/dist/components/feedback/busy/BusyProvider.js.map +6 -0
  81. package/dist/components/feedback/notification/NotificationBanner.d.ts.map +1 -1
  82. package/dist/components/feedback/notification/NotificationBanner.js +1 -1
  83. package/dist/components/feedback/notification/NotificationBanner.js.map +1 -1
  84. package/dist/components/feedback/notification/NotificationBell.d.ts.map +1 -1
  85. package/dist/components/feedback/notification/NotificationBell.js +4 -2
  86. package/dist/components/feedback/notification/NotificationBell.js.map +2 -2
  87. package/dist/components/feedback/notification/NotificationContext.d.ts.map +1 -1
  88. package/dist/components/feedback/notification/NotificationContext.js.map +1 -1
  89. package/dist/components/feedback/notification/NotificationProvider.d.ts.map +1 -1
  90. package/dist/components/feedback/notification/NotificationProvider.js +1 -0
  91. package/dist/components/feedback/notification/NotificationProvider.js.map +1 -1
  92. package/dist/components/form-control/Button.d.ts.map +1 -1
  93. package/dist/components/form-control/Button.js +2 -2
  94. package/dist/components/form-control/Button.js.map +1 -1
  95. package/dist/components/form-control/DropdownTrigger.styles.d.ts.map +1 -1
  96. package/dist/components/form-control/DropdownTrigger.styles.js +6 -1
  97. package/dist/components/form-control/DropdownTrigger.styles.js.map +1 -1
  98. package/dist/components/form-control/Invalid.d.ts +4 -2
  99. package/dist/components/form-control/Invalid.d.ts.map +1 -1
  100. package/dist/components/form-control/Invalid.js +81 -41
  101. package/dist/components/form-control/Invalid.js.map +2 -2
  102. package/dist/components/form-control/ThemeToggle.d.ts.map +1 -1
  103. package/dist/components/form-control/ThemeToggle.js +4 -5
  104. package/dist/components/form-control/ThemeToggle.js.map +2 -2
  105. package/dist/components/form-control/checkbox/Checkbox.d.ts +4 -2
  106. package/dist/components/form-control/checkbox/Checkbox.d.ts.map +1 -1
  107. package/dist/components/form-control/checkbox/Checkbox.js +65 -52
  108. package/dist/components/form-control/checkbox/Checkbox.js.map +2 -2
  109. package/dist/components/form-control/checkbox/Checkbox.styles.d.ts +1 -2
  110. package/dist/components/form-control/checkbox/Checkbox.styles.d.ts.map +1 -1
  111. package/dist/components/form-control/checkbox/Checkbox.styles.js +8 -10
  112. package/dist/components/form-control/checkbox/Checkbox.styles.js.map +1 -1
  113. package/dist/components/form-control/checkbox/CheckboxGroup.d.ts +9 -9
  114. package/dist/components/form-control/checkbox/CheckboxGroup.d.ts.map +1 -1
  115. package/dist/components/form-control/checkbox/CheckboxGroup.js +10 -82
  116. package/dist/components/form-control/checkbox/CheckboxGroup.js.map +2 -2
  117. package/dist/components/form-control/checkbox/Radio.d.ts +4 -2
  118. package/dist/components/form-control/checkbox/Radio.d.ts.map +1 -1
  119. package/dist/components/form-control/checkbox/Radio.js +64 -51
  120. package/dist/components/form-control/checkbox/Radio.js.map +2 -2
  121. package/dist/components/form-control/checkbox/RadioGroup.d.ts +9 -9
  122. package/dist/components/form-control/checkbox/RadioGroup.d.ts.map +1 -1
  123. package/dist/components/form-control/checkbox/RadioGroup.js +10 -77
  124. package/dist/components/form-control/checkbox/RadioGroup.js.map +2 -2
  125. package/dist/components/form-control/color-picker/ColorPicker.d.ts +8 -3
  126. package/dist/components/form-control/color-picker/ColorPicker.d.ts.map +1 -1
  127. package/dist/components/form-control/color-picker/ColorPicker.js +43 -26
  128. package/dist/components/form-control/color-picker/ColorPicker.js.map +2 -2
  129. package/dist/components/form-control/combobox/Combobox.d.ts +8 -8
  130. package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
  131. package/dist/components/form-control/combobox/Combobox.js +72 -59
  132. package/dist/components/form-control/combobox/Combobox.js.map +2 -2
  133. package/dist/components/form-control/editor/EditorToolbar.d.ts.map +1 -1
  134. package/dist/components/form-control/editor/EditorToolbar.js +3 -2
  135. package/dist/components/form-control/editor/EditorToolbar.js.map +2 -2
  136. package/dist/components/form-control/editor/RichTextEditor.d.ts.map +1 -1
  137. package/dist/components/form-control/editor/RichTextEditor.js.map +1 -1
  138. package/dist/components/form-control/field/DatePicker.d.ts +6 -0
  139. package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
  140. package/dist/components/form-control/field/DatePicker.js +138 -117
  141. package/dist/components/form-control/field/DatePicker.js.map +2 -2
  142. package/dist/components/form-control/field/DateTimePicker.d.ts +6 -0
  143. package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
  144. package/dist/components/form-control/field/DateTimePicker.js +138 -115
  145. package/dist/components/form-control/field/DateTimePicker.js.map +2 -2
  146. package/dist/components/form-control/field/Field.styles.d.ts +14 -0
  147. package/dist/components/form-control/field/Field.styles.d.ts.map +1 -1
  148. package/dist/components/form-control/field/Field.styles.js +47 -3
  149. package/dist/components/form-control/field/Field.styles.js.map +1 -1
  150. package/dist/components/form-control/field/FieldPlaceholder.d.ts +7 -0
  151. package/dist/components/form-control/field/FieldPlaceholder.d.ts.map +1 -0
  152. package/dist/components/form-control/field/FieldPlaceholder.js +34 -0
  153. package/dist/components/form-control/field/FieldPlaceholder.js.map +6 -0
  154. package/dist/components/form-control/field/NumberInput.d.ts +13 -0
  155. package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
  156. package/dist/components/form-control/field/NumberInput.js +163 -111
  157. package/dist/components/form-control/field/NumberInput.js.map +2 -2
  158. package/dist/components/form-control/field/TextInput.d.ts +16 -1
  159. package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
  160. package/dist/components/form-control/field/TextInput.js +177 -114
  161. package/dist/components/form-control/field/TextInput.js.map +2 -2
  162. package/dist/components/form-control/field/Textarea.d.ts +10 -0
  163. package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
  164. package/dist/components/form-control/field/Textarea.js +156 -121
  165. package/dist/components/form-control/field/Textarea.js.map +2 -2
  166. package/dist/components/form-control/field/TimePicker.d.ts +10 -0
  167. package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
  168. package/dist/components/form-control/field/TimePicker.js +126 -94
  169. package/dist/components/form-control/field/TimePicker.js.map +2 -2
  170. package/dist/components/form-control/select/Select.d.ts +7 -9
  171. package/dist/components/form-control/select/Select.d.ts.map +1 -1
  172. package/dist/components/form-control/select/Select.js +71 -60
  173. package/dist/components/form-control/select/Select.js.map +2 -2
  174. package/dist/components/form-control/select/SelectItem.d.ts.map +1 -1
  175. package/dist/components/form-control/select/SelectItem.js.map +1 -1
  176. package/dist/components/form-control/state-preset/StatePreset.d.ts.map +1 -1
  177. package/dist/components/form-control/state-preset/StatePreset.js +2 -1
  178. package/dist/components/form-control/state-preset/StatePreset.js.map +2 -2
  179. package/dist/components/layout/FormGroup.d.ts.map +1 -1
  180. package/dist/components/layout/FormGroup.js.map +1 -1
  181. package/dist/components/layout/sidebar/Sidebar.d.ts.map +1 -1
  182. package/dist/components/layout/sidebar/Sidebar.js +1 -1
  183. package/dist/components/layout/sidebar/Sidebar.js.map +1 -1
  184. package/dist/components/layout/sidebar/SidebarContainer.d.ts.map +1 -1
  185. package/dist/components/layout/sidebar/SidebarContainer.js.map +1 -1
  186. package/dist/components/layout/sidebar/SidebarMenu.js +1 -1
  187. package/dist/components/layout/sidebar/SidebarMenu.js.map +1 -1
  188. package/dist/components/layout/sidebar/SidebarUser.d.ts.map +1 -1
  189. package/dist/components/layout/sidebar/SidebarUser.js +4 -4
  190. package/dist/components/layout/sidebar/SidebarUser.js.map +1 -1
  191. package/dist/components/layout/topbar/Topbar.js +1 -1
  192. package/dist/components/layout/topbar/TopbarMenu.d.ts.map +1 -1
  193. package/dist/components/layout/topbar/TopbarMenu.js.map +1 -1
  194. package/dist/components/layout/topbar/TopbarUser.d.ts.map +1 -1
  195. package/dist/components/layout/topbar/TopbarUser.js.map +1 -1
  196. package/dist/helpers/createAppStructure.d.ts.map +1 -1
  197. package/dist/helpers/createAppStructure.js +17 -12
  198. package/dist/helpers/createAppStructure.js.map +1 -1
  199. package/dist/helpers/mergeStyles.d.ts.map +1 -1
  200. package/dist/helpers/mergeStyles.js +4 -1
  201. package/dist/helpers/mergeStyles.js.map +1 -1
  202. package/dist/helpers/splitSlots.d.ts.map +1 -1
  203. package/dist/helpers/splitSlots.js.map +1 -1
  204. package/dist/hooks/createControllableSignal.d.ts.map +1 -1
  205. package/dist/hooks/createControllableSignal.js.map +1 -1
  206. package/dist/hooks/createItemTemplate.d.ts +17 -0
  207. package/dist/hooks/createItemTemplate.d.ts.map +1 -0
  208. package/dist/hooks/createItemTemplate.js +40 -0
  209. package/dist/hooks/createItemTemplate.js.map +6 -0
  210. package/dist/hooks/createPointerDrag.d.ts +13 -0
  211. package/dist/hooks/createPointerDrag.d.ts.map +1 -0
  212. package/dist/hooks/createPointerDrag.js +15 -0
  213. package/dist/hooks/createPointerDrag.js.map +6 -0
  214. package/dist/hooks/createSelectionGroup.d.ts +70 -0
  215. package/dist/hooks/createSelectionGroup.d.ts.map +1 -0
  216. package/dist/hooks/createSelectionGroup.js +141 -0
  217. package/dist/hooks/createSelectionGroup.js.map +6 -0
  218. package/dist/hooks/useClipboardValueCopy.js +3 -1
  219. package/dist/hooks/useClipboardValueCopy.js.map +1 -1
  220. package/dist/hooks/useLocalStorage.d.ts +5 -3
  221. package/dist/hooks/useLocalStorage.d.ts.map +1 -1
  222. package/dist/hooks/useLocalStorage.js.map +1 -1
  223. package/dist/hooks/usePrint.d.ts.map +1 -1
  224. package/dist/hooks/usePrint.js +5 -3
  225. package/dist/hooks/usePrint.js.map +1 -1
  226. package/dist/hooks/{createPwaUpdate.d.ts → usePwaUpdate.d.ts} +2 -2
  227. package/dist/hooks/usePwaUpdate.d.ts.map +1 -0
  228. package/dist/hooks/{createPwaUpdate.js → usePwaUpdate.js} +3 -3
  229. package/dist/hooks/usePwaUpdate.js.map +6 -0
  230. package/dist/hooks/useRouterLink.d.ts.map +1 -1
  231. package/dist/hooks/useRouterLink.js.map +1 -1
  232. package/dist/hooks/useSyncConfig.d.ts +3 -3
  233. package/dist/hooks/useSyncConfig.d.ts.map +1 -1
  234. package/dist/hooks/useSyncConfig.js +6 -7
  235. package/dist/hooks/useSyncConfig.js.map +1 -1
  236. package/dist/index.d.ts +5 -6
  237. package/dist/index.d.ts.map +1 -1
  238. package/dist/index.js +6 -7
  239. package/dist/index.js.map +1 -1
  240. package/dist/providers/ConfigContext.d.ts +2 -2
  241. package/dist/providers/ConfigContext.d.ts.map +1 -1
  242. package/dist/providers/InitializeProvider.js +5 -5
  243. package/dist/providers/InitializeProvider.js.map +2 -2
  244. package/dist/providers/ServiceClientProvider.d.ts.map +1 -1
  245. package/dist/providers/ServiceClientProvider.js.map +1 -1
  246. package/dist/providers/ThemeContext.d.ts.map +1 -1
  247. package/dist/providers/ThemeContext.js +2 -1
  248. package/dist/providers/ThemeContext.js.map +2 -2
  249. package/dist/providers/shared-data/SharedDataChangeEvent.d.ts.map +1 -1
  250. package/dist/providers/shared-data/SharedDataChangeEvent.js +1 -3
  251. package/dist/providers/shared-data/SharedDataChangeEvent.js.map +1 -1
  252. package/dist/providers/shared-data/SharedDataContext.d.ts +1 -1
  253. package/dist/providers/shared-data/SharedDataContext.d.ts.map +1 -1
  254. package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
  255. package/dist/providers/shared-data/SharedDataProvider.js +6 -6
  256. package/dist/providers/shared-data/SharedDataProvider.js.map +2 -2
  257. package/dist/styles/patterns.styles.d.ts +1 -0
  258. package/dist/styles/patterns.styles.d.ts.map +1 -1
  259. package/dist/styles/patterns.styles.js +12 -1
  260. package/dist/styles/patterns.styles.js.map +1 -1
  261. package/dist/styles/tokens.styles.d.ts +2 -1
  262. package/dist/styles/tokens.styles.d.ts.map +1 -1
  263. package/dist/styles/tokens.styles.js +1 -1
  264. package/dist/styles/tokens.styles.js.map +1 -1
  265. package/docs/data-components.md +34 -5
  266. package/docs/disclosure.md +28 -8
  267. package/docs/display.md +19 -2
  268. package/docs/feedback.md +35 -12
  269. package/docs/form-controls.md +289 -33
  270. package/docs/hooks.md +21 -9
  271. package/docs/layout.md +15 -3
  272. package/docs/providers.md +120 -8
  273. package/docs/styling.md +90 -0
  274. package/package.json +3 -3
  275. package/src/components/data/Pagination.tsx +26 -22
  276. package/src/components/data/Table.tsx +1 -1
  277. package/src/components/data/calendar/Calendar.tsx +19 -5
  278. package/src/components/data/kanban/Kanban.tsx +72 -35
  279. package/src/components/data/list/List.tsx +11 -4
  280. package/src/components/data/list/ListItem.tsx +12 -2
  281. package/src/components/data/permission-table/PermissionTable.tsx +32 -5
  282. package/src/components/data/sheet/DataSheet.styles.ts +24 -6
  283. package/src/components/data/sheet/DataSheet.tsx +215 -149
  284. package/src/components/data/sheet/DataSheetColumn.tsx +5 -1
  285. package/src/components/data/sheet/DataSheetConfigDialog.tsx +27 -5
  286. package/src/components/data/sheet/sheetUtils.ts +12 -3
  287. package/src/components/data/sheet/types.ts +2 -2
  288. package/src/components/disclosure/Collapse.tsx +14 -3
  289. package/src/components/disclosure/Dialog.tsx +122 -106
  290. package/src/components/disclosure/DialogContext.ts +8 -5
  291. package/src/components/disclosure/DialogProvider.tsx +19 -7
  292. package/src/components/disclosure/Dropdown.tsx +12 -2
  293. package/src/components/disclosure/Tabs.tsx +29 -5
  294. package/src/components/display/Alert.tsx +3 -4
  295. package/src/components/display/Card.tsx +1 -2
  296. package/src/components/display/Echarts.tsx +12 -5
  297. package/src/components/display/Link.tsx +22 -0
  298. package/src/components/feedback/Progress.tsx +9 -5
  299. package/src/components/feedback/{loading/LoadingContainer.tsx → busy/BusyContainer.tsx} +52 -19
  300. package/src/components/feedback/busy/BusyContext.ts +20 -0
  301. package/src/components/feedback/{loading/LoadingProvider.tsx → busy/BusyProvider.tsx} +10 -10
  302. package/src/components/feedback/notification/NotificationBanner.tsx +14 -3
  303. package/src/components/feedback/notification/NotificationBell.tsx +21 -15
  304. package/src/components/feedback/notification/NotificationContext.ts +4 -1
  305. package/src/components/feedback/notification/NotificationProvider.tsx +4 -1
  306. package/src/components/form-control/Button.tsx +8 -3
  307. package/src/components/form-control/DropdownTrigger.styles.ts +7 -1
  308. package/src/components/form-control/Invalid.tsx +114 -48
  309. package/src/components/form-control/ThemeToggle.tsx +9 -18
  310. package/src/components/form-control/checkbox/Checkbox.styles.ts +7 -10
  311. package/src/components/form-control/checkbox/Checkbox.tsx +39 -28
  312. package/src/components/form-control/checkbox/CheckboxGroup.tsx +18 -97
  313. package/src/components/form-control/checkbox/Radio.tsx +39 -28
  314. package/src/components/form-control/checkbox/RadioGroup.tsx +18 -92
  315. package/src/components/form-control/color-picker/ColorPicker.tsx +51 -18
  316. package/src/components/form-control/combobox/Combobox.tsx +53 -35
  317. package/src/components/form-control/editor/EditorToolbar.tsx +19 -19
  318. package/src/components/form-control/editor/RichTextEditor.tsx +22 -4
  319. package/src/components/form-control/field/DatePicker.tsx +99 -93
  320. package/src/components/form-control/field/DateTimePicker.tsx +115 -96
  321. package/src/components/form-control/field/Field.styles.ts +62 -3
  322. package/src/components/form-control/field/FieldPlaceholder.tsx +18 -0
  323. package/src/components/form-control/field/NumberInput.tsx +136 -84
  324. package/src/components/form-control/field/TextInput.tsx +135 -88
  325. package/src/components/form-control/field/Textarea.tsx +126 -99
  326. package/src/components/form-control/field/TimePicker.tsx +101 -71
  327. package/src/components/form-control/select/Select.tsx +75 -42
  328. package/src/components/form-control/select/SelectItem.tsx +3 -1
  329. package/src/components/form-control/state-preset/StatePreset.tsx +41 -22
  330. package/src/components/layout/FormGroup.tsx +11 -2
  331. package/src/components/layout/sidebar/Sidebar.tsx +3 -2
  332. package/src/components/layout/sidebar/SidebarContainer.tsx +8 -1
  333. package/src/components/layout/sidebar/SidebarMenu.tsx +8 -2
  334. package/src/components/layout/sidebar/SidebarUser.tsx +12 -7
  335. package/src/components/layout/topbar/Topbar.tsx +1 -1
  336. package/src/components/layout/topbar/TopbarMenu.tsx +27 -5
  337. package/src/components/layout/topbar/TopbarUser.tsx +5 -1
  338. package/src/helpers/createAppStructure.ts +29 -15
  339. package/src/helpers/mergeStyles.ts +6 -2
  340. package/src/helpers/splitSlots.ts +4 -1
  341. package/src/hooks/createControllableSignal.ts +2 -1
  342. package/src/hooks/createItemTemplate.tsx +42 -0
  343. package/src/hooks/createPointerDrag.ts +28 -0
  344. package/src/hooks/createSelectionGroup.tsx +235 -0
  345. package/src/hooks/useClipboardValueCopy.ts +5 -2
  346. package/src/hooks/useLocalStorage.ts +11 -5
  347. package/src/hooks/usePrint.ts +9 -4
  348. package/src/hooks/{createPwaUpdate.ts → usePwaUpdate.ts} +1 -1
  349. package/src/hooks/useRouterLink.ts +3 -1
  350. package/src/hooks/useSyncConfig.ts +9 -13
  351. package/src/index.ts +6 -7
  352. package/src/providers/ConfigContext.ts +2 -2
  353. package/src/providers/InitializeProvider.tsx +4 -4
  354. package/src/providers/ServiceClientProvider.tsx +14 -3
  355. package/src/providers/ThemeContext.tsx +12 -3
  356. package/src/providers/shared-data/SharedDataChangeEvent.ts +4 -3
  357. package/src/providers/shared-data/SharedDataContext.ts +1 -1
  358. package/src/providers/shared-data/SharedDataProvider.tsx +13 -8
  359. package/src/styles/patterns.styles.ts +13 -1
  360. package/src/styles/tokens.styles.ts +2 -1
  361. package/tailwind.config.ts +9 -0
  362. package/tailwind.css +1 -1
  363. package/dist/components/display/Card.css +0 -15
  364. package/dist/components/feedback/loading/LoadingContainer.d.ts +0 -12
  365. package/dist/components/feedback/loading/LoadingContainer.d.ts.map +0 -1
  366. package/dist/components/feedback/loading/LoadingContainer.js.map +0 -6
  367. package/dist/components/feedback/loading/LoadingContext.d.ts +0 -11
  368. package/dist/components/feedback/loading/LoadingContext.d.ts.map +0 -1
  369. package/dist/components/feedback/loading/LoadingContext.js +0 -14
  370. package/dist/components/feedback/loading/LoadingContext.js.map +0 -6
  371. package/dist/components/feedback/loading/LoadingProvider.d.ts +0 -7
  372. package/dist/components/feedback/loading/LoadingProvider.d.ts.map +0 -1
  373. package/dist/components/feedback/loading/LoadingProvider.js.map +0 -6
  374. package/dist/hooks/createPwaUpdate.d.ts.map +0 -1
  375. package/dist/hooks/createPwaUpdate.js.map +0 -6
  376. package/src/components/display/Card.css +0 -15
  377. package/src/components/feedback/loading/LoadingContext.ts +0 -20
  378. /package/dist/components/feedback/{loading/LoadingContainer.css → busy/BusyContainer.css} +0 -0
  379. /package/src/components/feedback/{loading/LoadingContainer.css → busy/BusyContainer.css} +0 -0
@@ -11,7 +11,7 @@ import { Icon } from "../../display/Icon";
11
11
 
12
12
  void ripple;
13
13
 
14
- const containerClass = clsx("m-2 flex flex-col overflow-hidden rounded bg-white dark:bg-base-800");
14
+ const containerClass = clsx("m-2 flex flex-col overflow-hidden rounded bg-white dark:bg-base-900");
15
15
 
16
16
  const headerClass = clsx(
17
17
  "flex",
@@ -23,12 +23,15 @@ const headerClass = clsx(
23
23
  "cursor-pointer",
24
24
  "transition-colors",
25
25
  "hover:bg-base-500/10",
26
- "dark:hover:bg-base-700",
26
+ "dark:hover:bg-base-800",
27
27
  );
28
28
 
29
29
  const headerReadonlyClass = clsx("cursor-default hover:bg-transparent dark:hover:bg-transparent");
30
30
 
31
- const avatarClass = clsx("flex size-10 items-center justify-center rounded-full", "bg-primary-500 text-white");
31
+ const avatarClass = clsx(
32
+ "flex size-10 items-center justify-center rounded-full",
33
+ "bg-primary-500 text-white",
34
+ );
32
35
 
33
36
  export interface SidebarUserMenu {
34
37
  title: string;
@@ -114,17 +117,19 @@ export const SidebarUser: Component<SidebarUserProps> = (props) => {
114
117
  <div class={avatarClass}>
115
118
  <Icon icon={local.icon ?? IconUser} class="size-6" />
116
119
  </div>
117
- <Show when={local.description} fallback={<span class="font-semibold">{local.name}</span>}>
120
+ <Show when={local.description} fallback={<span class="font-bold">{local.name}</span>}>
118
121
  <div class="flex flex-col">
119
- <span class="font-semibold">{local.name}</span>
120
- <span class={clsx("text-sm", "text-base-500 dark:text-base-400")}>{local.description}</span>
122
+ <span class="font-bold">{local.name}</span>
123
+ <span class={clsx("text-sm", "text-base-500 dark:text-base-400")}>
124
+ {local.description}
125
+ </span>
121
126
  </div>
122
127
  </Show>
123
128
  </div>
124
129
  </button>
125
130
  <Show when={hasMenus()}>
126
131
  <Collapse open={open()}>
127
- <hr class={clsx("border-base-200 dark:border-base-700")} />
132
+ <hr class={clsx("border-base-100 dark:border-base-800")} />
128
133
  <List inset>
129
134
  <For each={local.menus}>
130
135
  {(menu) => <ListItem onClick={() => handleMenuClick(menu)}>{menu.title}</ListItem>}
@@ -24,7 +24,7 @@ const baseClass = clsx(
24
24
  "px-2",
25
25
  // 배경/테두리
26
26
  "bg-white",
27
- "dark:bg-base-950",
27
+ "dark:bg-base-900",
28
28
  "border-b",
29
29
  "border-base-200",
30
30
  "dark:border-base-700",
@@ -1,4 +1,12 @@
1
- import { type Component, type JSX, For, Show, splitProps, createSignal, createMemo } from "solid-js";
1
+ import {
2
+ type Component,
3
+ type JSX,
4
+ For,
5
+ Show,
6
+ splitProps,
7
+ createSignal,
8
+ createMemo,
9
+ } from "solid-js";
2
10
  import { useLocation, useNavigate } from "@solidjs/router";
3
11
  import { IconChevronDown, IconDotsVertical, type IconProps } from "@tabler/icons-solidjs";
4
12
  import { Icon } from "../../display/Icon";
@@ -76,10 +84,16 @@ export const TopbarMenu: Component<TopbarMenuProps> = (props) => {
76
84
  >
77
85
  <Icon icon={IconDotsVertical} size="1.25em" />
78
86
  </Button>
79
- <Dropdown triggerRef={() => mobileButtonRef} open={mobileMenuOpen()} onOpenChange={setMobileMenuOpen}>
87
+ <Dropdown
88
+ triggerRef={() => mobileButtonRef}
89
+ open={mobileMenuOpen()}
90
+ onOpenChange={setMobileMenuOpen}
91
+ >
80
92
  <List inset>
81
93
  <For each={local.menus}>
82
- {(menu) => <TopbarMenuDropdownItem menu={menu} onClose={() => setMobileMenuOpen(false)} />}
94
+ {(menu) => (
95
+ <TopbarMenuDropdownItem menu={menu} onClose={() => setMobileMenuOpen(false)} />
96
+ )}
83
97
  </For>
84
98
  </List>
85
99
  </Dropdown>
@@ -147,7 +161,11 @@ const TopbarMenuButton: Component<TopbarMenuButtonProps> = (props) => {
147
161
  </Show>
148
162
  <span>{props.menu.title}</span>
149
163
  <Show when={hasChildren()}>
150
- <Icon icon={IconChevronDown} size="1em" class={clsx("transition-transform", open() && "rotate-180")} />
164
+ <Icon
165
+ icon={IconChevronDown}
166
+ size="1em"
167
+ class={clsx("transition-transform", open() && "rotate-180")}
168
+ />
151
169
  </Show>
152
170
  </Button>
153
171
  <Show when={hasChildren()}>
@@ -189,7 +207,11 @@ const TopbarMenuDropdownItem: Component<TopbarMenuDropdownItemProps> = (props) =
189
207
  };
190
208
 
191
209
  return (
192
- <ListItem selected={isSelected()} readonly={props.menu.href === undefined && hasChildren()} onClick={handleClick}>
210
+ <ListItem
211
+ selected={isSelected()}
212
+ readonly={props.menu.href === undefined && hasChildren()}
213
+ onClick={handleClick}
214
+ >
193
215
  <Show when={props.menu.icon}>
194
216
  <Icon icon={props.menu.icon!} />
195
217
  </Show>
@@ -79,7 +79,11 @@ export const TopbarUser: ParentComponent<TopbarUserProps> = (props) => {
79
79
  >
80
80
  {local.children}
81
81
  <Show when={hasMenus()}>
82
- <Icon icon={IconChevronDown} size="1em" class={clsx("transition-transform", open() && "rotate-180")} />
82
+ <Icon
83
+ icon={IconChevronDown}
84
+ size="1em"
85
+ class={clsx("transition-transform", open() && "rotate-180")}
86
+ />
83
87
  </Show>
84
88
  </Button>
85
89
  <Show when={hasMenus()}>
@@ -1,4 +1,4 @@
1
- import { type Accessor, createMemo } from "solid-js";
1
+ import { type Accessor, createMemo, createRoot } from "solid-js";
2
2
  import type { Component } from "solid-js";
3
3
  import type { IconProps } from "@tabler/icons-solidjs";
4
4
  import type { SidebarMenuItem } from "../components/layout/sidebar/SidebarMenu";
@@ -26,7 +26,9 @@ export interface AppStructureLeafItem<TModule> {
26
26
  isNotMenu?: boolean;
27
27
  }
28
28
 
29
- export type AppStructureItem<TModule> = AppStructureGroupItem<TModule> | AppStructureLeafItem<TModule>;
29
+ export type AppStructureItem<TModule> =
30
+ | AppStructureGroupItem<TModule>
31
+ | AppStructureLeafItem<TModule>;
30
32
 
31
33
  export interface AppStructureSubPerm<TModule> {
32
34
  code: string;
@@ -59,7 +61,9 @@ export interface AppStructure<TModule> {
59
61
 
60
62
  // ── 내부 헬퍼 ──
61
63
 
62
- function isGroupItem<TModule>(item: AppStructureItem<TModule>): item is AppStructureGroupItem<TModule> {
64
+ function isGroupItem<TModule>(
65
+ item: AppStructureItem<TModule>,
66
+ ): item is AppStructureGroupItem<TModule> {
63
67
  return "children" in item;
64
68
  }
65
69
 
@@ -81,7 +85,11 @@ function checkModules<TModule>(
81
85
  return true;
82
86
  }
83
87
 
84
- function collectRoutes<TModule>(items: AppStructureItem<TModule>[], parentCodes: string[], routes: AppRoute[]): void {
88
+ function collectRoutes<TModule>(
89
+ items: AppStructureItem<TModule>[],
90
+ parentCodes: string[],
91
+ routes: AppRoute[],
92
+ ): void {
85
93
  for (const item of items) {
86
94
  const codes = [...parentCodes, item.code];
87
95
 
@@ -179,23 +187,29 @@ export function createAppStructure<TModule>(opts: {
179
187
 
180
188
  const routes = extractRoutes(opts.items);
181
189
 
182
- const usableMenus = createMemo(() => {
183
- const menus: SidebarMenuItem[] = [];
184
- for (const top of opts.items) {
185
- if (isGroupItem(top)) {
186
- menus.push(...buildMenus(top.children, "/" + top.code, opts.usableModules?.(), permRecord()));
190
+ const memos = createRoot(() => {
191
+ const usableMenus = createMemo(() => {
192
+ const menus: SidebarMenuItem[] = [];
193
+ for (const top of opts.items) {
194
+ if (isGroupItem(top)) {
195
+ menus.push(
196
+ ...buildMenus(top.children, "/" + top.code, opts.usableModules?.(), permRecord()),
197
+ );
198
+ }
187
199
  }
188
- }
189
- return menus;
190
- });
200
+ return menus;
201
+ });
191
202
 
192
- const usableFlatMenus = createMemo(() => flattenMenus(usableMenus()));
203
+ const usableFlatMenus = createMemo(() => flattenMenus(usableMenus()));
204
+
205
+ return { usableMenus, usableFlatMenus };
206
+ });
193
207
 
194
208
  return {
195
209
  items: opts.items,
196
210
  routes,
197
- usableMenus,
198
- usableFlatMenus,
211
+ usableMenus: memos.usableMenus,
212
+ usableFlatMenus: memos.usableFlatMenus,
199
213
  permRecord,
200
214
  getTitleChainByHref(href: string): string[] {
201
215
  const codes = href.split("/").filter(Boolean);
@@ -24,7 +24,9 @@ import { type JSX } from "solid-js";
24
24
  * // => { color: "red", background: "blue" }
25
25
  * ```
26
26
  */
27
- export function mergeStyles(...styles: (JSX.CSSProperties | string | undefined)[]): JSX.CSSProperties {
27
+ export function mergeStyles(
28
+ ...styles: (JSX.CSSProperties | string | undefined)[]
29
+ ): JSX.CSSProperties {
28
30
  const result: Record<string, string> = {};
29
31
 
30
32
  for (const style of styles) {
@@ -41,7 +43,9 @@ export function mergeStyles(...styles: (JSX.CSSProperties | string | undefined)[
41
43
  const value = declaration.slice(colonIndex + 1).trim();
42
44
  if (property && value) {
43
45
  // kebab-case를 camelCase로 변환
44
- const camelProperty = property.replace(/-([a-z])/g, (_, letter: string) => letter.toUpperCase());
46
+ const camelProperty = property.replace(/-([a-z])/g, (_, letter: string) =>
47
+ letter.toUpperCase(),
48
+ );
45
49
  result[camelProperty] = value;
46
50
  }
47
51
  }
@@ -26,7 +26,10 @@ export function splitSlots<K extends string>(
26
26
  ): [Accessor<Record<K, HTMLElement[]>>, Accessor<JSX.Element[]>] {
27
27
  const memo = createMemo(() => {
28
28
  const arr = resolved.toArray();
29
- const result = Object.fromEntries(keys.map((k) => [k, []])) as unknown as Record<K, HTMLElement[]>;
29
+ const result = Object.fromEntries(keys.map((k) => [k, []])) as unknown as Record<
30
+ K,
31
+ HTMLElement[]
32
+ >;
30
33
  const content: JSX.Element[] = [];
31
34
 
32
35
  for (const c of arr) {
@@ -50,7 +50,8 @@ export function createControllableSignal<TValue>(options: {
50
50
  const isControlled = () => options.onChange() !== undefined;
51
51
  const value = () => (isControlled() ? options.value() : internalValue());
52
52
  const setValue = (newValue: TValue | ((prev: TValue) => TValue)) => {
53
- const resolved = typeof newValue === "function" ? (newValue as (prev: TValue) => TValue)(value()) : newValue;
53
+ const resolved =
54
+ typeof newValue === "function" ? (newValue as (prev: TValue) => TValue)(value()) : newValue;
54
55
 
55
56
  if (isControlled()) {
56
57
  options.onChange()?.(resolved);
@@ -0,0 +1,42 @@
1
+ import type { JSX } from "solid-js";
2
+
3
+ /**
4
+ * WeakMap 기반 템플릿 슬롯 패턴을 생성합니다. SolidJS children을 통해 렌더 함수를 전달할 때 사용합니다.
5
+ *
6
+ * Select와 Combobox의 ItemTemplate 서브 컴포넌트 패턴에서 사용됩니다.
7
+ * TemplateSlot은 WeakMap에 렌더 함수를 ref로 저장하는 숨겨진 span을 렌더링합니다.
8
+ * getTemplate은 resolved 슬롯 엘리먼트에서 렌더 함수를 가져옵니다.
9
+ *
10
+ * @param dataAttr - 숨겨진 span에 사용할 HTML 속성 이름 (예: "data-select-item-template")
11
+ */
12
+ export function createItemTemplate<TArgs extends unknown[]>(
13
+ dataAttr: string,
14
+ ): {
15
+ TemplateSlot: (props: { children(...args: TArgs): JSX.Element }) => JSX.Element;
16
+ getTemplate: (slotElements: Element[]) => ((...args: TArgs) => JSX.Element) | undefined;
17
+ } {
18
+ const templateFnMap = new WeakMap<HTMLElement, (...args: TArgs) => JSX.Element>();
19
+
20
+ function TemplateSlot(props: { children(...args: TArgs): JSX.Element }): JSX.Element {
21
+ return (
22
+ <span
23
+ ref={(el) => {
24
+ templateFnMap.set(el, props.children);
25
+ }}
26
+ {...{ [dataAttr]: true }}
27
+ style={{ display: "none" }}
28
+ />
29
+ );
30
+ }
31
+
32
+ function getTemplate(slotElements: Element[]): ((...args: TArgs) => JSX.Element) | undefined {
33
+ if (slotElements.length === 0) return undefined;
34
+ const el = slotElements[0];
35
+ if (el instanceof HTMLElement) {
36
+ return templateFnMap.get(el);
37
+ }
38
+ return undefined;
39
+ }
40
+
41
+ return { TemplateSlot, getTemplate };
42
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Sets up pointer capture and manages pointermove/pointerup lifecycle on a target element.
3
+ *
4
+ * @param target - Element to capture pointer on
5
+ * @param pointerId - Pointer ID from the initiating PointerEvent
6
+ * @param options.onMove - Called on each pointermove
7
+ * @param options.onEnd - Called on pointerup (after listener cleanup)
8
+ */
9
+ export function createPointerDrag(
10
+ target: HTMLElement,
11
+ pointerId: number,
12
+ options: {
13
+ onMove: (e: PointerEvent) => void;
14
+ onEnd: (e: PointerEvent) => void;
15
+ },
16
+ ): void {
17
+ target.setPointerCapture(pointerId);
18
+
19
+ const onPointerMove = (e: PointerEvent) => options.onMove(e);
20
+ const onPointerUp = (e: PointerEvent) => {
21
+ target.removeEventListener("pointermove", onPointerMove);
22
+ target.removeEventListener("pointerup", onPointerUp);
23
+ options.onEnd(e);
24
+ };
25
+
26
+ target.addEventListener("pointermove", onPointerMove);
27
+ target.addEventListener("pointerup", onPointerUp);
28
+ }
@@ -0,0 +1,235 @@
1
+ import {
2
+ type JSX,
3
+ type ParentComponent,
4
+ createContext,
5
+ createMemo,
6
+ splitProps,
7
+ useContext,
8
+ } from "solid-js";
9
+ import { twMerge } from "tailwind-merge";
10
+ import { createControllableSignal } from "./createControllableSignal";
11
+ import { Invalid } from "../components/form-control/Invalid";
12
+ import type { CheckboxSize } from "../components/form-control/checkbox/Checkbox.styles";
13
+
14
+ interface SelectionItemComponentProps {
15
+ value: boolean;
16
+ onValueChange?: (value: boolean) => void;
17
+ disabled?: boolean;
18
+ size?: CheckboxSize;
19
+ inline?: boolean;
20
+ inset?: boolean;
21
+ children?: JSX.Element;
22
+ }
23
+
24
+ interface SelectionGroupContextBase {
25
+ disabled: () => boolean;
26
+ size: () => CheckboxSize | undefined;
27
+ inline: () => boolean;
28
+ inset: () => boolean;
29
+ }
30
+
31
+ interface MultiSelectContext extends SelectionGroupContextBase {
32
+ value: () => unknown[];
33
+ toggle: (item: unknown) => void;
34
+ }
35
+
36
+ interface SingleSelectContext extends SelectionGroupContextBase {
37
+ value: () => unknown | undefined;
38
+ select: (item: unknown) => void;
39
+ }
40
+
41
+ interface MultiGroupConfig {
42
+ mode: "multiple";
43
+ contextName: string;
44
+ ItemComponent: (props: SelectionItemComponentProps) => JSX.Element;
45
+ emptyErrorMsg: string;
46
+ }
47
+
48
+ interface SingleGroupConfig {
49
+ mode: "single";
50
+ contextName: string;
51
+ ItemComponent: (props: SelectionItemComponentProps) => JSX.Element;
52
+ emptyErrorMsg: string;
53
+ }
54
+
55
+ interface SelectionGroupItemProps<TValue> {
56
+ value: TValue;
57
+ disabled?: boolean;
58
+ children?: JSX.Element;
59
+ }
60
+
61
+ interface MultiGroupProps<TValue> {
62
+ value?: TValue[];
63
+ onValueChange?: (value: TValue[]) => void;
64
+ disabled?: boolean;
65
+ size?: CheckboxSize;
66
+ inline?: boolean;
67
+ inset?: boolean;
68
+ required?: boolean;
69
+ validate?: (value: TValue[]) => string | undefined;
70
+ touchMode?: boolean;
71
+ class?: string;
72
+ style?: JSX.CSSProperties;
73
+ children?: JSX.Element;
74
+ }
75
+
76
+ interface SingleGroupProps<TValue> {
77
+ value?: TValue;
78
+ onValueChange?: (value: TValue) => void;
79
+ disabled?: boolean;
80
+ size?: CheckboxSize;
81
+ inline?: boolean;
82
+ inset?: boolean;
83
+ required?: boolean;
84
+ validate?: (value: TValue | undefined) => string | undefined;
85
+ touchMode?: boolean;
86
+ class?: string;
87
+ style?: JSX.CSSProperties;
88
+ children?: JSX.Element;
89
+ }
90
+
91
+ export function createSelectionGroup(config: MultiGroupConfig): {
92
+ Group: {
93
+ <TValue = unknown>(props: MultiGroupProps<TValue>): JSX.Element;
94
+ Item: <TValue = unknown>(props: SelectionGroupItemProps<TValue>) => JSX.Element;
95
+ };
96
+ };
97
+ export function createSelectionGroup(config: SingleGroupConfig): {
98
+ Group: {
99
+ <TValue = unknown>(props: SingleGroupProps<TValue>): JSX.Element;
100
+ Item: <TValue = unknown>(props: SelectionGroupItemProps<TValue>) => JSX.Element;
101
+ };
102
+ };
103
+ export function createSelectionGroup(config: MultiGroupConfig | SingleGroupConfig): {
104
+ Group: {
105
+ <TValue = unknown>(props: MultiGroupProps<TValue> | SingleGroupProps<TValue>): JSX.Element;
106
+ Item: <TValue = unknown>(props: SelectionGroupItemProps<TValue>) => JSX.Element;
107
+ };
108
+ } {
109
+ const Context = createContext<MultiSelectContext | SingleSelectContext>();
110
+ const ItemComponent = config.ItemComponent;
111
+
112
+ function ItemInner<TValue>(props: SelectionGroupItemProps<TValue>) {
113
+ const ctx = useContext(Context);
114
+ if (!ctx)
115
+ throw new Error(
116
+ `${config.contextName}.Item은 ${config.contextName} 내부에서만 사용할 수 있습니다`,
117
+ );
118
+
119
+ const isSelected = (): boolean => {
120
+ if (config.mode === "multiple") {
121
+ return (ctx as MultiSelectContext).value().includes(props.value);
122
+ }
123
+ return (ctx as SingleSelectContext).value() === props.value;
124
+ };
125
+
126
+ const handleChange = () => {
127
+ if (config.mode === "multiple") {
128
+ (ctx as MultiSelectContext).toggle(props.value);
129
+ } else {
130
+ (ctx as SingleSelectContext).select(props.value);
131
+ }
132
+ };
133
+
134
+ return (
135
+ <ItemComponent
136
+ value={isSelected()}
137
+ onValueChange={handleChange}
138
+ disabled={props.disabled ?? ctx.disabled()}
139
+ size={ctx.size()}
140
+ inline={ctx.inline()}
141
+ inset={ctx.inset()}
142
+ >
143
+ {props.children}
144
+ </ItemComponent>
145
+ );
146
+ }
147
+
148
+ const GroupInner: ParentComponent<MultiGroupProps<unknown>> = (props) => {
149
+ const [local, rest] = splitProps(props, [
150
+ "value",
151
+ "onValueChange",
152
+ "disabled",
153
+ "size",
154
+ "inline",
155
+ "inset",
156
+ "required",
157
+ "validate",
158
+ "touchMode",
159
+ "class",
160
+ "style",
161
+ "children",
162
+ ]);
163
+
164
+ let contextValue: MultiSelectContext | SingleSelectContext;
165
+
166
+ if (config.mode === "multiple") {
167
+ const [value, setValue] = createControllableSignal<unknown[]>({
168
+ value: () => local.value ?? [],
169
+ onChange: () => local.onValueChange as ((v: unknown[]) => void) | undefined,
170
+ });
171
+ const toggle = (item: unknown) => {
172
+ setValue((prev) => {
173
+ if (prev.includes(item)) return prev.filter((v) => v !== item);
174
+ return [...prev, item];
175
+ });
176
+ };
177
+ contextValue = {
178
+ value,
179
+ toggle,
180
+ disabled: () => local.disabled ?? false,
181
+ size: () => local.size,
182
+ inline: () => local.inline ?? false,
183
+ inset: () => local.inset ?? false,
184
+ };
185
+ } else {
186
+ const [value, setValue] = createControllableSignal<unknown>({
187
+ value: () => local.value as unknown | undefined,
188
+ onChange: () => local.onValueChange as ((v: unknown) => void) | undefined,
189
+ });
190
+ const select = (item: unknown) => {
191
+ setValue(item);
192
+ };
193
+ contextValue = {
194
+ value,
195
+ select,
196
+ disabled: () => local.disabled ?? false,
197
+ size: () => local.size,
198
+ inline: () => local.inline ?? false,
199
+ inset: () => local.inset ?? false,
200
+ };
201
+ }
202
+
203
+ const errorMsg = createMemo(() => {
204
+ if (config.mode === "multiple") {
205
+ const v = local.value ?? [];
206
+ if (local.required && v.length === 0) return config.emptyErrorMsg;
207
+ return (local.validate as ((v: unknown[]) => string | undefined) | undefined)?.(v);
208
+ } else {
209
+ const v = local.value as unknown | undefined;
210
+ if (local.required && (v === undefined || v === null)) return config.emptyErrorMsg;
211
+ return (local.validate as ((v: unknown | undefined) => string | undefined) | undefined)?.(
212
+ v,
213
+ );
214
+ }
215
+ });
216
+
217
+ return (
218
+ <Invalid message={errorMsg()} variant="dot" touchMode={local.touchMode}>
219
+ <Context.Provider value={contextValue}>
220
+ <div {...rest} class={twMerge("inline-flex", local.class)} style={local.style}>
221
+ {local.children}
222
+ </div>
223
+ </Context.Provider>
224
+ </Invalid>
225
+ );
226
+ };
227
+
228
+ const Group = GroupInner as unknown as {
229
+ <TValue = unknown>(props: MultiGroupProps<TValue> | SingleGroupProps<TValue>): JSX.Element;
230
+ Item: <TValue = unknown>(props: SelectionGroupItemProps<TValue>) => JSX.Element;
231
+ };
232
+ Group.Item = ItemInner;
233
+
234
+ return { Group };
235
+ }
@@ -46,8 +46,11 @@ function extractTextFromRange(range: Range): string | null {
46
46
  if (!root) return null;
47
47
 
48
48
  // 선택 범위에 폼 컨트롤이 없으면 브라우저 기본 동작 사용
49
- const formSelector = 'input:not([type=hidden]), textarea, select, [role="checkbox"], [role="radio"]';
50
- const hasFormElements = [...root.querySelectorAll(formSelector)].some((el) => range.intersectsNode(el));
49
+ const formSelector =
50
+ 'input:not([type=hidden]), textarea, select, [role="checkbox"], [role="radio"]';
51
+ const hasFormElements = [...root.querySelectorAll(formSelector)].some((el) =>
52
+ range.intersectsNode(el),
53
+ );
51
54
  if (!hasFormElements) return null;
52
55
 
53
56
  const parts: string[] = [];
@@ -1,6 +1,10 @@
1
- import { type Accessor, type Setter, createSignal } from "solid-js";
1
+ import { type Accessor, createSignal } from "solid-js";
2
2
  import { useConfig } from "../providers/ConfigContext";
3
3
 
4
+ type StorageSetter<TValue> = (
5
+ value: TValue | undefined | ((prev: TValue | undefined) => TValue | undefined),
6
+ ) => TValue | undefined;
7
+
4
8
  /**
5
9
  * localStorage 기반 저장소 훅.
6
10
  * syncStorage 설정과 무관하게 항상 localStorage를 사용한다.
@@ -11,7 +15,7 @@ import { useConfig } from "../providers/ConfigContext";
11
15
  * @template T - 저장할 값의 타입
12
16
  * @param key - localStorage 키
13
17
  * @param initialValue - 초기값 (옵셔널)
14
- * @returns [Accessor<T | undefined>, Setter<T | undefined>] 튜플
18
+ * @returns [Accessor<T | undefined>, StorageSetter<T>] 튜플
15
19
  *
16
20
  * @example
17
21
  * ```tsx
@@ -30,7 +34,7 @@ import { useConfig } from "../providers/ConfigContext";
30
34
  export function useLocalStorage<TValue>(
31
35
  key: string,
32
36
  initialValue?: TValue,
33
- ): [Accessor<TValue | undefined>, Setter<TValue | undefined>] {
37
+ ): [Accessor<TValue | undefined>, StorageSetter<TValue>] {
34
38
  const config = useConfig();
35
39
  const prefixedKey = `${config.clientName}.${key}`;
36
40
 
@@ -47,7 +51,9 @@ export function useLocalStorage<TValue>(
47
51
 
48
52
  const [value, setValue] = createSignal<TValue | undefined>(storedValue);
49
53
 
50
- const setAndStore = (newValue: TValue | undefined | ((prev: TValue | undefined) => TValue | undefined)) => {
54
+ const setAndStore = (
55
+ newValue: TValue | undefined | ((prev: TValue | undefined) => TValue | undefined),
56
+ ) => {
51
57
  let resolved: TValue | undefined;
52
58
 
53
59
  if (typeof newValue === "function") {
@@ -67,5 +73,5 @@ export function useLocalStorage<TValue>(
67
73
  return resolved;
68
74
  };
69
75
 
70
- return [value, setAndStore as Setter<TValue | undefined>];
76
+ return [value, setAndStore];
71
77
  }
@@ -2,8 +2,11 @@ import type { JSX } from "solid-js";
2
2
  import { render } from "solid-js/web";
3
3
  import { jsPDF } from "jspdf";
4
4
  import * as htmlToImage from "html-to-image";
5
- import { useLoading } from "../components/feedback/loading/LoadingContext";
6
- import { PrintInstanceContext, type PrintInstance } from "../components/feedback/print/PrintInstanceContext";
5
+ import { useBusy } from "../components/feedback/busy/BusyContext";
6
+ import {
7
+ PrintInstanceContext,
8
+ type PrintInstance,
9
+ } from "../components/feedback/print/PrintInstanceContext";
7
10
 
8
11
  // --- Types ---
9
12
 
@@ -74,7 +77,9 @@ function waitForImages(container: HTMLElement): Promise<void> {
74
77
  ).then(() => undefined);
75
78
  }
76
79
 
77
- async function renderAndWait(factory: () => JSX.Element): Promise<{ container: HTMLElement; dispose: () => void }> {
80
+ async function renderAndWait(
81
+ factory: () => JSX.Element,
82
+ ): Promise<{ container: HTMLElement; dispose: () => void }> {
78
83
  const container = document.createElement("div");
79
84
  container.style.position = "fixed";
80
85
  container.style.left = "-9999px";
@@ -129,7 +134,7 @@ async function renderAndWait(factory: () => JSX.Element): Promise<{ container: H
129
134
  // --- Hook ---
130
135
 
131
136
  export function usePrint(): UsePrintReturn {
132
- const busy = useLoading();
137
+ const busy = useBusy();
133
138
 
134
139
  const toPrinter = async (factory: () => JSX.Element, options?: PrintOptions): Promise<void> => {
135
140
  busy.show();
@@ -15,7 +15,7 @@ const UPDATE_INTERVAL = 5 * 60 * 1000; // 5 minutes
15
15
  *
16
16
  * Must be called inside NotificationProvider.
17
17
  */
18
- export function createPwaUpdate(): void {
18
+ export function usePwaUpdate(): void {
19
19
  if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) return;
20
20
 
21
21
  const notification = useNotification();