@simplysm/solid 13.0.69 → 13.0.70
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.
- package/README.md +168 -195
- package/dist/components/data/calendar/Calendar.d.ts.map +1 -1
- package/dist/components/data/calendar/Calendar.js +15 -2
- package/dist/components/data/calendar/Calendar.js.map +2 -2
- package/dist/components/data/kanban/KanbanContext.js +2 -2
- package/dist/components/data/kanban/KanbanContext.js.map +1 -1
- package/dist/components/data/list/List.d.ts +8 -8
- package/dist/components/data/list/ListContext.d.ts +1 -1
- package/dist/components/data/list/ListItem.d.ts +15 -15
- package/dist/components/data/sheet/DataSheet.d.ts.map +1 -1
- package/dist/components/data/sheet/DataSheet.js +6 -4
- package/dist/components/data/sheet/DataSheet.js.map +2 -2
- package/dist/components/data/sheet/DataSheetConfigDialog.js +8 -8
- package/dist/components/data/sheet/DataSheetConfigDialog.js.map +1 -1
- package/dist/components/data/sheet/types.d.ts +4 -4
- package/dist/components/data/sheet/types.d.ts.map +1 -1
- package/dist/components/disclosure/Collapse.d.ts +4 -4
- package/dist/components/disclosure/Dialog.d.ts +24 -24
- package/dist/components/disclosure/Dialog.d.ts.map +1 -1
- package/dist/components/disclosure/Dialog.js +7 -2
- package/dist/components/disclosure/Dialog.js.map +2 -2
- package/dist/components/disclosure/DialogContext.d.ts +25 -25
- package/dist/components/disclosure/DialogContext.d.ts.map +1 -1
- package/dist/components/disclosure/DialogContext.js +1 -1
- package/dist/components/disclosure/DialogContext.js.map +1 -1
- package/dist/components/disclosure/DialogInstanceContext.d.ts +7 -7
- package/dist/components/disclosure/DialogInstanceContext.d.ts.map +1 -1
- package/dist/components/disclosure/DialogProvider.d.ts +3 -3
- package/dist/components/disclosure/Dropdown.d.ts +24 -24
- package/dist/components/disclosure/Tabs.js +1 -1
- package/dist/components/disclosure/Tabs.js.map +1 -1
- package/dist/components/disclosure/dialogZIndex.d.ts +7 -7
- package/dist/components/disclosure/dialogZIndex.d.ts.map +1 -1
- package/dist/components/features/crud-detail/CrudDetail.d.ts.map +1 -1
- package/dist/components/features/crud-detail/CrudDetail.js +19 -16
- package/dist/components/features/crud-detail/CrudDetail.js.map +2 -2
- package/dist/components/features/crud-sheet/CrudSheet.d.ts.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheet.js +34 -28
- package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
- package/dist/components/features/data-select-button/DataSelectButton.d.ts +14 -14
- package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -1
- package/dist/components/features/data-select-button/DataSelectButton.js +27 -9
- package/dist/components/features/data-select-button/DataSelectButton.js.map +2 -2
- package/dist/components/features/permission-table/PermissionTable.d.ts +3 -3
- package/dist/components/features/permission-table/PermissionTable.d.ts.map +1 -1
- package/dist/components/features/permission-table/PermissionTable.js +6 -2
- package/dist/components/features/permission-table/PermissionTable.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelect.d.ts +12 -12
- package/dist/components/features/shared-data/SharedDataSelect.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelect.js +8 -2
- package/dist/components/features/shared-data/SharedDataSelect.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelectButton.d.ts +10 -10
- package/dist/components/features/shared-data/SharedDataSelectButton.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelectList.d.ts +23 -13
- package/dist/components/features/shared-data/SharedDataSelectList.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelectList.js +219 -58
- package/dist/components/features/shared-data/SharedDataSelectList.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelectListContext.d.ts +15 -0
- package/dist/components/features/shared-data/SharedDataSelectListContext.d.ts.map +1 -0
- package/dist/components/features/shared-data/SharedDataSelectListContext.js +27 -0
- package/dist/components/features/shared-data/SharedDataSelectListContext.js.map +6 -0
- package/dist/components/feedback/Progress.d.ts +1 -1
- package/dist/components/feedback/Progress.d.ts.map +1 -1
- package/dist/components/feedback/busy/BusyContainer.d.ts +2 -2
- package/dist/components/feedback/busy/BusyContainer.d.ts.map +1 -1
- package/dist/components/feedback/busy/BusyContext.d.ts +11 -11
- package/dist/components/feedback/busy/BusyContext.d.ts.map +1 -1
- package/dist/components/feedback/busy/BusyContext.js +1 -1
- package/dist/components/feedback/busy/BusyContext.js.map +1 -1
- package/dist/components/feedback/busy/BusyProvider.d.ts +6 -6
- package/dist/components/feedback/busy/BusyProvider.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationBanner.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationBanner.js +7 -3
- package/dist/components/feedback/notification/NotificationBanner.js.map +2 -2
- package/dist/components/feedback/notification/NotificationBell.js +2 -2
- package/dist/components/feedback/notification/NotificationBell.js.map +1 -1
- package/dist/components/feedback/notification/NotificationContext.d.ts +22 -22
- package/dist/components/feedback/notification/NotificationContext.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationContext.js +1 -1
- package/dist/components/feedback/notification/NotificationContext.js.map +1 -1
- package/dist/components/feedback/notification/NotificationProvider.d.ts +5 -5
- package/dist/components/feedback/notification/NotificationProvider.js +1 -1
- package/dist/components/feedback/notification/NotificationProvider.js.map +1 -1
- package/dist/components/feedback/print/PrintContext.js +1 -1
- package/dist/components/feedback/print/PrintContext.js.map +1 -1
- package/dist/components/form-control/DropdownTrigger.styles.d.ts +1 -1
- package/dist/components/form-control/DropdownTrigger.styles.d.ts.map +1 -1
- package/dist/components/form-control/ThemeToggle.d.ts +7 -7
- package/dist/components/form-control/ThemeToggle.d.ts.map +1 -1
- package/dist/components/form-control/ThemeToggle.js +3 -3
- package/dist/components/form-control/checkbox/Checkbox.js +1 -1
- package/dist/components/form-control/checkbox/CheckboxGroup.js +1 -1
- package/dist/components/form-control/checkbox/Radio.js +1 -1
- package/dist/components/form-control/checkbox/RadioGroup.js +1 -1
- package/dist/components/form-control/color-picker/ColorPicker.d.ts +12 -12
- package/dist/components/form-control/color-picker/ColorPicker.d.ts.map +1 -1
- package/dist/components/form-control/color-picker/ColorPicker.js +2 -2
- package/dist/components/form-control/combobox/Combobox.d.ts +22 -22
- package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/form-control/combobox/Combobox.js +2 -2
- package/dist/components/form-control/combobox/ComboboxContext.d.ts +4 -4
- package/dist/components/form-control/combobox/ComboboxContext.d.ts.map +1 -1
- package/dist/components/form-control/combobox/ComboboxContext.js +1 -1
- package/dist/components/form-control/combobox/ComboboxContext.js.map +1 -1
- package/dist/components/form-control/combobox/ComboboxItem.d.ts +3 -3
- package/dist/components/form-control/combobox/ComboboxItem.d.ts.map +1 -1
- package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts +14 -14
- package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts.map +1 -1
- package/dist/components/form-control/date-range-picker/DateRangePicker.js +20 -9
- package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
- package/dist/components/form-control/editor/EditorToolbar.d.ts.map +1 -1
- package/dist/components/form-control/editor/EditorToolbar.js +65 -20
- package/dist/components/form-control/editor/EditorToolbar.js.map +2 -2
- package/dist/components/form-control/editor/RichTextEditor.d.ts +6 -6
- package/dist/components/form-control/editor/RichTextEditor.d.ts.map +1 -1
- package/dist/components/form-control/editor/RichTextEditor.js +1 -1
- package/dist/components/form-control/editor/editor.css +5 -5
- package/dist/components/form-control/field/DatePicker.d.ts +22 -22
- package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DatePicker.js +4 -4
- package/dist/components/form-control/field/DatePicker.js.map +1 -1
- package/dist/components/form-control/field/DateTimePicker.d.ts +21 -21
- package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DateTimePicker.js +4 -4
- package/dist/components/form-control/field/DateTimePicker.js.map +1 -1
- package/dist/components/form-control/field/FieldPlaceholder.d.ts +1 -1
- package/dist/components/form-control/field/FieldPlaceholder.d.ts.map +1 -1
- package/dist/components/form-control/field/NumberInput.d.ts +23 -23
- package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
- package/dist/components/form-control/field/NumberInput.js +4 -4
- package/dist/components/form-control/field/NumberInput.js.map +1 -1
- package/dist/components/form-control/field/TextInput.d.ts +25 -25
- package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
- package/dist/components/form-control/field/TextInput.js +5 -5
- package/dist/components/form-control/field/TextInput.js.map +1 -1
- package/dist/components/form-control/field/Textarea.d.ts +19 -19
- package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
- package/dist/components/form-control/field/Textarea.js +4 -4
- package/dist/components/form-control/field/Textarea.js.map +1 -1
- package/dist/components/form-control/field/TimePicker.d.ts +20 -20
- package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/TimePicker.js +4 -4
- package/dist/components/form-control/field/TimePicker.js.map +1 -1
- package/dist/components/form-control/numpad/Numpad.d.ts +11 -11
- package/dist/components/form-control/numpad/Numpad.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.d.ts +26 -26
- package/dist/components/form-control/select/Select.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.js +34 -23
- package/dist/components/form-control/select/Select.js.map +2 -2
- package/dist/components/form-control/select/SelectContext.d.ts +7 -7
- package/dist/components/form-control/select/SelectContext.d.ts.map +1 -1
- package/dist/components/form-control/select/SelectContext.js +1 -1
- package/dist/components/form-control/select/SelectContext.js.map +1 -1
- package/dist/components/form-control/select/SelectItem.d.ts +4 -4
- package/dist/components/form-control/select/SelectItem.d.ts.map +1 -1
- package/dist/components/form-control/state-preset/StatePreset.js +8 -8
- package/dist/components/form-control/state-preset/StatePreset.js.map +1 -1
- package/dist/components/layout/FormTable.js +4 -4
- package/dist/components/layout/sidebar/Sidebar.d.ts +5 -5
- package/dist/components/layout/sidebar/SidebarContainer.d.ts +11 -11
- package/dist/components/layout/sidebar/SidebarContainer.d.ts.map +1 -1
- package/dist/components/layout/sidebar/SidebarContainer.js +6 -1
- package/dist/components/layout/sidebar/SidebarContainer.js.map +2 -2
- package/dist/components/layout/sidebar/SidebarContext.d.ts +7 -7
- package/dist/components/layout/sidebar/SidebarContext.js +1 -1
- package/dist/components/layout/sidebar/SidebarContext.js.map +1 -1
- package/dist/components/layout/sidebar/SidebarMenu.d.ts +11 -11
- package/dist/components/layout/sidebar/SidebarUser.d.ts +14 -14
- package/dist/components/layout/topbar/Topbar.d.ts +6 -6
- package/dist/components/layout/topbar/Topbar.d.ts.map +1 -1
- package/dist/components/layout/topbar/Topbar.js +11 -6
- package/dist/components/layout/topbar/Topbar.js.map +2 -2
- package/dist/components/layout/topbar/TopbarContainer.d.ts +6 -6
- package/dist/components/layout/topbar/TopbarContext.js +2 -2
- package/dist/components/layout/topbar/TopbarContext.js.map +1 -1
- package/dist/components/layout/topbar/TopbarMenu.d.ts +11 -11
- package/dist/components/layout/topbar/TopbarMenu.d.ts.map +1 -1
- package/dist/components/layout/topbar/TopbarMenu.js +5 -1
- package/dist/components/layout/topbar/TopbarMenu.js.map +2 -2
- package/dist/components/layout/topbar/TopbarUser.d.ts +9 -9
- package/dist/directives/ripple.d.ts +5 -5
- package/dist/helpers/createAppStructure.d.ts.map +1 -1
- package/dist/helpers/createAppStructure.js +4 -1
- package/dist/helpers/createAppStructure.js.map +1 -1
- package/dist/helpers/createSlotComponent.d.ts +3 -3
- package/dist/helpers/mergeStyles.d.ts +8 -8
- package/dist/hooks/createControllableSignal.d.ts +10 -10
- package/dist/hooks/createControllableStore.d.ts +6 -6
- package/dist/hooks/createIMEHandler.d.ts +7 -7
- package/dist/hooks/createMountTransition.d.ts +4 -4
- package/dist/hooks/createSelectionGroup.js +1 -1
- package/dist/hooks/createSelectionGroup.js.map +1 -1
- package/dist/hooks/createSlotSignal.d.ts +2 -2
- package/dist/hooks/useLocalStorage.d.ts +11 -11
- package/dist/hooks/useLogger.d.ts +1 -1
- package/dist/hooks/useLogger.d.ts.map +1 -1
- package/dist/hooks/useLogger.js +1 -1
- package/dist/hooks/useLogger.js.map +1 -1
- package/dist/hooks/useRouterLink.d.ts +10 -10
- package/dist/hooks/useRouterLink.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/ClipboardProvider.d.ts +5 -5
- package/dist/providers/ConfigContext.d.ts +6 -6
- package/dist/providers/ConfigContext.js +2 -2
- package/dist/providers/ConfigContext.js.map +1 -1
- package/dist/providers/ErrorLoggerProvider.d.ts +3 -3
- package/dist/providers/LoggerContext.d.ts +13 -13
- package/dist/providers/PwaUpdateProvider.d.ts +4 -4
- package/dist/providers/PwaUpdateProvider.js +2 -2
- package/dist/providers/PwaUpdateProvider.js.map +1 -1
- package/dist/providers/ServiceClientContext.d.ts +8 -8
- package/dist/providers/ServiceClientContext.d.ts.map +1 -1
- package/dist/providers/ServiceClientContext.js +1 -1
- package/dist/providers/ServiceClientContext.js.map +1 -1
- package/dist/providers/ServiceClientProvider.d.ts +6 -6
- package/dist/providers/ServiceClientProvider.js +7 -7
- package/dist/providers/ServiceClientProvider.js.map +1 -1
- package/dist/providers/SyncStorageContext.d.ts +14 -14
- package/dist/providers/SystemProvider.d.ts.map +1 -1
- package/dist/providers/SystemProvider.js +21 -16
- package/dist/providers/SystemProvider.js.map +2 -2
- package/dist/providers/ThemeContext.d.ts +20 -20
- package/dist/providers/ThemeContext.d.ts.map +1 -1
- package/dist/providers/ThemeContext.js +1 -1
- package/dist/providers/ThemeContext.js.map +1 -1
- package/dist/providers/i18n/I18nContext.d.ts +44 -0
- package/dist/providers/i18n/I18nContext.d.ts.map +1 -0
- package/dist/providers/i18n/I18nContext.js +73 -0
- package/dist/providers/i18n/I18nContext.js.map +6 -0
- package/dist/providers/i18n/I18nContext.types.d.ts +28 -0
- package/dist/providers/i18n/I18nContext.types.d.ts.map +1 -0
- package/dist/providers/i18n/I18nContext.types.js +1 -0
- package/dist/providers/i18n/I18nContext.types.js.map +6 -0
- package/dist/providers/i18n/i18nUtils.d.ts +18 -0
- package/dist/providers/i18n/i18nUtils.d.ts.map +1 -0
- package/dist/providers/i18n/i18nUtils.js +25 -0
- package/dist/providers/i18n/i18nUtils.js.map +6 -0
- package/dist/providers/i18n/locales/en.d.ts +163 -0
- package/dist/providers/i18n/locales/en.d.ts.map +1 -0
- package/dist/providers/i18n/locales/en.js +165 -0
- package/dist/providers/i18n/locales/en.js.map +6 -0
- package/dist/providers/i18n/locales/ko.d.ts +163 -0
- package/dist/providers/i18n/locales/ko.d.ts.map +1 -0
- package/dist/providers/i18n/locales/ko.js +165 -0
- package/dist/providers/i18n/locales/ko.js.map +6 -0
- package/dist/providers/shared-data/SharedDataChangeEvent.d.ts +4 -4
- package/dist/providers/shared-data/SharedDataContext.d.ts +28 -28
- package/dist/providers/shared-data/SharedDataContext.d.ts.map +1 -1
- package/dist/providers/shared-data/SharedDataContext.js +1 -1
- package/dist/providers/shared-data/SharedDataContext.js.map +1 -1
- package/dist/providers/shared-data/SharedDataProvider.d.ts +9 -9
- package/dist/providers/shared-data/SharedDataProvider.js +4 -4
- package/dist/providers/shared-data/SharedDataProvider.js.map +1 -1
- package/package.json +8 -8
- package/src/components/data/calendar/Calendar.tsx +10 -4
- package/src/components/data/kanban/Kanban.tsx +14 -14
- package/src/components/data/kanban/KanbanContext.ts +3 -3
- package/src/components/data/list/List.tsx +10 -10
- package/src/components/data/list/ListContext.ts +1 -1
- package/src/components/data/list/ListItem.styles.ts +8 -8
- package/src/components/data/list/ListItem.tsx +15 -15
- package/src/components/data/sheet/DataSheet.styles.ts +22 -22
- package/src/components/data/sheet/DataSheet.tsx +52 -48
- package/src/components/data/sheet/DataSheetColumn.tsx +1 -1
- package/src/components/data/sheet/DataSheetConfigDialog.tsx +9 -9
- package/src/components/data/sheet/sheetUtils.ts +7 -7
- package/src/components/data/sheet/types.ts +16 -16
- package/src/components/disclosure/Collapse.tsx +11 -11
- package/src/components/disclosure/Dialog.tsx +60 -57
- package/src/components/disclosure/DialogContext.ts +26 -26
- package/src/components/disclosure/DialogInstanceContext.ts +7 -7
- package/src/components/disclosure/DialogProvider.tsx +5 -5
- package/src/components/disclosure/Dropdown.tsx +64 -64
- package/src/components/disclosure/Tabs.tsx +1 -1
- package/src/components/disclosure/dialogZIndex.ts +11 -11
- package/src/components/display/Echarts.tsx +4 -4
- package/src/components/features/address/AddressSearch.tsx +2 -2
- package/src/components/features/crud-detail/CrudDetail.tsx +18 -16
- package/src/components/features/crud-detail/CrudDetailAfter.tsx +1 -1
- package/src/components/features/crud-detail/CrudDetailBefore.tsx +1 -1
- package/src/components/features/crud-detail/CrudDetailTools.tsx +1 -1
- package/src/components/features/crud-sheet/CrudSheet.tsx +39 -37
- package/src/components/features/crud-sheet/CrudSheetColumn.tsx +1 -1
- package/src/components/features/crud-sheet/CrudSheetFilter.tsx +1 -1
- package/src/components/features/crud-sheet/CrudSheetHeader.tsx +1 -1
- package/src/components/features/crud-sheet/CrudSheetTools.tsx +1 -1
- package/src/components/features/data-select-button/DataSelectButton.tsx +34 -32
- package/src/components/features/permission-table/PermissionTable.tsx +22 -19
- package/src/components/features/shared-data/SharedDataSelect.tsx +22 -20
- package/src/components/features/shared-data/SharedDataSelectButton.tsx +10 -10
- package/src/components/features/shared-data/SharedDataSelectList.tsx +245 -48
- package/src/components/features/shared-data/SharedDataSelectListContext.ts +39 -0
- package/src/components/feedback/Progress.tsx +1 -1
- package/src/components/feedback/busy/BusyContainer.tsx +6 -6
- package/src/components/feedback/busy/BusyContext.ts +12 -12
- package/src/components/feedback/busy/BusyProvider.tsx +6 -6
- package/src/components/feedback/notification/NotificationBanner.tsx +3 -1
- package/src/components/feedback/notification/NotificationBell.tsx +4 -4
- package/src/components/feedback/notification/NotificationContext.ts +28 -28
- package/src/components/feedback/notification/NotificationProvider.tsx +9 -9
- package/src/components/feedback/print/PrintContext.ts +1 -1
- package/src/components/form-control/Button.tsx +1 -1
- package/src/components/form-control/DropdownTrigger.styles.ts +1 -1
- package/src/components/form-control/Invalid.tsx +5 -5
- package/src/components/form-control/ThemeToggle.tsx +10 -10
- package/src/components/form-control/checkbox/Checkbox.styles.ts +8 -8
- package/src/components/form-control/checkbox/Checkbox.tsx +2 -2
- package/src/components/form-control/checkbox/CheckboxGroup.tsx +1 -1
- package/src/components/form-control/checkbox/Radio.tsx +2 -2
- package/src/components/form-control/checkbox/RadioGroup.tsx +1 -1
- package/src/components/form-control/color-picker/ColorPicker.tsx +17 -17
- package/src/components/form-control/combobox/Combobox.tsx +55 -55
- package/src/components/form-control/combobox/ComboboxContext.ts +5 -5
- package/src/components/form-control/combobox/ComboboxItem.tsx +3 -3
- package/src/components/form-control/date-range-picker/DateRangePicker.tsx +40 -26
- package/src/components/form-control/editor/EditorToolbar.tsx +52 -50
- package/src/components/form-control/editor/RichTextEditor.tsx +16 -16
- package/src/components/form-control/editor/editor.css +5 -5
- package/src/components/form-control/field/DatePicker.tsx +39 -39
- package/src/components/form-control/field/DateTimePicker.tsx +38 -38
- package/src/components/form-control/field/Field.styles.ts +11 -11
- package/src/components/form-control/field/FieldPlaceholder.tsx +1 -1
- package/src/components/form-control/field/NumberInput.tsx +63 -63
- package/src/components/form-control/field/TextInput.tsx +48 -48
- package/src/components/form-control/field/Textarea.tsx +32 -32
- package/src/components/form-control/field/TimePicker.tsx +37 -37
- package/src/components/form-control/numpad/Numpad.tsx +26 -26
- package/src/components/form-control/select/Select.tsx +84 -84
- package/src/components/form-control/select/SelectContext.ts +8 -8
- package/src/components/form-control/select/SelectItem.tsx +5 -5
- package/src/components/form-control/state-preset/StatePreset.tsx +13 -13
- package/src/components/layout/FormTable.tsx +4 -4
- package/src/components/layout/sidebar/Sidebar.tsx +8 -8
- package/src/components/layout/sidebar/SidebarContainer.tsx +19 -17
- package/src/components/layout/sidebar/SidebarContext.ts +8 -8
- package/src/components/layout/sidebar/SidebarMenu.tsx +19 -19
- package/src/components/layout/sidebar/SidebarUser.tsx +14 -14
- package/src/components/layout/topbar/Topbar.tsx +15 -13
- package/src/components/layout/topbar/TopbarContainer.tsx +6 -6
- package/src/components/layout/topbar/TopbarContext.ts +2 -2
- package/src/components/layout/topbar/TopbarMenu.tsx +18 -16
- package/src/components/layout/topbar/TopbarUser.tsx +9 -9
- package/src/directives/ripple.ts +8 -8
- package/src/helpers/createAppStructure.ts +12 -6
- package/src/helpers/createSlotComponent.ts +4 -4
- package/src/helpers/mergeStyles.ts +11 -11
- package/src/hooks/createControllableSignal.ts +11 -11
- package/src/hooks/createControllableStore.ts +8 -8
- package/src/hooks/createIMEHandler.ts +7 -7
- package/src/hooks/createMountTransition.ts +4 -4
- package/src/hooks/createSelectionGroup.tsx +1 -1
- package/src/hooks/createSlotSignal.ts +2 -2
- package/src/hooks/useLocalStorage.ts +13 -13
- package/src/hooks/useLogger.ts +2 -2
- package/src/hooks/useRouterLink.ts +15 -15
- package/src/index.ts +4 -3
- package/src/providers/ClipboardProvider.tsx +19 -19
- package/src/providers/ConfigContext.tsx +8 -8
- package/src/providers/ErrorLoggerProvider.tsx +3 -3
- package/src/providers/LoggerContext.tsx +13 -13
- package/src/providers/PwaUpdateProvider.tsx +6 -6
- package/src/providers/ServiceClientContext.ts +9 -9
- package/src/providers/ServiceClientProvider.tsx +15 -15
- package/src/providers/SyncStorageContext.tsx +15 -15
- package/src/providers/SystemProvider.tsx +15 -12
- package/src/providers/ThemeContext.tsx +26 -26
- package/src/providers/i18n/I18nContext.tsx +129 -0
- package/src/providers/i18n/I18nContext.types.ts +30 -0
- package/src/providers/i18n/i18nUtils.ts +38 -0
- package/src/providers/i18n/locales/en.ts +161 -0
- package/src/providers/i18n/locales/ko.ts +161 -0
- package/src/providers/shared-data/SharedDataChangeEvent.ts +4 -4
- package/src/providers/shared-data/SharedDataContext.ts +29 -29
- package/src/providers/shared-data/SharedDataProvider.tsx +21 -21
- package/src/styles/patterns.styles.ts +6 -6
- package/src/styles/tokens.styles.ts +5 -5
- package/tailwind.config.ts +1 -1
- package/tailwind.css +4 -4
- package/tests/components/data/List.spec.tsx +689 -0
- package/tests/components/data/Pagination.spec.tsx +336 -0
- package/tests/components/data/Table.spec.tsx +55 -0
- package/tests/components/data/kanban/Kanban.selection.spec.tsx +213 -0
- package/tests/components/data/sheet/DataSheet.spec.tsx +645 -0
- package/tests/components/disclosure/Collapse.spec.tsx +173 -0
- package/tests/components/disclosure/Dialog.spec.tsx +438 -0
- package/tests/components/disclosure/DialogProvider.spec.tsx +142 -0
- package/tests/components/disclosure/Dropdown.spec.tsx +213 -0
- package/tests/components/disclosure/Tabs.spec.tsx +220 -0
- package/tests/components/display/Alert.spec.tsx +47 -0
- package/tests/components/display/Barcode.spec.tsx +61 -0
- package/tests/components/display/Card.spec.tsx +41 -0
- package/tests/components/display/Link.spec.tsx +62 -0
- package/tests/components/display/Tag.spec.tsx +47 -0
- package/tests/components/features/address/AddressSearch.spec.tsx +45 -0
- package/tests/components/features/crud-detail/CrudDetail.spec.tsx +537 -0
- package/tests/components/features/crud-sheet/CrudSheet.spec.tsx +491 -0
- package/tests/components/features/data-select-button/DataSelectButton.spec.tsx +482 -0
- package/tests/components/features/permission-table/PermissionTable.spec.tsx +288 -0
- package/tests/components/features/shared-data/SharedDataSelectList.spec.tsx +463 -0
- package/tests/components/feedback/busy/BusyContainer.spec.tsx +80 -0
- package/tests/components/feedback/notification/LiveRegion.spec.tsx +52 -0
- package/tests/components/feedback/notification/NotificationBanner.spec.tsx +187 -0
- package/tests/components/feedback/notification/NotificationBell.spec.tsx +226 -0
- package/tests/components/feedback/notification/NotificationContext.spec.tsx +362 -0
- package/tests/components/feedback/print/Print.spec.tsx +45 -0
- package/tests/components/form-control/Button.spec.tsx +119 -0
- package/tests/components/form-control/Invalid.spec.tsx +131 -0
- package/tests/components/form-control/checkbox/Checkbox.spec.tsx +137 -0
- package/tests/components/form-control/checkbox/CheckboxGroup.spec.tsx +108 -0
- package/tests/components/form-control/checkbox/Radio.spec.tsx +138 -0
- package/tests/components/form-control/checkbox/RadioGroup.spec.tsx +108 -0
- package/tests/components/form-control/color-picker/ColorPicker.spec.tsx +94 -0
- package/tests/components/form-control/combobox/Combobox.spec.tsx +253 -0
- package/tests/components/form-control/combobox/ComboboxItem.spec.tsx +88 -0
- package/tests/components/form-control/date-range-picker/DateRangePicker.spec.tsx +208 -0
- package/tests/components/form-control/field/DatePicker.spec.tsx +381 -0
- package/tests/components/form-control/field/DateTimePicker.spec.tsx +383 -0
- package/tests/components/form-control/field/NumberInput.spec.tsx +371 -0
- package/tests/components/form-control/field/TextInput.spec.tsx +341 -0
- package/tests/components/form-control/field/Textarea.spec.tsx +224 -0
- package/tests/components/form-control/field/TimePicker.spec.tsx +315 -0
- package/tests/components/form-control/numpad/Numpad.spec.tsx +248 -0
- package/tests/components/form-control/select/Select.spec.tsx +676 -0
- package/tests/components/form-control/select/SelectItem.spec.tsx +174 -0
- package/tests/components/layout/FormGroup.spec.tsx +104 -0
- package/tests/components/layout/FormTable.spec.tsx +43 -0
- package/tests/components/layout/sidebar/Sidebar.spec.tsx +192 -0
- package/tests/components/layout/sidebar/SidebarContainer.spec.tsx +261 -0
- package/tests/components/layout/sidebar/SidebarMenu.spec.tsx +219 -0
- package/tests/components/layout/sidebar/SidebarUser.spec.tsx +133 -0
- package/tests/components/layout/topbar/TopbarActions.spec.tsx +77 -0
- package/tests/components/layout/topbar/TopbarContainer.spec.tsx +38 -0
- package/tests/components/layout/topbar/createTopbarActions.spec.tsx +66 -0
- package/tests/directives/ripple.spec.tsx +130 -0
- package/tests/helpers/createAppStructure.spec.tsx +843 -0
- package/tests/helpers/mergeStyles.spec.ts +172 -0
- package/tests/hooks/createControllableSignal.spec.ts +194 -0
- package/tests/hooks/createIMEHandler.spec.ts +80 -0
- package/tests/hooks/createMountTransition.spec.ts +86 -0
- package/tests/hooks/useLocalStorage.spec.tsx +223 -0
- package/tests/hooks/useLogger.spec.tsx +116 -0
- package/tests/hooks/usePrint.spec.tsx +134 -0
- package/tests/hooks/useRouterLink.spec.tsx +183 -0
- package/tests/hooks/useSyncConfig.spec.tsx +304 -0
- package/tests/providers/ClipboardProvider.spec.tsx +20 -0
- package/tests/providers/ConfigContext.spec.tsx +42 -0
- package/tests/providers/ErrorLoggerProvider.spec.tsx +73 -0
- package/tests/providers/LoggerContext.spec.tsx +76 -0
- package/tests/providers/PwaUpdateProvider.spec.tsx +22 -0
- package/tests/providers/ServiceClientContext.spec.tsx +88 -0
- package/tests/providers/SyncStorageContext.spec.tsx +77 -0
- package/tests/providers/i18n/I18nContext.spec.tsx +110 -0
- package/tests/providers/shared-data/SharedDataProvider.spec.tsx +401 -0
- package/tests/vitest-env.d.ts +1 -0
- package/dist/components/form-control/select-list/SelectList.d.ts +0 -54
- package/dist/components/form-control/select-list/SelectList.d.ts.map +0 -1
- package/dist/components/form-control/select-list/SelectList.js +0 -280
- package/dist/components/form-control/select-list/SelectList.js.map +0 -6
- package/dist/components/form-control/select-list/SelectListContext.d.ts +0 -13
- package/dist/components/form-control/select-list/SelectListContext.d.ts.map +0 -1
- package/dist/components/form-control/select-list/SelectListContext.js +0 -14
- package/dist/components/form-control/select-list/SelectListContext.js.map +0 -6
- package/docs/data-components.md +0 -782
- package/docs/disclosure.md +0 -254
- package/docs/display.md +0 -153
- package/docs/feedback.md +0 -238
- package/docs/form-controls.md +0 -1068
- package/docs/helpers.md +0 -54
- package/docs/hooks.md +0 -588
- package/docs/layout.md +0 -384
- package/docs/providers.md +0 -211
- package/docs/styling.md +0 -184
- package/src/components/form-control/select-list/SelectList.tsx +0 -385
- package/src/components/form-control/select-list/SelectListContext.ts +0 -23
package/docs/data-components.md
DELETED
|
@@ -1,782 +0,0 @@
|
|
|
1
|
-
# Data Components
|
|
2
|
-
|
|
3
|
-
## Table
|
|
4
|
-
|
|
5
|
-
Basic HTML table wrapper. Provides consistent styling for borders, header backgrounds, etc.
|
|
6
|
-
|
|
7
|
-
```tsx
|
|
8
|
-
import { Table } from "@simplysm/solid";
|
|
9
|
-
|
|
10
|
-
<Table>
|
|
11
|
-
<thead>
|
|
12
|
-
<tr><th>Name</th><th>Age</th></tr>
|
|
13
|
-
</thead>
|
|
14
|
-
<tbody>
|
|
15
|
-
<tr><td>John Doe</td><td>30</td></tr>
|
|
16
|
-
<tr><td>Jane Smith</td><td>25</td></tr>
|
|
17
|
-
</tbody>
|
|
18
|
-
</Table>
|
|
19
|
-
|
|
20
|
-
// Inset style (removes outer border, fits parent container)
|
|
21
|
-
<Table inset>...</Table>
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
| Prop | Type | Default | Description |
|
|
25
|
-
|------|------|---------|-------------|
|
|
26
|
-
| `inset` | `boolean` | - | Inset style |
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## DataSheet
|
|
31
|
-
|
|
32
|
-
Advanced data table component. Supports sorting, pagination, row selection, tree expansion, column resize, column configuration, drag-and-drop reordering, and persistent column settings.
|
|
33
|
-
|
|
34
|
-
```tsx
|
|
35
|
-
import { DataSheet } from "@simplysm/solid";
|
|
36
|
-
|
|
37
|
-
// Basic usage
|
|
38
|
-
<DataSheet items={users()} persistKey="user-table">
|
|
39
|
-
<DataSheet.Column key="name" header="Name" sortable class="px-2 py-1">
|
|
40
|
-
{({ item }) => <>{item.name}</>}
|
|
41
|
-
</DataSheet.Column>
|
|
42
|
-
<DataSheet.Column key="age" header="Age" sortable width="80px" class="px-2 py-1">
|
|
43
|
-
{({ item }) => <>{item.age}</>}
|
|
44
|
-
</DataSheet.Column>
|
|
45
|
-
<DataSheet.Column key="email" header="Email" class="px-2 py-1">
|
|
46
|
-
{({ item }) => <>{item.email}</>}
|
|
47
|
-
</DataSheet.Column>
|
|
48
|
-
</DataSheet>
|
|
49
|
-
|
|
50
|
-
// With pagination + sorting + selection
|
|
51
|
-
<DataSheet
|
|
52
|
-
items={data()}
|
|
53
|
-
persistKey="data-table"
|
|
54
|
-
page={page()}
|
|
55
|
-
onPageChange={setPage}
|
|
56
|
-
itemsPerPage={20}
|
|
57
|
-
totalPageCount={totalPages()}
|
|
58
|
-
sorts={sorts()}
|
|
59
|
-
onSortsChange={setSorts}
|
|
60
|
-
selectMode="multiple"
|
|
61
|
-
selectedItems={selectedItems()}
|
|
62
|
-
onSelectedItemsChange={setSelectedItems}
|
|
63
|
-
>
|
|
64
|
-
{/* columns */}
|
|
65
|
-
</DataSheet>
|
|
66
|
-
|
|
67
|
-
// Tree structure with expansion
|
|
68
|
-
<DataSheet
|
|
69
|
-
items={treeData()}
|
|
70
|
-
persistKey="tree-table"
|
|
71
|
-
getChildren={(item) => item.children}
|
|
72
|
-
expandedItems={expanded()}
|
|
73
|
-
onExpandedItemsChange={setExpanded}
|
|
74
|
-
>
|
|
75
|
-
{/* columns */}
|
|
76
|
-
</DataSheet>
|
|
77
|
-
|
|
78
|
-
// Auto-select on row click + drag reorder
|
|
79
|
-
<DataSheet
|
|
80
|
-
items={items()}
|
|
81
|
-
persistKey="reorder-table"
|
|
82
|
-
autoSelect="click"
|
|
83
|
-
selectMode="single"
|
|
84
|
-
selectedItems={selected()}
|
|
85
|
-
onSelectedItemsChange={setSelected}
|
|
86
|
-
onItemsReorder={(e) => {
|
|
87
|
-
// e: { item: T, targetItem: T, position: "before" | "after" | "inside" }
|
|
88
|
-
reorderItems(e);
|
|
89
|
-
}}
|
|
90
|
-
>
|
|
91
|
-
{/* columns */}
|
|
92
|
-
</DataSheet>
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**DataSheet Props:**
|
|
96
|
-
|
|
97
|
-
| Prop | Type | Default | Description |
|
|
98
|
-
|------|------|---------|-------------|
|
|
99
|
-
| `items` | `T[]` | - | Data array |
|
|
100
|
-
| `persistKey` | `string` | - | Column configuration localStorage key |
|
|
101
|
-
| `class` | `string` | - | CSS class |
|
|
102
|
-
| `contentStyle` | `JSX.CSSProperties \| string` | - | Scroll area style |
|
|
103
|
-
| `inset` | `boolean` | - | Inset style |
|
|
104
|
-
| `hideConfigBar` | `boolean` | - | Hide config bar and pagination |
|
|
105
|
-
| `sorts` | `SortingDef[]` | - | Sort state (`{ key: string; desc: boolean }[]`) |
|
|
106
|
-
| `onSortsChange` | `(sorts: SortingDef[]) => void` | - | Sort change callback |
|
|
107
|
-
| `autoSort` | `boolean` | - | Client-side auto-sorting |
|
|
108
|
-
| `page` | `number` | - | Current page (1-based) |
|
|
109
|
-
| `onPageChange` | `(page: number) => void` | - | Page change callback |
|
|
110
|
-
| `totalPageCount` | `number` | - | Total page count |
|
|
111
|
-
| `itemsPerPage` | `number` | - | Items per page |
|
|
112
|
-
| `displayPageCount` | `number` | - | Number of page buttons to display |
|
|
113
|
-
| `selectMode` | `"single" \| "multiple"` | - | Selection mode |
|
|
114
|
-
| `selectedItems` | `T[]` | - | Selected items |
|
|
115
|
-
| `onSelectedItemsChange` | `(items: T[]) => void` | - | Selection change callback |
|
|
116
|
-
| `autoSelect` | `"click"` | - | Auto-select row on click |
|
|
117
|
-
| `isItemSelectable` | `(item: T) => boolean \| string` | - | Item selectability (string returns tooltip) |
|
|
118
|
-
| `getChildren` | `(item: T, index: number) => T[] \| undefined` | - | Tree structure children getter |
|
|
119
|
-
| `expandedItems` | `T[]` | - | Expanded tree items |
|
|
120
|
-
| `onExpandedItemsChange` | `(items: T[]) => void` | - | Expansion state change callback |
|
|
121
|
-
| `cellClass` | `(item: T, colKey: string) => string \| undefined` | - | Dynamic cell class function |
|
|
122
|
-
| `cellStyle` | `(item: T, colKey: string) => string \| undefined` | - | Dynamic cell style function |
|
|
123
|
-
| `onItemsReorder` | `(event: DataSheetReorderEvent<T>) => void` | - | Drag reorder handler (shows drag handle when set) |
|
|
124
|
-
|
|
125
|
-
`DataSheetReorderEvent<T>`: `{ item: T; targetItem: T; position: "before" | "after" | "inside" }`
|
|
126
|
-
|
|
127
|
-
**DataSheet.Column Props:**
|
|
128
|
-
|
|
129
|
-
| Prop | Type | Default | Description |
|
|
130
|
-
|------|------|---------|-------------|
|
|
131
|
-
| `key` | `string` | **(required)** | Column identifier key |
|
|
132
|
-
| `header` | `string \| string[]` | - | Header text (array for multi-level headers) |
|
|
133
|
-
| `headerContent` | `() => JSX.Element` | - | Custom header rendering |
|
|
134
|
-
| `headerStyle` | `string` | - | Header style |
|
|
135
|
-
| `summary` | `() => JSX.Element` | - | Summary row rendering |
|
|
136
|
-
| `tooltip` | `string` | - | Header tooltip |
|
|
137
|
-
| `width` | `string` | - | Column width (e.g., `"100px"`, `"10rem"`) |
|
|
138
|
-
| `class` | `string` | - | Cell CSS class |
|
|
139
|
-
| `fixed` | `boolean` | `false` | Fixed column |
|
|
140
|
-
| `hidden` | `boolean` | `false` | Default hidden state (overridable by user column config) |
|
|
141
|
-
| `collapse` | `boolean` | `false` | Hidden in config modal |
|
|
142
|
-
| `sortable` | `boolean` | `true` | Sortable |
|
|
143
|
-
| `resizable` | `boolean` | `true` | Resizable |
|
|
144
|
-
| `children` | `(ctx: DataSheetCellContext<T>) => JSX.Element` | **(required)** | Cell rendering function |
|
|
145
|
-
|
|
146
|
-
**DataSheetCellContext:**
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
interface DataSheetCellContext<T> {
|
|
150
|
-
item: T;
|
|
151
|
-
index: number; // Position within parent array (root: items[], child: parent.children[])
|
|
152
|
-
row: number; // Flat display row position (within current page)
|
|
153
|
-
depth: number;
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## List
|
|
160
|
-
|
|
161
|
-
Tree-view style list component. Supports keyboard navigation.
|
|
162
|
-
|
|
163
|
-
```tsx
|
|
164
|
-
import { List } from "@simplysm/solid";
|
|
165
|
-
|
|
166
|
-
<List>
|
|
167
|
-
<List.Item>Item 1</List.Item>
|
|
168
|
-
<List.Item>Item 2</List.Item>
|
|
169
|
-
<List.Item>
|
|
170
|
-
Parent item
|
|
171
|
-
<List.Item.Children>
|
|
172
|
-
<List.Item>Child item 1</List.Item>
|
|
173
|
-
<List.Item>Child item 2</List.Item>
|
|
174
|
-
</List.Item.Children>
|
|
175
|
-
</List.Item>
|
|
176
|
-
</List>
|
|
177
|
-
|
|
178
|
-
// Inset style
|
|
179
|
-
<List inset>
|
|
180
|
-
<List.Item>Inset item</List.Item>
|
|
181
|
-
</List>
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
**Keyboard navigation:**
|
|
185
|
-
- `ArrowUp` / `ArrowDown` -- Move focus to previous/next item
|
|
186
|
-
- `Space` / `Enter` -- Click current item
|
|
187
|
-
- `ArrowRight` -- Expand if collapsed, focus first child if expanded
|
|
188
|
-
- `ArrowLeft` -- Collapse if expanded, focus parent if collapsed
|
|
189
|
-
- `Home` / `End` -- Focus first/last item
|
|
190
|
-
|
|
191
|
-
**List Props:**
|
|
192
|
-
|
|
193
|
-
| Prop | Type | Default | Description |
|
|
194
|
-
|------|------|---------|-------------|
|
|
195
|
-
| `inset` | `boolean` | - | Transparent background style |
|
|
196
|
-
|
|
197
|
-
**List.Item Props:**
|
|
198
|
-
|
|
199
|
-
| Prop | Type | Default | Description |
|
|
200
|
-
|------|------|---------|-------------|
|
|
201
|
-
| `open` | `boolean` | - | Nested list open state (controlled mode) |
|
|
202
|
-
| `onOpenChange` | `(open: boolean) => void` | - | Open state change callback |
|
|
203
|
-
| `selected` | `boolean` | - | Selected state |
|
|
204
|
-
| `readonly` | `boolean` | - | Read-only (click disabled, normal color) |
|
|
205
|
-
| `disabled` | `boolean` | - | Disabled state (click disabled, dimmed) |
|
|
206
|
-
| `selectedIcon` | `Component<IconProps>` | - | Selected state icon (shown when no nested list) |
|
|
207
|
-
| `size` | `"xs" \| "sm" \| "lg" \| "xl"` | - | Size |
|
|
208
|
-
| `onClick` | `(e: MouseEvent) => void` | - | Click handler (called when no nested list) |
|
|
209
|
-
|
|
210
|
-
**Sub-components:**
|
|
211
|
-
- `List.Item` -- Individual list item
|
|
212
|
-
- `List.Item.Children` -- Nested child items container
|
|
213
|
-
|
|
214
|
-
**ListContext:**
|
|
215
|
-
|
|
216
|
-
`ListContext` and `useListContext` are exported for building custom List item sub-components. Provides the current nesting `level` (starts at 1 for the root List).
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
import { useListContext } from "@simplysm/solid";
|
|
220
|
-
|
|
221
|
-
const { level } = useListContext();
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
---
|
|
225
|
-
|
|
226
|
-
## Pagination
|
|
227
|
-
|
|
228
|
-
Page navigation component.
|
|
229
|
-
|
|
230
|
-
```tsx
|
|
231
|
-
import { Pagination } from "@simplysm/solid";
|
|
232
|
-
|
|
233
|
-
<Pagination
|
|
234
|
-
page={currentPage()}
|
|
235
|
-
onPageChange={setCurrentPage}
|
|
236
|
-
totalPageCount={20}
|
|
237
|
-
displayPageCount={10}
|
|
238
|
-
/>
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
| Prop | Type | Default | Description |
|
|
242
|
-
|------|------|---------|-------------|
|
|
243
|
-
| `page` | `number` | **(required)** | Current page (1-based) |
|
|
244
|
-
| `onPageChange` | `(page: number) => void` | - | Page change callback |
|
|
245
|
-
| `totalPageCount` | `number` | **(required)** | Total page count |
|
|
246
|
-
| `displayPageCount` | `number` | `10` | Number of pages to display at once |
|
|
247
|
-
| `size` | `"sm" \| "lg"` | - | Size |
|
|
248
|
-
|
|
249
|
-
---
|
|
250
|
-
|
|
251
|
-
## Calendar
|
|
252
|
-
|
|
253
|
-
Calendar-style data display component.
|
|
254
|
-
|
|
255
|
-
```tsx
|
|
256
|
-
import { Calendar } from "@simplysm/solid";
|
|
257
|
-
|
|
258
|
-
<Calendar
|
|
259
|
-
items={events()}
|
|
260
|
-
getItemDate={(event) => event.date}
|
|
261
|
-
renderItem={(event) => <div>{event.title}</div>}
|
|
262
|
-
yearMonth={yearMonth()}
|
|
263
|
-
onYearMonthChange={setYearMonth}
|
|
264
|
-
/>
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
| Prop | Type | Default | Description |
|
|
268
|
-
|------|------|---------|-------------|
|
|
269
|
-
| `items` | `T[]` | **(required)** | Data array |
|
|
270
|
-
| `getItemDate` | `(item: T, index: number) => DateOnly` | **(required)** | Item date extraction function |
|
|
271
|
-
| `renderItem` | `(item: T, index: number) => JSX.Element` | **(required)** | Item rendering function |
|
|
272
|
-
| `yearMonth` | `DateOnly` | - | Year-month to display |
|
|
273
|
-
| `onYearMonthChange` | `(value: DateOnly) => void` | - | Year-month change callback |
|
|
274
|
-
| `weekStartDay` | `number` | `0` (Sunday) | Week start day |
|
|
275
|
-
|
|
276
|
-
---
|
|
277
|
-
|
|
278
|
-
## PermissionTable
|
|
279
|
-
|
|
280
|
-
Hierarchical permission management table. Displays a tree of permission items with per-item checkboxes for each permission type. Supports cascading checks (parent toggles children) and permission dependencies (disabling the first permission disables the rest).
|
|
281
|
-
|
|
282
|
-
```tsx
|
|
283
|
-
import { createSignal } from "solid-js";
|
|
284
|
-
import { type AppPerm, PermissionTable } from "@simplysm/solid";
|
|
285
|
-
|
|
286
|
-
const items: AppPerm[] = [
|
|
287
|
-
{
|
|
288
|
-
title: "User Management",
|
|
289
|
-
href: "/user",
|
|
290
|
-
perms: ["use", "edit"],
|
|
291
|
-
children: [
|
|
292
|
-
{ title: "Permission Settings", href: "/user/permission", perms: ["use", "edit", "approve"] },
|
|
293
|
-
{ title: "User List", href: "/user/list", perms: ["use", "edit"] },
|
|
294
|
-
],
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
title: "Board",
|
|
298
|
-
href: "/board",
|
|
299
|
-
perms: ["use", "edit"],
|
|
300
|
-
modules: ["community"], // only shown when "community" module is active
|
|
301
|
-
children: [
|
|
302
|
-
{ title: "Notice", href: "/board/notice", perms: ["use", "edit"] },
|
|
303
|
-
{ title: "Free Board", href: "/board/free", perms: ["use"] },
|
|
304
|
-
],
|
|
305
|
-
},
|
|
306
|
-
];
|
|
307
|
-
|
|
308
|
-
const [value, setValue] = createSignal<Record<string, boolean>>({});
|
|
309
|
-
|
|
310
|
-
// Basic usage
|
|
311
|
-
<PermissionTable items={items} value={value()} onValueChange={setValue} />
|
|
312
|
-
|
|
313
|
-
// Filtered by module
|
|
314
|
-
<PermissionTable items={items} value={value()} onValueChange={setValue} modules={["community"]} />
|
|
315
|
-
|
|
316
|
-
// Disabled
|
|
317
|
-
<PermissionTable items={items} value={value()} disabled />
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
The `value` record uses keys in `"{href}/{perm}"` format (e.g., `{ "/user/use": true, "/user/edit": false }`).
|
|
321
|
-
|
|
322
|
-
**PermissionTable Props:**
|
|
323
|
-
|
|
324
|
-
| Prop | Type | Default | Description |
|
|
325
|
-
|------|------|---------|-------------|
|
|
326
|
-
| `items` | `AppPerm<TModule>[]` | - | Permission tree structure (same type as `useAppStructure().usablePerms()`) |
|
|
327
|
-
| `value` | `Record<string, boolean>` | - | Permission state record |
|
|
328
|
-
| `onValueChange` | `(value: Record<string, boolean>) => void` | - | State change callback |
|
|
329
|
-
| `modules` | `TModule[]` | - | Module filter (show only matching items) |
|
|
330
|
-
| `disabled` | `boolean` | - | Disable all checkboxes |
|
|
331
|
-
|
|
332
|
-
**AppPerm type** (used as items):
|
|
333
|
-
|
|
334
|
-
```typescript
|
|
335
|
-
interface AppPerm<TModule = string> {
|
|
336
|
-
title: string; // Display text
|
|
337
|
-
href?: string; // Permission path (used as value key prefix)
|
|
338
|
-
modules?: TModule[]; // Modules this item belongs to
|
|
339
|
-
perms?: string[]; // Permission types (e.g., ["use", "edit", "approve"])
|
|
340
|
-
children?: AppPerm<TModule>[]; // Child items
|
|
341
|
-
}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
`AppPerm` is the same type returned by `useAppStructure().usablePerms()`, so you can pass the output directly to `PermissionTable`.
|
|
345
|
-
|
|
346
|
-
**Cascading behavior:** Checking a parent checks all children. Unchecking `perms[0]` (base permission) automatically unchecks all other permissions for that item.
|
|
347
|
-
|
|
348
|
-
**Utility functions (exported):**
|
|
349
|
-
|
|
350
|
-
| Function | Signature | Description |
|
|
351
|
-
|----------|-----------|-------------|
|
|
352
|
-
| `collectAllPerms` | `(items: AppPerm[]) => string[]` | Collect all unique perm type strings from a tree |
|
|
353
|
-
| `filterByModules` | `(items: AppPerm<TModule>[], modules: TModule[] \| undefined) => AppPerm<TModule>[]` | Filter items by active modules |
|
|
354
|
-
| `changePermCheck` | `(value: Record<string,boolean>, item: AppPerm, perm: string, checked: boolean) => Record<string,boolean>` | Apply cascading check logic to a value record |
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
## CrudSheet
|
|
359
|
-
|
|
360
|
-
Full-featured CRUD data sheet component. Wraps `DataSheet` with built-in search, filter form, inline editing, modal editing, Excel import/export, select mode, pagination, sorting, and topbar action integration. Uses compound component pattern with `CrudSheet.Column`, `CrudSheet.Filter`, `CrudSheet.Tools`, and `CrudSheet.Header`.
|
|
361
|
-
|
|
362
|
-
```tsx
|
|
363
|
-
import { CrudSheet, type SearchResult, type SortingDef } from "@simplysm/solid";
|
|
364
|
-
|
|
365
|
-
interface User {
|
|
366
|
-
id?: number;
|
|
367
|
-
name: string;
|
|
368
|
-
email: string;
|
|
369
|
-
isDeleted?: boolean;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
interface UserFilter {
|
|
373
|
-
keyword: string;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// Inline editing mode
|
|
377
|
-
<CrudSheet<User, UserFilter>
|
|
378
|
-
search={async (filter, page, sorts) => {
|
|
379
|
-
const result = await api.getUsers(filter, page, sorts);
|
|
380
|
-
return { items: result.items, pageCount: result.pageCount };
|
|
381
|
-
}}
|
|
382
|
-
getItemKey={(item) => item.id}
|
|
383
|
-
persistKey="user-crud"
|
|
384
|
-
itemsPerPage={20}
|
|
385
|
-
filterInitial={{ keyword: "" }}
|
|
386
|
-
inlineEdit={{
|
|
387
|
-
newItem: () => ({ name: "", email: "" }),
|
|
388
|
-
submit: async (diffs) => { await api.saveUsers(diffs); },
|
|
389
|
-
deleteProp: "isDeleted",
|
|
390
|
-
}}
|
|
391
|
-
>
|
|
392
|
-
<CrudSheet.Filter>
|
|
393
|
-
{(filter, setFilter) => (
|
|
394
|
-
<FormGroup.Item label="Keyword">
|
|
395
|
-
<TextInput value={filter.keyword} onValueChange={(v) => setFilter("keyword", v)} />
|
|
396
|
-
</FormGroup.Item>
|
|
397
|
-
)}
|
|
398
|
-
</CrudSheet.Filter>
|
|
399
|
-
<CrudSheet.Column key="name" header="Name" class="px-2 py-1">
|
|
400
|
-
{(ctx) => (
|
|
401
|
-
<TextInput value={ctx.item.name} onValueChange={(v) => ctx.setItem("name", v)} />
|
|
402
|
-
)}
|
|
403
|
-
</CrudSheet.Column>
|
|
404
|
-
<CrudSheet.Column key="email" header="Email" class="px-2 py-1">
|
|
405
|
-
{(ctx) => (
|
|
406
|
-
<TextInput value={ctx.item.email} onValueChange={(v) => ctx.setItem("email", v)} />
|
|
407
|
-
)}
|
|
408
|
-
</CrudSheet.Column>
|
|
409
|
-
</CrudSheet>
|
|
410
|
-
|
|
411
|
-
// Modal editing mode
|
|
412
|
-
<CrudSheet<User, UserFilter>
|
|
413
|
-
search={async (filter, page, sorts) => {
|
|
414
|
-
return await api.getUsers(filter, page, sorts);
|
|
415
|
-
}}
|
|
416
|
-
getItemKey={(item) => item.id}
|
|
417
|
-
persistKey="user-modal-crud"
|
|
418
|
-
itemsPerPage={20}
|
|
419
|
-
modalEdit={{
|
|
420
|
-
editItem: async (item) => {
|
|
421
|
-
const result = await dialog.show((close) => <UserEditDialog item={item} onClose={close} />);
|
|
422
|
-
return result === true;
|
|
423
|
-
},
|
|
424
|
-
deleteItems: async (items) => {
|
|
425
|
-
if (!confirm("Delete selected items?")) return false;
|
|
426
|
-
await api.deleteUsers(items.map((i) => i.id!));
|
|
427
|
-
return true;
|
|
428
|
-
},
|
|
429
|
-
}}
|
|
430
|
-
>
|
|
431
|
-
<CrudSheet.Column key="name" header="Name" editable class="px-2 py-1">
|
|
432
|
-
{(ctx) => <>{ctx.item.name}</>}
|
|
433
|
-
</CrudSheet.Column>
|
|
434
|
-
<CrudSheet.Column key="email" header="Email" class="px-2 py-1">
|
|
435
|
-
{(ctx) => <>{ctx.item.email}</>}
|
|
436
|
-
</CrudSheet.Column>
|
|
437
|
-
</CrudSheet>
|
|
438
|
-
|
|
439
|
-
// Select mode (for picker dialogs)
|
|
440
|
-
<CrudSheet<User, UserFilter>
|
|
441
|
-
search={async (filter, page, sorts) => {
|
|
442
|
-
return await api.getUsers(filter, page, sorts);
|
|
443
|
-
}}
|
|
444
|
-
getItemKey={(item) => item.id}
|
|
445
|
-
persistKey="user-select"
|
|
446
|
-
itemsPerPage={20}
|
|
447
|
-
selectMode="multiple"
|
|
448
|
-
onSelect={(result) => {
|
|
449
|
-
// result.items: selected User[]
|
|
450
|
-
// result.keys: selected (string | number)[]
|
|
451
|
-
onConfirm(result.items);
|
|
452
|
-
}}
|
|
453
|
-
>
|
|
454
|
-
<CrudSheet.Column key="name" header="Name" class="px-2 py-1">
|
|
455
|
-
{(ctx) => <>{ctx.item.name}</>}
|
|
456
|
-
</CrudSheet.Column>
|
|
457
|
-
</CrudSheet>
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
**CrudSheet Props:**
|
|
461
|
-
|
|
462
|
-
| Prop | Type | Default | Description |
|
|
463
|
-
|------|------|---------|-------------|
|
|
464
|
-
| `search` | `(filter: TFilter, page: number, sorts: SortingDef[]) => Promise<SearchResult<TItem>>` | **(required)** | Search function. `page=0` means no pagination |
|
|
465
|
-
| `getItemKey` | `(item: TItem) => string \| number \| undefined` | **(required)** | Unique key extractor for diff tracking |
|
|
466
|
-
| `persistKey` | `string` | - | LocalStorage key for column configuration |
|
|
467
|
-
| `itemsPerPage` | `number` | - | Items per page (enables pagination when set) |
|
|
468
|
-
| `editable` | `() => boolean` | `() => true` | Whether editing is allowed |
|
|
469
|
-
| `itemEditable` | `(item: TItem) => boolean` | `() => true` | Per-item edit control (modal edit mode) |
|
|
470
|
-
| `itemDeletable` | `(item: TItem) => boolean` | `() => true` | Per-item delete control |
|
|
471
|
-
| `filterInitial` | `TFilter` | - | Initial filter state |
|
|
472
|
-
| `items` | `TItem[]` | - | Controlled items (external state) |
|
|
473
|
-
| `onItemsChange` | `(items: TItem[]) => void` | - | Items change callback (controlled mode) |
|
|
474
|
-
| `inlineEdit` | `InlineEditConfig<TItem>` | - | Inline editing configuration (mutually exclusive with `modalEdit`) |
|
|
475
|
-
| `modalEdit` | `ModalEditConfig<TItem>` | - | Modal editing configuration (mutually exclusive with `inlineEdit`) |
|
|
476
|
-
| `excel` | `ExcelConfig<TItem>` | - | Excel download/upload configuration |
|
|
477
|
-
| `selectMode` | `"single" \| "multiple"` | - | Select mode (disables editing, shows selection UI) |
|
|
478
|
-
| `onSelect` | `(result: SelectResult<TItem>) => void` | - | Select confirmation callback |
|
|
479
|
-
| `hideAutoTools` | `boolean` | - | Hide auto-generated toolbar buttons |
|
|
480
|
-
| `class` | `string` | - | CSS class |
|
|
481
|
-
|
|
482
|
-
**InlineEditConfig:**
|
|
483
|
-
|
|
484
|
-
```typescript
|
|
485
|
-
interface InlineEditConfig<TItem> {
|
|
486
|
-
submit: (diffs: ArrayDiffs2Result<TItem>[]) => Promise<void>;
|
|
487
|
-
newItem: () => TItem;
|
|
488
|
-
deleteProp?: keyof TItem & string;
|
|
489
|
-
}
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
| Field | Description |
|
|
493
|
-
|-------|-------------|
|
|
494
|
-
| `submit` | Save function receiving changed items (inserted/updated/deleted diffs) |
|
|
495
|
-
| `newItem` | Factory function for creating new empty rows |
|
|
496
|
-
| `deleteProp` | Property name for soft-delete flag (e.g., `"isDeleted"`) |
|
|
497
|
-
|
|
498
|
-
**ModalEditConfig:**
|
|
499
|
-
|
|
500
|
-
```typescript
|
|
501
|
-
interface ModalEditConfig<TItem> {
|
|
502
|
-
editItem: (item?: TItem) => Promise<boolean>;
|
|
503
|
-
deleteItems?: (items: TItem[]) => Promise<boolean>;
|
|
504
|
-
}
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
| Field | Description |
|
|
508
|
-
|-------|-------------|
|
|
509
|
-
| `editItem` | Open edit dialog. `undefined` = new item. Return `true` to refresh |
|
|
510
|
-
| `deleteItems` | Delete selected items. Return `true` to refresh |
|
|
511
|
-
|
|
512
|
-
**ExcelConfig:**
|
|
513
|
-
|
|
514
|
-
```typescript
|
|
515
|
-
interface ExcelConfig<TItem> {
|
|
516
|
-
download: (items: TItem[]) => Promise<void>;
|
|
517
|
-
upload?: (file: File) => Promise<void>;
|
|
518
|
-
}
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
**SelectResult:**
|
|
522
|
-
|
|
523
|
-
```typescript
|
|
524
|
-
interface SelectResult<TItem> {
|
|
525
|
-
items: TItem[];
|
|
526
|
-
keys: (string | number)[];
|
|
527
|
-
}
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
**Sub-components:**
|
|
531
|
-
|
|
532
|
-
- `CrudSheet.Column` -- Column definition (extends `DataSheet.Column` props + `editable`)
|
|
533
|
-
- `CrudSheet.Filter` -- Filter form render prop
|
|
534
|
-
- `CrudSheet.Tools` -- Custom toolbar render prop
|
|
535
|
-
- `CrudSheet.Header` -- Header area above filter
|
|
536
|
-
|
|
537
|
-
**CrudSheet.Column Props:**
|
|
538
|
-
|
|
539
|
-
Inherits all `DataSheet.Column` props (`key`, `header`, `width`, `fixed`, `hidden`, `sortable`, `resizable`, `class`, `headerContent`, `headerStyle`, `summary`, `tooltip`, `collapse`) plus:
|
|
540
|
-
|
|
541
|
-
| Prop | Type | Default | Description |
|
|
542
|
-
|------|------|---------|-------------|
|
|
543
|
-
| `editable` | `boolean` | `false` | Wrap cell with edit link (modal edit mode only) |
|
|
544
|
-
| `children` | `(ctx: CrudSheetCellContext<TItem>) => JSX.Element` | **(required)** | Cell render function |
|
|
545
|
-
|
|
546
|
-
**CrudSheetCellContext:**
|
|
547
|
-
|
|
548
|
-
```typescript
|
|
549
|
-
interface CrudSheetCellContext<TItem> {
|
|
550
|
-
item: TItem;
|
|
551
|
-
index: number;
|
|
552
|
-
row: number;
|
|
553
|
-
depth: number;
|
|
554
|
-
setItem: <TKey extends keyof TItem>(key: TKey, value: TItem[TKey]) => void;
|
|
555
|
-
}
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
`setItem` updates a specific field of the current row item (inline edit mode).
|
|
559
|
-
|
|
560
|
-
**CrudSheet.Filter:**
|
|
561
|
-
|
|
562
|
-
```tsx
|
|
563
|
-
<CrudSheet.Filter>
|
|
564
|
-
{(filter, setFilter) => (
|
|
565
|
-
<FormGroup.Item label="Search">
|
|
566
|
-
<TextInput value={filter.keyword} onValueChange={(v) => setFilter("keyword", v)} />
|
|
567
|
-
</FormGroup.Item>
|
|
568
|
-
)}
|
|
569
|
-
</CrudSheet.Filter>
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
Receives `filter` (store) and `setFilter` (`SetStoreFunction`) as render prop arguments.
|
|
573
|
-
|
|
574
|
-
**CrudSheet.Tools:**
|
|
575
|
-
|
|
576
|
-
```tsx
|
|
577
|
-
<CrudSheet.Tools>
|
|
578
|
-
{(ctx) => (
|
|
579
|
-
<Button size="sm" onClick={() => ctx.refresh()}>Custom Refresh</Button>
|
|
580
|
-
)}
|
|
581
|
-
</CrudSheet.Tools>
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
**CrudSheetContext (Tools render prop):**
|
|
585
|
-
|
|
586
|
-
```typescript
|
|
587
|
-
interface CrudSheetContext<TItem> {
|
|
588
|
-
items(): TItem[];
|
|
589
|
-
selectedItems(): TItem[];
|
|
590
|
-
page(): number;
|
|
591
|
-
sorts(): SortingDef[];
|
|
592
|
-
busy(): boolean;
|
|
593
|
-
hasChanges(): boolean;
|
|
594
|
-
save(): Promise<void>;
|
|
595
|
-
refresh(): Promise<void>;
|
|
596
|
-
addItem(): void;
|
|
597
|
-
setPage(page: number): void;
|
|
598
|
-
setSorts(sorts: SortingDef[]): void;
|
|
599
|
-
}
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
**CrudSheet.Header:**
|
|
603
|
-
|
|
604
|
-
```tsx
|
|
605
|
-
<CrudSheet.Header>
|
|
606
|
-
<h2 class="p-2 text-lg font-bold">User Management</h2>
|
|
607
|
-
</CrudSheet.Header>
|
|
608
|
-
```
|
|
609
|
-
|
|
610
|
-
Renders static content above the filter area.
|
|
611
|
-
|
|
612
|
-
**Keyboard shortcuts:**
|
|
613
|
-
- `Ctrl+S` -- Save (inline edit mode)
|
|
614
|
-
- `Ctrl+Alt+L` -- Refresh
|
|
615
|
-
|
|
616
|
-
**Topbar integration:** When used inside `Topbar.Container`, CrudSheet automatically registers Save and Refresh buttons in the topbar via `createTopbarActions`.
|
|
617
|
-
|
|
618
|
-
---
|
|
619
|
-
|
|
620
|
-
## CrudDetail
|
|
621
|
-
|
|
622
|
-
CRUD detail form component for single-record editing. Provides load, save, soft-delete/restore, change detection, and topbar action integration. Works both as a standalone page component and inside a `Dialog` (modal mode).
|
|
623
|
-
|
|
624
|
-
```tsx
|
|
625
|
-
import { CrudDetail, type CrudDetailInfo } from "@simplysm/solid";
|
|
626
|
-
import { FormTable, TextInput, NumberInput } from "@simplysm/solid";
|
|
627
|
-
|
|
628
|
-
interface User {
|
|
629
|
-
id?: number;
|
|
630
|
-
name: string;
|
|
631
|
-
age: number;
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
// Page mode (standalone)
|
|
635
|
-
<CrudDetail<User>
|
|
636
|
-
load={async () => {
|
|
637
|
-
const user = await api.getUser(userId);
|
|
638
|
-
return {
|
|
639
|
-
data: user,
|
|
640
|
-
info: { isNew: user.id == null, isDeleted: false, lastModifiedAt: user.updatedAt },
|
|
641
|
-
};
|
|
642
|
-
}}
|
|
643
|
-
submit={async (data) => {
|
|
644
|
-
await api.saveUser(data);
|
|
645
|
-
return true; // return true to trigger success notification + refresh/close
|
|
646
|
-
}}
|
|
647
|
-
toggleDelete={async (del) => {
|
|
648
|
-
await api.toggleDeleteUser(userId, del);
|
|
649
|
-
return true;
|
|
650
|
-
}}
|
|
651
|
-
>
|
|
652
|
-
{(ctx) => (
|
|
653
|
-
<FormTable>
|
|
654
|
-
<tbody>
|
|
655
|
-
<tr>
|
|
656
|
-
<th>Name</th>
|
|
657
|
-
<td>
|
|
658
|
-
<TextInput value={ctx.data.name} onValueChange={(v) => ctx.setData("name", v)} />
|
|
659
|
-
</td>
|
|
660
|
-
</tr>
|
|
661
|
-
<tr>
|
|
662
|
-
<th>Age</th>
|
|
663
|
-
<td>
|
|
664
|
-
<NumberInput value={ctx.data.age} onValueChange={(v) => ctx.setData("age", v!)} />
|
|
665
|
-
</td>
|
|
666
|
-
</tr>
|
|
667
|
-
</tbody>
|
|
668
|
-
</FormTable>
|
|
669
|
-
)}
|
|
670
|
-
</CrudDetail>
|
|
671
|
-
|
|
672
|
-
// Modal mode (inside Dialog via useDialog)
|
|
673
|
-
const dialog = useDialog();
|
|
674
|
-
|
|
675
|
-
const handleEdit = async () => {
|
|
676
|
-
const result = await dialog.show<boolean>(
|
|
677
|
-
() => (
|
|
678
|
-
<CrudDetail<User>
|
|
679
|
-
load={async () => ({ data: user, info: { isNew: false, isDeleted: false } })}
|
|
680
|
-
submit={async (data) => { await api.saveUser(data); return true; }}
|
|
681
|
-
>
|
|
682
|
-
{(ctx) => (
|
|
683
|
-
<FormTable>
|
|
684
|
-
<tbody>
|
|
685
|
-
<tr>
|
|
686
|
-
<th>Name</th>
|
|
687
|
-
<td><TextInput value={ctx.data.name} onValueChange={(v) => ctx.setData("name", v)} /></td>
|
|
688
|
-
</tr>
|
|
689
|
-
</tbody>
|
|
690
|
-
</FormTable>
|
|
691
|
-
)}
|
|
692
|
-
</CrudDetail>
|
|
693
|
-
),
|
|
694
|
-
{ header: "Edit User", width: 500 },
|
|
695
|
-
);
|
|
696
|
-
if (result) { /* saved successfully */ }
|
|
697
|
-
};
|
|
698
|
-
|
|
699
|
-
// With custom tools and before/after slots
|
|
700
|
-
<CrudDetail<User>
|
|
701
|
-
load={loadUser}
|
|
702
|
-
submit={saveUser}
|
|
703
|
-
editable={hasEditPermission()}
|
|
704
|
-
deletable={hasDeletePermission()}
|
|
705
|
-
>
|
|
706
|
-
{(ctx) => (
|
|
707
|
-
<>
|
|
708
|
-
<CrudDetail.Tools>
|
|
709
|
-
<Button size="sm" variant="ghost" onClick={() => ctx.refresh()}>Custom Refresh</Button>
|
|
710
|
-
</CrudDetail.Tools>
|
|
711
|
-
<CrudDetail.Before>
|
|
712
|
-
<div class="p-2 bg-info-50">Info banner (outside form)</div>
|
|
713
|
-
</CrudDetail.Before>
|
|
714
|
-
<FormTable>
|
|
715
|
-
<tbody>
|
|
716
|
-
<tr>
|
|
717
|
-
<th>Name</th>
|
|
718
|
-
<td><TextInput value={ctx.data.name} onValueChange={(v) => ctx.setData("name", v)} /></td>
|
|
719
|
-
</tr>
|
|
720
|
-
</tbody>
|
|
721
|
-
</FormTable>
|
|
722
|
-
<CrudDetail.After>
|
|
723
|
-
<div class="p-2">Footer content (outside form)</div>
|
|
724
|
-
</CrudDetail.After>
|
|
725
|
-
</>
|
|
726
|
-
)}
|
|
727
|
-
</CrudDetail>
|
|
728
|
-
```
|
|
729
|
-
|
|
730
|
-
**CrudDetail Props:**
|
|
731
|
-
|
|
732
|
-
| Prop | Type | Default | Description |
|
|
733
|
-
|------|------|---------|-------------|
|
|
734
|
-
| `load` | `() => Promise<{ data: TData; info: CrudDetailInfo }>` | **(required)** | Load function returning data and metadata |
|
|
735
|
-
| `children` | `(ctx: CrudDetailContext<TData>) => JSX.Element` | **(required)** | Render prop receiving context |
|
|
736
|
-
| `submit` | `(data: TData) => Promise<boolean \| undefined>` | - | Save function. Return `true` to trigger success notification |
|
|
737
|
-
| `toggleDelete` | `(del: boolean) => Promise<boolean \| undefined>` | - | Soft-delete/restore function. `del=true` for delete, `false` for restore |
|
|
738
|
-
| `editable` | `boolean` | `true` | Whether editing is allowed |
|
|
739
|
-
| `deletable` | `boolean` | `true` | Whether delete/restore is allowed |
|
|
740
|
-
| `data` | `TData` | - | Controlled data state |
|
|
741
|
-
| `onDataChange` | `(data: TData) => void` | - | Data change callback (controlled mode) |
|
|
742
|
-
| `class` | `string` | - | CSS class |
|
|
743
|
-
|
|
744
|
-
**CrudDetailInfo:**
|
|
745
|
-
|
|
746
|
-
```typescript
|
|
747
|
-
interface CrudDetailInfo {
|
|
748
|
-
isNew: boolean;
|
|
749
|
-
isDeleted: boolean;
|
|
750
|
-
lastModifiedAt?: DateTime;
|
|
751
|
-
lastModifiedBy?: string;
|
|
752
|
-
}
|
|
753
|
-
```
|
|
754
|
-
|
|
755
|
-
**CrudDetailContext (render prop argument):**
|
|
756
|
-
|
|
757
|
-
```typescript
|
|
758
|
-
interface CrudDetailContext<TData> {
|
|
759
|
-
data: TData;
|
|
760
|
-
setData: SetStoreFunction<TData>;
|
|
761
|
-
info: () => CrudDetailInfo;
|
|
762
|
-
busy: () => boolean;
|
|
763
|
-
hasChanges: () => boolean;
|
|
764
|
-
save: () => Promise<void>;
|
|
765
|
-
refresh: () => Promise<void>;
|
|
766
|
-
}
|
|
767
|
-
```
|
|
768
|
-
|
|
769
|
-
**Sub-components:**
|
|
770
|
-
- `CrudDetail.Tools` -- Custom toolbar buttons (rendered in the toolbar area)
|
|
771
|
-
- `CrudDetail.Before` -- Content rendered before the form (outside `<form>`)
|
|
772
|
-
- `CrudDetail.After` -- Content rendered after the form (outside `<form>`)
|
|
773
|
-
|
|
774
|
-
**Page vs Modal mode:**
|
|
775
|
-
- **Page mode**: Toolbar with Save/Refresh/Delete buttons appears at the top. When inside `Topbar.Container`, Save and Refresh are also registered in the topbar via `createTopbarActions`.
|
|
776
|
-
- **Modal mode** (inside `useDialog`): Refresh button appears in the dialog header. Save/Delete buttons appear in the bottom bar. On save/delete success, the dialog closes with `true` as the return value.
|
|
777
|
-
|
|
778
|
-
**Keyboard shortcuts:**
|
|
779
|
-
- `Ctrl+S` -- Save
|
|
780
|
-
- `Ctrl+Alt+L` -- Refresh
|
|
781
|
-
|
|
782
|
-
**Change detection:** On refresh, if unsaved changes exist, a confirmation dialog is shown. On save, if no changes exist (and not a new record), an info notification is shown instead.
|