@simplysm/solid 13.0.96 → 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.
package/README.md CHANGED
@@ -1,158 +1,349 @@
1
1
  # @simplysm/solid
2
2
 
3
- SolidJS + Tailwind CSS 기반 엔터프라이즈 UI 컴포넌트 라이브러리. 컨트롤, 데이터 테이블, 다이얼로그, 알림, 테마, i18n, CRUD, 권한 관리 등 100+ 컴포넌트를 제공한다.
3
+ SolidJS + Tailwind CSS UI component library for building enterprise web applications.
4
4
 
5
- ## 설치
5
+ ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @simplysm/solid
9
9
  ```
10
10
 
11
- **주요 의존성:** SolidJS, @solidjs/router, Tailwind CSS 3, Tiptap, Tabler Icons
12
- **선택 의존성:** echarts (ECharts 차트 사용 시)
13
-
14
- ## 문서
15
-
16
- | 카테고리 | 설명 |
17
- |---------|------|
18
- | [폼 컨트롤](docs/form-controls.md) | Button, TextInput, NumberInput, Select, Combobox, DatePicker, DateRangePicker, Checkbox, RadioGroup, CheckboxGroup, ColorPicker, RichTextEditor, Numpad, StatePreset 등 |
19
- | [레이아웃 & 데이터](docs/layout-data.md) | FormGroup, FormTable, Sidebar, Topbar, Table, DataSheet, List, Calendar, Kanban, Pagination 등 |
20
- | [디스플레이 & 피드백](docs/display-feedback.md) | Card, Alert, Icon, Link, Tag, Barcode, Echarts, Dialog, Dropdown, Collapse, Tabs, Notification, Busy, Progress, Print 등 |
21
- | [프로바이더 & 훅](docs/providers-hooks.md) | SystemProvider, ThemeProvider, I18nProvider, SharedDataProvider, useDialog, useBusy, useNotification, createAppStructure 등 |
22
- | [기능 컴포넌트](docs/features.md) | CrudSheet, CrudDetail, DataSelectButton, SharedDataSelect, SharedDataSelectButton, SharedDataSelectList, PermissionTable, AddressSearch |
23
-
24
- ## 빠른 시작
25
-
26
- ### SystemProvider (권장)
27
-
28
- `SystemProvider`는 모든 필수 프로바이더를 번에 감싸는 편의 컴포넌트다.
11
+ ## API Overview
12
+
13
+ ### Form Controls
14
+
15
+ | API | Type | Description |
16
+ |-----|------|-------------|
17
+ | `Button` | Component | Themed button with ripple effect |
18
+ | `Select` | Component | Single/multiple select dropdown |
19
+ | `Select.Item` | Sub-component | Selectable item within Select |
20
+ | `Select.Header` | Sub-component | Custom header slot for Select dropdown |
21
+ | `Select.Action` | Sub-component | Action button appended to Select trigger |
22
+ | `Select.ItemTemplate` | Sub-component | Render template for items in `items` mode |
23
+ | `Combobox` | Component | Autocomplete with async search |
24
+ | `Combobox.Item` | Sub-component | Selectable item within Combobox |
25
+ | `Combobox.ItemTemplate` | Sub-component | Render template for loaded items |
26
+ | `TextInput` | Component | Text input field with format support |
27
+ | `TextInput.Prefix` | Sub-component | Prefix slot for TextInput |
28
+ | `NumberInput` | Component | Numeric input with grouping and formatting |
29
+ | `NumberInput.Prefix` | Sub-component | Prefix slot for NumberInput |
30
+ | `DatePicker` | Component | Date input (year/month/date units) |
31
+ | `DateTimePicker` | Component | DateTime input (minute/second units) |
32
+ | `TimePicker` | Component | Time input (minute/second units) |
33
+ | `Textarea` | Component | Auto-resizing textarea |
34
+ | `Checkbox` | Component | Checkbox with indicator |
35
+ | `Radio` | Component | Radio button with indicator |
36
+ | `CheckboxGroup` | Component | Multi-select checkbox group |
37
+ | `CheckboxGroup.Item` | Sub-component | Item within CheckboxGroup |
38
+ | `RadioGroup` | Component | Single-select radio group |
39
+ | `RadioGroup.Item` | Sub-component | Item within RadioGroup |
40
+ | `ColorPicker` | Component | Native color picker input |
41
+ | `DateRangePicker` | Component | Date range with period type selector |
42
+ | `RichTextEditor` | Component | Tiptap-based rich text editor |
43
+ | `Numpad` | Component | Numeric keypad for touch input |
44
+ | `StatePreset` | Component | Save/restore state presets to storage |
45
+ | `ThemeToggle` | Component | Light/system/dark theme cycle button |
46
+ | `Invalid` | Component | Validation indicator wrapper |
47
+ | `fieldSurface`, `fieldBaseClass`, `fieldSizeClasses`, `fieldInputClass` | Style export | Field style tokens |
48
+ | `getFieldWrapperClass`, `getTextareaWrapperClass` | Function | Field wrapper class builders |
49
+ | `checkboxBaseClass`, `indicatorBaseClass`, `checkedClass`, `checkboxSizeClasses` | Style export | Checkbox style tokens |
50
+
51
+ -> See [docs/form-control.md](./docs/form-control.md) for details.
52
+
53
+ ### Layout
54
+
55
+ | API | Type | Description |
56
+ |-----|------|-------------|
57
+ | `FormGroup` | Component | Vertical/inline form field group |
58
+ | `FormGroup.Item` | Sub-component | Labeled form group item |
59
+ | `FormTable` | Component | Table-based form layout |
60
+ | `FormTable.Row` | Sub-component | Table row |
61
+ | `FormTable.Item` | Sub-component | Labeled table cell |
62
+ | `Sidebar` | Component | Collapsible sidebar panel |
63
+ | `Sidebar.Container` | Sub-component | Sidebar + content layout container |
64
+ | `Sidebar.Menu` | Sub-component | Recursive menu with route matching |
65
+ | `Sidebar.User` | Sub-component | User info with dropdown menu |
66
+ | `Topbar` | Component | Top navigation bar |
67
+ | `Topbar.Container` | Sub-component | Topbar + content layout container |
68
+ | `Topbar.Menu` | Sub-component | Dropdown navigation menu |
69
+ | `Topbar.User` | Sub-component | User info with dropdown |
70
+ | `Topbar.Actions` | Sub-component | Displays actions from useTopbarActions() |
71
+ | `useTopbarActions()` | Hook | Register topbar action elements |
72
+ | `useTopbarActionsAccessor()` | Hook | Read topbar actions signal |
73
+
74
+ -> See [docs/layout.md](./docs/layout.md) for details.
75
+
76
+ ### Data
77
+
78
+ | API | Type | Description |
79
+ |-----|------|-------------|
80
+ | `Table` | Component | Styled HTML table |
81
+ | `Table.Row` | Sub-component | Table row |
82
+ | `Table.HeaderCell` | Sub-component | Table header cell |
83
+ | `Table.Cell` | Sub-component | Table data cell |
84
+ | `List` | Component | Vertical list container |
85
+ | `ListContext` | Context | List nesting level context |
86
+ | `useListContext()` | Hook | Access list context |
87
+ | `Pagination` | Component | Page navigation controls |
88
+ | `DataSheet` | Component | Spreadsheet-like data grid |
89
+ | `DataSheet.Column` | Sub-component | Column definition |
90
+ | `Calendar` | Component | Month calendar with value items |
91
+ | `Kanban` | Component | Kanban board with drag-and-drop |
92
+ | `Kanban.Lane` | Sub-component | Kanban lane |
93
+ | `Kanban.Card` | Sub-component | Draggable card |
94
+
95
+ -> See [docs/data.md](./docs/data.md) for details.
96
+
97
+ ### Display
98
+
99
+ | API | Type | Description |
100
+ |-----|------|-------------|
101
+ | `Barcode` | Component | SVG barcode renderer (bwip-js) |
102
+ | `BarcodeType` | Type | Union of supported barcode formats |
103
+ | `Card` | Component | Elevated card container |
104
+ | `Echarts` | Component | Apache ECharts wrapper |
105
+ | `Icon` | Component | Tabler icon wrapper |
106
+ | `Tag` | Component | Themed inline tag/badge |
107
+ | `Link` | Component | Themed anchor link |
108
+ | `Alert` | Component | Themed alert box |
109
+
110
+ -> See [docs/display.md](./docs/display.md) for details.
111
+
112
+ ### Disclosure
113
+
114
+ | API | Type | Description |
115
+ |-----|------|-------------|
116
+ | `Collapse` | Component | Animated expand/collapse container |
117
+ | `Dropdown` | Component | Positioned popup with trigger |
118
+ | `Dropdown.Trigger` | Sub-component | Click target for dropdown |
119
+ | `Dropdown.Content` | Sub-component | Popup content |
120
+ | `Dialog` | Component | Modal/float dialog with drag/resize |
121
+ | `Dialog.Header` | Sub-component | Dialog title bar |
122
+ | `Dialog.Action` | Sub-component | Header action buttons |
123
+ | `DialogProvider` | Component | Programmatic dialog provider |
124
+ | `useDialog()` | Hook | Open dialogs programmatically |
125
+ | `DialogDefaultsContext` | Context | Default dialog configuration |
126
+ | `Tabs` | Component | Tab bar container |
127
+ | `Tabs.Tab` | Sub-component | Individual tab |
128
+
129
+ -> See [docs/disclosure.md](./docs/disclosure.md) for details.
130
+
131
+ ### Feedback
132
+
133
+ | API | Type | Description |
134
+ |-----|------|-------------|
135
+ | `Progress` | Component | Themed progress bar |
136
+ | `NotificationProvider` | Component | Notification system provider |
137
+ | `useNotification()` | Hook | Create/manage notifications |
138
+ | `NotificationBell` | Component | Bell icon with unread badge + dropdown |
139
+ | `NotificationBanner` | Component | Toast-style notification banner |
140
+ | `BusyProvider` | Component | Global loading overlay provider |
141
+ | `useBusy()` | Hook | Show/hide loading overlay |
142
+ | `BusyContainer` | Component | Local loading overlay container |
143
+ | `PrintProvider` | Component | Print/PDF generation provider |
144
+ | `usePrint()` | Hook | Print to printer or generate PDF |
145
+ | `usePrintInstance()` | Hook | Signal ready state in print content |
146
+ | `Print` | Component | Print content wrapper |
147
+ | `Print.Page` | Sub-component | Page break boundary |
148
+
149
+ -> See [docs/feedback.md](./docs/feedback.md) for details.
150
+
151
+ ### Features
152
+
153
+ | API | Type | Description |
154
+ |-----|------|-------------|
155
+ | `AddressSearchContent` | Component | Korean address search (Daum Postcode) |
156
+ | `SharedDataSelect` | Component | Select bound to shared data |
157
+ | `SharedDataSelectButton` | Component | Button that opens shared data dialog |
158
+ | `SharedDataSelectList` | Component | List bound to shared data |
159
+ | `DataSelectButton` | Component | Button that opens a data selection dialog |
160
+ | `CrudSheet` | Component | Full CRUD data grid |
161
+ | `CrudSheet.Column` | Sub-component | Column definition for CrudSheet |
162
+ | `CrudSheet.Filter` | Sub-component | Filter panel slot |
163
+ | `CrudSheet.Tools` | Sub-component | Toolbar slot |
164
+ | `CrudDetail` | Component | CRUD detail form |
165
+ | `CrudDetail.Header` | Sub-component | Detail header slot |
166
+ | `PermissionTable` | Component | Permission matrix table |
167
+
168
+ -> See [docs/features.md](./docs/features.md) for details.
169
+
170
+ ### Providers
171
+
172
+ | API | Type | Description |
173
+ |-----|------|-------------|
174
+ | `ConfigContext` | Context | App configuration (clientName) |
175
+ | `useConfig()` | Hook | Access app config |
176
+ | `ConfigProvider` | Component | Provides app config |
177
+ | `SyncStorageProvider` | Component | Pluggable storage provider |
178
+ | `useSyncStorage()` | Hook | Access sync storage adapter |
179
+ | `LoggerProvider` | Component | Logging adapter provider |
180
+ | `ThemeProvider` | Component | Light/dark/system theme provider |
181
+ | `useTheme()` | Hook | Access theme mode and toggle |
182
+ | `ServiceClientProvider` | Component | Service client connection provider |
183
+ | `useServiceClient()` | Hook | Access service client |
184
+ | `SystemProvider` | Component | Composite provider (bundles common providers) |
185
+ | `I18nProvider` | Component | Internationalization provider |
186
+ | `useI18n()` | Hook | Access translation functions |
187
+ | `SharedDataProvider` | Component | Shared data cache provider |
188
+ | `useSharedData()` | Hook | Access shared data definitions |
189
+ | `SharedDataChangeEvent` | Event | Event emitted on shared data changes |
190
+
191
+ -> See [docs/providers.md](./docs/providers.md) for details.
192
+
193
+ ### Hooks
194
+
195
+ | API | Type | Description |
196
+ |-----|------|-------------|
197
+ | `useLocalStorage` | Hook | localStorage-backed reactive signal |
198
+ | `useSyncConfig` | Hook | Storage-synced config signal |
199
+ | `useLogger` | Hook | Logging with pluggable adapter |
200
+ | `createControllableSignal` | Hook | Controlled/uncontrolled signal pattern |
201
+ | `createControllableStore` | Hook | Controlled/uncontrolled store pattern |
202
+ | `createIMEHandler` | Hook | IME composition handling for inputs |
203
+ | `createMountTransition` | Hook | Mount/unmount animation state |
204
+ | `useRouterLink` | Hook | Router navigation with modifier keys |
205
+
206
+ -> See [docs/hooks.md](./docs/hooks.md) for details.
207
+
208
+ ### Helpers
209
+
210
+ | API | Type | Description |
211
+ |-----|------|-------------|
212
+ | `mergeStyles` | Function | Merge CSS style objects and strings |
213
+ | `createAppStructure` | Function | Build app menus, routes, and permissions |
214
+ | `createSlot` | Function | Single-item slot pattern |
215
+ | `createSlots` | Function | Multi-item slot pattern |
216
+
217
+ -> See [docs/helpers.md](./docs/helpers.md) for details.
218
+
219
+ ### Styles + Directives
220
+
221
+ | API | Type | Description |
222
+ |-----|------|-------------|
223
+ | `border`, `bg`, `text` | Style tokens | Base design tokens |
224
+ | `state`, `ComponentSize`, `pad`, `gap` | Style tokens | Control design tokens |
225
+ | `themeTokens`, `SemanticTheme` | Style tokens | Theme color tokens |
226
+ | `ripple` | Directive | Pointer ripple effect |
227
+
228
+ -> See [docs/styles.md](./docs/styles.md) for details.
229
+
230
+ ## Usage Examples
231
+
232
+ ### Basic Form
29
233
 
30
234
  ```tsx
31
- import { SystemProvider } from "@simplysm/solid";
235
+ import { createSignal } from "solid-js";
236
+ import { TextInput, NumberInput, Button, Select } from "@simplysm/solid";
237
+
238
+ function OrderForm() {
239
+ const [name, setName] = createSignal("");
240
+ const [quantity, setQuantity] = createSignal<number>();
241
+ const [status, setStatus] = createSignal<string>();
32
242
 
33
- function App() {
34
243
  return (
35
- <SystemProvider clientName="my-app" busyVariant="spinner">
36
- <MyPage />
37
- </SystemProvider>
244
+ <FormGroup>
245
+ <FormGroup.Item label="Name">
246
+ <TextInput value={name()} onValueChange={setName} required />
247
+ </FormGroup.Item>
248
+ <FormGroup.Item label="Quantity">
249
+ <NumberInput value={quantity()} onValueChange={setQuantity} min={1} />
250
+ </FormGroup.Item>
251
+ <FormGroup.Item label="Status">
252
+ <Select value={status()} onValueChange={setStatus} renderValue={(v) => v}>
253
+ <Select.Item value="pending">Pending</Select.Item>
254
+ <Select.Item value="confirmed">Confirmed</Select.Item>
255
+ </Select>
256
+ </FormGroup.Item>
257
+ <Button theme="primary" variant="solid">Submit</Button>
258
+ </FormGroup>
38
259
  );
39
260
  }
40
261
  ```
41
262
 
42
- 내부적으로 다음 프로바이더를 순서대로 감싼다:
43
- `ConfigProvider` > `I18nProvider` > `SyncStorageProvider` > `LoggerProvider` > `NotificationProvider` > `ErrorLoggerProvider` > `PwaUpdateProvider` > `ClipboardProvider` > `ThemeProvider` > `ServiceClientProvider` > `SharedDataProvider` > `BusyProvider`
44
-
45
- ### 개별 프로바이더 조합
263
+ ### Dialog + Notification
46
264
 
47
265
  ```tsx
48
- import { ThemeProvider, I18nProvider, NotificationProvider, BusyProvider } from "@simplysm/solid";
266
+ import { useDialog, useNotification, Button } from "@simplysm/solid";
49
267
 
50
- function App() {
51
- return (
52
- <ThemeProvider>
53
- <I18nProvider>
54
- <NotificationProvider>
55
- <BusyProvider>
56
- <MyPage />
57
- </BusyProvider>
58
- </NotificationProvider>
59
- </I18nProvider>
60
- </ThemeProvider>
61
- );
268
+ function MyPage() {
269
+ const dialog = useDialog();
270
+ const notification = useNotification();
271
+
272
+ const handleOpen = async () => {
273
+ const result = await dialog.show(
274
+ MyDialogContent,
275
+ { title: "Edit Item" },
276
+ { header: "Edit", resizable: true },
277
+ );
278
+ if (result) {
279
+ notification.success("Saved", "Item saved successfully.");
280
+ }
281
+ };
282
+
283
+ return <Button onClick={handleOpen}>Open Editor</Button>;
62
284
  }
63
285
  ```
64
286
 
65
- ### 기본 예제
287
+ ### Sidebar + Topbar Layout
66
288
 
67
289
  ```tsx
68
- import { createSignal } from "solid-js";
69
- import { Card, FormGroup, TextInput, Select, Button } from "@simplysm/solid";
70
-
71
- function MyPage() {
72
- const [name, setName] = createSignal("");
73
- const [role, setRole] = createSignal<string>();
290
+ import { Sidebar, Topbar, ThemeToggle, NotificationBell } from "@simplysm/solid";
74
291
 
292
+ function AppLayout() {
75
293
  return (
76
- <Card>
77
- <FormGroup>
78
- <FormGroup.Item label="이름">
79
- <TextInput value={name()} onValueChange={setName} required />
80
- </FormGroup.Item>
81
- <FormGroup.Item label="역할">
82
- <Select
83
- value={role()}
84
- onValueChange={setRole}
85
- items={["admin", "user", "guest"]}
86
- renderValue={(item) => <span>{item}</span>}
87
- />
88
- </FormGroup.Item>
89
- </FormGroup>
90
- <Button theme="primary" onClick={() => save()}>저장</Button>
91
- </Card>
294
+ <div class="h-screen">
295
+ <Sidebar.Container>
296
+ <Sidebar>
297
+ <Sidebar.User name="Admin" description="admin@example.com" />
298
+ <Sidebar.Menu menus={appMenus} />
299
+ </Sidebar>
300
+ <Topbar.Container>
301
+ <Topbar>
302
+ <h1 class="text-lg font-bold">My App</h1>
303
+ <Topbar.Menu menus={navMenus} />
304
+ <div class="flex-1" />
305
+ <NotificationBell />
306
+ <ThemeToggle />
307
+ </Topbar>
308
+ <main class="flex-1 overflow-auto p-4">
309
+ {/* Page content */}
310
+ </main>
311
+ </Topbar.Container>
312
+ </Sidebar.Container>
313
+ </div>
92
314
  );
93
315
  }
94
316
  ```
95
317
 
96
- ## 공통 타입
97
-
98
- ### ComponentSize
99
-
100
- 모든 폼 컨트롤과 대부분의 컴포넌트가 `size` prop을 지원한다.
318
+ ### Data Table with Busy State
101
319
 
102
- ```typescript
103
- type ComponentSize = "xs" | "sm" | "md" | "lg" | "xl";
104
- ```
320
+ ```tsx
321
+ import { DataSheet, BusyContainer, Pagination, useBusy } from "@simplysm/solid";
105
322
 
106
- ### SemanticTheme
323
+ function DataPage() {
324
+ const busy = useBusy();
107
325
 
108
- 의미론적 색상 테마.
326
+ const loadData = async () => {
327
+ busy.show();
328
+ try {
329
+ // fetch data
330
+ } finally {
331
+ busy.hide();
332
+ }
333
+ };
109
334
 
110
- ```typescript
111
- type SemanticTheme = "base" | "primary" | "success" | "warning" | "danger" | "info";
112
- ```
113
-
114
- ### 스타일 유틸리티
115
-
116
- Tailwind 클래스 프리셋. 테마 일관성을 위해 사용한다.
117
-
118
- ```typescript
119
- import { bg, border, text, pad, gap, themeTokens } from "@simplysm/solid";
120
-
121
- // 배경색
122
- bg.surface // bg-white dark:bg-base-900
123
- bg.muted // bg-base-100 dark:bg-base-800
124
- bg.subtle // bg-base-200 dark:bg-base-700
125
-
126
- // 테두리색
127
- border.default // border-base-200 dark:border-base-700
128
-
129
- // 텍스트색
130
- text.default // text-base-900 dark:text-base-100
131
- text.muted // text-base-400 dark:text-base-500
132
- text.placeholder // placeholder 전용
133
-
134
- // 패딩/갭 프리셋
135
- pad.xs // px-1 py-0
136
- pad.sm // px-1.5 py-0.5
137
- pad.md // px-2 py-1
138
- pad.lg // px-3 py-2
139
- pad.xl // px-4 py-3
140
-
141
- gap.xs // gap-0
142
- gap.sm // gap-0.5
143
- gap.md // gap-1
144
- gap.lg // gap-1.5
145
- gap.xl // gap-2
146
-
147
- // 테마 토큰 (semantic theme별 solid/light/text/hoverBg/border)
148
- themeTokens.primary.solid // bg-primary-500 text-white
149
- themeTokens.primary.solidHover // hover:bg-primary-600 dark:hover:bg-primary-400
150
- themeTokens.primary.light // bg-primary-100 text-primary-900
151
- themeTokens.primary.text // text-primary-600 dark:text-primary-400
152
- themeTokens.primary.hoverBg // hover:bg-primary-100 dark:hover:bg-primary-800/30
153
- themeTokens.primary.border // border-primary-300 dark:border-primary-600
335
+ return (
336
+ <BusyContainer busy={loading()}>
337
+ <DataSheet items={items()} getItemKey={(item) => item.id}>
338
+ <DataSheet.Column header="Name" key="name">
339
+ {(ctx) => ctx.item.name}
340
+ </DataSheet.Column>
341
+ <DataSheet.Column header="Value" key="value" align="right">
342
+ {(ctx) => ctx.item.value}
343
+ </DataSheet.Column>
344
+ </DataSheet>
345
+ <Pagination page={page()} onPageChange={setPage} totalPageCount={10} />
346
+ </BusyContainer>
347
+ );
348
+ }
154
349
  ```
155
-
156
- ### 라이트/다크 테마
157
-
158
- `ThemeProvider`와 `useTheme()` 훅으로 라이트/다크/시스템 모드를 제어한다. localStorage에 설정이 자동 저장된다.
package/docs/data.md ADDED
@@ -0,0 +1,216 @@
1
+ # Data Components
2
+
3
+ Source: `src/components/data/**/*.tsx`
4
+
5
+ ## Table
6
+
7
+ Styled HTML table with border-separated cells.
8
+
9
+ ```ts
10
+ interface TableProps extends JSX.HTMLAttributes<HTMLTableElement> {
11
+ inset?: boolean; // borderless style for embedding
12
+ }
13
+ ```
14
+
15
+ ### Sub-components
16
+
17
+ - **`Table.Row`** -- `<tr>` element. Extends `JSX.HTMLAttributes<HTMLTableRowElement>`.
18
+ - **`Table.HeaderCell`** -- `<th>` element with bold text and muted background. Extends `JSX.ThHTMLAttributes<HTMLTableCellElement>`.
19
+ - **`Table.Cell`** -- `<td>` element with borders. Extends `JSX.TdHTMLAttributes<HTMLTableCellElement>`.
20
+
21
+ ## List
22
+
23
+ Vertical list container with nesting support via `ListContext`.
24
+
25
+ ```ts
26
+ interface ListProps extends JSX.HTMLAttributes<HTMLDivElement> {
27
+ inset?: boolean; // borderless style
28
+ }
29
+ ```
30
+
31
+ Uses `ListContext` to track nesting level for indentation.
32
+
33
+ ### ListContext
34
+
35
+ ```ts
36
+ interface ListContextValue {
37
+ level: number;
38
+ }
39
+
40
+ const ListContext: Context<ListContextValue>; // default: { level: 0 }
41
+ function useListContext(): ListContextValue;
42
+ ```
43
+
44
+ ### ListItem
45
+
46
+ Interactive list item with selection, expansion, and ripple support.
47
+
48
+ ```ts
49
+ interface ListItemProps extends Omit<JSX.HTMLAttributes<HTMLButtonElement>, "onClick"> {
50
+ selected?: boolean;
51
+ disabled?: boolean;
52
+ readOnly?: boolean;
53
+ size?: ComponentSize;
54
+ open?: boolean;
55
+ onOpenChange?: (open: boolean) => void;
56
+ onClick?: (e: MouseEvent) => void;
57
+ }
58
+ ```
59
+
60
+ - **`ListItem.Children`** -- Nested content rendered inside a `Collapse`. Children are wrapped in a nested `List`.
61
+
62
+ ## Pagination
63
+
64
+ Page navigation control with first/prev/next/last buttons.
65
+
66
+ ```ts
67
+ interface PaginationProps extends JSX.HTMLAttributes<HTMLElement> {
68
+ page: number;
69
+ onPageChange?: (page: number) => void;
70
+ totalPageCount: number;
71
+ displayPageCount?: number; // default: 10
72
+ size?: ComponentSize;
73
+ }
74
+ ```
75
+
76
+ ## DataSheet
77
+
78
+ Spreadsheet-like data grid with sorting, selection, expansion, reorder, column resize, and configuration.
79
+
80
+ ```ts
81
+ interface DataSheetProps<TItem> {
82
+ items: TItem[];
83
+ getItemKey: (item: TItem) => string | number | undefined;
84
+ getItemChildren?: (item: TItem, index: number, depth: number) => TItem[] | undefined;
85
+ storageKey?: string;
86
+ inset?: boolean;
87
+ page?: number;
88
+ onPageChange?: (page: number) => void;
89
+ totalPageCount?: number;
90
+ sorts?: SortingDef[];
91
+ onSortsChange?: (sorts: SortingDef[]) => void;
92
+ selectionMode?: "single" | "multiple";
93
+ selectedKeys?: (string | number)[];
94
+ onSelectedKeysChange?: (keys: (string | number)[]) => void;
95
+ onSelect?: (result: { items: TItem[]; keys: (string | number)[] }) => void;
96
+ onReorder?: (event: DataSheetReorderEvent<TItem>) => void;
97
+ class?: string;
98
+ style?: JSX.CSSProperties;
99
+ children: JSX.Element;
100
+ }
101
+ ```
102
+
103
+ ### Sub-components
104
+
105
+ - **`DataSheet.Column<TItem>`** -- Column definition.
106
+
107
+ ```ts
108
+ interface DataSheetColumnProps<TItem> {
109
+ key: string;
110
+ header?: string | string[];
111
+ width?: string;
112
+ minWidth?: string;
113
+ fixed?: boolean;
114
+ align?: "left" | "center" | "right";
115
+ sortable?: boolean;
116
+ sortKey?: string;
117
+ resizable?: boolean;
118
+ summary?: (items: TItem[]) => JSX.Element;
119
+ children: (ctx: DataSheetCellContext<TItem>) => JSX.Element;
120
+ }
121
+
122
+ interface DataSheetCellContext<TItem> {
123
+ item: TItem;
124
+ index: number;
125
+ row: number;
126
+ depth: number;
127
+ }
128
+ ```
129
+
130
+ ### DataSheet.Config
131
+
132
+ Column visibility and order configuration dialog, persisted via storage.
133
+
134
+ ```ts
135
+ interface DataSheetConfig {
136
+ columns: DataSheetConfigColumn[];
137
+ }
138
+
139
+ interface DataSheetConfigColumn {
140
+ key: string;
141
+ hidden?: boolean;
142
+ width?: string;
143
+ }
144
+ ```
145
+
146
+ ### Related Types
147
+
148
+ ```ts
149
+ interface SortingDef {
150
+ key: string;
151
+ desc: boolean;
152
+ }
153
+
154
+ interface DataSheetReorderEvent<TItem> {
155
+ item: TItem;
156
+ position: "before" | "after" | "inside";
157
+ target: TItem;
158
+ }
159
+ ```
160
+
161
+ ## Calendar
162
+
163
+ Month calendar displaying items on date cells.
164
+
165
+ ```ts
166
+ interface CalendarProps<TValue> extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> {
167
+ year: number;
168
+ month: number;
169
+ onYearChange?: (year: number) => void;
170
+ onMonthChange?: (month: number) => void;
171
+ items?: TValue[];
172
+ getItemDate?: (item: TValue) => DateOnly;
173
+ renderItem?: (item: TValue, index: number) => JSX.Element;
174
+ onDateClick?: (date: DateOnly) => void;
175
+ size?: ComponentSize;
176
+ class?: string;
177
+ style?: JSX.CSSProperties;
178
+ }
179
+ ```
180
+
181
+ ## Kanban
182
+
183
+ Kanban board with drag-and-drop cards between lanes.
184
+
185
+ ```ts
186
+ interface KanbanProps<TCardValue, TLaneValue> extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> {
187
+ onDrop?: (info: KanbanDropInfo<TLaneValue, TCardValue>) => void;
188
+ children: JSX.Element;
189
+ }
190
+
191
+ interface KanbanDropInfo<TLaneValue, TCardValue> {
192
+ card: KanbanCardRef<TLaneValue, TCardValue>;
193
+ target: KanbanDropTarget<TCardValue>;
194
+ }
195
+ ```
196
+
197
+ ### Sub-components
198
+
199
+ - **`Kanban.Lane<TLaneValue>`** -- Lane container.
200
+
201
+ ```ts
202
+ interface KanbanLaneProps<TLaneValue> extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> {
203
+ value: TLaneValue;
204
+ header?: JSX.Element;
205
+ children: JSX.Element;
206
+ }
207
+ ```
208
+
209
+ - **`Kanban.Card<TCardValue>`** -- Draggable card.
210
+
211
+ ```ts
212
+ interface KanbanCardProps<TCardValue> extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> {
213
+ value: TCardValue;
214
+ children: JSX.Element;
215
+ }
216
+ ```