@pantoia/ui 0.1.0 → 0.2.0
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/accordion/AGENTS.md +5 -5
- package/accordion/index.tsx +17 -9
- package/alert-dialog/AGENTS.md +7 -7
- package/alert-dialog/index.tsx +20 -10
- package/badge/AGENTS.md +5 -5
- package/badge/index.tsx +7 -7
- package/button/AGENTS.md +7 -7
- package/button/index.tsx +36 -36
- package/callout/AGENTS.md +4 -5
- package/callout/index.tsx +13 -14
- package/checkbox/AGENTS.md +5 -5
- package/checkbox/index.tsx +15 -13
- package/combobox/AGENTS.md +13 -13
- package/combobox/index.tsx +82 -38
- package/command-palette/AGENTS.md +3 -2
- package/command-palette/index.tsx +4 -2
- package/dialog/AGENTS.md +6 -6
- package/dialog/index.tsx +11 -5
- package/dist/index.js +63 -34
- package/drawer/AGENTS.md +5 -5
- package/drawer/index.tsx +8 -4
- package/dropdown-menu/AGENTS.md +12 -12
- package/dropdown-menu/index.tsx +23 -11
- package/field/AGENTS.md +8 -8
- package/field/index.tsx +27 -9
- package/input/AGENTS.md +4 -4
- package/input/index.tsx +8 -8
- package/kbd/AGENTS.md +1 -1
- package/kbd/index.tsx +6 -2
- package/label/AGENTS.md +1 -1
- package/label/index.tsx +3 -1
- package/number-field/AGENTS.md +6 -6
- package/number-field/index.tsx +22 -16
- package/package.json +3 -6
- package/popover/AGENTS.md +4 -4
- package/popover/index.tsx +14 -4
- package/press.css +7 -7
- package/radio-group/AGENTS.md +8 -8
- package/radio-group/index.tsx +20 -16
- package/registry.json +3 -51
- package/select/AGENTS.md +10 -10
- package/select/index.tsx +41 -23
- package/styles.css +291 -139
- package/switch/AGENTS.md +4 -4
- package/switch/index.tsx +13 -13
- package/table/AGENTS.md +9 -9
- package/table/index.tsx +17 -7
- package/tabs/AGENTS.md +4 -4
- package/tabs/index.module.css +1 -1
- package/tabs/index.tsx +17 -9
- package/textarea/AGENTS.md +4 -4
- package/textarea/index.tsx +8 -8
- package/toast/AGENTS.md +5 -13
- package/toast/index.tsx +31 -37
- package/toggle/AGENTS.md +4 -4
- package/toggle/index.tsx +10 -9
- package/tooltip/AGENTS.md +2 -2
- package/tooltip/index.tsx +14 -4
- package/code-block/AGENTS.md +0 -60
- package/code-block/index.module.css +0 -46
- package/code-block/index.tsx +0 -127
- package/copy-button/AGENTS.md +0 -43
- package/copy-button/index.tsx +0 -119
package/combobox/AGENTS.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
```
|
|
4
4
|
받기 npx @pantoia/ui add combobox
|
|
5
5
|
층 ui
|
|
6
|
-
파일 combobox/index.tsx
|
|
6
|
+
파일 combobox/index.tsx, combobox/AGENTS.md
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
## 부위
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
| `Combobox` | `ComboboxProps` |
|
|
14
14
|
| `ComboboxAnchor` | `ComboboxAnchorProps` |
|
|
15
15
|
| `ComboboxInput` | `ComboboxInputProps` |
|
|
16
|
-
| `ComboboxTrigger` |
|
|
17
|
-
| `ComboboxCancel` |
|
|
16
|
+
| `ComboboxTrigger` | - |
|
|
17
|
+
| `ComboboxCancel` | - |
|
|
18
18
|
| `ComboboxContent` | `ComboboxContentProps` |
|
|
19
|
-
| `ComboboxViewport` |
|
|
19
|
+
| `ComboboxViewport` | - |
|
|
20
20
|
| `ComboboxItem` | `ComboboxItemProps` |
|
|
21
|
-
| `ComboboxItemText` |
|
|
22
|
-
| `ComboboxItemDescription` |
|
|
23
|
-
| `ComboboxGroup` |
|
|
24
|
-
| `ComboboxEmpty` |
|
|
25
|
-
| `ComboboxSeparator` |
|
|
21
|
+
| `ComboboxItemText` | - |
|
|
22
|
+
| `ComboboxItemDescription` | - |
|
|
23
|
+
| `ComboboxGroup` | - |
|
|
24
|
+
| `ComboboxEmpty` | - |
|
|
25
|
+
| `ComboboxSeparator` | - |
|
|
26
26
|
|
|
27
27
|
### `ComboboxTrigger`
|
|
28
28
|
|
|
@@ -134,12 +134,12 @@
|
|
|
134
134
|
| `className` | `string` | |
|
|
135
135
|
| `children` | `ReactNode` | |
|
|
136
136
|
|
|
137
|
-
## 변형
|
|
137
|
+
## 변형 - `comboboxAnchor`
|
|
138
138
|
|
|
139
139
|
| 축 | 값 | 기본 |
|
|
140
140
|
|---|---|---|
|
|
141
|
-
| `surface` | `bare
|
|
142
|
-
| `size` | `sm
|
|
141
|
+
| `surface` | `bare`, `well` | `bare` |
|
|
142
|
+
| `size` | `sm`, `md`, `lg` | `md` |
|
|
143
143
|
|
|
144
144
|
## 함께 받는 것
|
|
145
145
|
|
|
@@ -147,4 +147,4 @@
|
|
|
147
147
|
|
|
148
148
|
## npm 의존
|
|
149
149
|
|
|
150
|
-
`lucide-react
|
|
150
|
+
`lucide-react`, `radix-ui`
|
package/combobox/index.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
use,
|
|
8
8
|
useEffect,
|
|
9
9
|
useId,
|
|
10
|
+
useRef,
|
|
10
11
|
useState,
|
|
11
12
|
type ComponentProps,
|
|
12
13
|
type InputHTMLAttributes,
|
|
@@ -23,6 +24,7 @@ interface ComboboxContext {
|
|
|
23
24
|
active: string | undefined
|
|
24
25
|
search: string
|
|
25
26
|
setSearch: (search: string) => void
|
|
27
|
+
setNotify: (notify: ((search: string) => void) | undefined) => void
|
|
26
28
|
setOpen: (open: boolean) => void
|
|
27
29
|
pick: (value: string) => void
|
|
28
30
|
move: (step: number) => void
|
|
@@ -73,6 +75,7 @@ export function Combobox({
|
|
|
73
75
|
const [search, setSearch] = useState('')
|
|
74
76
|
const [count, setCount] = useState(0)
|
|
75
77
|
const [seen, setSeen] = useState(false)
|
|
78
|
+
const notifyRef = useRef<((search: string) => void) | undefined>(undefined)
|
|
76
79
|
|
|
77
80
|
const isOpen = open ?? ownOpen
|
|
78
81
|
const current = value ?? ownValue
|
|
@@ -87,10 +90,19 @@ export function Combobox({
|
|
|
87
90
|
onOpenChange?.(next)
|
|
88
91
|
}
|
|
89
92
|
|
|
93
|
+
const setNotify = (next: ((search: string) => void) | undefined) => {
|
|
94
|
+
notifyRef.current = next
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const changeSearch = (next: string) => {
|
|
98
|
+
setSearch(next)
|
|
99
|
+
notifyRef.current?.(next)
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
const pick = (next: string) => {
|
|
91
103
|
if (value === undefined) setOwnValue(next)
|
|
92
104
|
onValueChange?.(next)
|
|
93
|
-
|
|
105
|
+
changeSearch(next)
|
|
94
106
|
setOpen(false)
|
|
95
107
|
}
|
|
96
108
|
|
|
@@ -122,7 +134,8 @@ export function Combobox({
|
|
|
122
134
|
open: isOpen,
|
|
123
135
|
active,
|
|
124
136
|
search,
|
|
125
|
-
setSearch,
|
|
137
|
+
setSearch: changeSearch,
|
|
138
|
+
setNotify,
|
|
126
139
|
setOpen,
|
|
127
140
|
pick,
|
|
128
141
|
see,
|
|
@@ -143,15 +156,15 @@ export function Combobox({
|
|
|
143
156
|
export const comboboxAnchor = tv({
|
|
144
157
|
base: 'flex items-center gap-tight rounded-r8 px-3'
|
|
145
158
|
+ ' transition-state'
|
|
146
|
-
+ ' invalid-within:ring-2 invalid-within:ring-danger'
|
|
147
|
-
+ ' has-disabled:bg-disabled has-disabled:cursor-not-allowed'
|
|
159
|
+
+ ' invalid-within:ring-2 invalid-within:ring-line-danger'
|
|
160
|
+
+ ' has-disabled:bg-bg-neutral-disabled has-disabled:cursor-not-allowed'
|
|
148
161
|
+ ' has-focus-visible:outline-2 has-focus-visible:outline-offset-2'
|
|
149
|
-
+ ' has-focus-visible:outline-ring',
|
|
162
|
+
+ ' has-focus-visible:outline-line-focus-ring',
|
|
150
163
|
|
|
151
164
|
variants: {
|
|
152
165
|
surface: {
|
|
153
166
|
bare: 'ring-1 ring-inset ring-line-strong',
|
|
154
|
-
well: 'bg-well',
|
|
167
|
+
well: 'bg-background-well',
|
|
155
168
|
},
|
|
156
169
|
size: { sm: 'h-8', md: 'h-9', lg: 'h-10 [&_input]:text-t16' },
|
|
157
170
|
},
|
|
@@ -179,19 +192,24 @@ export interface ComboboxInputProps extends Omit<InputHTMLAttributes<HTMLInputEl
|
|
|
179
192
|
onValueChange?: (value: string) => void
|
|
180
193
|
}
|
|
181
194
|
|
|
195
|
+
const comboboxInput = tv({
|
|
196
|
+
base: 'text-value text-foreground placeholder:text-foreground-placeholder'
|
|
197
|
+
+ ' w-full min-w-0 bg-transparent outline-none'
|
|
198
|
+
+ ' disabled:text-foreground-disabled disabled:cursor-not-allowed',
|
|
199
|
+
})
|
|
200
|
+
|
|
182
201
|
export function ComboboxInput({ value, onValueChange, className, ...rest }: ComboboxInputProps) {
|
|
183
202
|
const ctx = useCombobox()
|
|
184
203
|
const text = value ?? ctx.search
|
|
185
|
-
const
|
|
204
|
+
const { setNotify } = ctx
|
|
186
205
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
setNotify(onValueChange)
|
|
208
|
+
return () => setNotify(undefined)
|
|
209
|
+
})
|
|
191
210
|
|
|
192
211
|
const change = (next: string) => {
|
|
193
212
|
ctx.setSearch(next)
|
|
194
|
-
onValueChange?.(next)
|
|
195
213
|
if (!ctx.open) ctx.setOpen(true)
|
|
196
214
|
}
|
|
197
215
|
|
|
@@ -226,13 +244,18 @@ export function ComboboxInput({ value, onValueChange, className, ...rest }: Comb
|
|
|
226
244
|
value={text}
|
|
227
245
|
onChange={e => change(e.target.value)}
|
|
228
246
|
onKeyDown={onKeyDown}
|
|
229
|
-
className={
|
|
230
|
-
+ ' w-full min-w-0 bg-transparent outline-none'
|
|
231
|
-
+ ' disabled:text-fg-disabled disabled:cursor-not-allowed' })({ className })}
|
|
247
|
+
className={comboboxInput({ className })}
|
|
232
248
|
/>
|
|
233
249
|
)
|
|
234
250
|
}
|
|
235
251
|
|
|
252
|
+
const comboboxTrigger = tv({
|
|
253
|
+
base: 'text-foreground-subtle grid size-5 shrink-0 place-items-center rounded-r8'
|
|
254
|
+
+ ' transition-state press-shrink hover:text-foreground'
|
|
255
|
+
+ ' focus-visible:outline-2 focus-visible:outline-offset-2'
|
|
256
|
+
+ ' focus-visible:outline-line-focus-ring',
|
|
257
|
+
})
|
|
258
|
+
|
|
236
259
|
export function ComboboxTrigger({ label = '목록 열기', disabled, className }: {
|
|
237
260
|
label?: string
|
|
238
261
|
disabled?: boolean
|
|
@@ -248,10 +271,7 @@ export function ComboboxTrigger({ label = '목록 열기', disabled, className }
|
|
|
248
271
|
disabled={disabled}
|
|
249
272
|
data-state={ctx.open ? 'open' : 'closed'}
|
|
250
273
|
onClick={() => ctx.setOpen(!ctx.open)}
|
|
251
|
-
className={
|
|
252
|
-
+ ' transition-state press-shrink hover:text-fg'
|
|
253
|
-
+ ' focus-visible:outline-2 focus-visible:outline-offset-2'
|
|
254
|
-
+ ' focus-visible:outline-ring' })({ className })}
|
|
274
|
+
className={comboboxTrigger({ className })}
|
|
255
275
|
>
|
|
256
276
|
<ChevronDown
|
|
257
277
|
className="size-4 transition-transform open:rotate-180 motion-reduce:transition-none"
|
|
@@ -260,6 +280,13 @@ export function ComboboxTrigger({ label = '목록 열기', disabled, className }
|
|
|
260
280
|
)
|
|
261
281
|
}
|
|
262
282
|
|
|
283
|
+
const comboboxCancel = tv({
|
|
284
|
+
base: 'text-foreground-subtle grid size-5 shrink-0 place-items-center rounded-full'
|
|
285
|
+
+ ' transition-state press-shrink hover:text-foreground'
|
|
286
|
+
+ ' focus-visible:outline-2 focus-visible:outline-offset-2'
|
|
287
|
+
+ ' focus-visible:outline-line-focus-ring',
|
|
288
|
+
})
|
|
289
|
+
|
|
263
290
|
export function ComboboxCancel({ label = '지우기', className }: { label?: string, className?: string }) {
|
|
264
291
|
const ctx = useCombobox()
|
|
265
292
|
|
|
@@ -269,10 +296,7 @@ export function ComboboxCancel({ label = '지우기', className }: { label?: str
|
|
|
269
296
|
tabIndex={-1}
|
|
270
297
|
aria-label={label}
|
|
271
298
|
onClick={() => ctx.setSearch('')}
|
|
272
|
-
className={
|
|
273
|
-
+ ' transition-state press-shrink hover:text-fg'
|
|
274
|
-
+ ' focus-visible:outline-2 focus-visible:outline-offset-2'
|
|
275
|
-
+ ' focus-visible:outline-ring' })({ className })}
|
|
299
|
+
className={comboboxCancel({ className })}
|
|
276
300
|
>
|
|
277
301
|
<X className="size-4" />
|
|
278
302
|
</button>
|
|
@@ -282,6 +306,12 @@ export function ComboboxCancel({ label = '지우기', className }: { label?: str
|
|
|
282
306
|
export type ComboboxContentProps =
|
|
283
307
|
Omit<ComponentProps<typeof PopoverPrimitive.Content>, 'align' | 'sideOffset' | 'onOpenAutoFocus'>
|
|
284
308
|
|
|
309
|
+
const comboboxContent = tv({
|
|
310
|
+
base: 'float text-foreground rounded-float z-overlay'
|
|
311
|
+
+ ' w-(--radix-popover-trigger-width)'
|
|
312
|
+
+ ' open:animate-enter closed:animate-exit',
|
|
313
|
+
})
|
|
314
|
+
|
|
285
315
|
export function ComboboxContent({ className, children, ...rest }: ComboboxContentProps) {
|
|
286
316
|
const label = rest['aria-label']
|
|
287
317
|
|
|
@@ -292,9 +322,7 @@ export function ComboboxContent({ className, children, ...rest }: ComboboxConten
|
|
|
292
322
|
align="start"
|
|
293
323
|
sideOffset={4}
|
|
294
324
|
onOpenAutoFocus={e => e.preventDefault()}
|
|
295
|
-
className={
|
|
296
|
-
+ ' w-(--radix-popover-trigger-width) p-1'
|
|
297
|
-
+ ' open:animate-enter closed:animate-exit' })({ className })}
|
|
325
|
+
className={comboboxContent({ className })}
|
|
298
326
|
>
|
|
299
327
|
<ComboboxViewport label={label} className="max-h-72">
|
|
300
328
|
{children}
|
|
@@ -304,6 +332,8 @@ export function ComboboxContent({ className, children, ...rest }: ComboboxConten
|
|
|
304
332
|
)
|
|
305
333
|
}
|
|
306
334
|
|
|
335
|
+
const comboboxViewport = tv({ base: 'flex flex-col gap-px overflow-y-auto p-1' })
|
|
336
|
+
|
|
307
337
|
export function ComboboxViewport({ label, className, children }: {
|
|
308
338
|
label?: string
|
|
309
339
|
className?: string
|
|
@@ -316,7 +346,7 @@ export function ComboboxViewport({ label, className, children }: {
|
|
|
316
346
|
id={`${ctx.id}-list`}
|
|
317
347
|
role={ctx.count > 0 ? 'listbox' : undefined}
|
|
318
348
|
aria-label={ctx.count > 0 ? label : undefined}
|
|
319
|
-
className={
|
|
349
|
+
className={comboboxViewport({ className })}
|
|
320
350
|
>
|
|
321
351
|
{children}
|
|
322
352
|
</div>
|
|
@@ -331,6 +361,13 @@ export interface ComboboxItemProps {
|
|
|
331
361
|
children?: ReactNode
|
|
332
362
|
}
|
|
333
363
|
|
|
364
|
+
const comboboxItem = tv({
|
|
365
|
+
base: 'flex min-h-9 cursor-default items-center justify-between gap-stack'
|
|
366
|
+
+ ' shrink-0 rounded-r8 px-2 py-1 transition-state'
|
|
367
|
+
+ ' data-highlighted:bg-bg-neutral-hover data-highlighted:outline-none'
|
|
368
|
+
+ ' data-disabled:text-foreground-disabled data-disabled:pointer-events-none',
|
|
369
|
+
})
|
|
370
|
+
|
|
334
371
|
export function ComboboxItem({ value, textValue, disabled = false, className, children }: ComboboxItemProps) {
|
|
335
372
|
const ctx = useCombobox()
|
|
336
373
|
const shown = ctx.ignoreFilter || contains(textValue ?? value, ctx.search)
|
|
@@ -349,17 +386,14 @@ export function ComboboxItem({ value, textValue, disabled = false, className, ch
|
|
|
349
386
|
data-disabled={disabled ? '' : undefined}
|
|
350
387
|
onPointerMove={() => !disabled && ctx.setActive(value)}
|
|
351
388
|
onClick={() => !disabled && ctx.pick(value)}
|
|
352
|
-
className={
|
|
353
|
-
+ ' shrink-0 rounded-r8 px-2 py-1 transition-state'
|
|
354
|
-
+ ' data-highlighted:bg-hover data-highlighted:outline-none'
|
|
355
|
-
+ ' data-disabled:text-fg-disabled data-disabled:pointer-events-none' })({ className })}
|
|
389
|
+
className={comboboxItem({ className })}
|
|
356
390
|
>
|
|
357
391
|
<span className="flex min-w-0 flex-col gap-0.5">
|
|
358
392
|
{children}
|
|
359
393
|
</span>
|
|
360
394
|
|
|
361
395
|
{ctx.value === value && (
|
|
362
|
-
<span className="text-
|
|
396
|
+
<span className="text-foreground-muted flex shrink-0">
|
|
363
397
|
<Check className="size-4" />
|
|
364
398
|
</span>
|
|
365
399
|
)}
|
|
@@ -367,31 +401,37 @@ export function ComboboxItem({ value, textValue, disabled = false, className, ch
|
|
|
367
401
|
)
|
|
368
402
|
}
|
|
369
403
|
|
|
404
|
+
const comboboxItemText = tv({ base: 'text-label text-foreground' })
|
|
405
|
+
|
|
370
406
|
export function ComboboxItemText({ className, children }: { className?: string, children?: ReactNode }) {
|
|
371
407
|
return (
|
|
372
|
-
<span className={
|
|
408
|
+
<span className={comboboxItemText({ className })}>
|
|
373
409
|
{children}
|
|
374
410
|
</span>
|
|
375
411
|
)
|
|
376
412
|
}
|
|
377
413
|
|
|
414
|
+
const comboboxItemDescription = tv({ base: 'text-caption text-foreground-subtle' })
|
|
415
|
+
|
|
378
416
|
export function ComboboxItemDescription({ className, children }: { className?: string, children?: ReactNode }) {
|
|
379
417
|
return (
|
|
380
|
-
<span className={
|
|
418
|
+
<span className={comboboxItemDescription({ className })}>
|
|
381
419
|
{children}
|
|
382
420
|
</span>
|
|
383
421
|
)
|
|
384
422
|
}
|
|
385
423
|
|
|
424
|
+
const comboboxGroup = tv({ base: 'flex flex-col gap-px' })
|
|
425
|
+
|
|
386
426
|
export function ComboboxGroup({ label, className, children }: {
|
|
387
427
|
label?: string
|
|
388
428
|
className?: string
|
|
389
429
|
children?: ReactNode
|
|
390
430
|
}) {
|
|
391
431
|
return (
|
|
392
|
-
<div role="group" className={
|
|
432
|
+
<div role="group" className={comboboxGroup({ className })}>
|
|
393
433
|
{label && (
|
|
394
|
-
<span className="text-caption text-
|
|
434
|
+
<span className="text-caption text-foreground-subtle px-2 pb-1 pt-2">
|
|
395
435
|
{label}
|
|
396
436
|
</span>
|
|
397
437
|
)}
|
|
@@ -400,19 +440,23 @@ export function ComboboxGroup({ label, className, children }: {
|
|
|
400
440
|
)
|
|
401
441
|
}
|
|
402
442
|
|
|
443
|
+
const comboboxEmpty = tv({ base: 'text-caption text-foreground-subtle px-2 py-3 text-center' })
|
|
444
|
+
|
|
403
445
|
export function ComboboxEmpty({ className, children }: { className?: string, children?: ReactNode }) {
|
|
404
446
|
const ctx = useCombobox()
|
|
405
447
|
if (ctx.count > 0) return null
|
|
406
448
|
|
|
407
449
|
return (
|
|
408
|
-
<div role="presentation" className={
|
|
450
|
+
<div role="presentation" className={comboboxEmpty({ className })}>
|
|
409
451
|
{children}
|
|
410
452
|
</div>
|
|
411
453
|
)
|
|
412
454
|
}
|
|
413
455
|
|
|
456
|
+
const comboboxSeparator = tv({ base: 'bg-line -mx-1 my-1 h-px' })
|
|
457
|
+
|
|
414
458
|
export function ComboboxSeparator({ className }: { className?: string }) {
|
|
415
|
-
return <div className={
|
|
459
|
+
return <div className={comboboxSeparator({ className })} />
|
|
416
460
|
}
|
|
417
461
|
|
|
418
462
|
export function contains(text: string, search: string) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
```
|
|
4
4
|
받기 npx @pantoia/ui add command-palette
|
|
5
5
|
층 derived
|
|
6
|
-
파일 command-palette/index.tsx
|
|
6
|
+
파일 command-palette/index.tsx, command-palette/AGENTS.md
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
## 부위
|
|
@@ -34,10 +34,11 @@
|
|
|
34
34
|
| `placeholder` | `string` | 예 |
|
|
35
35
|
| `emptyText` | `string` | 예 |
|
|
36
36
|
| `onSelect` | `(value: string) => void` | |
|
|
37
|
+
| `className` | `string` | |
|
|
37
38
|
|
|
38
39
|
## 함께 받는 것
|
|
39
40
|
|
|
40
|
-
`combobox
|
|
41
|
+
`combobox`, `dialog`, `kbd`
|
|
41
42
|
|
|
42
43
|
## npm 의존
|
|
43
44
|
|
|
@@ -31,6 +31,7 @@ export interface CommandPaletteProps {
|
|
|
31
31
|
placeholder: string
|
|
32
32
|
emptyText: string
|
|
33
33
|
onSelect?: (value: string) => void
|
|
34
|
+
className?: string
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export function CommandPalette({
|
|
@@ -42,6 +43,7 @@ export function CommandPalette({
|
|
|
42
43
|
placeholder,
|
|
43
44
|
emptyText,
|
|
44
45
|
onSelect,
|
|
46
|
+
className,
|
|
45
47
|
}: CommandPaletteProps) {
|
|
46
48
|
const [own, setOwn] = useState(defaultOpen)
|
|
47
49
|
const [search, setSearch] = useState('')
|
|
@@ -68,7 +70,7 @@ export function CommandPalette({
|
|
|
68
70
|
|
|
69
71
|
return (
|
|
70
72
|
<Dialog open={isOpen} onOpenChange={setOpen}>
|
|
71
|
-
<DialogContent size="top">
|
|
73
|
+
<DialogContent size="top" className={className}>
|
|
72
74
|
<DialogTitle className="sr-only">{title}</DialogTitle>
|
|
73
75
|
<DialogDescription className="sr-only">
|
|
74
76
|
{placeholder}
|
|
@@ -76,7 +78,7 @@ export function CommandPalette({
|
|
|
76
78
|
|
|
77
79
|
<Combobox open onValueChange={pick}>
|
|
78
80
|
<div className="border-line flex h-14 items-center gap-stack border-b px-4">
|
|
79
|
-
<Search className="text-
|
|
81
|
+
<Search className="text-foreground-subtle size-5 shrink-0" />
|
|
80
82
|
<ComboboxInput
|
|
81
83
|
value={search}
|
|
82
84
|
onValueChange={setSearch}
|
package/dialog/AGENTS.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
```
|
|
4
4
|
받기 npx @pantoia/ui add dialog
|
|
5
5
|
층 ui
|
|
6
|
-
파일 dialog/index.tsx
|
|
6
|
+
파일 dialog/index.tsx, dialog/AGENTS.md
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
## 부위
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
| 이름 | props |
|
|
12
12
|
|---|---|
|
|
13
13
|
| `Dialog` | `DialogProps` |
|
|
14
|
-
| `DialogTrigger` |
|
|
15
|
-
| `DialogClose` |
|
|
14
|
+
| `DialogTrigger` | - |
|
|
15
|
+
| `DialogClose` | - |
|
|
16
16
|
| `DialogContent` | `DialogContentProps` |
|
|
17
17
|
| `DialogTitle` | `ComponentProps<typeof DialogPrimitive.Title>` |
|
|
18
18
|
| `DialogDescription` | `ComponentProps<typeof DialogPrimitive.Description>` |
|
|
19
19
|
| `DialogHeader` | `DialogHeaderProps` |
|
|
20
|
-
| `DialogFooter` |
|
|
20
|
+
| `DialogFooter` | - |
|
|
21
21
|
|
|
22
22
|
### `DialogTrigger`
|
|
23
23
|
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
| `className` | `string` | |
|
|
67
67
|
| `children` | `ReactNode` | |
|
|
68
68
|
|
|
69
|
-
## 변형
|
|
69
|
+
## 변형 - `dialog`
|
|
70
70
|
|
|
71
71
|
| 축 | 값 | 기본 |
|
|
72
72
|
|---|---|---|
|
|
73
|
-
| `size` | `md
|
|
73
|
+
| `size` | `md`, `full`, `top` | `md` |
|
|
74
74
|
|
|
75
75
|
## 함께 받는 것
|
|
76
76
|
|
package/dialog/index.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import type { ComponentProps, ReactNode } from 'react'
|
|
|
6
6
|
import { tv } from '../tv'
|
|
7
7
|
|
|
8
8
|
export const dialog = tv({
|
|
9
|
-
base: '
|
|
9
|
+
base: 'sheet text-foreground z-overlay fixed flex flex-col gap-stack overflow-y-auto'
|
|
10
10
|
+ ' open:animate-fade-in closed:animate-fade-out focus-visible:outline-none',
|
|
11
11
|
|
|
12
12
|
variants: {
|
|
@@ -52,7 +52,7 @@ export interface DialogContentProps extends ComponentProps<typeof DialogPrimitiv
|
|
|
52
52
|
export function DialogContent({ size, className, children, ...rest }: DialogContentProps) {
|
|
53
53
|
return (
|
|
54
54
|
<DialogPrimitive.Portal>
|
|
55
|
-
<DialogPrimitive.Overlay className="bg-overlay z-overlay fixed inset-0 open:animate-fade-in closed:animate-fade-out" />
|
|
55
|
+
<DialogPrimitive.Overlay className="bg-background-overlay z-overlay fixed inset-0 open:animate-fade-in closed:animate-fade-out" />
|
|
56
56
|
|
|
57
57
|
<DialogPrimitive.Content {...rest} className={dialog({ size, className })}>
|
|
58
58
|
{children}
|
|
@@ -61,13 +61,17 @@ export function DialogContent({ size, className, children, ...rest }: DialogCont
|
|
|
61
61
|
)
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
const dialogTitle = tv({ base: 'text-section min-w-0' })
|
|
65
|
+
|
|
64
66
|
export function DialogTitle({ className, ...rest }: ComponentProps<typeof DialogPrimitive.Title>) {
|
|
65
|
-
return <DialogPrimitive.Title {...rest} className={
|
|
67
|
+
return <DialogPrimitive.Title {...rest} className={dialogTitle({ className })} />
|
|
66
68
|
}
|
|
67
69
|
|
|
70
|
+
const dialogDescription = tv({ base: 'text-prose text-foreground-muted' })
|
|
71
|
+
|
|
68
72
|
export function DialogDescription({ className, ...rest }: ComponentProps<typeof DialogPrimitive.Description>) {
|
|
69
73
|
return (
|
|
70
|
-
<DialogPrimitive.Description {...rest} className={
|
|
74
|
+
<DialogPrimitive.Description {...rest} className={dialogDescription({ className })} />
|
|
71
75
|
)
|
|
72
76
|
}
|
|
73
77
|
|
|
@@ -99,9 +103,11 @@ export function DialogHeader({ lead, trail, className, children }: DialogHeaderP
|
|
|
99
103
|
)
|
|
100
104
|
}
|
|
101
105
|
|
|
106
|
+
const dialogFooter = tv({ base: 'flex justify-end gap-2' })
|
|
107
|
+
|
|
102
108
|
export function DialogFooter({ className, children }: { className?: string, children?: ReactNode }) {
|
|
103
109
|
return (
|
|
104
|
-
<div className={
|
|
110
|
+
<div className={dialogFooter({ className })}>
|
|
105
111
|
{children}
|
|
106
112
|
</div>
|
|
107
113
|
)
|