@simplysm/solid 13.0.95 → 13.0.97
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/dist/components/layout/sidebar/Sidebar.d.ts +5 -0
- package/dist/components/layout/sidebar/Sidebar.d.ts.map +1 -1
- package/dist/components/layout/sidebar/Sidebar.js +7 -4
- package/dist/components/layout/sidebar/Sidebar.js.map +2 -2
- package/package.json +19 -26
- package/src/components/layout/sidebar/Sidebar.tsx +9 -3
- package/README.md +0 -145
- package/docs/display-feedback.md +0 -279
- package/docs/features.md +0 -653
- package/docs/form-controls.md +0 -378
- package/docs/layout-data.md +0 -386
- package/docs/providers-hooks.md +0 -411
package/docs/form-controls.md
DELETED
|
@@ -1,378 +0,0 @@
|
|
|
1
|
-
# 폼 컨트롤
|
|
2
|
-
|
|
3
|
-
## Button
|
|
4
|
-
|
|
5
|
-
```tsx
|
|
6
|
-
import { Button } from "@simplysm/solid";
|
|
7
|
-
|
|
8
|
-
<Button theme="primary" variant="solid" size="md" onClick={handleClick}>
|
|
9
|
-
저장
|
|
10
|
-
</Button>
|
|
11
|
-
<Button variant="outline" disabled>취소</Button>
|
|
12
|
-
<Button variant="ghost" inset>아이콘 버튼</Button>
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
| Prop | 타입 | 기본값 | 설명 |
|
|
16
|
-
|------|------|--------|------|
|
|
17
|
-
| `theme` | `"base" \| "primary" \| "success" \| "warning" \| "danger"` | `"base"` | 색상 테마 |
|
|
18
|
-
| `variant` | `"solid" \| "outline" \| "ghost"` | `"solid"` | 스타일 변형 |
|
|
19
|
-
| `size` | `ComponentSize` | `"md"` | 크기 |
|
|
20
|
-
| `inset` | `boolean` | `false` | 테두리 없음 |
|
|
21
|
-
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## TextInput
|
|
26
|
-
|
|
27
|
-
```tsx
|
|
28
|
-
import { TextInput } from "@simplysm/solid";
|
|
29
|
-
|
|
30
|
-
<TextInput value={name()} onValueChange={setName} placeholder="이름 입력" />
|
|
31
|
-
|
|
32
|
-
// 접두사 슬롯
|
|
33
|
-
<TextInput value={phone()} onValueChange={setPhone} format="XXX-XXXX-XXXX">
|
|
34
|
-
<TextInput.Prefix>+82</TextInput.Prefix>
|
|
35
|
-
</TextInput>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
| Prop | 타입 | 설명 |
|
|
39
|
-
|------|------|------|
|
|
40
|
-
| `value` | `string` | 값 |
|
|
41
|
-
| `onValueChange` | `(v: string) => void` | 변경 콜백 |
|
|
42
|
-
| `type` | `"text" \| "password" \| "email"` | 입력 타입 |
|
|
43
|
-
| `format` | `string` | 형식 마스크 (예: `"XXX-XXXX-XXXX"`) |
|
|
44
|
-
| `size`, `inset`, `disabled`, `readOnly`, `required` | | 공통 |
|
|
45
|
-
| `minLength`, `maxLength`, `pattern` | | 유효성 |
|
|
46
|
-
| `validate` | `(v: string) => string \| undefined` | 커스텀 유효성 |
|
|
47
|
-
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## NumberInput
|
|
52
|
-
|
|
53
|
-
```tsx
|
|
54
|
-
<NumberInput value={amount()} onValueChange={setAmount} min={0} max={100} />
|
|
55
|
-
<NumberInput value={price()} onValueChange={setPrice} useGrouping minimumFractionDigits={2} />
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
| Prop | 타입 | 설명 |
|
|
59
|
-
|------|------|------|
|
|
60
|
-
| `value` | `number` | 값 |
|
|
61
|
-
| `onValueChange` | `(v: number \| undefined) => void` | 변경 콜백 |
|
|
62
|
-
| `useGrouping` | `boolean` | 천단위 구분자 (기본: true) |
|
|
63
|
-
| `minimumFractionDigits` | `number` | 최소 소수점 자릿수 |
|
|
64
|
-
| `min`, `max` | `number` | 범위 |
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Textarea
|
|
69
|
-
|
|
70
|
-
```tsx
|
|
71
|
-
<Textarea value={memo()} onValueChange={setMemo} minRows={3} />
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Alt+Enter로 줄바꿈. `minRows`로 최소 높이 설정.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## DatePicker
|
|
79
|
-
|
|
80
|
-
```tsx
|
|
81
|
-
import { DatePicker } from "@simplysm/solid";
|
|
82
|
-
|
|
83
|
-
<DatePicker value={date()} onValueChange={setDate} />
|
|
84
|
-
<DatePicker value={month()} onValueChange={setMonth} unit="month" />
|
|
85
|
-
<DatePicker value={year()} onValueChange={setYear} unit="year" />
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
| Prop | 타입 | 설명 |
|
|
89
|
-
|------|------|------|
|
|
90
|
-
| `value` | `DateOnly` | 값 |
|
|
91
|
-
| `onValueChange` | `(v: DateOnly \| undefined) => void` | 변경 콜백 |
|
|
92
|
-
| `unit` | `"year" \| "month" \| "date"` | 선택 단위 (기본: `"date"`) |
|
|
93
|
-
| `min`, `max` | `DateOnly` | 범위 제한 |
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## DateTimePicker
|
|
98
|
-
|
|
99
|
-
```tsx
|
|
100
|
-
<DateTimePicker value={dt()} onValueChange={setDt} unit="minute" />
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
`unit`: `"minute"` (기본) 또는 `"second"`
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## TimePicker
|
|
108
|
-
|
|
109
|
-
```tsx
|
|
110
|
-
<TimePicker value={time()} onValueChange={setTime} />
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## DateRangePicker
|
|
116
|
-
|
|
117
|
-
기간 유형(일/월/범위) 선택과 시작/종료일 입력을 조합한 날짜 범위 선택기.
|
|
118
|
-
|
|
119
|
-
```tsx
|
|
120
|
-
import { DateRangePicker, type DateRangePeriodType } from "@simplysm/solid";
|
|
121
|
-
|
|
122
|
-
const [periodType, setPeriodType] = createSignal<DateRangePeriodType>("range");
|
|
123
|
-
const [from, setFrom] = createSignal<DateOnly>();
|
|
124
|
-
const [to, setTo] = createSignal<DateOnly>();
|
|
125
|
-
|
|
126
|
-
<DateRangePicker
|
|
127
|
-
periodType={periodType()}
|
|
128
|
-
onPeriodTypeChange={setPeriodType}
|
|
129
|
-
from={from()}
|
|
130
|
-
onFromChange={setFrom}
|
|
131
|
-
to={to()}
|
|
132
|
-
onToChange={setTo}
|
|
133
|
-
required
|
|
134
|
-
/>
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
| Prop | 타입 | 설명 |
|
|
138
|
-
|------|------|------|
|
|
139
|
-
| `periodType` | `"day" \| "month" \| "range"` | 기간 유형 |
|
|
140
|
-
| `onPeriodTypeChange` | `(v: DateRangePeriodType) => void` | 기간 유형 변경 콜백 |
|
|
141
|
-
| `from` | `DateOnly` | 시작일 |
|
|
142
|
-
| `onFromChange` | `(v: DateOnly \| undefined) => void` | 시작일 변경 콜백 |
|
|
143
|
-
| `to` | `DateOnly` | 종료일 |
|
|
144
|
-
| `onToChange` | `(v: DateOnly \| undefined) => void` | 종료일 변경 콜백 |
|
|
145
|
-
|
|
146
|
-
기간 유형에 따라 자동으로 from/to를 조정한다:
|
|
147
|
-
- `"day"`: from = to (동일)
|
|
148
|
-
- `"month"`: from = 월 첫째 날, to = 월 마지막 날
|
|
149
|
-
- `"range"`: 시작일/종료일 독립 선택
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## Checkbox / Radio
|
|
154
|
-
|
|
155
|
-
```tsx
|
|
156
|
-
<Checkbox checked={active()} onCheckedChange={setActive}>활성</Checkbox>
|
|
157
|
-
<Checkbox checked={agreed()} onCheckedChange={setAgreed} required>약관 동의</Checkbox>
|
|
158
|
-
|
|
159
|
-
<RadioGroup value={role()} onValueChange={setRole}>
|
|
160
|
-
<Radio value="admin">관리자</Radio>
|
|
161
|
-
<Radio value="user">사용자</Radio>
|
|
162
|
-
</RadioGroup>
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## CheckboxGroup
|
|
168
|
-
|
|
169
|
-
다중 선택을 위한 체크박스 그룹.
|
|
170
|
-
|
|
171
|
-
```tsx
|
|
172
|
-
import { CheckboxGroup } from "@simplysm/solid";
|
|
173
|
-
|
|
174
|
-
const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
|
|
175
|
-
|
|
176
|
-
<CheckboxGroup value={selectedTags()} onValueChange={setSelectedTags} required>
|
|
177
|
-
<CheckboxGroup.Item value="frontend">프론트엔드</CheckboxGroup.Item>
|
|
178
|
-
<CheckboxGroup.Item value="backend">백엔드</CheckboxGroup.Item>
|
|
179
|
-
<CheckboxGroup.Item value="devops">DevOps</CheckboxGroup.Item>
|
|
180
|
-
</CheckboxGroup>
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
| Prop | 타입 | 설명 |
|
|
184
|
-
|------|------|------|
|
|
185
|
-
| `value` | `TValue[]` | 선택된 값 배열 |
|
|
186
|
-
| `onValueChange` | `(v: TValue[]) => void` | 변경 콜백 |
|
|
187
|
-
| `disabled` | `boolean` | 비활성화 |
|
|
188
|
-
| `inline` | `boolean` | 가로 배치 |
|
|
189
|
-
| `inset` | `boolean` | 테두리 없음 |
|
|
190
|
-
| `required` | `boolean` | 최소 1개 선택 필수 |
|
|
191
|
-
| `validate` | `(v: TValue[]) => string \| undefined` | 커스텀 유효성 |
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## Select
|
|
196
|
-
|
|
197
|
-
```tsx
|
|
198
|
-
// 단일 선택 (items 모드)
|
|
199
|
-
<Select
|
|
200
|
-
value={selected()}
|
|
201
|
-
onValueChange={setSelected}
|
|
202
|
-
items={options}
|
|
203
|
-
renderValue={(item) => <span>{item.label}</span>}
|
|
204
|
-
itemSearchText={(item) => item.label}
|
|
205
|
-
/>
|
|
206
|
-
|
|
207
|
-
// 다중 선택
|
|
208
|
-
<Select
|
|
209
|
-
multiple
|
|
210
|
-
value={selectedList()}
|
|
211
|
-
onValueChange={setSelectedList}
|
|
212
|
-
items={options}
|
|
213
|
-
renderValue={(item) => <span>{item.label}</span>}
|
|
214
|
-
tagDirection="horizontal"
|
|
215
|
-
/>
|
|
216
|
-
|
|
217
|
-
// 트리 구조
|
|
218
|
-
<Select
|
|
219
|
-
value={selected()}
|
|
220
|
-
onValueChange={setSelected}
|
|
221
|
-
items={categories}
|
|
222
|
-
itemChildren={(item) => item.children}
|
|
223
|
-
renderValue={(item) => <span>{item.name}</span>}
|
|
224
|
-
/>
|
|
225
|
-
|
|
226
|
-
// Children 모드
|
|
227
|
-
<Select value={v()} onValueChange={setV}>
|
|
228
|
-
<Select.Item value="a">옵션 A</Select.Item>
|
|
229
|
-
<Select.Item value="b">옵션 B</Select.Item>
|
|
230
|
-
<Select.Header>그룹 헤더</Select.Header>
|
|
231
|
-
</Select>
|
|
232
|
-
|
|
233
|
-
// ItemTemplate (items 모드에서 드롭다운 렌더링 커스터마이징)
|
|
234
|
-
<Select items={users} renderValue={(u) => <span>{u.name}</span>}>
|
|
235
|
-
<Select.ItemTemplate>
|
|
236
|
-
{(item, _index, _depth) => <span>{item.name} ({item.email})</span>}
|
|
237
|
-
</Select.ItemTemplate>
|
|
238
|
-
</Select>
|
|
239
|
-
|
|
240
|
-
// Action (드롭다운 하단 커스텀 액션)
|
|
241
|
-
<Select items={users} renderValue={(u) => <span>{u.name}</span>}>
|
|
242
|
-
<Select.Action onClick={handleSearch}>
|
|
243
|
-
<Icon icon={IconSearch} />
|
|
244
|
-
</Select.Action>
|
|
245
|
-
</Select>
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
---
|
|
249
|
-
|
|
250
|
-
## Combobox
|
|
251
|
-
|
|
252
|
-
```tsx
|
|
253
|
-
<Combobox
|
|
254
|
-
value={user()}
|
|
255
|
-
onValueChange={setUser}
|
|
256
|
-
loadItems={async (query) => await searchUsers(query)}
|
|
257
|
-
renderValue={(u) => <span>{u.name}</span>}
|
|
258
|
-
debounceMs={300}
|
|
259
|
-
/>
|
|
260
|
-
|
|
261
|
-
// 커스텀 값 허용
|
|
262
|
-
<Combobox
|
|
263
|
-
allowsCustomValue
|
|
264
|
-
parseCustomValue={(text) => ({ id: 0, name: text })}
|
|
265
|
-
loadItems={loadItems}
|
|
266
|
-
renderValue={(v) => <span>{v.name}</span>}
|
|
267
|
-
/>
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
## ColorPicker
|
|
273
|
-
|
|
274
|
-
```tsx
|
|
275
|
-
<ColorPicker value={color()} onValueChange={setColor} />
|
|
276
|
-
// value: "#RRGGBB" 형식
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
---
|
|
280
|
-
|
|
281
|
-
## RichTextEditor
|
|
282
|
-
|
|
283
|
-
Tiptap 기반 리치 텍스트 에디터. 서식, 텍스트 스타일, 정렬, 테이블, 이미지, 하이라이트 도구 포함.
|
|
284
|
-
|
|
285
|
-
```tsx
|
|
286
|
-
<RichTextEditor value={html()} onValueChange={setHtml} />
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
---
|
|
290
|
-
|
|
291
|
-
## Numpad
|
|
292
|
-
|
|
293
|
-
터치 환경용 숫자 키패드 컴포넌트.
|
|
294
|
-
|
|
295
|
-
```tsx
|
|
296
|
-
import { Numpad } from "@simplysm/solid";
|
|
297
|
-
|
|
298
|
-
<Numpad value={quantity()} onValueChange={setQuantity} />
|
|
299
|
-
|
|
300
|
-
// Enter 버튼 + 마이너스 버튼 포함
|
|
301
|
-
<Numpad
|
|
302
|
-
value={amount()}
|
|
303
|
-
onValueChange={setAmount}
|
|
304
|
-
withEnterButton
|
|
305
|
-
withMinusButton
|
|
306
|
-
onEnterButtonClick={() => submit()}
|
|
307
|
-
required
|
|
308
|
-
/>
|
|
309
|
-
|
|
310
|
-
// 직접 입력 비활성화 (키패드만 사용)
|
|
311
|
-
<Numpad value={code()} onValueChange={setCode} inputDisabled />
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
| Prop | 타입 | 설명 |
|
|
315
|
-
|------|------|------|
|
|
316
|
-
| `value` | `number` | 값 |
|
|
317
|
-
| `onValueChange` | `(v: number \| undefined) => void` | 변경 콜백 |
|
|
318
|
-
| `withEnterButton` | `boolean` | Enter 버튼 표시 |
|
|
319
|
-
| `withMinusButton` | `boolean` | 마이너스 토글 버튼 표시 |
|
|
320
|
-
| `onEnterButtonClick` | `() => void` | Enter 버튼 클릭 콜백 |
|
|
321
|
-
| `inputDisabled` | `boolean` | NumberInput 직접 입력 비활성화 |
|
|
322
|
-
| `required` | `boolean` | 필수 입력 |
|
|
323
|
-
| `size` | `ComponentSize` | 크기 |
|
|
324
|
-
|
|
325
|
-
---
|
|
326
|
-
|
|
327
|
-
## StatePreset
|
|
328
|
-
|
|
329
|
-
필터/설정 상태를 프리셋으로 저장하고 복원하는 컴포넌트. localStorage에 자동 저장된다.
|
|
330
|
-
|
|
331
|
-
```tsx
|
|
332
|
-
import { StatePreset } from "@simplysm/solid";
|
|
333
|
-
|
|
334
|
-
const [filterState, setFilterState] = createSignal({ status: "active", keyword: "" });
|
|
335
|
-
|
|
336
|
-
<StatePreset
|
|
337
|
-
storageKey="user-list-filter"
|
|
338
|
-
value={filterState()}
|
|
339
|
-
onValueChange={setFilterState}
|
|
340
|
-
/>
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
| Prop | 타입 | 설명 |
|
|
344
|
-
|------|------|------|
|
|
345
|
-
| `storageKey` | `string` | localStorage 저장 키 |
|
|
346
|
-
| `value` | `TValue` | 현재 상태 값 |
|
|
347
|
-
| `onValueChange` | `(v: TValue) => void` | 상태 복원 콜백 |
|
|
348
|
-
| `size` | `ComponentSize` | 크기 |
|
|
349
|
-
|
|
350
|
-
프리셋 칩 UI를 제공하며, 클릭으로 복원, 저장(덮어쓰기), 삭제가 가능하다. 삭제/덮어쓰기 시 실행 취소 알림을 표시한다.
|
|
351
|
-
|
|
352
|
-
---
|
|
353
|
-
|
|
354
|
-
## ThemeToggle
|
|
355
|
-
|
|
356
|
-
라이트/다크/시스템 모드 전환 버튼.
|
|
357
|
-
|
|
358
|
-
```tsx
|
|
359
|
-
<ThemeToggle />
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
---
|
|
363
|
-
|
|
364
|
-
## 유효성 검증
|
|
365
|
-
|
|
366
|
-
모든 폼 컨트롤은 `validate`, `required`, `lazyValidation` prop을 지원한다.
|
|
367
|
-
|
|
368
|
-
```tsx
|
|
369
|
-
<TextInput
|
|
370
|
-
value={email()}
|
|
371
|
-
onValueChange={setEmail}
|
|
372
|
-
required
|
|
373
|
-
validate={(v) => v.includes("@") ? undefined : "이메일 형식이 아닙니다"}
|
|
374
|
-
lazyValidation // blur 시 검증
|
|
375
|
-
/>
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
`Invalid` 컴포넌트로 검증 에러를 감싸서 표시할 수 있다.
|