@simplysm/solid 13.0.97 → 13.0.98

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.
@@ -0,0 +1,164 @@
1
+ # Disclosure Components
2
+
3
+ Source: `src/components/disclosure/**/*.tsx`
4
+
5
+ ## Collapse
6
+
7
+ Animated expand/collapse container using margin-top transition.
8
+
9
+ ```ts
10
+ interface CollapseProps extends JSX.HTMLAttributes<HTMLDivElement> {
11
+ open?: boolean; // default: false
12
+ }
13
+ ```
14
+
15
+ - Uses `ResizeObserver` to track content height.
16
+ - Disables transition on initial render to prevent flicker.
17
+ - Sets `visibility: hidden` when closed to prevent focusable element access.
18
+
19
+ ## Dropdown
20
+
21
+ Positioned popup with trigger element. Uses Portal for rendering.
22
+
23
+ ```ts
24
+ interface DropdownProps {
25
+ position?: { x: number; y: number }; // absolute position (for context menus)
26
+ open?: boolean;
27
+ onOpenChange?: (open: boolean) => void;
28
+ maxHeight?: number; // default: 300
29
+ disabled?: boolean;
30
+ keyboardNav?: boolean; // arrow key navigation
31
+ class?: string;
32
+ style?: JSX.CSSProperties;
33
+ children: JSX.Element;
34
+ }
35
+ ```
36
+
37
+ - Auto-positions above or below trigger based on available viewport space.
38
+ - Closes on outside click, Escape key, scroll, and resize.
39
+ - `keyboardNav`: ArrowDown/Up navigates between tabbable items in popup.
40
+
41
+ ### Sub-components
42
+
43
+ - **`Dropdown.Trigger`** -- Click target that toggles the dropdown. Slot component.
44
+ - **`Dropdown.Content`** -- Popup content. Slot component.
45
+
46
+ ## Dialog
47
+
48
+ Modal or floating dialog with drag, resize, z-index management, and animation.
49
+
50
+ ```ts
51
+ interface DialogProps {
52
+ open?: boolean;
53
+ onOpenChange?: (open: boolean) => void;
54
+ withCloseButton?: boolean; // default: true
55
+ closeOnInteractOutside?: boolean; // default: false (uses DialogDefaults)
56
+ closeOnEscape?: boolean; // default: true (uses DialogDefaults)
57
+ resizable?: boolean; // default: false
58
+ draggable?: boolean; // default: true
59
+ mode?: "float" | "fill";
60
+ width?: number;
61
+ height?: number;
62
+ minWidth?: number;
63
+ minHeight?: number;
64
+ position?: "bottom-right" | "top-right";
65
+ headerStyle?: JSX.CSSProperties | string;
66
+ beforeClose?: () => boolean; // return false to prevent close
67
+ onCloseComplete?: () => void;
68
+ class?: string;
69
+ }
70
+ ```
71
+
72
+ - `mode="float"`: no backdrop, pointer-events pass through.
73
+ - `mode="fill"`: full-screen dialog.
74
+ - 8-direction resize handles when `resizable=true`.
75
+ - Automatic z-index stacking across multiple open dialogs.
76
+
77
+ ### Sub-components
78
+
79
+ - **`Dialog.Header`** -- Dialog title bar. Enables drag when `draggable=true`.
80
+ - **`Dialog.Action`** -- Action buttons rendered in the header next to the close button.
81
+
82
+ ## DialogProvider
83
+
84
+ Programmatic dialog provider. Enables `useDialog().show()` to open dialogs as Promises.
85
+
86
+ ```ts
87
+ interface DialogProviderProps extends DialogDefaults {}
88
+
89
+ interface DialogDefaults {
90
+ closeOnEscape?: boolean;
91
+ closeOnInteractOutside?: boolean;
92
+ }
93
+ ```
94
+
95
+ ### useDialog()
96
+
97
+ Hook to open dialogs programmatically.
98
+
99
+ ```ts
100
+ function useDialog(): DialogContextValue;
101
+
102
+ interface DialogContextValue {
103
+ show<P extends Record<string, any>>(
104
+ component: Component<P>,
105
+ props: Omit<P, "close">,
106
+ options?: DialogShowOptions,
107
+ ): Promise<ExtractCloseResult<P> | undefined>;
108
+ }
109
+
110
+ interface DialogShowOptions {
111
+ header?: JSX.Element;
112
+ withCloseButton?: boolean;
113
+ closeOnInteractOutside?: boolean;
114
+ closeOnEscape?: boolean;
115
+ resizable?: boolean;
116
+ draggable?: boolean;
117
+ mode?: "float" | "fill";
118
+ width?: number;
119
+ height?: number;
120
+ minWidth?: number;
121
+ minHeight?: number;
122
+ position?: "bottom-right" | "top-right";
123
+ headerStyle?: JSX.CSSProperties | string;
124
+ beforeClose?: () => boolean;
125
+ }
126
+ ```
127
+
128
+ The dialog component receives a `close` prop. Call `close(result)` to resolve the Promise.
129
+
130
+ ### DialogDefaultsContext
131
+
132
+ Context providing default dialog configuration. Used by `Dialog` when per-instance props are not set.
133
+
134
+ ```ts
135
+ const DialogDefaultsContext: Context<Accessor<DialogDefaults>>;
136
+ ```
137
+
138
+ ## Tabs
139
+
140
+ Tab bar with value-based selection.
141
+
142
+ ```ts
143
+ interface TabsProps {
144
+ value?: string;
145
+ onValueChange?: (value: string) => void;
146
+ size?: ComponentSize;
147
+ class?: string;
148
+ style?: JSX.CSSProperties;
149
+ children?: JSX.Element;
150
+ }
151
+ ```
152
+
153
+ ### Sub-components
154
+
155
+ - **`Tabs.Tab`** -- Individual tab button.
156
+
157
+ ```ts
158
+ interface TabsTabProps {
159
+ value: string;
160
+ disabled?: boolean;
161
+ class?: string;
162
+ children?: JSX.Element;
163
+ }
164
+ ```
@@ -0,0 +1,94 @@
1
+ # Display Components
2
+
3
+ Source: `src/components/display/**/*.tsx`
4
+
5
+ ## Barcode
6
+
7
+ SVG barcode renderer powered by bwip-js.
8
+
9
+ ```ts
10
+ interface BarcodeProps extends JSX.HTMLAttributes<HTMLDivElement> {
11
+ type: BarcodeType;
12
+ value?: string;
13
+ }
14
+ ```
15
+
16
+ ### BarcodeType
17
+
18
+ Union type of all supported barcode formats. Common values include: `"qrcode"`, `"code128"`, `"ean13"`, `"datamatrix"`, `"pdf417"`, `"azteccode"`, `"code39"`, `"upca"`, `"isbn"`.
19
+
20
+ Full list exported from `src/components/display/Barcode.types.ts` with 100+ formats.
21
+
22
+ ## Card
23
+
24
+ Elevated container with shadow and fade-in animation.
25
+
26
+ ```ts
27
+ interface CardProps extends JSX.HTMLAttributes<HTMLDivElement> {}
28
+ ```
29
+
30
+ Applies surface background, rounded corners, shadow with hover/focus-within elevation.
31
+
32
+ ## Echarts
33
+
34
+ Apache ECharts wrapper with reactive option updates and resize handling.
35
+
36
+ ```ts
37
+ interface EchartsProps extends JSX.HTMLAttributes<HTMLDivElement> {
38
+ option: echarts.EChartsOption;
39
+ busy?: boolean; // shows/hides loading indicator
40
+ }
41
+ ```
42
+
43
+ - Uses SVG renderer.
44
+ - Automatically resizes with container via `ResizeObserver`.
45
+
46
+ ## Icon
47
+
48
+ Tabler icon wrapper using `Dynamic` rendering.
49
+
50
+ ```ts
51
+ interface IconProps extends Omit<TablerIconProps, "size"> {
52
+ icon: Component<TablerIconProps>;
53
+ size?: string | number; // default: "1.25em"
54
+ }
55
+ ```
56
+
57
+ Adds `inline` display and vertical alignment.
58
+
59
+ ## Tag
60
+
61
+ Themed inline tag/badge with solid background.
62
+
63
+ ```ts
64
+ type TagTheme = SemanticTheme;
65
+
66
+ interface TagProps extends JSX.HTMLAttributes<HTMLSpanElement> {
67
+ theme?: TagTheme; // default: "base"
68
+ }
69
+ ```
70
+
71
+ ## Link
72
+
73
+ Themed anchor link with hover underline.
74
+
75
+ ```ts
76
+ type LinkTheme = SemanticTheme;
77
+
78
+ interface LinkProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {
79
+ theme?: LinkTheme; // default: "primary"
80
+ disabled?: boolean;
81
+ }
82
+ ```
83
+
84
+ ## Alert
85
+
86
+ Themed alert/callout box with light background.
87
+
88
+ ```ts
89
+ type AlertTheme = SemanticTheme;
90
+
91
+ interface AlertProps extends JSX.HTMLAttributes<HTMLDivElement> {
92
+ theme?: AlertTheme; // default: "base"
93
+ }
94
+ ```
@@ -0,0 +1,279 @@
1
+ # Feature Components
2
+
3
+ Source: `src/components/features/**/*.tsx`
4
+
5
+ ## AddressSearchContent
6
+
7
+ Korean address search component using Daum Postcode API.
8
+
9
+ ```ts
10
+ interface AddressSearchResult {
11
+ postNumber: string | undefined;
12
+ address: string | undefined;
13
+ buildingName: string | undefined;
14
+ }
15
+
16
+ const AddressSearchContent: Component<{
17
+ close?: (result?: AddressSearchResult) => void;
18
+ }>;
19
+ ```
20
+
21
+ Designed for use with `useDialog().show()`. Loads the Daum Postcode script on mount.
22
+
23
+ ## SharedDataSelect
24
+
25
+ Select component bound to a shared data definition. Supports single and multiple modes with the same prop variants as `Select`.
26
+
27
+ ```ts
28
+ type SharedDataSelectProps<TItem, TDataKey extends string> = {
29
+ dataKey: TDataKey;
30
+ // ...inherits Select props (value, onValueChange, multiple, etc.)
31
+ // plus shared data specific:
32
+ getItemSearchText?: (item: TItem) => string;
33
+ isItemHidden?: (item: TItem) => boolean;
34
+ };
35
+ ```
36
+
37
+ ### Sub-components
38
+
39
+ - **`SharedDataSelect.ItemTemplate`** -- Render template for items.
40
+
41
+ ## SharedDataSelectButton
42
+
43
+ Button that opens a shared data selection dialog.
44
+
45
+ ```ts
46
+ type SharedDataSelectButtonProps<TItem, TDataKey extends string> = {
47
+ dataKey: TDataKey;
48
+ value?: TItem | TItem[];
49
+ onValueChange?: (value: TItem | TItem[] | undefined) => void;
50
+ renderValue?: (value: TItem) => JSX.Element;
51
+ // ...plus button/validation props
52
+ };
53
+ ```
54
+
55
+ ## SharedDataSelectList
56
+
57
+ List component bound to shared data, rendering items from a shared data definition.
58
+
59
+ ```ts
60
+ interface SharedDataSelectListProps<TItem> {
61
+ dataKey: string;
62
+ value?: unknown[];
63
+ onValueChange?: (value: unknown[]) => void;
64
+ // ...list configuration props
65
+ }
66
+ ```
67
+
68
+ ### Sub-components
69
+
70
+ - **`SharedDataSelectList.ItemTemplate`** -- Render template for list items.
71
+
72
+ ## DataSelectButton
73
+
74
+ Button that opens a custom data selection dialog. Generic over key type and dialog props.
75
+
76
+ ```ts
77
+ interface DataSelectButtonProps<TKey, TDialogProps> {
78
+ value?: TKey | TKey[];
79
+ onValueChange?: (value: TKey | TKey[] | undefined) => void;
80
+ renderValue?: (value: TKey) => JSX.Element;
81
+ dialog: Component<TDialogProps>;
82
+ dialogProps?: Omit<TDialogProps, "close">;
83
+ multiple?: boolean;
84
+ disabled?: boolean;
85
+ required?: boolean;
86
+ size?: ComponentSize;
87
+ inset?: boolean;
88
+ class?: string;
89
+ style?: JSX.CSSProperties;
90
+ }
91
+
92
+ interface DataSelectDialogResult<TKey> {
93
+ selectedKeys: TKey[];
94
+ }
95
+
96
+ interface SelectDialogBaseProps<TKey> {
97
+ close?: (result?: DataSelectDialogResult<TKey>) => void;
98
+ initialSelectedKeys?: TKey[];
99
+ selectionMode?: "single" | "multiple";
100
+ }
101
+ ```
102
+
103
+ ## CrudSheet
104
+
105
+ Full-featured CRUD data grid combining DataSheet with search, pagination, sorting, inline/dialog editing, selection, and Excel import/export.
106
+
107
+ ```ts
108
+ type CrudSheetProps<TItem, TFilter extends Record<string, unknown>> = {
109
+ search: (filter: TFilter, page: number | undefined, sorts: SortingDef[]) => Promise<SearchResult<TItem>>;
110
+ getItemKey: (item: TItem) => string | number | undefined;
111
+ storageKey?: string;
112
+ editable?: boolean;
113
+ isItemEditable?: (item: TItem) => boolean;
114
+ isItemDeletable?: (item: TItem) => boolean;
115
+ isItemDeleted?: (item: TItem) => boolean;
116
+ isItemSelectable?: (item: TItem) => boolean | string;
117
+ lastModifiedAtProp?: string;
118
+ lastModifiedByProp?: string;
119
+ filterInitial?: TFilter;
120
+ items?: TItem[];
121
+ onItemsChange?: (items: TItem[]) => void;
122
+ excel?: ExcelConfig<TItem>;
123
+ selectionMode?: "single" | "multiple";
124
+ selectedKeys?: (string | number)[];
125
+ onSelectedKeysChange?: (keys: (string | number)[]) => void;
126
+ onSelect?: (result: SelectResult<TItem>) => void;
127
+ onSubmitComplete?: () => void;
128
+ hideAutoTools?: boolean;
129
+ close?: () => void;
130
+ class?: string;
131
+ children: JSX.Element;
132
+ } & (
133
+ | { inlineEdit: InlineEditConfig<TItem>; dialogEdit?: never }
134
+ | { dialogEdit: DialogEditConfig<TItem>; inlineEdit?: never }
135
+ | { inlineEdit?: never; dialogEdit?: never }
136
+ );
137
+
138
+ interface SearchResult<TItem> {
139
+ items: TItem[];
140
+ pageCount?: number;
141
+ }
142
+
143
+ interface InlineEditConfig<TItem> {
144
+ submit: (diffs: ArrayOneWayDiffResult<TItem>[]) => Promise<void>;
145
+ newItem: () => TItem;
146
+ deleteProp?: keyof TItem & string;
147
+ diffsExcludes?: string[];
148
+ }
149
+
150
+ interface DialogEditConfig<TItem> {
151
+ editItem: (item?: TItem) => Promise<boolean | undefined>;
152
+ deleteItems?: (items: TItem[]) => Promise<boolean>;
153
+ restoreItems?: (items: TItem[]) => Promise<boolean>;
154
+ }
155
+
156
+ interface ExcelConfig<TItem> {
157
+ download: (items: TItem[]) => Promise<void>;
158
+ upload?: (file: File) => Promise<void>;
159
+ }
160
+ ```
161
+
162
+ ### Sub-components
163
+
164
+ - **`CrudSheet.Column<TItem>`** -- Column definition with cell context.
165
+
166
+ ```ts
167
+ interface CrudSheetColumnProps<TItem> extends Omit<DataSheetColumnProps<TItem>, "children"> {
168
+ editTrigger?: boolean;
169
+ children: (ctx: CrudSheetCellContext<TItem>) => JSX.Element;
170
+ }
171
+
172
+ interface CrudSheetCellContext<TItem> {
173
+ item: TItem;
174
+ index: number;
175
+ row: number;
176
+ depth: number;
177
+ setItem: <TKey extends keyof TItem>(key: TKey, value: TItem[TKey]) => void;
178
+ }
179
+ ```
180
+
181
+ - **`CrudSheet.Filter<TFilter>`** -- Filter panel slot.
182
+
183
+ ```ts
184
+ interface CrudSheetFilterSlotProps<TFilter> {
185
+ filter: TFilter;
186
+ setFilter: SetStoreFunction<TFilter>;
187
+ }
188
+ ```
189
+
190
+ - **`CrudSheet.Tools<TItem>`** -- Toolbar slot with context.
191
+
192
+ ```ts
193
+ interface CrudSheetToolsSlotProps<TItem> {
194
+ ctx: CrudSheetContext<TItem>;
195
+ }
196
+
197
+ interface CrudSheetContext<TItem> {
198
+ items(): TItem[];
199
+ selection(): TItem[];
200
+ page(): number;
201
+ sorts(): SortingDef[];
202
+ busy(): boolean;
203
+ hasChanges(): boolean;
204
+ save(): Promise<void>;
205
+ refresh(): Promise<void>;
206
+ addItem(): void;
207
+ clearSelection(): void;
208
+ setPage(page: number): void;
209
+ setSorts(sorts: SortingDef[]): void;
210
+ }
211
+ ```
212
+
213
+ ## CrudDetail
214
+
215
+ CRUD detail form with load, save, delete, and change tracking.
216
+
217
+ ```ts
218
+ interface CrudDetailProps<TData extends object> {
219
+ load: () => Promise<{ data: TData; info: CrudDetailInfo }>;
220
+ children: (ctx: CrudDetailContext<TData>) => JSX.Element;
221
+ submit?: (data: TData) => Promise<boolean | undefined>;
222
+ toggleDelete?: (del: boolean) => Promise<boolean | undefined>;
223
+ editable?: boolean;
224
+ deletable?: boolean;
225
+ data?: TData;
226
+ onDataChange?: (data: TData) => void;
227
+ close?: (result?: boolean) => void;
228
+ class?: string;
229
+ }
230
+
231
+ interface CrudDetailInfo {
232
+ isNew: boolean;
233
+ isDeleted: boolean;
234
+ lastModifiedAt?: DateTime;
235
+ lastModifiedBy?: string;
236
+ }
237
+
238
+ interface CrudDetailContext<TData> {
239
+ data: TData;
240
+ setData: SetStoreFunction<TData>;
241
+ info: () => CrudDetailInfo;
242
+ busy: () => boolean;
243
+ hasChanges: () => boolean;
244
+ save: () => Promise<void>;
245
+ refresh: () => Promise<void>;
246
+ }
247
+ ```
248
+
249
+ ### Sub-components
250
+
251
+ - **`CrudDetail.Header`** -- Header content slot.
252
+
253
+ ## PermissionTable
254
+
255
+ Permission matrix table displaying app permissions with checkboxes.
256
+
257
+ ```ts
258
+ interface PermissionTableProps<TModule = string> {
259
+ perms: AppPerm<TModule>[];
260
+ value?: string[];
261
+ onValueChange?: (value: string[]) => void;
262
+ disabled?: boolean;
263
+ class?: string;
264
+ style?: JSX.CSSProperties;
265
+ }
266
+ ```
267
+
268
+ ### Helper Functions
269
+
270
+ ```ts
271
+ function collectAllPerms<TModule>(items: AppPerm<TModule>[]): string[];
272
+ function filterByModules<TModule>(items: AppPerm<TModule>[], enabledModules: TModule[]): AppPerm<TModule>[];
273
+ function changePermCheck<TModule>(
274
+ items: AppPerm<TModule>[],
275
+ currentPerms: string[],
276
+ changedPerm: string,
277
+ checked: boolean,
278
+ ): string[];
279
+ ```