@simplysm/solid 13.0.93 → 13.0.96

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.
@@ -14,12 +14,14 @@ import { Button } from "@simplysm/solid";
14
14
 
15
15
  | Prop | 타입 | 기본값 | 설명 |
16
16
  |------|------|--------|------|
17
- | `theme` | `"base" \| "primary" \| "success" \| "warning" \| "danger"` | `"base"` | 색상 테마 |
18
- | `variant` | `"solid" \| "outline" \| "ghost"` | `"solid"` | 스타일 변형 |
17
+ | `theme` | `SemanticTheme` | `"base"` | 색상 테마 |
18
+ | `variant` | `"solid" \| "outline" \| "ghost"` | `"outline"` | 스타일 변형 |
19
19
  | `size` | `ComponentSize` | `"md"` | 크기 |
20
- | `inset` | `boolean` | `false` | 테두리 없음 |
20
+ | `inset` | `boolean` | `false` | 테두리/라운드 없음 |
21
21
  | `disabled` | `boolean` | `false` | 비활성화 |
22
22
 
23
+ `<button>` HTML 속성을 모두 상속한다. `type` 기본값은 `"button"`.
24
+
23
25
  ---
24
26
 
25
27
  ## TextInput
@@ -39,40 +41,97 @@ import { TextInput } from "@simplysm/solid";
39
41
  |------|------|------|
40
42
  | `value` | `string` | 값 |
41
43
  | `onValueChange` | `(v: string) => void` | 변경 콜백 |
42
- | `type` | `"text" \| "password" \| "email"` | 입력 타입 |
44
+ | `type` | `"text" \| "password" \| "email"` | 입력 타입 (기본: `"text"`) |
43
45
  | `format` | `string` | 형식 마스크 (예: `"XXX-XXXX-XXXX"`) |
44
- | `size`, `inset`, `disabled`, `readOnly`, `required` | | 공통 |
45
- | `minLength`, `maxLength`, `pattern` | | 유효성 |
46
- | `validate` | `(v: string) => string \| undefined` | 커스텀 유효성 |
46
+ | `placeholder` | `string` | 플레이스홀더 |
47
+ | `title` | `string` | 툴팁 |
48
+ | `autocomplete` | `string` | autocomplete 속성 (기본: `"one-time-code"`) |
49
+ | `size` | `ComponentSize` | 크기 |
50
+ | `inset` | `boolean` | 테두리 없음 |
51
+ | `disabled` | `boolean` | 비활성화 |
52
+ | `readOnly` | `boolean` | 읽기 전용 |
53
+ | `required` | `boolean` | 필수 입력 |
54
+ | `minLength` | `number` | 최소 길이 |
55
+ | `maxLength` | `number` | 최대 길이 |
56
+ | `pattern` | `string \| RegExp` | 입력 패턴 (정규식) |
57
+ | `validate` | `(v: string) => string \| undefined` | 커스텀 유효성 검증 |
47
58
  | `lazyValidation` | `boolean` | blur 시 검증 |
48
59
 
60
+ ### 서브 컴포넌트
61
+
62
+ | 컴포넌트 | 설명 |
63
+ |----------|------|
64
+ | `TextInput.Prefix` | 입력 필드 앞에 표시할 접두사 슬롯 |
65
+
49
66
  ---
50
67
 
51
68
  ## NumberInput
52
69
 
53
70
  ```tsx
71
+ import { NumberInput } from "@simplysm/solid";
72
+
54
73
  <NumberInput value={amount()} onValueChange={setAmount} min={0} max={100} />
55
74
  <NumberInput value={price()} onValueChange={setPrice} useGrouping minimumFractionDigits={2} />
75
+
76
+ // 접두사 슬롯
77
+ <NumberInput value={price()} onValueChange={setPrice}>
78
+ <NumberInput.Prefix>$</NumberInput.Prefix>
79
+ </NumberInput>
56
80
  ```
57
81
 
58
82
  | Prop | 타입 | 설명 |
59
83
  |------|------|------|
60
84
  | `value` | `number` | 값 |
61
85
  | `onValueChange` | `(v: number \| undefined) => void` | 변경 콜백 |
62
- | `useGrouping` | `boolean` | 천단위 구분자 (기본: true) |
86
+ | `useGrouping` | `boolean` | 천단위 구분자 (기본: `true`) |
63
87
  | `minimumFractionDigits` | `number` | 최소 소수점 자릿수 |
64
- | `min`, `max` | `number` | 범위 |
88
+ | `placeholder` | `string` | 플레이스홀더 |
89
+ | `title` | `string` | 툴팁 |
90
+ | `size` | `ComponentSize` | 크기 |
91
+ | `inset` | `boolean` | 테두리 없음 |
92
+ | `disabled` | `boolean` | 비활성화 |
93
+ | `readOnly` | `boolean` | 읽기 전용 |
94
+ | `required` | `boolean` | 필수 입력 |
95
+ | `min` | `number` | 최솟값 |
96
+ | `max` | `number` | 최댓값 |
97
+ | `validate` | `(v: number \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
98
+ | `lazyValidation` | `boolean` | blur 시 검증 |
99
+
100
+ ### 서브 컴포넌트
101
+
102
+ | 컴포넌트 | 설명 |
103
+ |----------|------|
104
+ | `NumberInput.Prefix` | 입력 필드 앞에 표시할 접두사 슬롯 |
65
105
 
66
106
  ---
67
107
 
68
108
  ## Textarea
69
109
 
70
110
  ```tsx
111
+ import { Textarea } from "@simplysm/solid";
112
+
71
113
  <Textarea value={memo()} onValueChange={setMemo} minRows={3} />
72
114
  ```
73
115
 
74
116
  Alt+Enter로 줄바꿈. `minRows`로 최소 높이 설정.
75
117
 
118
+ | Prop | 타입 | 설명 |
119
+ |------|------|------|
120
+ | `value` | `string` | 값 |
121
+ | `onValueChange` | `(v: string) => void` | 변경 콜백 |
122
+ | `placeholder` | `string` | 플레이스홀더 |
123
+ | `title` | `string` | 툴팁 |
124
+ | `minRows` | `number` | 최소 행 수 (기본: `1`) |
125
+ | `size` | `ComponentSize` | 크기 |
126
+ | `inset` | `boolean` | 테두리 없음 |
127
+ | `disabled` | `boolean` | 비활성화 |
128
+ | `readOnly` | `boolean` | 읽기 전용 |
129
+ | `required` | `boolean` | 필수 입력 |
130
+ | `minLength` | `number` | 최소 길이 |
131
+ | `maxLength` | `number` | 최대 길이 |
132
+ | `validate` | `(v: string) => string \| undefined` | 커스텀 유효성 검증 |
133
+ | `lazyValidation` | `boolean` | blur 시 검증 |
134
+
76
135
  ---
77
136
 
78
137
  ## DatePicker
@@ -87,29 +146,65 @@ import { DatePicker } from "@simplysm/solid";
87
146
 
88
147
  | Prop | 타입 | 설명 |
89
148
  |------|------|------|
90
- | `value` | `DateOnly` | 값 |
149
+ | `value` | `DateOnly` | 값 (`@simplysm/core-common`의 `DateOnly`) |
91
150
  | `onValueChange` | `(v: DateOnly \| undefined) => void` | 변경 콜백 |
92
151
  | `unit` | `"year" \| "month" \| "date"` | 선택 단위 (기본: `"date"`) |
93
- | `min`, `max` | `DateOnly` | 범위 제한 |
152
+ | `min` | `DateOnly` | 최소 날짜 |
153
+ | `max` | `DateOnly` | 최대 날짜 |
154
+ | `title` | `string` | 툴팁 |
155
+ | `size` | `ComponentSize` | 크기 |
156
+ | `inset` | `boolean` | 테두리 없음 |
157
+ | `disabled` | `boolean` | 비활성화 |
158
+ | `readOnly` | `boolean` | 읽기 전용 |
159
+ | `required` | `boolean` | 필수 입력 |
160
+ | `validate` | `(v: DateOnly \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
161
+ | `lazyValidation` | `boolean` | blur 시 검증 |
94
162
 
95
163
  ---
96
164
 
97
165
  ## DateTimePicker
98
166
 
99
167
  ```tsx
168
+ import { DateTimePicker } from "@simplysm/solid";
169
+
100
170
  <DateTimePicker value={dt()} onValueChange={setDt} unit="minute" />
101
171
  ```
102
172
 
103
- `unit`: `"minute"` (기본) 또는 `"second"`
173
+ | Prop | 타입 | 설명 |
174
+ |------|------|------|
175
+ | `value` | `DateTime` | 값 (`@simplysm/core-common`의 `DateTime`) |
176
+ | `onValueChange` | `(v: DateTime \| undefined) => void` | 변경 콜백 |
177
+ | `unit` | `"minute" \| "second"` | 시간 단위 (기본: `"minute"`) |
178
+ | `min` | `DateTime` | 최소 일시 |
179
+ | `max` | `DateTime` | 최대 일시 |
180
+ | `title` | `string` | 툴팁 |
181
+ | `size`, `inset`, `disabled`, `readOnly`, `required` | | 공통 |
182
+ | `validate` | `(v: DateTime \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
183
+ | `lazyValidation` | `boolean` | blur 시 검증 |
104
184
 
105
185
  ---
106
186
 
107
187
  ## TimePicker
108
188
 
109
189
  ```tsx
190
+ import { TimePicker } from "@simplysm/solid";
191
+
110
192
  <TimePicker value={time()} onValueChange={setTime} />
193
+ <TimePicker value={time()} onValueChange={setTime} unit="second" />
111
194
  ```
112
195
 
196
+ | Prop | 타입 | 설명 |
197
+ |------|------|------|
198
+ | `value` | `Time` | 값 (`@simplysm/core-common`의 `Time`) |
199
+ | `onValueChange` | `(v: Time \| undefined) => void` | 변경 콜백 |
200
+ | `unit` | `"minute" \| "second"` | 시간 단위 (기본: `"minute"`) |
201
+ | `min` | `Time` | 최소 시간 |
202
+ | `max` | `Time` | 최대 시간 |
203
+ | `title` | `string` | 툴팁 |
204
+ | `size`, `inset`, `disabled`, `readOnly`, `required` | | 공통 |
205
+ | `validate` | `(v: Time \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
206
+ | `lazyValidation` | `boolean` | blur 시 검증 |
207
+
113
208
  ---
114
209
 
115
210
  ## DateRangePicker
@@ -153,6 +248,8 @@ const [to, setTo] = createSignal<DateOnly>();
153
248
  ## Checkbox / Radio
154
249
 
155
250
  ```tsx
251
+ import { Checkbox, Radio, RadioGroup } from "@simplysm/solid";
252
+
156
253
  <Checkbox checked={active()} onCheckedChange={setActive}>활성</Checkbox>
157
254
  <Checkbox checked={agreed()} onCheckedChange={setAgreed} required>약관 동의</Checkbox>
158
255
 
@@ -162,6 +259,32 @@ const [to, setTo] = createSignal<DateOnly>();
162
259
  </RadioGroup>
163
260
  ```
164
261
 
262
+ ### Checkbox Props
263
+
264
+ | Prop | 타입 | 설명 |
265
+ |------|------|------|
266
+ | `checked` | `boolean` | 체크 상태 |
267
+ | `onCheckedChange` | `(v: boolean) => void` | 변경 콜백 |
268
+ | `disabled` | `boolean` | 비활성화 |
269
+ | `size` | `ComponentSize` | 크기 |
270
+ | `inset` | `boolean` | 테두리 없음 |
271
+ | `inline` | `boolean` | 인라인 배치 |
272
+ | `required` | `boolean` | 필수 체크 |
273
+ | `validate` | `(v: boolean) => string \| undefined` | 커스텀 유효성 검증 |
274
+ | `lazyValidation` | `boolean` | blur 시 검증 |
275
+
276
+ ### RadioGroup Props
277
+
278
+ | Prop | 타입 | 설명 |
279
+ |------|------|------|
280
+ | `value` | `TValue` | 선택 값 |
281
+ | `onValueChange` | `(v: TValue) => void` | 변경 콜백 |
282
+ | `disabled` | `boolean` | 비활성화 |
283
+ | `inline` | `boolean` | 가로 배치 |
284
+ | `inset` | `boolean` | 테두리 없음 |
285
+ | `required` | `boolean` | 필수 선택 |
286
+ | `validate` | `(v: TValue \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
287
+
165
288
  ---
166
289
 
167
290
  ## CheckboxGroup
@@ -188,13 +311,15 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
188
311
  | `inline` | `boolean` | 가로 배치 |
189
312
  | `inset` | `boolean` | 테두리 없음 |
190
313
  | `required` | `boolean` | 최소 1개 선택 필수 |
191
- | `validate` | `(v: TValue[]) => string \| undefined` | 커스텀 유효성 |
314
+ | `validate` | `(v: TValue[]) => string \| undefined` | 커스텀 유효성 검증 |
192
315
 
193
316
  ---
194
317
 
195
318
  ## Select
196
319
 
197
320
  ```tsx
321
+ import { Select } from "@simplysm/solid";
322
+
198
323
  // 단일 선택 (items 모드)
199
324
  <Select
200
325
  value={selected()}
@@ -224,10 +349,9 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
224
349
  />
225
350
 
226
351
  // Children 모드
227
- <Select value={v()} onValueChange={setV}>
352
+ <Select value={v()} onValueChange={setV} renderValue={(v) => <span>{v}</span>}>
228
353
  <Select.Item value="a">옵션 A</Select.Item>
229
354
  <Select.Item value="b">옵션 B</Select.Item>
230
- <Select.Header>그룹 헤더</Select.Header>
231
355
  </Select>
232
356
 
233
357
  // ItemTemplate (items 모드에서 드롭다운 렌더링 커스터마이징)
@@ -237,7 +361,13 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
237
361
  </Select.ItemTemplate>
238
362
  </Select>
239
363
 
240
- // Action (드롭다운 하단 커스텀 액션)
364
+ // Header (드롭다운 상단 커스텀 영역)
365
+ <Select value={v()} onValueChange={setV} renderValue={(v) => <span>{v}</span>}>
366
+ <Select.Header><div>그룹 헤더</div></Select.Header>
367
+ <Select.Item value="a">옵션 A</Select.Item>
368
+ </Select>
369
+
370
+ // Action (트리거 옆 커스텀 액션 버튼)
241
371
  <Select items={users} renderValue={(u) => <span>{u.name}</span>}>
242
372
  <Select.Action onClick={handleSearch}>
243
373
  <Icon icon={IconSearch} />
@@ -245,18 +375,58 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
245
375
  </Select>
246
376
  ```
247
377
 
378
+ ### Select Props
379
+
380
+ | Prop | 타입 | 설명 |
381
+ |------|------|------|
382
+ | `value` | `TValue \| TValue[]` | 선택 값 (multiple 시 배열) |
383
+ | `onValueChange` | `(v) => void` | 변경 콜백 |
384
+ | `multiple` | `boolean` | 다중 선택 모드 |
385
+ | `items` | `TValue[]` | 아이템 배열 (items 모드) |
386
+ | `itemChildren` | `(item, index, depth) => TValue[] \| undefined` | 트리 자식 접근자 |
387
+ | `renderValue` | `(v: TValue) => JSX.Element` | 선택된 값 렌더링 |
388
+ | `itemSearchText` | `(item: TValue) => string` | 검색 텍스트 추출 (설정 시 검색 입력 표시) |
389
+ | `isItemHidden` | `(item: TValue) => boolean` | 아이템 숨김 여부 |
390
+ | `tagDirection` | `"horizontal" \| "vertical"` | 다중 선택 태그 방향 |
391
+ | `hideSelectAll` | `boolean` | 전체 선택 버튼 숨김 (다중 선택) |
392
+ | `placeholder` | `string` | 플레이스홀더 |
393
+ | `size` | `ComponentSize` | 크기 |
394
+ | `inset` | `boolean` | 테두리 없음 |
395
+ | `disabled` | `boolean` | 비활성화 |
396
+ | `required` | `boolean` | 필수 선택 |
397
+ | `validate` | `(v: unknown) => string \| undefined` | 커스텀 유효성 검증 |
398
+ | `lazyValidation` | `boolean` | blur 시 검증 |
399
+
400
+ ### 서브 컴포넌트
401
+
402
+ | 컴포넌트 | 설명 |
403
+ |----------|------|
404
+ | `Select.Item` | 드롭다운 선택 항목. props: `value`, `disabled` |
405
+ | `Select.Item.Children` | 중첩 아이템 슬롯 (트리 구조) |
406
+ | `Select.ItemTemplate` | items 모드에서 드롭다운 아이템 렌더링 커스터마이징 |
407
+ | `Select.Header` | 드롭다운 상단 커스텀 영역 |
408
+ | `Select.Action` | 트리거 옆 커스텀 액션 버튼 |
409
+
248
410
  ---
249
411
 
250
412
  ## Combobox
251
413
 
414
+ 비동기 검색 기반 자동완성 컴포넌트.
415
+
252
416
  ```tsx
417
+ import { Combobox } from "@simplysm/solid";
418
+
253
419
  <Combobox
254
420
  value={user()}
255
421
  onValueChange={setUser}
256
422
  loadItems={async (query) => await searchUsers(query)}
257
423
  renderValue={(u) => <span>{u.name}</span>}
258
424
  debounceMs={300}
259
- />
425
+ >
426
+ <Combobox.ItemTemplate>
427
+ {(item) => <span>{item.name} ({item.email})</span>}
428
+ </Combobox.ItemTemplate>
429
+ </Combobox>
260
430
 
261
431
  // 커스텀 값 허용
262
432
  <Combobox
@@ -265,13 +435,48 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
265
435
  loadItems={loadItems}
266
436
  renderValue={(v) => <span>{v.name}</span>}
267
437
  />
438
+
439
+ // Children 모드
440
+ <Combobox loadItems={loadItems} renderValue={(v) => v.name}>
441
+ <For each={items()}>
442
+ {(item) => <Combobox.Item value={item}>{item.name}</Combobox.Item>}
443
+ </For>
444
+ </Combobox>
268
445
  ```
269
446
 
447
+ ### Combobox Props
448
+
449
+ | Prop | 타입 | 설명 |
450
+ |------|------|------|
451
+ | `value` | `TValue` | 선택 값 |
452
+ | `onValueChange` | `(v: TValue) => void` | 변경 콜백 |
453
+ | `loadItems` | `(query: string) => TValue[] \| Promise<TValue[]>` | 아이템 검색 함수 (필수) |
454
+ | `renderValue` | `(v: TValue) => JSX.Element` | 선택된 값 렌더링 (필수) |
455
+ | `debounceMs` | `number` | 검색 디바운스 (기본: `300`) |
456
+ | `allowsCustomValue` | `boolean` | 커스텀 값 입력 허용 |
457
+ | `parseCustomValue` | `(text: string) => TValue` | 텍스트를 값으로 변환 |
458
+ | `placeholder` | `string` | 플레이스홀더 |
459
+ | `size` | `ComponentSize` | 크기 |
460
+ | `inset` | `boolean` | 테두리 없음 |
461
+ | `disabled` | `boolean` | 비활성화 |
462
+ | `required` | `boolean` | 필수 선택 |
463
+ | `validate` | `(v: TValue \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
464
+ | `lazyValidation` | `boolean` | blur 시 검증 |
465
+
466
+ ### 서브 컴포넌트
467
+
468
+ | 컴포넌트 | 설명 |
469
+ |----------|------|
470
+ | `Combobox.Item` | 드롭다운 선택 항목. props: `value`, `disabled` |
471
+ | `Combobox.ItemTemplate` | 아이템 렌더링 커스터마이징 |
472
+
270
473
  ---
271
474
 
272
475
  ## ColorPicker
273
476
 
274
477
  ```tsx
478
+ import { ColorPicker } from "@simplysm/solid";
479
+
275
480
  <ColorPicker value={color()} onValueChange={setColor} />
276
481
  // value: "#RRGGBB" 형식
277
482
  ```
@@ -283,6 +488,8 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
283
488
  Tiptap 기반 리치 텍스트 에디터. 서식, 텍스트 스타일, 정렬, 테이블, 이미지, 하이라이트 도구 포함.
284
489
 
285
490
  ```tsx
491
+ import { RichTextEditor } from "@simplysm/solid";
492
+
286
493
  <RichTextEditor value={html()} onValueChange={setHtml} />
287
494
  ```
288
495
 
@@ -356,6 +563,8 @@ const [filterState, setFilterState] = createSignal({ status: "active", keyword:
356
563
  라이트/다크/시스템 모드 전환 버튼.
357
564
 
358
565
  ```tsx
566
+ import { ThemeToggle } from "@simplysm/solid";
567
+
359
568
  <ThemeToggle />
360
569
  ```
361
570
 
@@ -96,6 +96,12 @@ sidebar.setToggle(true); // 열기/닫기 토글
96
96
  - `toggle=false` (기본): 데스크탑(640px+)에서 열림, 모바일(640px-)에서 닫힘
97
97
  - `toggle=true`: 데스크탑에서 닫힘, 모바일에서 오버레이로 열림
98
98
 
99
+ 하위 메뉴 기본 펼침:
100
+ ```tsx
101
+ <Sidebar.Menu menus={menus} defaultOpen />
102
+ ```
103
+ - `defaultOpen`: 모든 하위 메뉴를 처음부터 펼친 상태로 렌더링한다. 기본값 `false`.
104
+
99
105
  ---
100
106
 
101
107
  ## Topbar