@simplysm/solid 13.0.69 → 13.0.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/README.md +168 -195
  2. package/dist/components/data/calendar/Calendar.d.ts.map +1 -1
  3. package/dist/components/data/calendar/Calendar.js +15 -2
  4. package/dist/components/data/calendar/Calendar.js.map +2 -2
  5. package/dist/components/data/kanban/KanbanContext.js +2 -2
  6. package/dist/components/data/kanban/KanbanContext.js.map +1 -1
  7. package/dist/components/data/list/List.d.ts +8 -8
  8. package/dist/components/data/list/ListContext.d.ts +1 -1
  9. package/dist/components/data/list/ListItem.d.ts +15 -15
  10. package/dist/components/data/sheet/DataSheet.d.ts.map +1 -1
  11. package/dist/components/data/sheet/DataSheet.js +6 -4
  12. package/dist/components/data/sheet/DataSheet.js.map +2 -2
  13. package/dist/components/data/sheet/DataSheetConfigDialog.js +8 -8
  14. package/dist/components/data/sheet/DataSheetConfigDialog.js.map +1 -1
  15. package/dist/components/data/sheet/types.d.ts +4 -4
  16. package/dist/components/data/sheet/types.d.ts.map +1 -1
  17. package/dist/components/disclosure/Collapse.d.ts +4 -4
  18. package/dist/components/disclosure/Dialog.d.ts +24 -24
  19. package/dist/components/disclosure/Dialog.d.ts.map +1 -1
  20. package/dist/components/disclosure/Dialog.js +7 -2
  21. package/dist/components/disclosure/Dialog.js.map +2 -2
  22. package/dist/components/disclosure/DialogContext.d.ts +25 -25
  23. package/dist/components/disclosure/DialogContext.d.ts.map +1 -1
  24. package/dist/components/disclosure/DialogContext.js +1 -1
  25. package/dist/components/disclosure/DialogContext.js.map +1 -1
  26. package/dist/components/disclosure/DialogInstanceContext.d.ts +7 -7
  27. package/dist/components/disclosure/DialogInstanceContext.d.ts.map +1 -1
  28. package/dist/components/disclosure/DialogProvider.d.ts +3 -3
  29. package/dist/components/disclosure/Dropdown.d.ts +26 -24
  30. package/dist/components/disclosure/Dropdown.d.ts.map +1 -1
  31. package/dist/components/disclosure/Dropdown.js +24 -8
  32. package/dist/components/disclosure/Dropdown.js.map +2 -2
  33. package/dist/components/disclosure/Tabs.js +1 -1
  34. package/dist/components/disclosure/Tabs.js.map +1 -1
  35. package/dist/components/disclosure/dialogZIndex.d.ts +9 -7
  36. package/dist/components/disclosure/dialogZIndex.d.ts.map +1 -1
  37. package/dist/components/disclosure/dialogZIndex.js +4 -0
  38. package/dist/components/disclosure/dialogZIndex.js.map +1 -1
  39. package/dist/components/features/crud-detail/CrudDetail.d.ts.map +1 -1
  40. package/dist/components/features/crud-detail/CrudDetail.js +34 -22
  41. package/dist/components/features/crud-detail/CrudDetail.js.map +2 -2
  42. package/dist/components/features/crud-sheet/CrudSheet.d.ts.map +1 -1
  43. package/dist/components/features/crud-sheet/CrudSheet.js +48 -33
  44. package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
  45. package/dist/components/features/crudRegistry.d.ts +16 -0
  46. package/dist/components/features/crudRegistry.d.ts.map +1 -0
  47. package/dist/components/features/crudRegistry.js +37 -0
  48. package/dist/components/features/crudRegistry.js.map +6 -0
  49. package/dist/components/features/data-select-button/DataSelectButton.d.ts +14 -14
  50. package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -1
  51. package/dist/components/features/data-select-button/DataSelectButton.js +27 -9
  52. package/dist/components/features/data-select-button/DataSelectButton.js.map +2 -2
  53. package/dist/components/features/permission-table/PermissionTable.d.ts +3 -3
  54. package/dist/components/features/permission-table/PermissionTable.d.ts.map +1 -1
  55. package/dist/components/features/permission-table/PermissionTable.js +74 -85
  56. package/dist/components/features/permission-table/PermissionTable.js.map +2 -2
  57. package/dist/components/features/shared-data/SharedDataSelect.d.ts +12 -12
  58. package/dist/components/features/shared-data/SharedDataSelect.d.ts.map +1 -1
  59. package/dist/components/features/shared-data/SharedDataSelect.js +10 -6
  60. package/dist/components/features/shared-data/SharedDataSelect.js.map +2 -2
  61. package/dist/components/features/shared-data/SharedDataSelectButton.d.ts +10 -10
  62. package/dist/components/features/shared-data/SharedDataSelectButton.d.ts.map +1 -1
  63. package/dist/components/features/shared-data/SharedDataSelectList.d.ts +23 -15
  64. package/dist/components/features/shared-data/SharedDataSelectList.d.ts.map +1 -1
  65. package/dist/components/features/shared-data/SharedDataSelectList.js +191 -65
  66. package/dist/components/features/shared-data/SharedDataSelectList.js.map +2 -2
  67. package/dist/components/features/shared-data/SharedDataSelectListContext.d.ts +15 -0
  68. package/dist/components/features/shared-data/SharedDataSelectListContext.d.ts.map +1 -0
  69. package/dist/components/features/shared-data/SharedDataSelectListContext.js +27 -0
  70. package/dist/components/features/shared-data/SharedDataSelectListContext.js.map +6 -0
  71. package/dist/components/feedback/Progress.d.ts +1 -1
  72. package/dist/components/feedback/Progress.d.ts.map +1 -1
  73. package/dist/components/feedback/busy/BusyContainer.d.ts +2 -2
  74. package/dist/components/feedback/busy/BusyContainer.d.ts.map +1 -1
  75. package/dist/components/feedback/busy/BusyContext.d.ts +11 -11
  76. package/dist/components/feedback/busy/BusyContext.d.ts.map +1 -1
  77. package/dist/components/feedback/busy/BusyContext.js +1 -1
  78. package/dist/components/feedback/busy/BusyContext.js.map +1 -1
  79. package/dist/components/feedback/busy/BusyProvider.d.ts +6 -6
  80. package/dist/components/feedback/busy/BusyProvider.d.ts.map +1 -1
  81. package/dist/components/feedback/notification/NotificationBanner.d.ts.map +1 -1
  82. package/dist/components/feedback/notification/NotificationBanner.js +7 -3
  83. package/dist/components/feedback/notification/NotificationBanner.js.map +2 -2
  84. package/dist/components/feedback/notification/NotificationBell.js +2 -2
  85. package/dist/components/feedback/notification/NotificationBell.js.map +1 -1
  86. package/dist/components/feedback/notification/NotificationContext.d.ts +22 -22
  87. package/dist/components/feedback/notification/NotificationContext.d.ts.map +1 -1
  88. package/dist/components/feedback/notification/NotificationContext.js +1 -1
  89. package/dist/components/feedback/notification/NotificationContext.js.map +1 -1
  90. package/dist/components/feedback/notification/NotificationProvider.d.ts +5 -5
  91. package/dist/components/feedback/notification/NotificationProvider.js +1 -1
  92. package/dist/components/feedback/notification/NotificationProvider.js.map +1 -1
  93. package/dist/components/feedback/print/PrintContext.js +1 -1
  94. package/dist/components/feedback/print/PrintContext.js.map +1 -1
  95. package/dist/components/form-control/DropdownTrigger.styles.d.ts +1 -1
  96. package/dist/components/form-control/DropdownTrigger.styles.d.ts.map +1 -1
  97. package/dist/components/form-control/ThemeToggle.d.ts +7 -7
  98. package/dist/components/form-control/ThemeToggle.d.ts.map +1 -1
  99. package/dist/components/form-control/ThemeToggle.js +3 -3
  100. package/dist/components/form-control/checkbox/Checkbox.js +1 -1
  101. package/dist/components/form-control/checkbox/CheckboxGroup.js +1 -1
  102. package/dist/components/form-control/checkbox/Radio.js +1 -1
  103. package/dist/components/form-control/checkbox/RadioGroup.js +1 -1
  104. package/dist/components/form-control/color-picker/ColorPicker.d.ts +12 -12
  105. package/dist/components/form-control/color-picker/ColorPicker.d.ts.map +1 -1
  106. package/dist/components/form-control/color-picker/ColorPicker.js +2 -2
  107. package/dist/components/form-control/combobox/Combobox.d.ts +22 -22
  108. package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
  109. package/dist/components/form-control/combobox/Combobox.js +2 -2
  110. package/dist/components/form-control/combobox/ComboboxContext.d.ts +4 -4
  111. package/dist/components/form-control/combobox/ComboboxContext.d.ts.map +1 -1
  112. package/dist/components/form-control/combobox/ComboboxContext.js +1 -1
  113. package/dist/components/form-control/combobox/ComboboxContext.js.map +1 -1
  114. package/dist/components/form-control/combobox/ComboboxItem.d.ts +3 -3
  115. package/dist/components/form-control/combobox/ComboboxItem.d.ts.map +1 -1
  116. package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts +14 -14
  117. package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts.map +1 -1
  118. package/dist/components/form-control/date-range-picker/DateRangePicker.js +20 -9
  119. package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
  120. package/dist/components/form-control/editor/EditorToolbar.d.ts.map +1 -1
  121. package/dist/components/form-control/editor/EditorToolbar.js +65 -20
  122. package/dist/components/form-control/editor/EditorToolbar.js.map +2 -2
  123. package/dist/components/form-control/editor/RichTextEditor.d.ts +6 -6
  124. package/dist/components/form-control/editor/RichTextEditor.d.ts.map +1 -1
  125. package/dist/components/form-control/editor/RichTextEditor.js +1 -1
  126. package/dist/components/form-control/editor/editor.css +5 -5
  127. package/dist/components/form-control/field/DatePicker.d.ts +22 -22
  128. package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
  129. package/dist/components/form-control/field/DatePicker.js +4 -4
  130. package/dist/components/form-control/field/DatePicker.js.map +1 -1
  131. package/dist/components/form-control/field/DateTimePicker.d.ts +21 -21
  132. package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
  133. package/dist/components/form-control/field/DateTimePicker.js +4 -4
  134. package/dist/components/form-control/field/DateTimePicker.js.map +1 -1
  135. package/dist/components/form-control/field/FieldPlaceholder.d.ts +1 -1
  136. package/dist/components/form-control/field/FieldPlaceholder.d.ts.map +1 -1
  137. package/dist/components/form-control/field/NumberInput.d.ts +23 -23
  138. package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
  139. package/dist/components/form-control/field/NumberInput.js +4 -4
  140. package/dist/components/form-control/field/NumberInput.js.map +1 -1
  141. package/dist/components/form-control/field/TextInput.d.ts +25 -25
  142. package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
  143. package/dist/components/form-control/field/TextInput.js +5 -5
  144. package/dist/components/form-control/field/TextInput.js.map +1 -1
  145. package/dist/components/form-control/field/Textarea.d.ts +19 -19
  146. package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
  147. package/dist/components/form-control/field/Textarea.js +4 -4
  148. package/dist/components/form-control/field/Textarea.js.map +1 -1
  149. package/dist/components/form-control/field/TimePicker.d.ts +20 -20
  150. package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
  151. package/dist/components/form-control/field/TimePicker.js +4 -4
  152. package/dist/components/form-control/field/TimePicker.js.map +1 -1
  153. package/dist/components/form-control/numpad/Numpad.d.ts +11 -11
  154. package/dist/components/form-control/numpad/Numpad.d.ts.map +1 -1
  155. package/dist/components/form-control/select/Select.d.ts +26 -26
  156. package/dist/components/form-control/select/Select.d.ts.map +1 -1
  157. package/dist/components/form-control/select/Select.js +34 -23
  158. package/dist/components/form-control/select/Select.js.map +2 -2
  159. package/dist/components/form-control/select/SelectContext.d.ts +7 -7
  160. package/dist/components/form-control/select/SelectContext.d.ts.map +1 -1
  161. package/dist/components/form-control/select/SelectContext.js +1 -1
  162. package/dist/components/form-control/select/SelectContext.js.map +1 -1
  163. package/dist/components/form-control/select/SelectItem.d.ts +4 -4
  164. package/dist/components/form-control/select/SelectItem.d.ts.map +1 -1
  165. package/dist/components/form-control/state-preset/StatePreset.js +8 -8
  166. package/dist/components/form-control/state-preset/StatePreset.js.map +1 -1
  167. package/dist/components/layout/FormTable.js +4 -4
  168. package/dist/components/layout/sidebar/Sidebar.d.ts +5 -5
  169. package/dist/components/layout/sidebar/SidebarContainer.d.ts +11 -11
  170. package/dist/components/layout/sidebar/SidebarContainer.d.ts.map +1 -1
  171. package/dist/components/layout/sidebar/SidebarContainer.js +6 -1
  172. package/dist/components/layout/sidebar/SidebarContainer.js.map +2 -2
  173. package/dist/components/layout/sidebar/SidebarContext.d.ts +7 -7
  174. package/dist/components/layout/sidebar/SidebarContext.js +1 -1
  175. package/dist/components/layout/sidebar/SidebarContext.js.map +1 -1
  176. package/dist/components/layout/sidebar/SidebarMenu.d.ts +11 -11
  177. package/dist/components/layout/sidebar/SidebarUser.d.ts +14 -14
  178. package/dist/components/layout/topbar/Topbar.d.ts +6 -6
  179. package/dist/components/layout/topbar/Topbar.d.ts.map +1 -1
  180. package/dist/components/layout/topbar/Topbar.js +11 -6
  181. package/dist/components/layout/topbar/Topbar.js.map +2 -2
  182. package/dist/components/layout/topbar/TopbarContainer.d.ts +6 -6
  183. package/dist/components/layout/topbar/TopbarContext.js +2 -2
  184. package/dist/components/layout/topbar/TopbarContext.js.map +1 -1
  185. package/dist/components/layout/topbar/TopbarMenu.d.ts +11 -11
  186. package/dist/components/layout/topbar/TopbarMenu.d.ts.map +1 -1
  187. package/dist/components/layout/topbar/TopbarMenu.js +5 -1
  188. package/dist/components/layout/topbar/TopbarMenu.js.map +2 -2
  189. package/dist/components/layout/topbar/TopbarUser.d.ts +9 -9
  190. package/dist/directives/ripple.d.ts +5 -5
  191. package/dist/helpers/createAppStructure.d.ts.map +1 -1
  192. package/dist/helpers/createAppStructure.js +7 -3
  193. package/dist/helpers/createAppStructure.js.map +1 -1
  194. package/dist/helpers/createHmrSafeContext.d.ts +3 -0
  195. package/dist/helpers/createHmrSafeContext.d.ts.map +1 -0
  196. package/dist/helpers/createHmrSafeContext.js +10 -0
  197. package/dist/helpers/createHmrSafeContext.js.map +6 -0
  198. package/dist/helpers/createSlotComponent.d.ts +3 -3
  199. package/dist/helpers/mergeStyles.d.ts +8 -8
  200. package/dist/hooks/createControllableSignal.d.ts +10 -10
  201. package/dist/hooks/createControllableStore.d.ts +6 -6
  202. package/dist/hooks/createIMEHandler.d.ts +7 -7
  203. package/dist/hooks/createMountTransition.d.ts +4 -4
  204. package/dist/hooks/createSelectionGroup.d.ts.map +1 -1
  205. package/dist/hooks/createSelectionGroup.js +4 -3
  206. package/dist/hooks/createSelectionGroup.js.map +2 -2
  207. package/dist/hooks/createSlotSignal.d.ts +2 -2
  208. package/dist/hooks/useLocalStorage.d.ts +11 -11
  209. package/dist/hooks/useLogger.d.ts +1 -1
  210. package/dist/hooks/useLogger.d.ts.map +1 -1
  211. package/dist/hooks/useLogger.js +1 -1
  212. package/dist/hooks/useLogger.js.map +1 -1
  213. package/dist/hooks/useRouterLink.d.ts +10 -10
  214. package/dist/hooks/useRouterLink.d.ts.map +1 -1
  215. package/dist/index.d.ts +2 -1
  216. package/dist/index.d.ts.map +1 -1
  217. package/dist/index.js +2 -1
  218. package/dist/index.js.map +1 -1
  219. package/dist/providers/ClipboardProvider.d.ts +5 -5
  220. package/dist/providers/ConfigContext.d.ts +6 -6
  221. package/dist/providers/ConfigContext.js +2 -2
  222. package/dist/providers/ConfigContext.js.map +1 -1
  223. package/dist/providers/ErrorLoggerProvider.d.ts +3 -3
  224. package/dist/providers/LoggerContext.d.ts +13 -13
  225. package/dist/providers/PwaUpdateProvider.d.ts +4 -4
  226. package/dist/providers/PwaUpdateProvider.js +2 -2
  227. package/dist/providers/PwaUpdateProvider.js.map +1 -1
  228. package/dist/providers/ServiceClientContext.d.ts +8 -8
  229. package/dist/providers/ServiceClientContext.d.ts.map +1 -1
  230. package/dist/providers/ServiceClientContext.js +1 -1
  231. package/dist/providers/ServiceClientContext.js.map +1 -1
  232. package/dist/providers/ServiceClientProvider.d.ts +6 -6
  233. package/dist/providers/ServiceClientProvider.js +7 -7
  234. package/dist/providers/ServiceClientProvider.js.map +1 -1
  235. package/dist/providers/SyncStorageContext.d.ts +14 -14
  236. package/dist/providers/SystemProvider.d.ts.map +1 -1
  237. package/dist/providers/SystemProvider.js +21 -16
  238. package/dist/providers/SystemProvider.js.map +2 -2
  239. package/dist/providers/ThemeContext.d.ts +20 -20
  240. package/dist/providers/ThemeContext.d.ts.map +1 -1
  241. package/dist/providers/ThemeContext.js +1 -1
  242. package/dist/providers/ThemeContext.js.map +1 -1
  243. package/dist/providers/i18n/I18nContext.d.ts +44 -0
  244. package/dist/providers/i18n/I18nContext.d.ts.map +1 -0
  245. package/dist/providers/i18n/I18nContext.js +73 -0
  246. package/dist/providers/i18n/I18nContext.js.map +6 -0
  247. package/dist/providers/i18n/I18nContext.types.d.ts +28 -0
  248. package/dist/providers/i18n/I18nContext.types.d.ts.map +1 -0
  249. package/dist/providers/i18n/I18nContext.types.js +1 -0
  250. package/dist/providers/i18n/I18nContext.types.js.map +6 -0
  251. package/dist/providers/i18n/i18nUtils.d.ts +18 -0
  252. package/dist/providers/i18n/i18nUtils.d.ts.map +1 -0
  253. package/dist/providers/i18n/i18nUtils.js +25 -0
  254. package/dist/providers/i18n/i18nUtils.js.map +6 -0
  255. package/dist/providers/i18n/locales/en.d.ts +163 -0
  256. package/dist/providers/i18n/locales/en.d.ts.map +1 -0
  257. package/dist/providers/i18n/locales/en.js +165 -0
  258. package/dist/providers/i18n/locales/en.js.map +6 -0
  259. package/dist/providers/i18n/locales/ko.d.ts +163 -0
  260. package/dist/providers/i18n/locales/ko.d.ts.map +1 -0
  261. package/dist/providers/i18n/locales/ko.js +165 -0
  262. package/dist/providers/i18n/locales/ko.js.map +6 -0
  263. package/dist/providers/shared-data/SharedDataChangeEvent.d.ts +4 -4
  264. package/dist/providers/shared-data/SharedDataContext.d.ts +28 -28
  265. package/dist/providers/shared-data/SharedDataContext.d.ts.map +1 -1
  266. package/dist/providers/shared-data/SharedDataContext.js +1 -1
  267. package/dist/providers/shared-data/SharedDataContext.js.map +1 -1
  268. package/dist/providers/shared-data/SharedDataProvider.d.ts +9 -9
  269. package/dist/providers/shared-data/SharedDataProvider.js +4 -4
  270. package/dist/providers/shared-data/SharedDataProvider.js.map +1 -1
  271. package/package.json +9 -8
  272. package/src/components/data/calendar/Calendar.tsx +10 -4
  273. package/src/components/data/kanban/Kanban.tsx +14 -14
  274. package/src/components/data/kanban/KanbanContext.ts +3 -3
  275. package/src/components/data/list/List.tsx +10 -10
  276. package/src/components/data/list/ListContext.ts +1 -1
  277. package/src/components/data/list/ListItem.styles.ts +8 -8
  278. package/src/components/data/list/ListItem.tsx +15 -15
  279. package/src/components/data/sheet/DataSheet.styles.ts +22 -22
  280. package/src/components/data/sheet/DataSheet.tsx +52 -48
  281. package/src/components/data/sheet/DataSheetColumn.tsx +1 -1
  282. package/src/components/data/sheet/DataSheetConfigDialog.tsx +9 -9
  283. package/src/components/data/sheet/sheetUtils.ts +7 -7
  284. package/src/components/data/sheet/types.ts +16 -16
  285. package/src/components/disclosure/Collapse.tsx +11 -11
  286. package/src/components/disclosure/Dialog.tsx +60 -57
  287. package/src/components/disclosure/DialogContext.ts +26 -26
  288. package/src/components/disclosure/DialogInstanceContext.ts +7 -7
  289. package/src/components/disclosure/DialogProvider.tsx +5 -5
  290. package/src/components/disclosure/Dropdown.tsx +89 -75
  291. package/src/components/disclosure/Tabs.tsx +1 -1
  292. package/src/components/disclosure/dialogZIndex.ts +16 -11
  293. package/src/components/display/Echarts.tsx +4 -4
  294. package/src/components/features/address/AddressSearch.tsx +2 -2
  295. package/src/components/features/crud-detail/CrudDetail.tsx +34 -21
  296. package/src/components/features/crud-detail/CrudDetailAfter.tsx +1 -1
  297. package/src/components/features/crud-detail/CrudDetailBefore.tsx +1 -1
  298. package/src/components/features/crud-detail/CrudDetailTools.tsx +1 -1
  299. package/src/components/features/crud-sheet/CrudSheet.tsx +52 -40
  300. package/src/components/features/crud-sheet/CrudSheetColumn.tsx +1 -1
  301. package/src/components/features/crud-sheet/CrudSheetFilter.tsx +1 -1
  302. package/src/components/features/crud-sheet/CrudSheetHeader.tsx +1 -1
  303. package/src/components/features/crud-sheet/CrudSheetTools.tsx +1 -1
  304. package/src/components/features/crudRegistry.ts +60 -0
  305. package/src/components/features/data-select-button/DataSelectButton.tsx +34 -32
  306. package/src/components/features/permission-table/PermissionTable.tsx +70 -64
  307. package/src/components/features/shared-data/SharedDataSelect.tsx +24 -22
  308. package/src/components/features/shared-data/SharedDataSelectButton.tsx +10 -10
  309. package/src/components/features/shared-data/SharedDataSelectList.tsx +231 -59
  310. package/src/components/features/shared-data/SharedDataSelectListContext.ts +39 -0
  311. package/src/components/feedback/Progress.tsx +1 -1
  312. package/src/components/feedback/busy/BusyContainer.tsx +6 -6
  313. package/src/components/feedback/busy/BusyContext.ts +12 -12
  314. package/src/components/feedback/busy/BusyProvider.tsx +6 -6
  315. package/src/components/feedback/notification/NotificationBanner.tsx +3 -1
  316. package/src/components/feedback/notification/NotificationBell.tsx +4 -4
  317. package/src/components/feedback/notification/NotificationContext.ts +28 -28
  318. package/src/components/feedback/notification/NotificationProvider.tsx +9 -9
  319. package/src/components/feedback/print/PrintContext.ts +1 -1
  320. package/src/components/form-control/Button.tsx +1 -1
  321. package/src/components/form-control/DropdownTrigger.styles.ts +1 -1
  322. package/src/components/form-control/Invalid.tsx +5 -5
  323. package/src/components/form-control/ThemeToggle.tsx +10 -10
  324. package/src/components/form-control/checkbox/Checkbox.styles.ts +8 -8
  325. package/src/components/form-control/checkbox/Checkbox.tsx +2 -2
  326. package/src/components/form-control/checkbox/CheckboxGroup.tsx +1 -1
  327. package/src/components/form-control/checkbox/Radio.tsx +2 -2
  328. package/src/components/form-control/checkbox/RadioGroup.tsx +1 -1
  329. package/src/components/form-control/color-picker/ColorPicker.tsx +17 -17
  330. package/src/components/form-control/combobox/Combobox.tsx +55 -55
  331. package/src/components/form-control/combobox/ComboboxContext.ts +5 -5
  332. package/src/components/form-control/combobox/ComboboxItem.tsx +3 -3
  333. package/src/components/form-control/date-range-picker/DateRangePicker.tsx +40 -26
  334. package/src/components/form-control/editor/EditorToolbar.tsx +52 -50
  335. package/src/components/form-control/editor/RichTextEditor.tsx +16 -16
  336. package/src/components/form-control/editor/editor.css +5 -5
  337. package/src/components/form-control/field/DatePicker.tsx +39 -39
  338. package/src/components/form-control/field/DateTimePicker.tsx +38 -38
  339. package/src/components/form-control/field/Field.styles.ts +11 -11
  340. package/src/components/form-control/field/FieldPlaceholder.tsx +1 -1
  341. package/src/components/form-control/field/NumberInput.tsx +63 -63
  342. package/src/components/form-control/field/TextInput.tsx +48 -48
  343. package/src/components/form-control/field/Textarea.tsx +32 -32
  344. package/src/components/form-control/field/TimePicker.tsx +37 -37
  345. package/src/components/form-control/numpad/Numpad.tsx +26 -26
  346. package/src/components/form-control/select/Select.tsx +82 -86
  347. package/src/components/form-control/select/SelectContext.ts +8 -8
  348. package/src/components/form-control/select/SelectItem.tsx +5 -5
  349. package/src/components/form-control/state-preset/StatePreset.tsx +13 -13
  350. package/src/components/layout/FormTable.tsx +4 -4
  351. package/src/components/layout/sidebar/Sidebar.tsx +8 -8
  352. package/src/components/layout/sidebar/SidebarContainer.tsx +19 -17
  353. package/src/components/layout/sidebar/SidebarContext.ts +8 -8
  354. package/src/components/layout/sidebar/SidebarMenu.tsx +19 -19
  355. package/src/components/layout/sidebar/SidebarUser.tsx +14 -14
  356. package/src/components/layout/topbar/Topbar.tsx +15 -13
  357. package/src/components/layout/topbar/TopbarContainer.tsx +6 -6
  358. package/src/components/layout/topbar/TopbarContext.ts +2 -2
  359. package/src/components/layout/topbar/TopbarMenu.tsx +18 -16
  360. package/src/components/layout/topbar/TopbarUser.tsx +9 -9
  361. package/src/directives/ripple.ts +8 -8
  362. package/src/helpers/createAppStructure.ts +15 -8
  363. package/src/helpers/createHmrSafeContext.ts +8 -0
  364. package/src/helpers/createSlotComponent.ts +4 -4
  365. package/src/helpers/mergeStyles.ts +11 -11
  366. package/src/hooks/createControllableSignal.ts +11 -11
  367. package/src/hooks/createControllableStore.ts +8 -8
  368. package/src/hooks/createIMEHandler.ts +7 -7
  369. package/src/hooks/createMountTransition.ts +4 -4
  370. package/src/hooks/createSelectionGroup.tsx +5 -3
  371. package/src/hooks/createSlotSignal.ts +2 -2
  372. package/src/hooks/useLocalStorage.ts +13 -13
  373. package/src/hooks/useLogger.ts +2 -2
  374. package/src/hooks/useRouterLink.ts +15 -15
  375. package/src/index.ts +4 -3
  376. package/src/providers/ClipboardProvider.tsx +19 -19
  377. package/src/providers/ConfigContext.tsx +8 -8
  378. package/src/providers/ErrorLoggerProvider.tsx +3 -3
  379. package/src/providers/LoggerContext.tsx +13 -13
  380. package/src/providers/PwaUpdateProvider.tsx +6 -6
  381. package/src/providers/ServiceClientContext.ts +9 -9
  382. package/src/providers/ServiceClientProvider.tsx +15 -15
  383. package/src/providers/SyncStorageContext.tsx +15 -15
  384. package/src/providers/SystemProvider.tsx +15 -12
  385. package/src/providers/ThemeContext.tsx +26 -26
  386. package/src/providers/i18n/I18nContext.tsx +129 -0
  387. package/src/providers/i18n/I18nContext.types.ts +30 -0
  388. package/src/providers/i18n/i18nUtils.ts +38 -0
  389. package/src/providers/i18n/locales/en.ts +161 -0
  390. package/src/providers/i18n/locales/ko.ts +161 -0
  391. package/src/providers/shared-data/SharedDataChangeEvent.ts +4 -4
  392. package/src/providers/shared-data/SharedDataContext.ts +29 -29
  393. package/src/providers/shared-data/SharedDataProvider.tsx +21 -21
  394. package/src/styles/patterns.styles.ts +6 -6
  395. package/src/styles/tokens.styles.ts +5 -5
  396. package/tailwind.config.ts +1 -1
  397. package/tailwind.css +4 -4
  398. package/tests/components/data/List.spec.tsx +689 -0
  399. package/tests/components/data/Pagination.spec.tsx +336 -0
  400. package/tests/components/data/Table.spec.tsx +55 -0
  401. package/tests/components/data/kanban/Kanban.selection.spec.tsx +213 -0
  402. package/tests/components/data/sheet/DataSheet.spec.tsx +645 -0
  403. package/tests/components/disclosure/Collapse.spec.tsx +173 -0
  404. package/tests/components/disclosure/Dialog.spec.tsx +438 -0
  405. package/tests/components/disclosure/DialogProvider.spec.tsx +142 -0
  406. package/tests/components/disclosure/Dropdown.spec.tsx +333 -0
  407. package/tests/components/disclosure/Tabs.spec.tsx +220 -0
  408. package/tests/components/disclosure/dialogZIndex.spec.ts +45 -0
  409. package/tests/components/display/Alert.spec.tsx +47 -0
  410. package/tests/components/display/Barcode.spec.tsx +61 -0
  411. package/tests/components/display/Card.spec.tsx +41 -0
  412. package/tests/components/display/Link.spec.tsx +62 -0
  413. package/tests/components/display/Tag.spec.tsx +47 -0
  414. package/tests/components/features/address/AddressSearch.spec.tsx +45 -0
  415. package/tests/components/features/crud-detail/CrudDetail.spec.tsx +537 -0
  416. package/tests/components/features/crud-sheet/CrudSheet.spec.tsx +491 -0
  417. package/tests/components/features/crudRegistry.spec.ts +119 -0
  418. package/tests/components/features/data-select-button/DataSelectButton.spec.tsx +482 -0
  419. package/tests/components/features/permission-table/PermissionTable.spec.tsx +288 -0
  420. package/tests/components/features/shared-data/SharedDataSelectList.spec.tsx +448 -0
  421. package/tests/components/feedback/busy/BusyContainer.spec.tsx +80 -0
  422. package/tests/components/feedback/notification/LiveRegion.spec.tsx +52 -0
  423. package/tests/components/feedback/notification/NotificationBanner.spec.tsx +187 -0
  424. package/tests/components/feedback/notification/NotificationBell.spec.tsx +226 -0
  425. package/tests/components/feedback/notification/NotificationContext.spec.tsx +362 -0
  426. package/tests/components/feedback/print/Print.spec.tsx +45 -0
  427. package/tests/components/form-control/Button.spec.tsx +119 -0
  428. package/tests/components/form-control/Invalid.spec.tsx +131 -0
  429. package/tests/components/form-control/checkbox/Checkbox.spec.tsx +137 -0
  430. package/tests/components/form-control/checkbox/CheckboxGroup.spec.tsx +108 -0
  431. package/tests/components/form-control/checkbox/Radio.spec.tsx +138 -0
  432. package/tests/components/form-control/checkbox/RadioGroup.spec.tsx +108 -0
  433. package/tests/components/form-control/color-picker/ColorPicker.spec.tsx +94 -0
  434. package/tests/components/form-control/combobox/Combobox.spec.tsx +253 -0
  435. package/tests/components/form-control/combobox/ComboboxItem.spec.tsx +88 -0
  436. package/tests/components/form-control/date-range-picker/DateRangePicker.spec.tsx +208 -0
  437. package/tests/components/form-control/field/DatePicker.spec.tsx +381 -0
  438. package/tests/components/form-control/field/DateTimePicker.spec.tsx +383 -0
  439. package/tests/components/form-control/field/NumberInput.spec.tsx +371 -0
  440. package/tests/components/form-control/field/TextInput.spec.tsx +341 -0
  441. package/tests/components/form-control/field/Textarea.spec.tsx +224 -0
  442. package/tests/components/form-control/field/TimePicker.spec.tsx +315 -0
  443. package/tests/components/form-control/numpad/Numpad.spec.tsx +248 -0
  444. package/tests/components/form-control/select/Select.spec.tsx +676 -0
  445. package/tests/components/form-control/select/SelectItem.spec.tsx +174 -0
  446. package/tests/components/layout/FormGroup.spec.tsx +104 -0
  447. package/tests/components/layout/FormTable.spec.tsx +43 -0
  448. package/tests/components/layout/sidebar/Sidebar.spec.tsx +192 -0
  449. package/tests/components/layout/sidebar/SidebarContainer.spec.tsx +261 -0
  450. package/tests/components/layout/sidebar/SidebarMenu.spec.tsx +219 -0
  451. package/tests/components/layout/sidebar/SidebarUser.spec.tsx +133 -0
  452. package/tests/components/layout/topbar/TopbarActions.spec.tsx +77 -0
  453. package/tests/components/layout/topbar/TopbarContainer.spec.tsx +38 -0
  454. package/tests/components/layout/topbar/createTopbarActions.spec.tsx +66 -0
  455. package/tests/directives/ripple.spec.tsx +130 -0
  456. package/tests/helpers/createAppStructure.spec.tsx +843 -0
  457. package/tests/helpers/mergeStyles.spec.ts +172 -0
  458. package/tests/hooks/createControllableSignal.spec.ts +194 -0
  459. package/tests/hooks/createIMEHandler.spec.ts +80 -0
  460. package/tests/hooks/createMountTransition.spec.ts +86 -0
  461. package/tests/hooks/useLocalStorage.spec.tsx +223 -0
  462. package/tests/hooks/useLogger.spec.tsx +116 -0
  463. package/tests/hooks/usePrint.spec.tsx +134 -0
  464. package/tests/hooks/useRouterLink.spec.tsx +183 -0
  465. package/tests/hooks/useSyncConfig.spec.tsx +304 -0
  466. package/tests/providers/ClipboardProvider.spec.tsx +20 -0
  467. package/tests/providers/ConfigContext.spec.tsx +42 -0
  468. package/tests/providers/ErrorLoggerProvider.spec.tsx +73 -0
  469. package/tests/providers/LoggerContext.spec.tsx +76 -0
  470. package/tests/providers/PwaUpdateProvider.spec.tsx +22 -0
  471. package/tests/providers/ServiceClientContext.spec.tsx +88 -0
  472. package/tests/providers/SyncStorageContext.spec.tsx +77 -0
  473. package/tests/providers/i18n/I18nContext.spec.tsx +110 -0
  474. package/tests/providers/shared-data/SharedDataProvider.spec.tsx +401 -0
  475. package/tests/vitest-env.d.ts +1 -0
  476. package/dist/components/form-control/select-list/SelectList.d.ts +0 -54
  477. package/dist/components/form-control/select-list/SelectList.d.ts.map +0 -1
  478. package/dist/components/form-control/select-list/SelectList.js +0 -280
  479. package/dist/components/form-control/select-list/SelectList.js.map +0 -6
  480. package/dist/components/form-control/select-list/SelectListContext.d.ts +0 -13
  481. package/dist/components/form-control/select-list/SelectListContext.d.ts.map +0 -1
  482. package/dist/components/form-control/select-list/SelectListContext.js +0 -14
  483. package/dist/components/form-control/select-list/SelectListContext.js.map +0 -6
  484. package/docs/data-components.md +0 -782
  485. package/docs/disclosure.md +0 -254
  486. package/docs/display.md +0 -153
  487. package/docs/feedback.md +0 -238
  488. package/docs/form-controls.md +0 -1068
  489. package/docs/helpers.md +0 -54
  490. package/docs/hooks.md +0 -588
  491. package/docs/layout.md +0 -384
  492. package/docs/providers.md +0 -211
  493. package/docs/styling.md +0 -184
  494. package/src/components/form-control/select-list/SelectList.tsx +0 -385
  495. package/src/components/form-control/select-list/SelectListContext.ts +0 -23
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Crud activation registry
3
+ *
4
+ * Tracks mounted CrudDetail/CrudSheet instances and determines which one
5
+ * should respond to keyboard shortcuts (Ctrl+S, Ctrl+Alt+L).
6
+ *
7
+ * Priority rules:
8
+ * 1. If a Dialog is open, only cruds inside the topmost Dialog are candidates.
9
+ * 2. Among candidates, the most recently activated (interacted) crud wins.
10
+ * 3. On mount, cruds are auto-activated (last mounted = active).
11
+ */
12
+
13
+ import { getTopmostDialog } from "../disclosure/dialogZIndex";
14
+
15
+ interface CrudEntry {
16
+ id: string;
17
+ formEl: HTMLFormElement;
18
+ lastActivatedAt: number;
19
+ }
20
+
21
+ const entries: CrudEntry[] = [];
22
+ let _counter = 0;
23
+
24
+ export function registerCrud(id: string, formEl: HTMLFormElement): void {
25
+ const existing = entries.find((e) => e.id === id);
26
+ if (existing) return;
27
+ entries.push({ id, formEl, lastActivatedAt: ++_counter });
28
+ }
29
+
30
+ export function unregisterCrud(id: string): void {
31
+ const idx = entries.findIndex((e) => e.id === id);
32
+ if (idx >= 0) entries.splice(idx, 1);
33
+ }
34
+
35
+ export function activateCrud(id: string): void {
36
+ const entry = entries.find((e) => e.id === id);
37
+ if (entry) entry.lastActivatedAt = ++_counter;
38
+ }
39
+
40
+ export function isActiveCrud(id: string): boolean {
41
+ const entry = entries.find((e) => e.id === id);
42
+ if (!entry) return false;
43
+
44
+ const topDialog = getTopmostDialog();
45
+
46
+ const candidates = topDialog
47
+ ? entries.filter((e) => topDialog.contains(e.formEl))
48
+ : entries;
49
+
50
+ if (candidates.length === 0) return false;
51
+
52
+ let best = candidates[0];
53
+ for (let i = 1; i < candidates.length; i++) {
54
+ if (candidates[i].lastActivatedAt > best.lastActivatedAt) {
55
+ best = candidates[i];
56
+ }
57
+ }
58
+
59
+ return best.id === id;
60
+ }
@@ -15,6 +15,7 @@ import { IconSearch, IconX } from "@tabler/icons-solidjs";
15
15
  import { Icon } from "../../display/Icon";
16
16
  import { Invalid } from "../../form-control/Invalid";
17
17
  import { useDialog, type DialogShowOptions } from "../../disclosure/DialogContext";
18
+ import { useI18nOptional } from "../../../providers/i18n/I18nContext";
18
19
  import { createControllableSignal } from "../../../hooks/createControllableSignal";
19
20
  import { type ComponentSize, textMuted } from "../../../styles/tokens.styles";
20
21
  import {
@@ -24,46 +25,46 @@ import {
24
25
  triggerSizeClasses,
25
26
  } from "../../form-control/DropdownTrigger.styles";
26
27
 
27
- /** 모달에서 반환하는 결과 인터페이스 */
28
+ /** Result interface returned from modal */
28
29
  export interface DataSelectModalResult<TKey> {
29
30
  selectedKeys: TKey[];
30
31
  }
31
32
 
32
33
  /** DataSelectButton Props */
33
34
  export interface DataSelectButtonProps<TItem, TKey = string | number> {
34
- /** 현재 선택된 (단일 또는 다중) */
35
+ /** Currently selected key(s) (single or multiple) */
35
36
  value?: TKey | TKey[];
36
- /** 변경 콜백 */
37
+ /** Value change callback */
37
38
  onValueChange?: (value: TKey | TKey[] | undefined) => void;
38
39
 
39
- /** 키로 아이템을 로드하는 함수 */
40
+ /** Function to load items by key */
40
41
  load: (keys: TKey[]) => TItem[] | Promise<TItem[]>;
41
- /** 선택 모달 컴포넌트 팩토리 */
42
+ /** Selection modal component factory */
42
43
  modal: () => JSX.Element;
43
- /** 아이템 렌더링 함수 */
44
+ /** Item rendering function */
44
45
  renderItem: (item: TItem) => JSX.Element;
45
46
 
46
- /** 다중 선택 모드 */
47
+ /** Multiple selection mode */
47
48
  multiple?: boolean;
48
- /** 필수 입력 */
49
+ /** Required input */
49
50
  required?: boolean;
50
- /** 비활성화 */
51
+ /** Disabled */
51
52
  disabled?: boolean;
52
- /** 트리거 크기 */
53
+ /** Trigger size */
53
54
  size?: ComponentSize;
54
- /** 테두리 없는 스타일 */
55
+ /** Borderless style */
55
56
  inset?: boolean;
56
57
 
57
- /** 커스텀 유효성 검사 함수 */
58
+ /** Custom validation function */
58
59
  validate?: (value: unknown) => string | undefined;
59
- /** touchMode: 포커스 해제 후에만 에러 표시 */
60
+ /** touchMode: show error only after focus is lost */
60
61
  touchMode?: boolean;
61
62
 
62
- /** 다이얼로그 옵션 */
63
+ /** Dialog options */
63
64
  dialogOptions?: DialogShowOptions;
64
65
  }
65
66
 
66
- // 스타일
67
+ // Styles
67
68
  const containerClass = clsx("inline-flex items-center", "group");
68
69
  const selectedValueClass = clsx("flex-1", "whitespace-nowrap", "overflow-hidden", "text-ellipsis");
69
70
  const actionButtonClass = clsx(
@@ -111,27 +112,28 @@ export function DataSelectButton<TItem, TKey = string | number>(
111
112
  "dialogOptions",
112
113
  ]);
113
114
 
115
+ const i18n = useI18nOptional();
114
116
  const dialog = useDialog();
115
117
 
116
- // value 항상 배열로 정규화
118
+ // Always normalize value to array
117
119
  const normalizeKeys = (value: TKey | TKey[] | undefined): TKey[] => {
118
120
  if (value === undefined || value === null) return [];
119
121
  if (Array.isArray(value)) return value;
120
122
  return [value];
121
123
  };
122
124
 
123
- // controlled/uncontrolled 패턴
125
+ // Controlled/uncontrolled pattern
124
126
  type ValueType = TKey | TKey[] | undefined;
125
127
  const [getValue, setValue] = createControllableSignal<ValueType>({
126
128
  value: () => local.value,
127
129
  onChange: () => local.onValueChange as ((v: ValueType) => void) | undefined,
128
130
  } as Parameters<typeof createControllableSignal<ValueType>>[0]);
129
131
 
130
- // load를 위한 추적 signal
131
- // eslint-disable-next-line solid/reactivity -- 초기값은 mount 시점에 번만 읽음
132
+ // Track keys for loading
133
+ // eslint-disable-next-line solid/reactivity -- initial value read once at mount time
132
134
  const [loadKeys, setLoadKeys] = createSignal<TKey[]>(normalizeKeys(local.value));
133
135
 
134
- // value가 변경되면 loadKeys 업데이트
136
+ // Update loadKeys when value changes
135
137
  createEffect(
136
138
  on(
137
139
  () => getValue(),
@@ -141,33 +143,33 @@ export function DataSelectButton<TItem, TKey = string | number>(
141
143
  ),
142
144
  );
143
145
 
144
- // createResource로 load 호출
145
- // eslint-disable-next-line solid/reactivity -- createResource fetcher source 변경 호출됨
146
+ // Call load via createResource
147
+ // eslint-disable-next-line solid/reactivity -- createResource fetcher is called when source changes
146
148
  const [selectedItems] = createResource(loadKeys, async (keys) => {
147
149
  if (keys.length === 0) return [];
148
150
  return Promise.resolve(local.load(keys));
149
151
  });
150
152
 
151
- // 값이 있는지 확인
153
+ // Check if has value
152
154
  const hasValue = createMemo(() => {
153
155
  const keys = normalizeKeys(getValue());
154
156
  return keys.length > 0;
155
157
  });
156
158
 
157
- // 지우기 가능 여부
159
+ // Check if clearable
158
160
  const clearable = createMemo(() => !local.required && hasValue() && !local.disabled);
159
161
 
160
- // 유효성 검사
162
+ // Validation
161
163
  const errorMsg = createMemo(() => {
162
164
  const v = getValue();
163
165
  if (local.required) {
164
166
  const keys = normalizeKeys(v);
165
- if (keys.length === 0) return "필수 입력 항목입니다";
167
+ if (keys.length === 0) return "Required field";
166
168
  }
167
169
  return local.validate?.(v);
168
170
  });
169
171
 
170
- // 모달 열기
172
+ // Open modal
171
173
  const handleOpenModal = async () => {
172
174
  if (local.disabled) return;
173
175
 
@@ -186,7 +188,7 @@ export function DataSelectButton<TItem, TKey = string | number>(
186
188
  }
187
189
  };
188
190
 
189
- // 지우기
191
+ // Clear selection
190
192
  const handleClear = (e: MouseEvent) => {
191
193
  e.stopPropagation();
192
194
  if (local.multiple) {
@@ -196,7 +198,7 @@ export function DataSelectButton<TItem, TKey = string | number>(
196
198
  }
197
199
  };
198
200
 
199
- // 선택된 표시
201
+ // Render selected value display
200
202
  const renderSelectedDisplay = (): JSX.Element => {
201
203
  const items = selectedItems();
202
204
  if (!items || items.length === 0) {
@@ -218,7 +220,7 @@ export function DataSelectButton<TItem, TKey = string | number>(
218
220
  );
219
221
  };
220
222
 
221
- // 트리거 클래스 계산
223
+ // Calculate trigger class
222
224
  const triggerClassName = () =>
223
225
  getTriggerContainerClass({
224
226
  size: local.size,
@@ -254,7 +256,7 @@ export function DataSelectButton<TItem, TKey = string | number>(
254
256
  class={twMerge(actionButtonClass, "text-base-400 hover:text-danger-500")}
255
257
  onClick={handleClear}
256
258
  tabIndex={-1}
257
- aria-label="선택 해제"
259
+ aria-label={i18n?.t("dataSelectButton.deselect") ?? "Deselect"}
258
260
  >
259
261
  <Icon icon={IconX} size="0.875em" />
260
262
  </button>
@@ -266,7 +268,7 @@ export function DataSelectButton<TItem, TKey = string | number>(
266
268
  class={twMerge(actionButtonClass, "text-base-400 hover:text-primary-500")}
267
269
  onClick={() => void handleOpenModal()}
268
270
  tabIndex={-1}
269
- aria-label="검색"
271
+ aria-label={i18n?.t("dataSelectButton.search") ?? "Search"}
270
272
  >
271
273
  <Icon icon={IconSearch} size="0.875em" />
272
274
  </button>
@@ -10,17 +10,17 @@ import {
10
10
  splitProps,
11
11
  } from "solid-js";
12
12
  import clsx from "clsx";
13
- import { twMerge } from "tailwind-merge";
14
13
  import { DataSheet } from "../../data/sheet/DataSheet";
15
14
  import { Checkbox } from "../../form-control/checkbox/Checkbox";
16
15
  import { borderDefault } from "../../../styles/tokens.styles";
17
16
  import type { AppPerm } from "../../../helpers/createAppStructure";
17
+ import { useI18nOptional } from "../../../providers/i18n/I18nContext";
18
18
 
19
19
  const titleCellClass = clsx("flex items-stretch", "px-2");
20
20
  const indentGuideWrapperClass = clsx("mr-1 flex w-3", "justify-center");
21
21
  const indentGuideLineClass = clsx("w-0 self-stretch", "border-r", borderDefault);
22
22
 
23
- // --- 타입 ---
23
+ // --- Types ---
24
24
 
25
25
  export interface PermissionTableProps<TModule = string> {
26
26
  items?: AppPerm<TModule>[];
@@ -32,9 +32,9 @@ export interface PermissionTableProps<TModule = string> {
32
32
  style?: JSX.CSSProperties;
33
33
  }
34
34
 
35
- // --- 유틸리티 (테스트에서도 사용) ---
35
+ // --- Utilities (also used in tests) ---
36
36
 
37
- /** 트리에서 모든 고유 perm 타입을 수집 */
37
+ /** Collect all unique perm types from the tree */
38
38
  export function collectAllPerms<TModule>(items: AppPerm<TModule>[]): string[] {
39
39
  const set = new Set<string>();
40
40
  const walk = (list: AppPerm<TModule>[]) => {
@@ -49,7 +49,7 @@ export function collectAllPerms<TModule>(items: AppPerm<TModule>[]): string[] {
49
49
  return [...set];
50
50
  }
51
51
 
52
- /** modules 필터: 활성 모듈과 교차가 있는 아이템만 남김 */
52
+ /** Filter by modules: keep only items that have intersection with active modules */
53
53
  export function filterByModules<TModule>(
54
54
  items: AppPerm<TModule>[],
55
55
  modules: TModule[] | undefined,
@@ -72,7 +72,7 @@ export function filterByModules<TModule>(
72
72
  return result;
73
73
  }
74
74
 
75
- /** 체크 변경 cascading 처리 */
75
+ /** Handle cascading when checkbox changes */
76
76
  export function changePermCheck<TModule>(
77
77
  value: Record<string, boolean>,
78
78
  item: AppPerm<TModule>,
@@ -112,9 +112,9 @@ export function changePermCheck<TModule>(
112
112
  return result;
113
113
  }
114
114
 
115
- // --- 내부 헬퍼 ---
115
+ // --- Internal Helpers ---
116
116
 
117
- /** 모듈 필터에 의해 보이는지 확인 (객체 참조 유지) */
117
+ /** Check if item is visible by module filter (preserve object reference) */
118
118
  function isItemVisible<TModule>(item: AppPerm<TModule>, modules: TModule[] | undefined): boolean {
119
119
  if (!modules || modules.length === 0) return true;
120
120
  if (item.modules && !item.modules.some((m) => modules.includes(m))) return false;
@@ -124,7 +124,7 @@ function isItemVisible<TModule>(item: AppPerm<TModule>, modules: TModule[] | und
124
124
  return true;
125
125
  }
126
126
 
127
- /** 보이는 아이템에서만 고유 perm 타입 수집 */
127
+ /** Collect unique perm types from visible items only */
128
128
  function collectVisiblePerms<TModule>(
129
129
  items: AppPerm<TModule>[],
130
130
  modules: TModule[] | undefined,
@@ -145,7 +145,7 @@ function collectVisiblePerms<TModule>(
145
145
  return [...set];
146
146
  }
147
147
 
148
- /** 그룹 노드의 체크 상태: 하위 하나라도 체크면 true */
148
+ /** Get check state of group node: true if any child is checked */
149
149
  function isGroupPermChecked<TModule>(
150
150
  item: AppPerm<TModule>,
151
151
  perm: string,
@@ -160,7 +160,7 @@ function isGroupPermChecked<TModule>(
160
160
  return false;
161
161
  }
162
162
 
163
- /** 하위에 특정 perm 하나라도 있으면 true */
163
+ /** Check if specific perm exists in subtree */
164
164
  function hasPermInTree<TModule>(item: AppPerm<TModule>, perm: string): boolean {
165
165
  if (item.perms?.includes(perm)) return true;
166
166
  if (item.children) {
@@ -169,7 +169,7 @@ function hasPermInTree<TModule>(item: AppPerm<TModule>, perm: string): boolean {
169
169
  return false;
170
170
  }
171
171
 
172
- /** 기본 권한(perms[0])이 꺼져 있어서 비활성화해야 하는지 */
172
+ /** Check if perm should be disabled (base perm is off) */
173
173
  function isPermDisabled<TModule>(
174
174
  item: AppPerm<TModule>,
175
175
  perm: string,
@@ -181,7 +181,7 @@ function isPermDisabled<TModule>(
181
181
  return !(value[item.href + "/" + basePerm] ?? false);
182
182
  }
183
183
 
184
- /** 확장 가능한 모든 아이템 수집 (객체 참조 유지) */
184
+ /** Collect all expandable items (preserve object reference) */
185
185
  function collectExpandable<TModule>(
186
186
  items: AppPerm<TModule>[],
187
187
  getChildren: (item: AppPerm<TModule>) => AppPerm<TModule>[] | undefined,
@@ -202,7 +202,7 @@ function collectExpandable<TModule>(
202
202
  return result;
203
203
  }
204
204
 
205
- // --- 컴포넌트 ---
205
+ // --- Component ---
206
206
 
207
207
  export const PermissionTable: Component<PermissionTableProps> = (props) => {
208
208
  const [local] = splitProps(props, [
@@ -215,14 +215,16 @@ export const PermissionTable: Component<PermissionTableProps> = (props) => {
215
215
  "style",
216
216
  ]);
217
217
 
218
- // 보이는 최상위 아이템 (객체 참조 유지)
218
+ const i18n = useI18nOptional();
219
+
220
+ // Visible top-level items (preserve object reference)
219
221
  const visibleItems = createMemo(() => {
220
222
  const items = local.items ?? [];
221
223
  if (!local.modules || local.modules.length === 0) return items;
222
224
  return items.filter((item) => isItemVisible(item, local.modules));
223
225
  });
224
226
 
225
- // Sheet getChildren — 모듈 필터 적용, 객체 참조 유지
227
+ // Sheet's getChildren — apply module filter, preserve object reference
226
228
  const getChildren = (item: AppPerm): AppPerm[] | undefined => {
227
229
  if (!item.children || item.children.length === 0) return undefined;
228
230
  const modules = local.modules;
@@ -231,17 +233,17 @@ export const PermissionTable: Component<PermissionTableProps> = (props) => {
231
233
  return filtered.length > 0 ? filtered : undefined;
232
234
  };
233
235
 
234
- // 보이는 아이템의 모든 고유 perm 타입
236
+ // All unique perm types from visible items
235
237
  const allPerms = createMemo(() => collectVisiblePerms(local.items ?? [], local.modules));
236
238
 
237
239
  const currentValue = createMemo(() => local.value ?? {});
238
240
 
239
- // 확장 상태기본적으로 모두 펼침
241
+ // Expanded stateall expanded by default
240
242
  const getAllExpandable = () => collectExpandable(visibleItems(), getChildren);
241
243
 
242
244
  const [expandedItems, setExpandedItems] = createSignal<AppPerm[]>(getAllExpandable());
243
245
 
244
- // 트리 구조 변경 모두 다시 펼침 (모듈 필터 변경 )
246
+ // Re-expand all when tree structure changes (e.g., module filter changed)
245
247
  createEffect(
246
248
  on(
247
249
  visibleItems,
@@ -258,51 +260,55 @@ export const PermissionTable: Component<PermissionTableProps> = (props) => {
258
260
  };
259
261
 
260
262
  return (
261
- <div data-permission-table class={twMerge(local.class)} style={local.style}>
262
- <DataSheet
263
- items={visibleItems()}
264
- getChildren={getChildren}
265
- expandedItems={expandedItems()}
266
- onExpandedItemsChange={setExpandedItems}
267
- hideConfigBar
263
+ <DataSheet
264
+ data-permission-table
265
+ items={visibleItems()}
266
+ getChildren={getChildren}
267
+ expandedItems={expandedItems()}
268
+ onExpandedItemsChange={setExpandedItems}
269
+ hideConfigBar
270
+ >
271
+ <DataSheet.Column
272
+ key="title"
273
+ header={i18n?.t("permissionTable.permissionItem") ?? "Permission Item"}
274
+ sortable={false}
275
+ resizable={false}
268
276
  >
269
- <DataSheet.Column key="title" header="권한 항목" sortable={false} resizable={false}>
270
- {(ctx) => {
271
- const item = ctx.item as AppPerm;
272
- return (
273
- <div class={titleCellClass}>
274
- <For each={Array.from({ length: ctx.depth })}>
275
- {() => (
276
- <div class={indentGuideWrapperClass}>
277
- <div class={indentGuideLineClass} />
278
- </div>
279
- )}
280
- </For>
281
- <span class="py-1">{item.title}</span>
282
- </div>
283
- );
284
- }}
285
- </DataSheet.Column>
286
- <For each={allPerms()}>
287
- {(perm) => (
288
- <DataSheet.Column key={`perm-${perm}`} header={perm} sortable={false} resizable={false}>
289
- {(ctx) => {
290
- const item = ctx.item as AppPerm;
291
- return (
292
- <Show when={hasPermInTree(item, perm)}>
293
- <Checkbox
294
- value={isGroupPermChecked(item, perm, currentValue())}
295
- onValueChange={(checked) => handlePermChange(item, perm, checked)}
296
- disabled={local.disabled || isPermDisabled(item, perm, currentValue())}
297
- inset
298
- />
299
- </Show>
300
- );
301
- }}
302
- </DataSheet.Column>
303
- )}
304
- </For>
305
- </DataSheet>
306
- </div>
277
+ {(ctx) => {
278
+ const item = ctx.item as AppPerm;
279
+ return (
280
+ <div class={titleCellClass}>
281
+ <For each={Array.from({ length: ctx.depth })}>
282
+ {() => (
283
+ <div class={indentGuideWrapperClass}>
284
+ <div class={indentGuideLineClass} />
285
+ </div>
286
+ )}
287
+ </For>
288
+ <span class="py-1">{item.title}</span>
289
+ </div>
290
+ );
291
+ }}
292
+ </DataSheet.Column>
293
+ <For each={allPerms()}>
294
+ {(perm) => (
295
+ <DataSheet.Column key={`perm-${perm}`} header={perm} sortable={false} resizable={false}>
296
+ {(ctx) => {
297
+ const item = ctx.item as AppPerm;
298
+ return (
299
+ <Show when={hasPermInTree(item, perm)}>
300
+ <Checkbox
301
+ value={isGroupPermChecked(item, perm, currentValue())}
302
+ onValueChange={(checked) => handlePermChange(item, perm, checked)}
303
+ disabled={local.disabled || isPermDisabled(item, perm, currentValue())}
304
+ inset
305
+ />
306
+ </Show>
307
+ );
308
+ }}
309
+ </DataSheet.Column>
310
+ )}
311
+ </For>
312
+ </DataSheet>
307
313
  );
308
314
  };
@@ -4,72 +4,74 @@ import { type SharedDataAccessor } from "../../../providers/shared-data/SharedDa
4
4
  import { Select, type SelectProps } from "../../form-control/select/Select";
5
5
  import { Icon } from "../../display/Icon";
6
6
  import { useDialog } from "../../disclosure/DialogContext";
7
+ import { useI18nOptional } from "../../../providers/i18n/I18nContext";
7
8
  import { type ComponentSize } from "../../../styles/tokens.styles";
8
9
 
9
10
  /** SharedDataSelect Props */
10
11
  export interface SharedDataSelectProps<TItem> {
11
- /** 공유 데이터 접근자 */
12
+ /** Shared data accessor */
12
13
  data: SharedDataAccessor<TItem>;
13
14
 
14
- /** 현재 선택된 */
15
+ /** Currently selected value */
15
16
  value?: unknown;
16
- /** 변경 콜백 */
17
+ /** Value change callback */
17
18
  onValueChange?: (value: unknown) => void;
18
- /** 다중 선택 모드 */
19
+ /** Multiple selection mode */
19
20
  multiple?: boolean;
20
- /** 필수 입력 */
21
+ /** Required input */
21
22
  required?: boolean;
22
- /** 비활성화 */
23
+ /** Disabled */
23
24
  disabled?: boolean;
24
- /** 트리거 크기 */
25
+ /** Trigger size */
25
26
  size?: ComponentSize;
26
- /** 테두리 없는 스타일 */
27
+ /** Borderless style */
27
28
  inset?: boolean;
28
29
 
29
- /** 항목 필터 함수 */
30
+ /** Item filter function */
30
31
  filterFn?: (item: TItem, index: number) => boolean;
31
- /** 선택 모달 컴포넌트 팩토리 */
32
+ /** Selection modal component factory */
32
33
  modal?: () => JSX.Element;
33
- /** 편집 모달 컴포넌트 팩토리 */
34
+ /** Edit modal component factory */
34
35
  editModal?: () => JSX.Element;
35
36
 
36
- /** 아이템 렌더링 함수 */
37
+ /** Item rendering function */
37
38
  children: (item: TItem, index: number, depth: number) => JSX.Element;
38
39
  }
39
40
 
40
41
  export function SharedDataSelect<TItem>(props: SharedDataSelectProps<TItem>): JSX.Element {
41
42
  const [local, rest] = splitProps(props, ["data", "filterFn", "modal", "editModal", "children"]);
42
43
 
44
+ const i18n = useI18nOptional();
43
45
  const dialog = useDialog();
44
46
 
45
- // filterFn 적용된 items
47
+ // Items with filterFn applied
46
48
  const items = createMemo(() => {
47
49
  const allItems = local.data.items();
48
50
  if (!local.filterFn) return allItems;
49
51
  return allItems.filter(local.filterFn);
50
52
  });
51
53
 
52
- // modal 열기
54
+ // Open modal
53
55
  const handleOpenModal = async () => {
54
56
  if (!local.modal) return;
55
57
  await dialog.show(local.modal, {});
56
58
  };
57
59
 
58
- // editModal 열기
60
+ // Open edit modal
59
61
  const handleOpenEditModal = async () => {
60
62
  if (!local.editModal) return;
61
63
  await dialog.show(local.editModal, {});
62
64
  };
63
65
 
64
- // Select discriminated union (multiple: true | false?) TItem → unknown 변환을 위해 mergeProps + as 사용
65
- // getter 래핑하여 SolidJS 반응성 lint 규칙 충족
66
+ // Use mergeProps + as for Select's discriminated union (multiple: true | false?) and TItem → unknown conversion
67
+ // Wrap with getter to satisfy SolidJS reactivity lint rules
66
68
  const selectProps = mergeProps(rest, {
67
69
  get items() {
68
70
  return items();
69
71
  },
70
72
  get getChildren() {
71
73
  if (!local.data.getParentKey) return undefined;
72
- // eslint-disable-next-line solid/reactivity -- 반환 함수는 Select 내부 JSX tracked scope에서 호출됨
74
+ // eslint-disable-next-line solid/reactivity -- return function is called within Select's internal JSX tracked scope
73
75
  return (item: TItem) => {
74
76
  const key = local.data.getKey(item);
75
77
  return items().filter((child) => local.data.getParentKey!(child) === key);
@@ -87,13 +89,13 @@ export function SharedDataSelect<TItem>(props: SharedDataSelectProps<TItem>): JS
87
89
  <Select {...selectProps}>
88
90
  <Select.ItemTemplate>{local.children}</Select.ItemTemplate>
89
91
  {local.modal && (
90
- <Select.Action onClick={() => void handleOpenModal()} aria-label="검색">
91
- <Icon icon={IconSearch} size="1em" />
92
+ <Select.Action onClick={() => void handleOpenModal()} aria-label={i18n?.t("sharedDataSelect.search") ?? "Search"}>
93
+ <Icon icon={IconSearch} />
92
94
  </Select.Action>
93
95
  )}
94
96
  {local.editModal && (
95
- <Select.Action onClick={() => void handleOpenEditModal()} aria-label="편집">
96
- <Icon icon={IconEdit} size="1em" />
97
+ <Select.Action onClick={() => void handleOpenEditModal()} aria-label={i18n?.t("sharedDataSelect.edit") ?? "Edit"}>
98
+ <Icon icon={IconEdit} />
97
99
  </Select.Action>
98
100
  )}
99
101
  </Select>
@@ -8,27 +8,27 @@ import { type ComponentSize } from "../../../styles/tokens.styles";
8
8
 
9
9
  /** SharedDataSelectButton Props */
10
10
  export interface SharedDataSelectButtonProps<TItem> {
11
- /** 공유 데이터 접근자 */
11
+ /** Shared data accessor */
12
12
  data: SharedDataAccessor<TItem>;
13
13
 
14
- /** 현재 선택된 (단일 또는 다중) */
14
+ /** Currently selected key(s) (single or multiple) */
15
15
  value?: DataSelectButtonProps<TItem>["value"];
16
- /** 변경 콜백 */
16
+ /** Value change callback */
17
17
  onValueChange?: DataSelectButtonProps<TItem>["onValueChange"];
18
- /** 다중 선택 모드 */
18
+ /** Multiple selection mode */
19
19
  multiple?: boolean;
20
- /** 필수 입력 */
20
+ /** Required input */
21
21
  required?: boolean;
22
- /** 비활성화 */
22
+ /** Disabled */
23
23
  disabled?: boolean;
24
- /** 트리거 크기 */
24
+ /** Trigger size */
25
25
  size?: ComponentSize;
26
- /** 테두리 없는 스타일 */
26
+ /** Borderless style */
27
27
  inset?: boolean;
28
28
 
29
- /** 선택 모달 컴포넌트 팩토리 */
29
+ /** Selection modal component factory */
30
30
  modal: () => JSX.Element;
31
- /** 아이템 렌더링 함수 */
31
+ /** Item rendering function */
32
32
  children: (item: TItem) => JSX.Element;
33
33
  }
34
34