@simplysm/solid 13.0.78 → 13.0.81

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 (206) hide show
  1. package/README.md +23 -217
  2. package/dist/components/data/Pagination.js +2 -2
  3. package/dist/components/data/Pagination.js.map +2 -2
  4. package/dist/components/data/Table.js +2 -2
  5. package/dist/components/data/Table.js.map +2 -2
  6. package/dist/components/data/calendar/Calendar.js +2 -2
  7. package/dist/components/data/calendar/Calendar.js.map +2 -2
  8. package/dist/components/data/kanban/Kanban.js +3 -3
  9. package/dist/components/data/kanban/Kanban.js.map +2 -2
  10. package/dist/components/data/list/ListItem.js +1 -1
  11. package/dist/components/data/list/ListItem.js.map +1 -1
  12. package/dist/components/data/list/ListItem.styles.js +1 -1
  13. package/dist/components/data/list/ListItem.styles.js.map +1 -1
  14. package/dist/components/data/sheet/DataSheet.js +16 -16
  15. package/dist/components/data/sheet/DataSheet.js.map +2 -2
  16. package/dist/components/data/sheet/DataSheet.styles.d.ts.map +1 -1
  17. package/dist/components/data/sheet/DataSheet.styles.js +2 -2
  18. package/dist/components/data/sheet/DataSheet.styles.js.map +1 -1
  19. package/dist/components/data/sheet/DataSheetConfigDialog.js +5 -5
  20. package/dist/components/data/sheet/DataSheetConfigDialog.js.map +2 -2
  21. package/dist/components/data/sheet/hooks/{useDataSheetExpansion.d.ts → createDataSheetExpansion.d.ts} +4 -4
  22. package/dist/components/data/sheet/hooks/createDataSheetExpansion.d.ts.map +1 -0
  23. package/dist/components/data/sheet/hooks/{useDataSheetExpansion.js → createDataSheetExpansion.js} +3 -3
  24. package/dist/components/data/sheet/hooks/{useDataSheetExpansion.js.map → createDataSheetExpansion.js.map} +2 -2
  25. package/dist/components/data/sheet/hooks/{useDataSheetFixedColumns.d.ts → createDataSheetFixedColumns.d.ts} +3 -3
  26. package/dist/components/data/sheet/hooks/createDataSheetFixedColumns.d.ts.map +1 -0
  27. package/dist/components/data/sheet/hooks/{useDataSheetFixedColumns.js → createDataSheetFixedColumns.js} +3 -3
  28. package/dist/components/data/sheet/hooks/{useDataSheetFixedColumns.js.map → createDataSheetFixedColumns.js.map} +2 -2
  29. package/dist/components/data/sheet/hooks/{useDataSheetHeaderCell.d.ts → createDataSheetHeaderCell.d.ts} +3 -3
  30. package/dist/components/data/sheet/hooks/createDataSheetHeaderCell.d.ts.map +1 -0
  31. package/dist/components/data/sheet/hooks/{useDataSheetHeaderCell.js → createDataSheetHeaderCell.js} +3 -3
  32. package/dist/components/data/sheet/hooks/{useDataSheetHeaderCell.js.map → createDataSheetHeaderCell.js.map} +3 -3
  33. package/dist/components/data/sheet/hooks/{useDataSheetPaging.d.ts → createDataSheetPaging.d.ts} +4 -4
  34. package/dist/components/data/sheet/hooks/createDataSheetPaging.d.ts.map +1 -0
  35. package/dist/components/data/sheet/hooks/{useDataSheetPaging.js → createDataSheetPaging.js} +3 -3
  36. package/dist/components/data/sheet/hooks/{useDataSheetPaging.js.map → createDataSheetPaging.js.map} +2 -2
  37. package/dist/components/data/sheet/hooks/{useDataSheetReorder.d.ts → createDataSheetReorder.d.ts} +3 -3
  38. package/dist/components/data/sheet/hooks/createDataSheetReorder.d.ts.map +1 -0
  39. package/dist/components/data/sheet/hooks/{useDataSheetReorder.js → createDataSheetReorder.js} +3 -3
  40. package/dist/components/data/sheet/hooks/{useDataSheetReorder.js.map → createDataSheetReorder.js.map} +2 -2
  41. package/dist/components/data/sheet/hooks/{useDataSheetSelection.d.ts → createDataSheetSelection.d.ts} +4 -4
  42. package/dist/components/data/sheet/hooks/createDataSheetSelection.d.ts.map +1 -0
  43. package/dist/components/data/sheet/hooks/{useDataSheetSelection.js → createDataSheetSelection.js} +3 -3
  44. package/dist/components/data/sheet/hooks/{useDataSheetSelection.js.map → createDataSheetSelection.js.map} +2 -2
  45. package/dist/components/data/sheet/hooks/{useDataSheetSorting.d.ts → createDataSheetSorting.d.ts} +4 -4
  46. package/dist/components/data/sheet/hooks/createDataSheetSorting.d.ts.map +1 -0
  47. package/dist/components/data/sheet/hooks/{useDataSheetSorting.js → createDataSheetSorting.js} +3 -3
  48. package/dist/components/data/sheet/hooks/{useDataSheetSorting.js.map → createDataSheetSorting.js.map} +2 -2
  49. package/dist/components/disclosure/Dialog.d.ts +2 -2
  50. package/dist/components/disclosure/Dialog.d.ts.map +1 -1
  51. package/dist/components/disclosure/Dialog.js +4 -4
  52. package/dist/components/disclosure/Dialog.js.map +2 -2
  53. package/dist/components/disclosure/Tabs.js +3 -3
  54. package/dist/components/disclosure/Tabs.js.map +2 -2
  55. package/dist/components/features/crud-sheet/CrudSheet.js +3 -3
  56. package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
  57. package/dist/components/features/data-select-button/DataSelectButton.d.ts +23 -9
  58. package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -1
  59. package/dist/components/features/data-select-button/DataSelectButton.js +1 -1
  60. package/dist/components/features/data-select-button/DataSelectButton.js.map +1 -1
  61. package/dist/components/features/permission-table/PermissionTable.js +2 -2
  62. package/dist/components/features/permission-table/PermissionTable.js.map +2 -2
  63. package/dist/components/features/shared-data/SharedDataSelect.d.ts +23 -9
  64. package/dist/components/features/shared-data/SharedDataSelect.d.ts.map +1 -1
  65. package/dist/components/features/shared-data/SharedDataSelect.js.map +1 -1
  66. package/dist/components/features/shared-data/SharedDataSelectButton.d.ts +25 -10
  67. package/dist/components/features/shared-data/SharedDataSelectButton.d.ts.map +1 -1
  68. package/dist/components/features/shared-data/SharedDataSelectButton.js.map +1 -1
  69. package/dist/components/features/shared-data/SharedDataSelectList.js +1 -1
  70. package/dist/components/features/shared-data/SharedDataSelectList.js.map +2 -2
  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/Progress.js +3 -3
  74. package/dist/components/feedback/Progress.js.map +2 -2
  75. package/dist/components/form-control/Button.js +2 -2
  76. package/dist/components/form-control/Button.js.map +2 -2
  77. package/dist/components/form-control/DropdownTrigger.styles.js +2 -2
  78. package/dist/components/form-control/DropdownTrigger.styles.js.map +1 -1
  79. package/dist/components/form-control/ThemeToggle.js +4 -4
  80. package/dist/components/form-control/ThemeToggle.js.map +2 -2
  81. package/dist/components/form-control/checkbox/Checkbox.d.ts +3 -3
  82. package/dist/components/form-control/checkbox/Checkbox.d.ts.map +1 -1
  83. package/dist/components/form-control/checkbox/Checkbox.styles.d.ts.map +1 -1
  84. package/dist/components/form-control/checkbox/Checkbox.styles.js +3 -3
  85. package/dist/components/form-control/checkbox/Checkbox.styles.js.map +1 -1
  86. package/dist/components/form-control/checkbox/CheckboxGroup.js +2 -2
  87. package/dist/components/form-control/checkbox/CheckboxGroup.js.map +2 -2
  88. package/dist/components/form-control/checkbox/Radio.d.ts +3 -3
  89. package/dist/components/form-control/checkbox/Radio.d.ts.map +1 -1
  90. package/dist/components/form-control/checkbox/RadioGroup.js +2 -2
  91. package/dist/components/form-control/checkbox/RadioGroup.js.map +2 -2
  92. package/dist/components/form-control/checkbox/SelectableBase.d.ts +3 -3
  93. package/dist/components/form-control/checkbox/SelectableBase.d.ts.map +1 -1
  94. package/dist/components/form-control/checkbox/SelectableBase.js +10 -10
  95. package/dist/components/form-control/checkbox/SelectableBase.js.map +2 -2
  96. package/dist/components/form-control/color-picker/ColorPicker.js +2 -2
  97. package/dist/components/form-control/color-picker/ColorPicker.js.map +2 -2
  98. package/dist/components/form-control/date-range-picker/DateRangePicker.js +1 -1
  99. package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
  100. package/dist/components/form-control/editor/EditorToolbar.js +1 -1
  101. package/dist/components/form-control/editor/EditorToolbar.js.map +2 -2
  102. package/dist/components/form-control/editor/RichTextEditor.js +2 -2
  103. package/dist/components/form-control/editor/RichTextEditor.js.map +2 -2
  104. package/dist/components/form-control/field/Field.styles.js +7 -7
  105. package/dist/components/form-control/field/Field.styles.js.map +1 -1
  106. package/dist/components/form-control/field/NumberInput.js +1 -1
  107. package/dist/components/form-control/field/NumberInput.js.map +1 -1
  108. package/dist/components/form-control/field/TextInput.js +1 -1
  109. package/dist/components/form-control/field/TextInput.js.map +1 -1
  110. package/dist/components/form-control/field/Textarea.js +1 -1
  111. package/dist/components/form-control/field/Textarea.js.map +1 -1
  112. package/dist/components/form-control/numpad/Numpad.d.ts +2 -2
  113. package/dist/components/form-control/numpad/Numpad.d.ts.map +1 -1
  114. package/dist/components/form-control/numpad/Numpad.js +4 -4
  115. package/dist/components/form-control/numpad/Numpad.js.map +2 -2
  116. package/dist/components/form-control/select/Select.js +1 -1
  117. package/dist/components/form-control/select/Select.js.map +2 -2
  118. package/dist/components/form-control/state-preset/StatePreset.js +8 -8
  119. package/dist/components/form-control/state-preset/StatePreset.js.map +2 -2
  120. package/dist/components/layout/topbar/Topbar.js +3 -3
  121. package/dist/components/layout/topbar/Topbar.js.map +2 -2
  122. package/dist/providers/PwaUpdateProvider.d.ts.map +1 -1
  123. package/dist/providers/PwaUpdateProvider.js +11 -4
  124. package/dist/providers/PwaUpdateProvider.js.map +2 -2
  125. package/dist/styles/control.styles.d.ts +3 -3
  126. package/dist/styles/control.styles.d.ts.map +1 -1
  127. package/dist/styles/control.styles.js +2 -2
  128. package/dist/styles/control.styles.js.map +1 -1
  129. package/docs/data.md +204 -0
  130. package/docs/disclosure.md +139 -0
  131. package/docs/display.md +125 -0
  132. package/docs/features.md +282 -0
  133. package/docs/feedback.md +136 -0
  134. package/docs/form-controls.md +520 -0
  135. package/docs/helpers.md +172 -0
  136. package/docs/hooks.md +146 -0
  137. package/docs/layout.md +94 -0
  138. package/docs/providers.md +179 -0
  139. package/package.json +19 -18
  140. package/src/components/data/Pagination.tsx +2 -2
  141. package/src/components/data/Table.tsx +2 -2
  142. package/src/components/data/calendar/Calendar.tsx +2 -2
  143. package/src/components/data/kanban/Kanban.tsx +2 -2
  144. package/src/components/data/list/ListItem.styles.ts +1 -1
  145. package/src/components/data/list/ListItem.tsx +1 -1
  146. package/src/components/data/sheet/DataSheet.styles.ts +2 -2
  147. package/src/components/data/sheet/DataSheet.tsx +16 -16
  148. package/src/components/data/sheet/DataSheetConfigDialog.tsx +5 -5
  149. package/src/components/data/sheet/hooks/{useDataSheetExpansion.ts → createDataSheetExpansion.ts} +5 -5
  150. package/src/components/data/sheet/hooks/{useDataSheetFixedColumns.ts → createDataSheetFixedColumns.ts} +3 -3
  151. package/src/components/data/sheet/hooks/{useDataSheetHeaderCell.tsx → createDataSheetHeaderCell.tsx} +2 -2
  152. package/src/components/data/sheet/hooks/{useDataSheetPaging.ts → createDataSheetPaging.ts} +5 -5
  153. package/src/components/data/sheet/hooks/{useDataSheetReorder.ts → createDataSheetReorder.ts} +3 -3
  154. package/src/components/data/sheet/hooks/{useDataSheetSelection.ts → createDataSheetSelection.ts} +5 -5
  155. package/src/components/data/sheet/hooks/{useDataSheetSorting.ts → createDataSheetSorting.ts} +5 -5
  156. package/src/components/disclosure/Dialog.tsx +5 -5
  157. package/src/components/disclosure/Tabs.tsx +3 -3
  158. package/src/components/features/crud-sheet/CrudSheet.tsx +3 -3
  159. package/src/components/features/data-select-button/DataSelectButton.tsx +42 -11
  160. package/src/components/features/permission-table/PermissionTable.tsx +2 -2
  161. package/src/components/features/shared-data/SharedDataSelect.tsx +45 -14
  162. package/src/components/features/shared-data/SharedDataSelectButton.tsx +38 -11
  163. package/src/components/features/shared-data/SharedDataSelectList.tsx +1 -1
  164. package/src/components/feedback/Progress.tsx +4 -4
  165. package/src/components/form-control/Button.tsx +2 -2
  166. package/src/components/form-control/DropdownTrigger.styles.ts +2 -2
  167. package/src/components/form-control/ThemeToggle.tsx +4 -4
  168. package/src/components/form-control/checkbox/Checkbox.styles.ts +3 -3
  169. package/src/components/form-control/checkbox/Checkbox.tsx +3 -3
  170. package/src/components/form-control/checkbox/CheckboxGroup.tsx +2 -2
  171. package/src/components/form-control/checkbox/Radio.tsx +3 -3
  172. package/src/components/form-control/checkbox/RadioGroup.tsx +2 -2
  173. package/src/components/form-control/checkbox/SelectableBase.tsx +15 -15
  174. package/src/components/form-control/color-picker/ColorPicker.tsx +2 -2
  175. package/src/components/form-control/date-range-picker/DateRangePicker.tsx +1 -1
  176. package/src/components/form-control/editor/EditorToolbar.tsx +1 -1
  177. package/src/components/form-control/editor/RichTextEditor.tsx +2 -2
  178. package/src/components/form-control/field/Field.styles.ts +7 -7
  179. package/src/components/form-control/field/NumberInput.tsx +1 -1
  180. package/src/components/form-control/field/TextInput.tsx +1 -1
  181. package/src/components/form-control/field/Textarea.tsx +1 -1
  182. package/src/components/form-control/numpad/Numpad.tsx +6 -6
  183. package/src/components/form-control/select/Select.tsx +1 -1
  184. package/src/components/form-control/state-preset/StatePreset.tsx +9 -9
  185. package/src/components/layout/topbar/Topbar.tsx +3 -3
  186. package/src/providers/PwaUpdateProvider.tsx +12 -5
  187. package/src/styles/control.styles.ts +3 -3
  188. package/tests/components/data/sheet/hooks/{useDataSheetExpansion.spec.ts → createDataSheetExpansion.spec.ts} +16 -16
  189. package/tests/components/data/sheet/hooks/{useDataSheetFixedColumns.spec.ts → createDataSheetFixedColumns.spec.ts} +27 -27
  190. package/tests/components/data/sheet/hooks/{useDataSheetPaging.spec.ts → createDataSheetPaging.spec.ts} +16 -16
  191. package/tests/components/data/sheet/hooks/{useDataSheetReorder.spec.ts → createDataSheetReorder.spec.ts} +14 -14
  192. package/tests/components/data/sheet/hooks/{useDataSheetSelection.spec.ts → createDataSheetSelection.spec.ts} +26 -26
  193. package/tests/components/data/sheet/hooks/{useDataSheetSorting.spec.ts → createDataSheetSorting.spec.ts} +13 -13
  194. package/tests/components/disclosure/Dialog.spec.tsx +2 -2
  195. package/tests/components/features/data-select-button/DataSelectButton.spec.tsx +55 -6
  196. package/tests/components/features/shared-data/SharedDataSelect.spec.tsx +40 -0
  197. package/tests/components/form-control/checkbox/Checkbox.spec.tsx +8 -8
  198. package/tests/components/form-control/checkbox/Radio.spec.tsx +9 -9
  199. package/tests/components/form-control/numpad/Numpad.spec.tsx +10 -10
  200. package/dist/components/data/sheet/hooks/useDataSheetExpansion.d.ts.map +0 -1
  201. package/dist/components/data/sheet/hooks/useDataSheetFixedColumns.d.ts.map +0 -1
  202. package/dist/components/data/sheet/hooks/useDataSheetHeaderCell.d.ts.map +0 -1
  203. package/dist/components/data/sheet/hooks/useDataSheetPaging.d.ts.map +0 -1
  204. package/dist/components/data/sheet/hooks/useDataSheetReorder.d.ts.map +0 -1
  205. package/dist/components/data/sheet/hooks/useDataSheetSelection.d.ts.map +0 -1
  206. package/dist/components/data/sheet/hooks/useDataSheetSorting.d.ts.map +0 -1
@@ -0,0 +1,282 @@
1
+ # Features
2
+
3
+ High-level, domain-specific components built on top of the core primitives.
4
+
5
+ ## CrudSheet
6
+
7
+ ```typescript
8
+ interface CrudSheetBaseProps<TItem, TFilter> {
9
+ search(filter: TFilter, page: number | undefined, sorts: SortingDef[]): Promise<SearchResult<TItem>>;
10
+ getItemKey(item: TItem): string | number | undefined;
11
+ storageKey?: string;
12
+ editable?: boolean;
13
+ isItemEditable?: (item: TItem) => boolean;
14
+ isItemDeletable?: (item: TItem) => boolean;
15
+ isItemDeleted?: (item: TItem) => boolean;
16
+ isItemSelectable?: (item: TItem) => boolean | string;
17
+ lastModifiedAtProp?: string;
18
+ lastModifiedByProp?: string;
19
+ filterInitial?: TFilter;
20
+ items?: TItem[];
21
+ onItemsChange?: (items: TItem[]) => void;
22
+ excel?: ExcelConfig<TItem>;
23
+ selectionMode?: "single" | "multiple";
24
+ onSelect?: (result: SelectResult<TItem>) => void;
25
+ onSubmitComplete?: () => void;
26
+ hideAutoTools?: boolean;
27
+ close?: () => void;
28
+ class?: string;
29
+ children: JSX.Element;
30
+ }
31
+ ```
32
+
33
+ Full CRUD data grid built on `DataSheet`. Supports two editing modes:
34
+
35
+ **Inline editing** — edit cells directly in the grid:
36
+ ```typescript
37
+ interface InlineEditConfig<TItem> {
38
+ submit(diffs: ArrayOneWayDiffResult<TItem>[]): Promise<void>;
39
+ newItem(): TItem;
40
+ deleteProp?: keyof TItem & string;
41
+ diffsExcludes?: string[];
42
+ }
43
+ ```
44
+
45
+ **Dialog editing** — edit records in a dialog:
46
+ ```typescript
47
+ interface DialogEditConfig<TItem> {
48
+ editItem(item?: TItem): Promise<boolean | undefined>;
49
+ deleteItems?(items: TItem[]): Promise<boolean>;
50
+ restoreItems?(items: TItem[]): Promise<boolean>;
51
+ }
52
+ ```
53
+
54
+ **Sub-components:**
55
+ - `CrudSheet.Column` — extends `DataSheet.Column` with `editTrigger` prop
56
+ - `CrudSheet.Filter` — filter form area
57
+ - `CrudSheet.Tools` — custom toolbar buttons
58
+ - `CrudSheet.Header` — custom header content
59
+
60
+ **Context:** `CrudSheetContext<TItem>` — access internal state via context:
61
+ ```typescript
62
+ interface CrudSheetContext<TItem> {
63
+ items(): TItem[];
64
+ selection(): TItem[];
65
+ page(): number;
66
+ sorts(): SortingDef[];
67
+ busy(): boolean;
68
+ hasChanges(): boolean;
69
+ save(): Promise<void>;
70
+ refresh(): Promise<void>;
71
+ addItem(): void;
72
+ clearSelection(): void;
73
+ setPage(page: number): void;
74
+ setSorts(sorts: SortingDef[]): void;
75
+ }
76
+ ```
77
+
78
+ ---
79
+
80
+ ## CrudDetail
81
+
82
+ ```typescript
83
+ interface CrudDetailProps<TData extends object> {
84
+ load(): Promise<{ data: TData; info: CrudDetailInfo }>;
85
+ children(ctx: CrudDetailContext<TData>): JSX.Element;
86
+ submit?(data: TData): Promise<boolean | undefined>;
87
+ toggleDelete?(del: boolean): Promise<boolean | undefined>;
88
+ editable?: boolean;
89
+ deletable?: boolean;
90
+ data?: TData;
91
+ onDataChange?: (data: TData) => void;
92
+ close?(result?: boolean): void;
93
+ class?: string;
94
+ }
95
+
96
+ interface CrudDetailContext<TData> {
97
+ data: TData;
98
+ setData: SetStoreFunction<TData>;
99
+ info(): CrudDetailInfo;
100
+ busy(): boolean;
101
+ hasChanges(): boolean;
102
+ save(): Promise<void>;
103
+ refresh(): Promise<void>;
104
+ }
105
+
106
+ interface CrudDetailInfo {
107
+ isNew: boolean;
108
+ isDeleted: boolean;
109
+ lastModifiedAt?: DateTime;
110
+ lastModifiedBy?: string;
111
+ }
112
+ ```
113
+
114
+ Single-record CRUD detail form. `load` fetches data, `submit` saves changes, `toggleDelete` handles soft-delete. The `children` render prop receives a context with reactive data and mutation helpers.
115
+
116
+ **Sub-components:**
117
+ - `CrudDetail.Tools` — custom toolbar
118
+ - `CrudDetail.Before` — content before the form
119
+ - `CrudDetail.After` — content after the form
120
+
121
+ ---
122
+
123
+ ## SharedDataSelect
124
+
125
+ ```typescript
126
+ interface SharedDataSelectCommonProps<TItem, TKey, TDialogProps> {
127
+ data: SharedDataAccessor<TItem>;
128
+ required?: boolean;
129
+ disabled?: boolean;
130
+ size?: ComponentSize;
131
+ inset?: boolean;
132
+ filterFn?: (item: TItem, index: number) => boolean;
133
+ dialog?: Component<TDialogProps>;
134
+ dialogOptions?: DialogShowOptions;
135
+ children: JSX.Element;
136
+ }
137
+
138
+ // Single: { multiple?: false; value?: TKey; onValueChange?: (value: TKey | undefined) => void }
139
+ // Multiple: { multiple: true; value?: TKey[]; onValueChange?: (value: TKey[]) => void }
140
+ ```
141
+
142
+ Select component bound to `SharedDataProvider` data. Automatically uses the shared data's search text and hidden item logic. Optionally opens a dialog for advanced selection.
143
+
144
+ **Sub-components:** `SharedDataSelect.ItemTemplate`, `SharedDataSelect.Action`
145
+
146
+ ---
147
+
148
+ ## SharedDataSelectButton
149
+
150
+ ```typescript
151
+ interface SharedDataSelectButtonCommonProps<TItem, TDialogProps> {
152
+ data: SharedDataAccessor<TItem>;
153
+ required?: boolean;
154
+ disabled?: boolean;
155
+ size?: ComponentSize;
156
+ inset?: boolean;
157
+ dialog: Component<TDialogProps>;
158
+ dialogOptions?: DialogShowOptions;
159
+ children(item: TItem): JSX.Element;
160
+ }
161
+ ```
162
+
163
+ Button that opens a dialog for selecting shared data items. Displays the selected item(s) using the `children` render prop.
164
+
165
+ ---
166
+
167
+ ## SharedDataSelectList
168
+
169
+ ```typescript
170
+ interface SharedDataSelectListProps<TItem> {
171
+ data: SharedDataAccessor<TItem>;
172
+ value?: TItem;
173
+ onValueChange?: (value: TItem | undefined) => void;
174
+ required?: boolean;
175
+ disabled?: boolean;
176
+ filterFn?: (item: TItem, index: number) => boolean;
177
+ canChange?: (item: TItem | undefined) => boolean | Promise<boolean>;
178
+ pageSize?: number;
179
+ header?: JSX.Element;
180
+ children?: JSX.Element;
181
+ class?: string;
182
+ style?: JSX.CSSProperties;
183
+ }
184
+ ```
185
+
186
+ List view for selecting from shared data. Supports pagination, filtering, and custom item templates.
187
+
188
+ **Sub-components:** `SharedDataSelectList.ItemTemplate`, `SharedDataSelectList.Filter`
189
+
190
+ ---
191
+
192
+ ## DataSelectButton
193
+
194
+ ```typescript
195
+ interface DataSelectButtonCommonProps<TItem, TKey, TDialogProps> {
196
+ load(keys: TKey[]): TItem[] | Promise<TItem[]>;
197
+ renderItem(item: TItem): JSX.Element;
198
+ dialog: Component<TDialogProps>;
199
+ dialogOptions?: DialogShowOptions;
200
+ required?: boolean;
201
+ disabled?: boolean;
202
+ size?: ComponentSize;
203
+ inset?: boolean;
204
+ validate?: (value: unknown) => string | undefined;
205
+ lazyValidation?: boolean;
206
+ }
207
+
208
+ // Single: { multiple?: false; value?: TKey; onValueChange?: (value: TKey | undefined) => void }
209
+ // Multiple: { multiple: true; value?: TKey[]; onValueChange?: (value: TKey[]) => void }
210
+ ```
211
+
212
+ Button that opens a dialog for selecting data items. Unlike `SharedDataSelect`, this is not tied to `SharedDataProvider` — it uses a custom `load` function to resolve selected keys to items, and a custom `dialog` for the selection UI.
213
+
214
+ ---
215
+
216
+ ## AddressSearch
217
+
218
+ ```typescript
219
+ interface AddressSearchResult {
220
+ postNumber?: string;
221
+ address?: string;
222
+ buildingName?: string;
223
+ }
224
+ ```
225
+
226
+ Korean address search dialog content component. Use with `dialog.show(AddressSearchContent, {})` to open. Returns `AddressSearchResult` on selection.
227
+
228
+ ---
229
+
230
+ ## PermissionTable
231
+
232
+ ```typescript
233
+ interface PermissionTableProps<TModule> {
234
+ items?: AppPerm<TModule>[];
235
+ value?: Record<string, boolean>;
236
+ onValueChange?: (value: Record<string, boolean>) => void;
237
+ modules?: TModule[];
238
+ disabled?: boolean;
239
+ class?: string;
240
+ style?: JSX.CSSProperties;
241
+ }
242
+ ```
243
+
244
+ Renders a permission matrix from `AppPerm` tree structure. `value` is a `Record<permCode, boolean>` map.
245
+
246
+ **Utility functions:**
247
+ - `collectAllPerms(items)` — extracts all permission codes from the tree
248
+ - `filterByModules(items, modules)` — filters permissions by active modules
249
+ - `changePermCheck(value, item, perm, checked)` — returns new value with cascading check/uncheck logic
250
+
251
+ ---
252
+
253
+ ## Usage Examples
254
+
255
+ ```typescript
256
+ import { CrudSheet, CrudDetail, SharedDataSelect } from "@simplysm/solid";
257
+
258
+ // CrudSheet with inline editing
259
+ <CrudSheet
260
+ search={(filter, page, sorts) => api.searchUsers(filter, page, sorts)}
261
+ getItemKey={(item) => item.id}
262
+ inlineEdit={{
263
+ submit: (diffs) => api.saveUsers(diffs),
264
+ newItem: () => ({ id: undefined, name: "", age: 0 }),
265
+ }}
266
+ storageKey="users"
267
+ >
268
+ <CrudSheet.Filter>
269
+ <TextInput value={filter.name} onValueChange={(v) => setFilter("name", v)} />
270
+ </CrudSheet.Filter>
271
+ <CrudSheet.Column key="name" header="Name" sortable editTrigger>
272
+ {(ctx) => <TextInput value={ctx.item.name} onValueChange={(v) => ctx.setItem("name", v)} inset />}
273
+ </CrudSheet.Column>
274
+ </CrudSheet>
275
+
276
+ // SharedDataSelect
277
+ <SharedDataSelect data={sharedData.departments} value={deptId()} onValueChange={setDeptId}>
278
+ <SharedDataSelect.ItemTemplate>
279
+ {(item) => item.name}
280
+ </SharedDataSelect.ItemTemplate>
281
+ </SharedDataSelect>
282
+ ```
@@ -0,0 +1,136 @@
1
+ # Feedback
2
+
3
+ ## Notification System
4
+
5
+ ### NotificationProvider / useNotification
6
+
7
+ ```typescript
8
+ type NotificationTheme = "info" | "success" | "warning" | "danger";
9
+
10
+ interface NotificationContextValue {
11
+ items: Accessor<NotificationItem[]>;
12
+ unreadCount: Accessor<number>;
13
+ latestUnread: Accessor<NotificationItem | undefined>;
14
+
15
+ info(title: string, message?: string, options?: NotificationOptions): string;
16
+ success(title: string, message?: string, options?: NotificationOptions): string;
17
+ warning(title: string, message?: string, options?: NotificationOptions): string;
18
+ danger(title: string, message?: string, options?: NotificationOptions): string;
19
+ error(err?: any, header?: string): void;
20
+
21
+ update(id: string, updates: Partial<NotificationItem>, options?: NotificationUpdateOptions): void;
22
+ remove(id: string): void;
23
+ markAsRead(id: string): void;
24
+ markAllAsRead(): void;
25
+ dismissBanner(): void;
26
+ clear(): void;
27
+ }
28
+ ```
29
+
30
+ Centralized notification management. Each `info`/`success`/`warning`/`danger` call creates a notification and returns its `id`. Use `error(err)` to display an error object as a danger notification.
31
+
32
+ ### NotificationBell
33
+
34
+ ```typescript
35
+ interface NotificationBellProps {
36
+ showBanner?: boolean;
37
+ }
38
+ ```
39
+
40
+ Bell icon button showing unread notification count. Set `showBanner` to display the latest notification as a banner.
41
+
42
+ ### NotificationBanner
43
+
44
+ Displays the latest unread notification as a dismissible banner. No props.
45
+
46
+ ---
47
+
48
+ ## Busy Overlay
49
+
50
+ ### BusyProvider / useBusy
51
+
52
+ ```typescript
53
+ type BusyVariant = "spinner" | "bar";
54
+
55
+ interface BusyContextValue {
56
+ variant: Accessor<BusyVariant>;
57
+ show(message?: string): void;
58
+ hide(): void;
59
+ setProgress(percent: number | undefined): void;
60
+ }
61
+
62
+ interface BusyProviderProps {
63
+ variant?: BusyVariant;
64
+ }
65
+ ```
66
+
67
+ Full-screen loading overlay with nestable `show`/`hide` calls (managed with an internal counter). Each `show` must have a matching `hide`.
68
+
69
+ - `variant="spinner"` — centered spinner (default)
70
+ - `variant="bar"` — top progress bar animation
71
+ - `setProgress(percent)` — display a determinate progress bar (0–100, `undefined` for indeterminate)
72
+
73
+ ### BusyContainer
74
+
75
+ ```typescript
76
+ interface BusyContainerProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> {
77
+ busy?: boolean;
78
+ ready?: boolean;
79
+ variant?: BusyVariant;
80
+ message?: string;
81
+ progressPercent?: number;
82
+ children?: JSX.Element;
83
+ }
84
+ ```
85
+
86
+ Local loading overlay for a specific container. Two modes:
87
+ - `busy` — shows overlay while preserving children
88
+ - `ready={false}` — hides children entirely until data is loaded
89
+
90
+ ---
91
+
92
+ ## Print System
93
+
94
+ ### PrintProvider / usePrint
95
+
96
+ ```typescript
97
+ interface PrintContextValue {
98
+ toPrinter(factory: () => JSX.Element, options?: PrintOptions): Promise<void>;
99
+ toPdf(factory: () => JSX.Element, options?: PrintOptions): Promise<Uint8Array>;
100
+ }
101
+
102
+ interface PrintOptions {
103
+ size?: string;
104
+ margin?: string;
105
+ }
106
+ ```
107
+
108
+ Print and PDF generation. `toPrinter` opens the browser print dialog. `toPdf` generates a PDF as a byte array.
109
+
110
+ ### Print
111
+
112
+ Component used inside the print factory to signal readiness via `usePrintInstance().ready()`.
113
+
114
+ ---
115
+
116
+ ## Usage Examples
117
+
118
+ ```typescript
119
+ import { useNotification, useBusy, BusyContainer } from "@simplysm/solid";
120
+
121
+ // Notifications
122
+ const notification = useNotification();
123
+ notification.success("Saved", "Record updated successfully");
124
+ notification.error(new Error("Connection failed"));
125
+
126
+ // Global loading
127
+ const busy = useBusy();
128
+ busy.show("Loading data...");
129
+ try { await fetchData(); }
130
+ finally { busy.hide(); }
131
+
132
+ // Local loading container
133
+ <BusyContainer busy={isLoading()} variant="spinner">
134
+ <DataContent />
135
+ </BusyContainer>
136
+ ```