@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.
@@ -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` 컴포넌트로 검증 에러를 감싸서 표시할 수 있다.