@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 +314 -123
- package/docs/data.md +216 -0
- package/docs/disclosure.md +164 -0
- package/docs/display.md +94 -0
- package/docs/features.md +211 -625
- package/docs/feedback.md +210 -0
- package/docs/form-control.md +537 -0
- package/docs/helpers.md +168 -0
- package/docs/hooks.md +143 -0
- package/docs/layout.md +182 -0
- package/docs/providers.md +177 -0
- package/docs/styles.md +127 -0
- package/package.json +19 -26
- package/docs/display-feedback.md +0 -404
- package/docs/form-controls.md +0 -587
- package/docs/layout-data.md +0 -392
- package/docs/providers-hooks.md +0 -516
package/README.md
CHANGED
|
@@ -1,158 +1,349 @@
|
|
|
1
1
|
# @simplysm/solid
|
|
2
2
|
|
|
3
|
-
SolidJS + Tailwind CSS
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
`
|
|
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 {
|
|
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
|
-
<
|
|
36
|
-
<
|
|
37
|
-
|
|
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 {
|
|
266
|
+
import { useDialog, useNotification, Button } from "@simplysm/solid";
|
|
49
267
|
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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 {
|
|
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
|
-
<
|
|
77
|
-
<
|
|
78
|
-
<
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
```
|
|
103
|
-
|
|
104
|
-
```
|
|
320
|
+
```tsx
|
|
321
|
+
import { DataSheet, BusyContainer, Pagination, useBusy } from "@simplysm/solid";
|
|
105
322
|
|
|
106
|
-
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
+
```
|