@simplysm/solid 13.0.84 → 13.0.86

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 (180) hide show
  1. package/README.md +143 -28
  2. package/dist/components/data/list/ListItem.d.ts.map +1 -1
  3. package/dist/components/data/list/ListItem.js +11 -4
  4. package/dist/components/data/list/ListItem.js.map +2 -2
  5. package/dist/components/data/list/ListItem.styles.d.ts +2 -0
  6. package/dist/components/data/list/ListItem.styles.d.ts.map +1 -1
  7. package/dist/components/data/list/ListItem.styles.js +11 -1
  8. package/dist/components/data/list/ListItem.styles.js.map +1 -1
  9. package/dist/components/data/sheet/DataSheet.d.ts.map +1 -1
  10. package/dist/components/data/sheet/DataSheet.js +6 -9
  11. package/dist/components/data/sheet/DataSheet.js.map +2 -2
  12. package/dist/components/data/sheet/hooks/createDataSheetExpansion.d.ts.map +1 -1
  13. package/dist/components/data/sheet/hooks/createDataSheetExpansion.js +15 -17
  14. package/dist/components/data/sheet/hooks/createDataSheetExpansion.js.map +1 -1
  15. package/dist/components/data/sheet/hooks/createDataSheetReorder.d.ts.map +1 -1
  16. package/dist/components/data/sheet/hooks/createDataSheetReorder.js +12 -12
  17. package/dist/components/data/sheet/hooks/createDataSheetReorder.js.map +1 -1
  18. package/dist/components/data/sheet/hooks/createDataSheetSelection.d.ts.map +1 -1
  19. package/dist/components/data/sheet/hooks/createDataSheetSelection.js +9 -3
  20. package/dist/components/data/sheet/hooks/createDataSheetSelection.js.map +1 -1
  21. package/dist/components/disclosure/Dialog.d.ts.map +1 -1
  22. package/dist/components/disclosure/Dialog.js +3 -21
  23. package/dist/components/disclosure/Dialog.js.map +2 -2
  24. package/dist/components/disclosure/Dropdown.d.ts.map +1 -1
  25. package/dist/components/disclosure/Dropdown.js +1 -11
  26. package/dist/components/disclosure/Dropdown.js.map +2 -2
  27. package/dist/components/disclosure/Tabs.d.ts.map +1 -1
  28. package/dist/components/disclosure/Tabs.js +1 -3
  29. package/dist/components/disclosure/Tabs.js.map +2 -2
  30. package/dist/components/features/crud-detail/CrudDetail.js +103 -102
  31. package/dist/components/features/crud-detail/CrudDetail.js.map +2 -2
  32. package/dist/components/features/crud-sheet/CrudSheet.d.ts.map +1 -1
  33. package/dist/components/features/crud-sheet/CrudSheet.js +10 -5
  34. package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
  35. package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -1
  36. package/dist/components/features/data-select-button/DataSelectButton.js +30 -26
  37. package/dist/components/features/data-select-button/DataSelectButton.js.map +2 -2
  38. package/dist/components/features/permission-table/PermissionTable.js +5 -1
  39. package/dist/components/features/permission-table/PermissionTable.js.map +2 -2
  40. package/dist/components/feedback/busy/BusyContainer.d.ts.map +1 -1
  41. package/dist/components/feedback/busy/BusyContainer.js +1 -6
  42. package/dist/components/feedback/busy/BusyContainer.js.map +2 -2
  43. package/dist/components/form-control/DropdownTrigger.styles.js +1 -1
  44. package/dist/components/form-control/checkbox/SelectableBase.d.ts.map +1 -1
  45. package/dist/components/form-control/checkbox/SelectableBase.js +2 -4
  46. package/dist/components/form-control/checkbox/SelectableBase.js.map +2 -2
  47. package/dist/components/form-control/combobox/Combobox.d.ts +19 -5
  48. package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
  49. package/dist/components/form-control/combobox/Combobox.js +2 -4
  50. package/dist/components/form-control/combobox/Combobox.js.map +1 -1
  51. package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts +2 -2
  52. package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts.map +1 -1
  53. package/dist/components/form-control/date-range-picker/DateRangePicker.js +11 -3
  54. package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
  55. package/dist/components/form-control/editor/RichTextEditor.d.ts +2 -2
  56. package/dist/components/form-control/editor/RichTextEditor.d.ts.map +1 -1
  57. package/dist/components/form-control/editor/RichTextEditor.js +2 -4
  58. package/dist/components/form-control/editor/RichTextEditor.js.map +2 -2
  59. package/dist/components/form-control/field/DatePicker.d.ts +2 -2
  60. package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
  61. package/dist/components/form-control/field/DatePicker.js.map +1 -1
  62. package/dist/components/form-control/field/DateTimePicker.d.ts +2 -2
  63. package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
  64. package/dist/components/form-control/field/DateTimePicker.js.map +1 -1
  65. package/dist/components/form-control/field/Field.styles.d.ts +6 -7
  66. package/dist/components/form-control/field/Field.styles.d.ts.map +1 -1
  67. package/dist/components/form-control/field/Field.styles.js.map +1 -1
  68. package/dist/components/form-control/field/NumberInput.d.ts +2 -2
  69. package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
  70. package/dist/components/form-control/field/NumberInput.js +7 -7
  71. package/dist/components/form-control/field/NumberInput.js.map +2 -2
  72. package/dist/components/form-control/field/TextInput.d.ts +2 -2
  73. package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
  74. package/dist/components/form-control/field/TextInput.js.map +1 -1
  75. package/dist/components/form-control/field/Textarea.d.ts +2 -2
  76. package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
  77. package/dist/components/form-control/field/Textarea.js +1 -3
  78. package/dist/components/form-control/field/Textarea.js.map +2 -2
  79. package/dist/components/form-control/field/TimePicker.d.ts +2 -2
  80. package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
  81. package/dist/components/form-control/field/TimePicker.js.map +1 -1
  82. package/dist/components/form-control/numpad/Numpad.d.ts.map +1 -1
  83. package/dist/components/form-control/numpad/Numpad.js +4 -17
  84. package/dist/components/form-control/numpad/Numpad.js.map +2 -2
  85. package/dist/components/form-control/select/Select.d.ts +2 -0
  86. package/dist/components/form-control/select/Select.d.ts.map +1 -1
  87. package/dist/components/form-control/select/Select.js +29 -15
  88. package/dist/components/form-control/select/Select.js.map +2 -2
  89. package/dist/components/form-control/state-preset/StatePreset.d.ts +1 -3
  90. package/dist/components/form-control/state-preset/StatePreset.d.ts.map +1 -1
  91. package/dist/components/form-control/state-preset/StatePreset.js +69 -95
  92. package/dist/components/form-control/state-preset/StatePreset.js.map +2 -2
  93. package/dist/components/layout/FormGroup.js +1 -1
  94. package/dist/components/layout/FormGroup.js.map +1 -1
  95. package/dist/components/layout/FormTable.js +3 -3
  96. package/dist/components/layout/FormTable.js.map +1 -1
  97. package/dist/components/layout/sidebar/Sidebar.d.ts.map +1 -1
  98. package/dist/components/layout/sidebar/Sidebar.js +3 -6
  99. package/dist/components/layout/sidebar/Sidebar.js.map +2 -2
  100. package/dist/components/layout/topbar/Topbar.js +1 -3
  101. package/dist/components/layout/topbar/Topbar.js.map +2 -2
  102. package/dist/hooks/createControllableStore.d.ts.map +1 -1
  103. package/dist/hooks/createControllableStore.js +8 -5
  104. package/dist/hooks/createControllableStore.js.map +1 -1
  105. package/dist/hooks/useLocalStorage.d.ts.map +1 -1
  106. package/dist/hooks/useLocalStorage.js +3 -2
  107. package/dist/hooks/useLocalStorage.js.map +1 -1
  108. package/dist/hooks/useSyncConfig.d.ts.map +1 -1
  109. package/dist/hooks/useSyncConfig.js +5 -4
  110. package/dist/hooks/useSyncConfig.js.map +1 -1
  111. package/dist/providers/i18n/locales/en.d.ts +2 -3
  112. package/dist/providers/i18n/locales/en.d.ts.map +1 -1
  113. package/dist/providers/i18n/locales/en.js +3 -4
  114. package/dist/providers/i18n/locales/en.js.map +1 -1
  115. package/dist/providers/i18n/locales/ko.d.ts +2 -3
  116. package/dist/providers/i18n/locales/ko.d.ts.map +1 -1
  117. package/dist/providers/i18n/locales/ko.js +3 -4
  118. package/dist/providers/i18n/locales/ko.js.map +1 -1
  119. package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
  120. package/dist/providers/shared-data/SharedDataProvider.js +0 -1
  121. package/dist/providers/shared-data/SharedDataProvider.js.map +1 -1
  122. package/docs/display-feedback.md +279 -0
  123. package/docs/features.md +357 -213
  124. package/docs/form-controls.md +261 -403
  125. package/docs/layout-data.md +386 -0
  126. package/docs/providers-hooks.md +411 -0
  127. package/package.json +5 -5
  128. package/src/components/data/list/ListItem.styles.ts +14 -2
  129. package/src/components/data/list/ListItem.tsx +13 -4
  130. package/src/components/data/sheet/DataSheet.tsx +6 -10
  131. package/src/components/data/sheet/hooks/createDataSheetExpansion.ts +17 -18
  132. package/src/components/data/sheet/hooks/createDataSheetReorder.ts +12 -13
  133. package/src/components/data/sheet/hooks/createDataSheetSelection.ts +9 -3
  134. package/src/components/disclosure/Dialog.tsx +45 -59
  135. package/src/components/disclosure/Dropdown.tsx +4 -14
  136. package/src/components/disclosure/Tabs.tsx +12 -17
  137. package/src/components/features/crud-detail/CrudDetail.tsx +4 -4
  138. package/src/components/features/crud-sheet/CrudSheet.tsx +12 -5
  139. package/src/components/features/data-select-button/DataSelectButton.tsx +39 -32
  140. package/src/components/features/permission-table/PermissionTable.tsx +1 -1
  141. package/src/components/feedback/busy/BusyContainer.tsx +12 -18
  142. package/src/components/form-control/DropdownTrigger.styles.ts +1 -1
  143. package/src/components/form-control/checkbox/SelectableBase.tsx +10 -16
  144. package/src/components/form-control/combobox/Combobox.tsx +42 -16
  145. package/src/components/form-control/date-range-picker/DateRangePicker.tsx +7 -8
  146. package/src/components/form-control/editor/RichTextEditor.tsx +14 -16
  147. package/src/components/form-control/field/DatePicker.tsx +3 -2
  148. package/src/components/form-control/field/DateTimePicker.tsx +3 -2
  149. package/src/components/form-control/field/Field.styles.ts +6 -8
  150. package/src/components/form-control/field/NumberInput.tsx +9 -10
  151. package/src/components/form-control/field/TextInput.tsx +3 -2
  152. package/src/components/form-control/field/Textarea.tsx +14 -12
  153. package/src/components/form-control/field/TimePicker.tsx +3 -2
  154. package/src/components/form-control/numpad/Numpad.tsx +16 -18
  155. package/src/components/form-control/select/Select.tsx +41 -13
  156. package/src/components/form-control/state-preset/StatePreset.tsx +39 -71
  157. package/src/components/layout/FormGroup.tsx +1 -1
  158. package/src/components/layout/FormTable.tsx +3 -3
  159. package/src/components/layout/sidebar/Sidebar.tsx +2 -3
  160. package/src/components/layout/topbar/Topbar.tsx +2 -2
  161. package/src/hooks/createControllableStore.ts +8 -4
  162. package/src/hooks/useLocalStorage.ts +3 -2
  163. package/src/hooks/useSyncConfig.ts +5 -4
  164. package/src/providers/i18n/locales/en.ts +2 -3
  165. package/src/providers/i18n/locales/ko.ts +2 -3
  166. package/src/providers/shared-data/SharedDataProvider.tsx +0 -1
  167. package/tests/components/features/crud-detail/CrudDetail.spec.tsx +49 -0
  168. package/tests/components/features/data-select-button/DataSelectButton.spec.tsx +62 -7
  169. package/tests/components/form-control/combobox/Combobox.spec.tsx +3 -3
  170. package/tests/components/form-control/date-range-picker/DateRangePicker.spec.tsx +56 -0
  171. package/tests/components/form-control/select/SelectItem.spec.tsx +5 -0
  172. package/tests/providers/shared-data/SharedDataProvider.spec.tsx +0 -104
  173. package/docs/data.md +0 -204
  174. package/docs/disclosure.md +0 -146
  175. package/docs/display.md +0 -125
  176. package/docs/feedback.md +0 -156
  177. package/docs/helpers.md +0 -173
  178. package/docs/hooks.md +0 -146
  179. package/docs/layout.md +0 -94
  180. package/docs/providers.md +0 -180
@@ -0,0 +1,386 @@
1
+ # 레이아웃 & 데이터
2
+
3
+ ## FormGroup
4
+
5
+ 폼 필드를 레이블과 함께 배치하는 레이아웃.
6
+
7
+ ```tsx
8
+ import { FormGroup } from "@simplysm/solid";
9
+
10
+ <FormGroup>
11
+ <FormGroup.Item label="이름">
12
+ <TextInput value={name()} onValueChange={setName} />
13
+ </FormGroup.Item>
14
+ <FormGroup.Item label="이메일">
15
+ <TextInput value={email()} onValueChange={setEmail} />
16
+ </FormGroup.Item>
17
+ </FormGroup>
18
+
19
+ // 인라인 배치
20
+ <FormGroup inline>
21
+ <FormGroup.Item label="시작일"><DatePicker ... /></FormGroup.Item>
22
+ <FormGroup.Item label="종료일"><DatePicker ... /></FormGroup.Item>
23
+ </FormGroup>
24
+ ```
25
+
26
+ | Prop | 타입 | 설명 |
27
+ |------|------|------|
28
+ | `inline` | `boolean` | 가로 배치 (기본: 세로) |
29
+
30
+ ---
31
+
32
+ ## FormTable
33
+
34
+ HTML 테이블 기반 폼 레이아웃. 라벨-값 쌍을 테이블 셀로 배치한다.
35
+
36
+ ```tsx
37
+ import { FormTable } from "@simplysm/solid";
38
+
39
+ <FormTable>
40
+ <FormTable.Row>
41
+ <FormTable.Item label="이름">
42
+ <TextInput value={name()} onValueChange={setName} />
43
+ </FormTable.Item>
44
+ <FormTable.Item label="이메일">
45
+ <TextInput value={email()} onValueChange={setEmail} />
46
+ </FormTable.Item>
47
+ </FormTable.Row>
48
+ <FormTable.Row>
49
+ <FormTable.Item label="주소" colspan={3}>
50
+ <TextInput value={addr()} onValueChange={setAddr} />
51
+ </FormTable.Item>
52
+ </FormTable.Row>
53
+ </FormTable>
54
+ ```
55
+
56
+ | 서브 컴포넌트 | 설명 |
57
+ |-------------|------|
58
+ | `FormTable.Row` | 테이블 행 |
59
+ | `FormTable.Item` | 테이블 셀. `label` prop으로 라벨을 `<th>`에, 내용을 `<td>`에 배치. `colspan`으로 열 병합 |
60
+
61
+ ---
62
+
63
+ ## Sidebar
64
+
65
+ 네비게이션 사이드바. `AppMenu` 배열을 받아 트리 구조 메뉴를 렌더링한다.
66
+
67
+ ```tsx
68
+ import { Sidebar, useSidebar } from "@simplysm/solid";
69
+ import type { AppMenu } from "@simplysm/solid";
70
+
71
+ const menus: AppMenu[] = [
72
+ { title: "대시보드", href: "/dashboard", icon: IconDashboard },
73
+ {
74
+ title: "사용자 관리",
75
+ icon: IconUsers,
76
+ children: [
77
+ { title: "사용자 목록", href: "/users" },
78
+ { title: "역할 관리", href: "/roles" },
79
+ ],
80
+ },
81
+ ];
82
+
83
+ <Sidebar.Container>
84
+ <Sidebar menus={menus} homeHref="/" logoText="My App" />
85
+ <Sidebar.Content>
86
+ <main>{/* 페이지 콘텐츠 */}</main>
87
+ </Sidebar.Content>
88
+ </Sidebar.Container>
89
+
90
+ // 토글 제어
91
+ const sidebar = useSidebar();
92
+ sidebar.setToggle(true); // 열기/닫기 토글
93
+ ```
94
+
95
+ 토글 동작:
96
+ - `toggle=false` (기본): 데스크탑(640px+)에서 열림, 모바일(640px-)에서 닫힘
97
+ - `toggle=true`: 데스크탑에서 닫힘, 모바일에서 오버레이로 열림
98
+
99
+ ---
100
+
101
+ ## Topbar
102
+
103
+ 상단 앱 바. 뒤로가기, 브레드크럼, 액션 버튼 등을 표시한다.
104
+
105
+ ```tsx
106
+ import { Topbar, useTopbarActions } from "@simplysm/solid";
107
+
108
+ <Topbar.Container>
109
+ <Topbar titleChain={["사용자 관리", "사용자 목록"]} />
110
+ <div>{/* 페이지 콘텐츠 */}</div>
111
+ </Topbar.Container>
112
+
113
+ // 페이지별 커스텀 액션 (Topbar.Container 내부에서 사용)
114
+ useTopbarActions(() => (
115
+ <>
116
+ <Button onClick={save}>저장</Button>
117
+ <Button onClick={refresh}>새로고침</Button>
118
+ </>
119
+ ));
120
+ ```
121
+
122
+ CrudSheet/CrudDetail이 Topbar 내부에 배치되면 자동으로 Page 모드로 동작하며, Topbar에 저장/삭제/새로고침 버튼을 주입한다.
123
+
124
+ ---
125
+
126
+ ## Table
127
+
128
+ 기본 HTML 테이블 래퍼.
129
+
130
+ ```tsx
131
+ import { Table } from "@simplysm/solid";
132
+
133
+ <Table inset>
134
+ <thead>
135
+ <tr>
136
+ <Table.HeaderCell>이름</Table.HeaderCell>
137
+ <Table.HeaderCell>이메일</Table.HeaderCell>
138
+ </tr>
139
+ </thead>
140
+ <tbody>
141
+ <Table.Row>
142
+ <Table.Cell>Alice</Table.Cell>
143
+ <Table.Cell>alice@example.com</Table.Cell>
144
+ </Table.Row>
145
+ </tbody>
146
+ </Table>
147
+ ```
148
+
149
+ ---
150
+
151
+ ## DataSheet
152
+
153
+ 고급 데이터 테이블. 정렬, 페이징, 선택, 컬럼 리사이즈/리오더/고정, 셀 편집, 트리 확장, 요약행, 드래그 리오더, 설정 저장을 지원한다.
154
+
155
+ ```tsx
156
+ import { DataSheet } from "@simplysm/solid";
157
+
158
+ <DataSheet items={users()}>
159
+ <DataSheet.Column key="name" header="이름" sortable>
160
+ {(ctx) => ctx.item.name}
161
+ </DataSheet.Column>
162
+ <DataSheet.Column key="email" header="이메일">
163
+ {(ctx) => ctx.item.email}
164
+ </DataSheet.Column>
165
+ <DataSheet.Column key="score" header="점수" sortable>
166
+ {(ctx) => ctx.item.score}
167
+ </DataSheet.Column>
168
+ </DataSheet>
169
+ ```
170
+
171
+ ### DataSheet Props
172
+
173
+ | Prop | 타입 | 설명 |
174
+ |------|------|------|
175
+ | `items` | `TItem[]` | 데이터 배열 |
176
+ | `storageKey` | `string` | 컬럼 설정 localStorage 키 |
177
+ | `hideConfigBar` | `boolean` | 설정 바 숨기기 |
178
+ | `inset` | `boolean` | 테두리 없음 |
179
+ | `sorts` / `onSortsChange` | `SortingDef[]` | 정렬 상태 |
180
+ | `autoSort` | `boolean` | 클라이언트 자동 정렬 |
181
+ | `page` / `onPageChange` / `totalPageCount` / `pageSize` | | 페이징 |
182
+ | `selectionMode` | `"single" \| "multiple"` | 선택 모드 |
183
+ | `selection` / `onSelectionChange` | `TItem[]` | 선택 상태 |
184
+ | `isItemSelectable` | `(item: TItem) => boolean \| string` | 선택 가능 여부 (string은 비활성 사유 tooltip) |
185
+ | `expandedItems` / `onExpandedItemsChange` | `TItem[]` | 트리 확장 상태 |
186
+ | `itemChildren` | `(item, index) => TItem[] \| undefined` | 트리 자식 접근자 |
187
+ | `cellClass` / `cellStyle` | `(item, colKey) => string \| undefined` | 셀별 스타일링 |
188
+ | `onItemsReorder` | `(event: DataSheetReorderEvent) => void` | 행 드래그 리오더 |
189
+
190
+ ### DataSheet.Column Props
191
+
192
+ | Prop | 타입 | 설명 |
193
+ |------|------|------|
194
+ | `key` | `string` | 컬럼 고유 키 |
195
+ | `header` | `string \| string[]` | 헤더 텍스트 (배열 시 다중 행 헤더, 동일 값은 셀 병합) |
196
+ | `headerContent` | `() => JSX.Element` | 커스텀 헤더 콘텐츠 |
197
+ | `summary` | `() => JSX.Element` | 요약행 콘텐츠 |
198
+ | `fixed` | `boolean` | 좌측 고정 |
199
+ | `hidden` | `boolean` | 숨김 |
200
+ | `collapse` | `boolean` | 축소 가능 |
201
+ | `width` | `string` | 너비 |
202
+ | `sortable` | `boolean` | 정렬 가능 |
203
+ | `resizable` | `boolean` | 리사이즈 가능 |
204
+ | `children` | `(ctx: DataSheetCellContext) => JSX.Element` | 셀 렌더링 |
205
+
206
+ ### DataSheetCellContext
207
+
208
+ ```typescript
209
+ interface DataSheetCellContext<TItem> {
210
+ item: TItem; // 현재 행 데이터
211
+ index: number; // 소속 배열 내 인덱스
212
+ row: number; // 플랫 표시 행 번호 (현재 페이지 내)
213
+ depth: number; // 트리 깊이
214
+ }
215
+ ```
216
+
217
+ ### 부가 기능
218
+
219
+ - `DataSheetConfigDialog` -- 컬럼 표시/순서/너비 설정 UI
220
+ - 설정 자동 저장 (localStorage)
221
+
222
+ ---
223
+
224
+ ## List
225
+
226
+ 트리 뷰 스타일의 항목 목록. 키보드 내비게이션과 아코디언 동작을 지원한다.
227
+
228
+ ```tsx
229
+ import { List } from "@simplysm/solid";
230
+
231
+ // 기본 사용
232
+ <List>
233
+ <List.Item onClick={handleClick}>항목 1</List.Item>
234
+ <List.Item selected>선택된 항목</List.Item>
235
+ <List.Item disabled>비활성 항목</List.Item>
236
+ </List>
237
+
238
+ // 중첩 리스트 (아코디언)
239
+ <List>
240
+ <List.Item>
241
+ 폴더
242
+ <List.Item.Children>
243
+ <List.Item>파일 1</List.Item>
244
+ <List.Item>파일 2</List.Item>
245
+ </List.Item.Children>
246
+ </List.Item>
247
+ </List>
248
+
249
+ // 선택 아이콘
250
+ <List>
251
+ <List.Item selectedIcon={IconCheck} selected>체크 표시</List.Item>
252
+ </List>
253
+ ```
254
+
255
+ | Prop (List) | 타입 | 설명 |
256
+ |------------|------|------|
257
+ | `inset` | `boolean` | 테두리 없음 |
258
+
259
+ | Prop (List.Item) | 타입 | 설명 |
260
+ |-----------------|------|------|
261
+ | `selected` | `boolean` | 선택 상태 |
262
+ | `open` / `onOpenChange` | `boolean` | 제어 모드 열림/닫힘 |
263
+ | `disabled` | `boolean` | 비활성화 |
264
+ | `readOnly` | `boolean` | 읽기 전용 |
265
+ | `selectedIcon` | `Component<IconProps>` | 선택 시 표시할 아이콘 |
266
+ | `size` | `ComponentSize` | 크기 |
267
+ | `onClick` | `(e: MouseEvent) => void` | 클릭 핸들러 |
268
+
269
+ 키보드 내비게이션:
270
+ - `Space` / `Enter`: 현재 항목 토글
271
+ - `ArrowUp` / `ArrowDown`: 이전/다음 항목으로 포커스 이동
272
+ - `ArrowRight`: 닫혀 있으면 열기, 열려 있으면 첫 자식으로 포커스
273
+ - `ArrowLeft`: 열려 있으면 닫기, 닫혀 있으면 부모로 포커스
274
+ - `Home` / `End`: 첫/마지막 항목으로 포커스
275
+
276
+ ---
277
+
278
+ ## Calendar
279
+
280
+ 달력 위젯. 항목 데이터를 날짜별로 배치한다.
281
+
282
+ ```tsx
283
+ import { Calendar } from "@simplysm/solid";
284
+
285
+ <Calendar
286
+ items={events()}
287
+ getItemDate={(event) => event.date}
288
+ renderItem={(event) => <div>{event.title}</div>}
289
+ yearMonth={yearMonth()}
290
+ onYearMonthChange={setYearMonth}
291
+ />
292
+ ```
293
+
294
+ | Prop | 타입 | 설명 |
295
+ |------|------|------|
296
+ | `items` | `TValue[]` | 데이터 배열 |
297
+ | `getItemDate` | `(item, index) => DateOnly` | 항목에서 날짜 추출 |
298
+ | `renderItem` | `(item, index) => JSX.Element` | 항목 렌더링 |
299
+ | `yearMonth` / `onYearMonthChange` | `DateOnly` | 표시 년월 |
300
+ | `weekStartDay` | `number` | 주 시작 요일 (0=일요일, 기본: 0) |
301
+ | `minDaysInFirstWeek` | `number` | 첫 주 최소 일수 (기본: 1) |
302
+
303
+ ---
304
+
305
+ ## Kanban
306
+
307
+ 칸반 보드. 레인/카드 구조의 드래그 앤 드롭을 지원한다.
308
+
309
+ ```tsx
310
+ import { Kanban } from "@simplysm/solid";
311
+
312
+ <Kanban onDrop={(info) => handleDrop(info)}>
313
+ <Kanban.Lane value="todo">
314
+ <Kanban.LaneTitle><span>할 일</span></Kanban.LaneTitle>
315
+ <Kanban.LaneTools><Button size="xs">+</Button></Kanban.LaneTools>
316
+ <Kanban.Card value={1} draggable>
317
+ <div>작업 1</div>
318
+ </Kanban.Card>
319
+ <Kanban.Card value={2} draggable>
320
+ <div>작업 2</div>
321
+ </Kanban.Card>
322
+ </Kanban.Lane>
323
+ <Kanban.Lane value="doing">
324
+ <Kanban.LaneTitle><span>진행 중</span></Kanban.LaneTitle>
325
+ <Kanban.Card value={3} draggable>
326
+ <div>작업 3</div>
327
+ </Kanban.Card>
328
+ </Kanban.Lane>
329
+ </Kanban>
330
+ ```
331
+
332
+ ### Kanban Props
333
+
334
+ | Prop | 타입 | 설명 |
335
+ |------|------|------|
336
+ | `onDrop` | `(info: KanbanDropInfo) => void` | 드롭 이벤트 콜백 |
337
+ | `selectedValues` / `onSelectedValuesChange` | `TCardValue[]` | 선택된 카드 값 배열 |
338
+
339
+ ### KanbanDropInfo
340
+
341
+ ```typescript
342
+ interface KanbanDropInfo<TLaneValue, TCardValue> {
343
+ sourceValue?: TCardValue; // 드래그한 카드 값
344
+ targetLaneValue?: TLaneValue; // 드롭된 레인 값
345
+ targetCardValue?: TCardValue; // 드롭 위치의 카드 값
346
+ position?: "before" | "after"; // 드롭 위치
347
+ }
348
+ ```
349
+
350
+ ### 서브 컴포넌트
351
+
352
+ | 컴포넌트 | 설명 |
353
+ |----------|------|
354
+ | `Kanban.Lane` | 칸반 레인. props: `value`, `busy`, `collapsible`, `collapsed`, `onCollapsedChange` |
355
+ | `Kanban.Card` | 칸반 카드. props: `value`, `draggable`, `selectable`, `contentClass` |
356
+ | `Kanban.LaneTitle` | 레인 타이틀 슬롯 |
357
+ | `Kanban.LaneTools` | 레인 도구 슬롯 |
358
+
359
+ 카드 선택:
360
+ - `Shift+Click`: 다중 선택 토글
361
+ - 롱 프레스 (500ms): 해당 카드만 선택
362
+ - 레인 헤더 체크박스: 레인 내 전체 선택/해제
363
+
364
+ ---
365
+
366
+ ## Pagination
367
+
368
+ 페이지 네비게이션.
369
+
370
+ ```tsx
371
+ import { Pagination } from "@simplysm/solid";
372
+
373
+ <Pagination
374
+ page={currentPage()}
375
+ onPageChange={setCurrentPage}
376
+ totalPageCount={totalPages()}
377
+ />
378
+ ```
379
+
380
+ | Prop | 타입 | 설명 |
381
+ |------|------|------|
382
+ | `page` | `number` | 현재 페이지 |
383
+ | `onPageChange` | `(page: number) => void` | 페이지 변경 콜백 |
384
+ | `totalPageCount` | `number` | 전체 페이지 수 |
385
+ | `displayPageCount` | `number` | 표시할 페이지 버튼 수 |
386
+ | `size` | `ComponentSize` | 크기 |