@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
@@ -1,29 +1,16 @@
1
1
  import { type Component, type JSX, splitProps, Switch, Match } from "solid-js";
2
- import clsx from "clsx";
3
2
  import { twMerge } from "tailwind-merge";
4
3
  import { IconSun, IconMoon, IconDeviceDesktop } from "@tabler/icons-solidjs";
5
4
  import { useTheme, type ThemeMode } from "../../providers/ThemeContext";
6
5
  import { Icon } from "../display/Icon";
7
6
  import { ripple } from "../../directives/ripple";
7
+ import { iconButtonBase } from "../../styles/patterns.styles";
8
8
 
9
9
  void ripple;
10
10
 
11
- const baseClass = clsx(
12
- "inline-flex",
13
- "items-center",
14
- "justify-center",
15
- "cursor-pointer",
16
- "rounded",
17
- "transition-colors",
18
- "text-base-500 dark:text-base-400",
19
- "hover:bg-base-200 dark:hover:bg-base-700",
20
- "focus:outline-none",
21
- "focus-visible:ring-2",
22
- );
23
-
24
11
  const sizeClasses: Record<"sm" | "lg", string> = {
25
- sm: clsx("p-1"),
26
- lg: clsx("p-2"),
12
+ sm: "p-1",
13
+ lg: "p-2",
27
14
  };
28
15
 
29
16
  const iconSizes: Record<"sm" | "lg", string> = {
@@ -37,7 +24,10 @@ const modeLabels: Record<ThemeMode, string> = {
37
24
  dark: "다크 모드",
38
25
  };
39
26
 
40
- export interface ThemeToggleProps extends Omit<JSX.ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
27
+ export interface ThemeToggleProps extends Omit<
28
+ JSX.ButtonHTMLAttributes<HTMLButtonElement>,
29
+ "children"
30
+ > {
41
31
  /** 버튼 크기 */
42
32
  size?: "sm" | "lg";
43
33
  }
@@ -65,7 +55,8 @@ export const ThemeToggle: Component<ThemeToggleProps> = (props) => {
65
55
 
66
56
  const { mode, cycleMode } = useTheme();
67
57
 
68
- const getClassName = () => twMerge(baseClass, "p-1.5", local.size && sizeClasses[local.size], local.class);
58
+ const getClassName = () =>
59
+ twMerge(iconButtonBase, "p-1.5", local.size && sizeClasses[local.size], local.class);
69
60
 
70
61
  const iconSize = () => (local.size ? iconSizes[local.size] : "1.25em");
71
62
 
@@ -10,7 +10,6 @@ import {
10
10
  } from "../../../styles/tokens.styles";
11
11
  import { insetBase, insetFocusOutlineSelf } from "../../../styles/patterns.styles";
12
12
 
13
- export type CheckboxTheme = "primary" | "info" | "success" | "warning" | "danger";
14
13
  export type CheckboxSize = ComponentSize;
15
14
 
16
15
  // wrapper 기본 스타일
@@ -36,14 +35,8 @@ export const indicatorBaseClass = clsx(
36
35
  "transition-colors",
37
36
  );
38
37
 
39
- // 테마별 체크 상태
40
- export const themeCheckedClasses: Record<CheckboxTheme, string> = {
41
- primary: clsx("border-primary-500 bg-primary-500", "text-white"),
42
- info: clsx("border-info-500 bg-info-500", "text-white"),
43
- success: clsx("border-success-500 bg-success-500", "text-white"),
44
- warning: clsx("border-warning-500 bg-warning-500", "text-white"),
45
- danger: clsx("border-danger-500 bg-danger-500", "text-white"),
46
- };
38
+ // 체크 상태 스타일 (primary 고정)
39
+ export const checkedClass = clsx("border-primary-500 bg-primary-500", "text-white");
47
40
 
48
41
  // 사이즈별 스타일
49
42
  export const checkboxSizeClasses: Record<CheckboxSize, string> = {
@@ -53,7 +46,11 @@ export const checkboxSizeClasses: Record<CheckboxSize, string> = {
53
46
  };
54
47
 
55
48
  // inset 스타일
56
- export const checkboxInsetClass = clsx("h-field-inset justify-center bg-transparent", insetBase, insetFocusOutlineSelf);
49
+ export const checkboxInsetClass = clsx(
50
+ "h-field-inset justify-center bg-transparent",
51
+ insetBase,
52
+ insetFocusOutlineSelf,
53
+ );
57
54
 
58
55
  // inset 사이즈별 높이 (border 2px 제외)
59
56
  export const checkboxInsetSizeHeightClasses: Record<CheckboxSize, string> = {
@@ -1,21 +1,21 @@
1
- import { type JSX, type ParentComponent, Show, splitProps } from "solid-js";
1
+ import { type JSX, type ParentComponent, Show, splitProps, createMemo } from "solid-js";
2
2
  import { twMerge } from "tailwind-merge";
3
3
  import { IconCheck } from "@tabler/icons-solidjs";
4
4
  import { createControllableSignal } from "../../../hooks/createControllableSignal";
5
5
  import { ripple } from "../../../directives/ripple";
6
6
  import { Icon } from "../../display/Icon";
7
7
  import {
8
- type CheckboxTheme,
9
8
  type CheckboxSize,
10
9
  checkboxBaseClass,
11
10
  indicatorBaseClass,
12
- themeCheckedClasses,
11
+ checkedClass,
13
12
  checkboxSizeClasses,
14
13
  checkboxInsetClass,
15
14
  checkboxInsetSizeHeightClasses,
16
15
  checkboxInlineClass,
17
16
  checkboxDisabledClass,
18
17
  } from "./Checkbox.styles";
18
+ import { Invalid } from "../Invalid";
19
19
 
20
20
  // Directive 사용 선언 (TypeScript용)
21
21
  void ripple;
@@ -25,9 +25,11 @@ export interface CheckboxProps {
25
25
  onValueChange?: (value: boolean) => void;
26
26
  disabled?: boolean;
27
27
  size?: CheckboxSize;
28
- theme?: CheckboxTheme;
29
28
  inset?: boolean;
30
29
  inline?: boolean;
30
+ required?: boolean;
31
+ validate?: (value: boolean) => string | undefined;
32
+ touchMode?: boolean;
31
33
  class?: string;
32
34
  style?: JSX.CSSProperties;
33
35
  children?: JSX.Element;
@@ -39,9 +41,11 @@ export const Checkbox: ParentComponent<CheckboxProps> = (props) => {
39
41
  "onValueChange",
40
42
  "disabled",
41
43
  "size",
42
- "theme",
43
44
  "inset",
44
45
  "inline",
46
+ "required",
47
+ "validate",
48
+ "touchMode",
45
49
  "class",
46
50
  "style",
47
51
  "children",
@@ -75,32 +79,39 @@ export const Checkbox: ParentComponent<CheckboxProps> = (props) => {
75
79
  local.class,
76
80
  );
77
81
 
78
- const getIndicatorClass = () => {
79
- const theme = local.theme ?? "primary";
82
+ const getIndicatorClass = () =>
83
+ twMerge(indicatorBaseClass, "rounded-sm", value() && checkedClass);
80
84
 
81
- return twMerge(indicatorBaseClass, "rounded-sm", value() && themeCheckedClasses[theme]);
82
- };
85
+ const errorMsg = createMemo(() => {
86
+ const v = local.value ?? false;
87
+ if (local.required && !v) return "필수 선택 항목입니다";
88
+ return local.validate?.(v);
89
+ });
83
90
 
84
91
  return (
85
- <label
86
- {...rest}
87
- use:ripple={!local.disabled}
88
- role="checkbox"
89
- aria-checked={value()}
90
- tabIndex={local.disabled ? -1 : 0}
91
- class={getWrapperClass()}
92
- style={local.style}
93
- onClick={handleClick}
94
- onKeyDown={handleKeyDown}
95
- >
96
- <div class={getIndicatorClass()}>
97
- <Show when={value()}>
98
- <Icon icon={IconCheck} size="1em" />
99
- </Show>
92
+ <Invalid message={errorMsg()} variant="border" touchMode={local.touchMode}>
93
+ <div class="inline-flex">
94
+ <label
95
+ {...rest}
96
+ use:ripple={!local.disabled}
97
+ role="checkbox"
98
+ aria-checked={value()}
99
+ tabIndex={local.disabled ? -1 : 0}
100
+ class={getWrapperClass()}
101
+ style={local.style}
102
+ onClick={handleClick}
103
+ onKeyDown={handleKeyDown}
104
+ >
105
+ <div class={getIndicatorClass()}>
106
+ <Show when={value()}>
107
+ <Icon icon={IconCheck} size="1em" />
108
+ </Show>
109
+ </div>
110
+ <Show when={local.children}>
111
+ <span>{local.children}</span>
112
+ </Show>
113
+ </label>
100
114
  </div>
101
- <Show when={local.children}>
102
- <span>{local.children}</span>
103
- </Show>
104
- </label>
115
+ </Invalid>
105
116
  );
106
117
  };
@@ -1,60 +1,18 @@
1
- import { type JSX, type ParentComponent, createContext, splitProps, useContext } from "solid-js";
2
- import { twMerge } from "tailwind-merge";
3
- import { createControllableSignal } from "../../../hooks/createControllableSignal";
1
+ import { type JSX } from "solid-js";
4
2
  import { Checkbox } from "./Checkbox";
5
- import type { CheckboxSize, CheckboxTheme } from "./Checkbox.styles";
6
-
7
- interface CheckboxGroupContextValue<TValue> {
8
- value: () => TValue[];
9
- toggle: (item: TValue) => void;
10
- disabled: () => boolean;
11
- size: () => CheckboxSize | undefined;
12
- theme: () => CheckboxTheme | undefined;
13
- inline: () => boolean;
14
- inset: () => boolean;
15
- }
16
-
17
- const CheckboxGroupContext = createContext<CheckboxGroupContextValue<any>>();
18
-
19
- // --- CheckboxGroup.Item ---
20
-
21
- interface CheckboxGroupItemProps<TValue> {
22
- value: TValue;
23
- disabled?: boolean;
24
- children?: JSX.Element;
25
- }
26
-
27
- function CheckboxGroupItemInner<TValue>(props: CheckboxGroupItemProps<TValue>) {
28
- const ctx = useContext(CheckboxGroupContext);
29
- if (!ctx) throw new Error("CheckboxGroup.Item은 CheckboxGroup 내부에서만 사용할 수 있습니다");
30
-
31
- const isSelected = () => ctx.value().includes(props.value);
32
-
33
- return (
34
- <Checkbox
35
- value={isSelected()}
36
- onValueChange={() => ctx.toggle(props.value)}
37
- disabled={props.disabled ?? ctx.disabled()}
38
- size={ctx.size()}
39
- theme={ctx.theme()}
40
- inline={ctx.inline()}
41
- inset={ctx.inset()}
42
- >
43
- {props.children}
44
- </Checkbox>
45
- );
46
- }
47
-
48
- // --- CheckboxGroup ---
3
+ import { createSelectionGroup } from "../../../hooks/createSelectionGroup";
4
+ import type { CheckboxSize } from "./Checkbox.styles";
49
5
 
50
6
  interface CheckboxGroupProps<TValue> {
51
7
  value?: TValue[];
52
8
  onValueChange?: (value: TValue[]) => void;
53
9
  disabled?: boolean;
54
10
  size?: CheckboxSize;
55
- theme?: CheckboxTheme;
56
11
  inline?: boolean;
57
12
  inset?: boolean;
13
+ required?: boolean;
14
+ validate?: (value: TValue[]) => string | undefined;
15
+ touchMode?: boolean;
58
16
  class?: string;
59
17
  style?: JSX.CSSProperties;
60
18
  children?: JSX.Element;
@@ -62,55 +20,18 @@ interface CheckboxGroupProps<TValue> {
62
20
 
63
21
  interface CheckboxGroupComponent {
64
22
  <TValue = unknown>(props: CheckboxGroupProps<TValue>): JSX.Element;
65
- Item: typeof CheckboxGroupItemInner;
23
+ Item: <TValue = unknown>(props: {
24
+ value: TValue;
25
+ disabled?: boolean;
26
+ children?: JSX.Element;
27
+ }) => JSX.Element;
66
28
  }
67
29
 
68
- const CheckboxGroupInner: ParentComponent<CheckboxGroupProps<unknown>> = (props) => {
69
- const [local, rest] = splitProps(props, [
70
- "value",
71
- "onValueChange",
72
- "disabled",
73
- "size",
74
- "theme",
75
- "inline",
76
- "inset",
77
- "class",
78
- "style",
79
- "children",
80
- ]);
81
-
82
- const [value, setValue] = createControllableSignal({
83
- value: () => local.value ?? [],
84
- onChange: () => local.onValueChange,
85
- });
86
-
87
- const toggle = (item: unknown) => {
88
- setValue((prev) => {
89
- if (prev.includes(item)) {
90
- return prev.filter((v) => v !== item);
91
- }
92
- return [...prev, item];
93
- });
94
- };
95
-
96
- const contextValue: CheckboxGroupContextValue<unknown> = {
97
- value,
98
- toggle,
99
- disabled: () => local.disabled ?? false,
100
- size: () => local.size,
101
- theme: () => local.theme,
102
- inline: () => local.inline ?? false,
103
- inset: () => local.inset ?? false,
104
- };
105
-
106
- return (
107
- <CheckboxGroupContext.Provider value={contextValue}>
108
- <div {...rest} class={twMerge("inline-flex", local.class)} style={local.style}>
109
- {local.children}
110
- </div>
111
- </CheckboxGroupContext.Provider>
112
- );
113
- };
30
+ const { Group } = createSelectionGroup({
31
+ mode: "multiple",
32
+ contextName: "CheckboxGroup",
33
+ ItemComponent: Checkbox,
34
+ emptyErrorMsg: "항목을 선택해 주세요",
35
+ });
114
36
 
115
- export const CheckboxGroup = CheckboxGroupInner as unknown as CheckboxGroupComponent;
116
- CheckboxGroup.Item = CheckboxGroupItemInner;
37
+ export const CheckboxGroup = Group as unknown as CheckboxGroupComponent;
@@ -1,20 +1,20 @@
1
- import { type JSX, type ParentComponent, Show, splitProps } from "solid-js";
1
+ import { type JSX, type ParentComponent, Show, splitProps, createMemo } from "solid-js";
2
2
  import { twMerge } from "tailwind-merge";
3
3
  import { createControllableSignal } from "../../../hooks/createControllableSignal";
4
4
  import { ripple } from "../../../directives/ripple";
5
5
  import clsx from "clsx";
6
6
  import {
7
- type CheckboxTheme,
8
7
  type CheckboxSize,
9
8
  checkboxBaseClass,
10
9
  indicatorBaseClass,
11
- themeCheckedClasses,
10
+ checkedClass,
12
11
  checkboxSizeClasses,
13
12
  checkboxInsetClass,
14
13
  checkboxInsetSizeHeightClasses,
15
14
  checkboxInlineClass,
16
15
  checkboxDisabledClass,
17
16
  } from "./Checkbox.styles";
17
+ import { Invalid } from "../Invalid";
18
18
 
19
19
  const radioDotClass = clsx("size-2", "rounded-full", "bg-current");
20
20
 
@@ -26,9 +26,11 @@ export interface RadioProps {
26
26
  onValueChange?: (value: boolean) => void;
27
27
  disabled?: boolean;
28
28
  size?: CheckboxSize;
29
- theme?: CheckboxTheme;
30
29
  inset?: boolean;
31
30
  inline?: boolean;
31
+ required?: boolean;
32
+ validate?: (value: boolean) => string | undefined;
33
+ touchMode?: boolean;
32
34
  class?: string;
33
35
  style?: JSX.CSSProperties;
34
36
  children?: JSX.Element;
@@ -40,9 +42,11 @@ export const Radio: ParentComponent<RadioProps> = (props) => {
40
42
  "onValueChange",
41
43
  "disabled",
42
44
  "size",
43
- "theme",
44
45
  "inset",
45
46
  "inline",
47
+ "required",
48
+ "validate",
49
+ "touchMode",
46
50
  "class",
47
51
  "style",
48
52
  "children",
@@ -76,32 +80,39 @@ export const Radio: ParentComponent<RadioProps> = (props) => {
76
80
  local.class,
77
81
  );
78
82
 
79
- const getIndicatorClass = () => {
80
- const theme = local.theme ?? "primary";
83
+ const getIndicatorClass = () =>
84
+ twMerge(indicatorBaseClass, "rounded-full", value() && checkedClass);
81
85
 
82
- return twMerge(indicatorBaseClass, "rounded-full", value() && themeCheckedClasses[theme]);
83
- };
86
+ const errorMsg = createMemo(() => {
87
+ const v = local.value ?? false;
88
+ if (local.required && !v) return "필수 선택 항목입니다";
89
+ return local.validate?.(v);
90
+ });
84
91
 
85
92
  return (
86
- <label
87
- {...rest}
88
- use:ripple={!local.disabled}
89
- role="radio"
90
- aria-checked={value()}
91
- tabIndex={local.disabled ? -1 : 0}
92
- class={getWrapperClass()}
93
- style={local.style}
94
- onClick={handleClick}
95
- onKeyDown={handleKeyDown}
96
- >
97
- <div class={getIndicatorClass()}>
98
- <Show when={value()}>
99
- <div class={radioDotClass} />
100
- </Show>
93
+ <Invalid message={errorMsg()} variant="border" touchMode={local.touchMode}>
94
+ <div class="inline-flex">
95
+ <label
96
+ {...rest}
97
+ use:ripple={!local.disabled}
98
+ role="radio"
99
+ aria-checked={value()}
100
+ tabIndex={local.disabled ? -1 : 0}
101
+ class={getWrapperClass()}
102
+ style={local.style}
103
+ onClick={handleClick}
104
+ onKeyDown={handleKeyDown}
105
+ >
106
+ <div class={getIndicatorClass()}>
107
+ <Show when={value()}>
108
+ <div class={radioDotClass} />
109
+ </Show>
110
+ </div>
111
+ <Show when={local.children}>
112
+ <span>{local.children}</span>
113
+ </Show>
114
+ </label>
101
115
  </div>
102
- <Show when={local.children}>
103
- <span>{local.children}</span>
104
- </Show>
105
- </label>
116
+ </Invalid>
106
117
  );
107
118
  };
@@ -1,60 +1,18 @@
1
- import { type JSX, type ParentComponent, createContext, splitProps, useContext } from "solid-js";
2
- import { twMerge } from "tailwind-merge";
3
- import { createControllableSignal } from "../../../hooks/createControllableSignal";
1
+ import { type JSX } from "solid-js";
4
2
  import { Radio } from "./Radio";
5
- import type { CheckboxSize, CheckboxTheme } from "./Checkbox.styles";
6
-
7
- interface RadioGroupContextValue<TValue> {
8
- value: () => TValue | undefined;
9
- select: (item: TValue) => void;
10
- disabled: () => boolean;
11
- size: () => CheckboxSize | undefined;
12
- theme: () => CheckboxTheme | undefined;
13
- inline: () => boolean;
14
- inset: () => boolean;
15
- }
16
-
17
- const RadioGroupContext = createContext<RadioGroupContextValue<any>>();
18
-
19
- // --- RadioGroup.Item ---
20
-
21
- interface RadioGroupItemProps<TValue> {
22
- value: TValue;
23
- disabled?: boolean;
24
- children?: JSX.Element;
25
- }
26
-
27
- function RadioGroupItemInner<TValue>(props: RadioGroupItemProps<TValue>) {
28
- const ctx = useContext(RadioGroupContext);
29
- if (!ctx) throw new Error("RadioGroup.Item은 RadioGroup 내부에서만 사용할 수 있습니다");
30
-
31
- const isSelected = () => ctx.value() === props.value;
32
-
33
- return (
34
- <Radio
35
- value={isSelected()}
36
- onValueChange={() => ctx.select(props.value)}
37
- disabled={props.disabled ?? ctx.disabled()}
38
- size={ctx.size()}
39
- theme={ctx.theme()}
40
- inline={ctx.inline()}
41
- inset={ctx.inset()}
42
- >
43
- {props.children}
44
- </Radio>
45
- );
46
- }
47
-
48
- // --- RadioGroup ---
3
+ import { createSelectionGroup } from "../../../hooks/createSelectionGroup";
4
+ import type { CheckboxSize } from "./Checkbox.styles";
49
5
 
50
6
  interface RadioGroupProps<TValue> {
51
7
  value?: TValue;
52
8
  onValueChange?: (value: TValue) => void;
53
9
  disabled?: boolean;
54
10
  size?: CheckboxSize;
55
- theme?: CheckboxTheme;
56
11
  inline?: boolean;
57
12
  inset?: boolean;
13
+ required?: boolean;
14
+ validate?: (value: TValue | undefined) => string | undefined;
15
+ touchMode?: boolean;
58
16
  class?: string;
59
17
  style?: JSX.CSSProperties;
60
18
  children?: JSX.Element;
@@ -62,50 +20,18 @@ interface RadioGroupProps<TValue> {
62
20
 
63
21
  interface RadioGroupComponent {
64
22
  <TValue = unknown>(props: RadioGroupProps<TValue>): JSX.Element;
65
- Item: typeof RadioGroupItemInner;
23
+ Item: <TValue = unknown>(props: {
24
+ value: TValue;
25
+ disabled?: boolean;
26
+ children?: JSX.Element;
27
+ }) => JSX.Element;
66
28
  }
67
29
 
68
- const RadioGroupInner: ParentComponent<RadioGroupProps<unknown>> = (props) => {
69
- const [local, rest] = splitProps(props, [
70
- "value",
71
- "onValueChange",
72
- "disabled",
73
- "size",
74
- "theme",
75
- "inline",
76
- "inset",
77
- "class",
78
- "style",
79
- "children",
80
- ]);
81
-
82
- const [value, setValue] = createControllableSignal({
83
- value: () => local.value,
84
- onChange: () => local.onValueChange,
85
- });
86
-
87
- const select = (item: unknown) => {
88
- setValue(item);
89
- };
90
-
91
- const contextValue: RadioGroupContextValue<unknown> = {
92
- value,
93
- select,
94
- disabled: () => local.disabled ?? false,
95
- size: () => local.size,
96
- theme: () => local.theme,
97
- inline: () => local.inline ?? false,
98
- inset: () => local.inset ?? false,
99
- };
100
-
101
- return (
102
- <RadioGroupContext.Provider value={contextValue}>
103
- <div {...rest} class={twMerge("inline-flex", local.class)} style={local.style}>
104
- {local.children}
105
- </div>
106
- </RadioGroupContext.Provider>
107
- );
108
- };
30
+ const { Group } = createSelectionGroup({
31
+ mode: "single",
32
+ contextName: "RadioGroup",
33
+ ItemComponent: Radio,
34
+ emptyErrorMsg: "항목을 선택해 주세요",
35
+ });
109
36
 
110
- export const RadioGroup = RadioGroupInner as unknown as RadioGroupComponent;
111
- RadioGroup.Item = RadioGroupItemInner;
37
+ export const RadioGroup = Group as unknown as RadioGroupComponent;
@@ -1,9 +1,9 @@
1
- import { type Component, type JSX, splitProps } from "solid-js";
1
+ import { type Component, createMemo, type JSX, splitProps } from "solid-js";
2
2
  import clsx from "clsx";
3
3
  import { twMerge } from "tailwind-merge";
4
4
  import { createControllableSignal } from "../../../hooks/createControllableSignal";
5
-
6
- type ColorPickerSize = "sm" | "lg";
5
+ import { Invalid } from "../Invalid";
6
+ import { type ComponentSizeCompact } from "../../../styles/tokens.styles";
7
7
 
8
8
  // 기본 스타일
9
9
  const baseClass = clsx(
@@ -20,7 +20,7 @@ const baseClass = clsx(
20
20
  );
21
21
 
22
22
  // 사이즈별 스타일
23
- const sizeClasses: Record<ColorPickerSize, string> = {
23
+ const sizeClasses: Record<ComponentSizeCompact, string> = {
24
24
  sm: "size-field-sm",
25
25
  lg: "size-field-lg",
26
26
  };
@@ -48,7 +48,16 @@ export interface ColorPickerProps {
48
48
  disabled?: boolean;
49
49
 
50
50
  /** 사이즈 */
51
- size?: ColorPickerSize;
51
+ size?: ComponentSizeCompact;
52
+
53
+ /** 필수 입력 여부 */
54
+ required?: boolean;
55
+
56
+ /** 커스텀 유효성 검사 함수 */
57
+ validate?: (value: string | undefined) => string | undefined;
58
+
59
+ /** touchMode: 포커스 해제 후에만 에러 표시 */
60
+ touchMode?: boolean;
52
61
 
53
62
  /** 커스텀 class */
54
63
  class?: string;
@@ -66,7 +75,18 @@ export interface ColorPickerProps {
66
75
  * ```
67
76
  */
68
77
  export const ColorPicker: Component<ColorPickerProps> = (props) => {
69
- const [local, rest] = splitProps(props, ["value", "onValueChange", "title", "disabled", "size", "class", "style"]);
78
+ const [local, rest] = splitProps(props, [
79
+ "value",
80
+ "onValueChange",
81
+ "title",
82
+ "disabled",
83
+ "size",
84
+ "required",
85
+ "validate",
86
+ "touchMode",
87
+ "class",
88
+ "style",
89
+ ]);
70
90
 
71
91
  const [value, setValue] = createControllableSignal({
72
92
  value: () => local.value ?? "#000000",
@@ -78,19 +98,32 @@ export const ColorPicker: Component<ColorPickerProps> = (props) => {
78
98
  };
79
99
 
80
100
  const getClassName = () =>
81
- twMerge(baseClass, local.size && sizeClasses[local.size], local.disabled && disabledClass, local.class);
101
+ twMerge(
102
+ baseClass,
103
+ local.size && sizeClasses[local.size],
104
+ local.disabled && disabledClass,
105
+ local.class,
106
+ );
107
+
108
+ const errorMsg = createMemo(() => {
109
+ const v = props.value;
110
+ if (local.required && (v === undefined || v === "")) return "필수 입력 항목입니다";
111
+ return local.validate?.(v);
112
+ });
82
113
 
83
114
  return (
84
- <input
85
- {...rest}
86
- data-color-picker
87
- type="color"
88
- class={getClassName()}
89
- style={local.style}
90
- value={value()}
91
- title={local.title}
92
- disabled={local.disabled}
93
- onInput={handleInput}
94
- />
115
+ <Invalid variant="border" message={errorMsg()} touchMode={local.touchMode}>
116
+ <input
117
+ {...rest}
118
+ data-color-picker
119
+ type="color"
120
+ class={getClassName()}
121
+ style={local.style}
122
+ value={value()}
123
+ title={local.title}
124
+ disabled={local.disabled}
125
+ onInput={handleInput}
126
+ />
127
+ </Invalid>
95
128
  );
96
129
  };