@pantoia/ui 0.1.0 → 0.3.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.
Files changed (68) hide show
  1. package/accordion/AGENTS.md +5 -5
  2. package/accordion/index.tsx +21 -11
  3. package/alert-dialog/AGENTS.md +7 -7
  4. package/alert-dialog/index.tsx +20 -10
  5. package/badge/AGENTS.md +5 -5
  6. package/badge/index.tsx +8 -8
  7. package/button/AGENTS.md +7 -7
  8. package/button/index.tsx +34 -34
  9. package/callout/AGENTS.md +4 -9
  10. package/callout/index.tsx +42 -22
  11. package/checkbox/AGENTS.md +5 -5
  12. package/checkbox/index.tsx +19 -16
  13. package/combobox/AGENTS.md +13 -13
  14. package/combobox/index.tsx +90 -42
  15. package/command-palette/AGENTS.md +3 -6
  16. package/command-palette/index.tsx +7 -3
  17. package/dialog/AGENTS.md +6 -6
  18. package/dialog/index.tsx +11 -5
  19. package/dist/index.js +200 -43
  20. package/drawer/AGENTS.md +5 -5
  21. package/drawer/index.tsx +8 -4
  22. package/dropdown-menu/AGENTS.md +12 -12
  23. package/dropdown-menu/index.tsx +27 -12
  24. package/field/AGENTS.md +8 -12
  25. package/field/index.tsx +39 -13
  26. package/input/AGENTS.md +4 -4
  27. package/input/index.tsx +5 -5
  28. package/kbd/AGENTS.md +1 -1
  29. package/kbd/index.tsx +6 -2
  30. package/label/AGENTS.md +1 -1
  31. package/label/index.tsx +3 -1
  32. package/number-field/AGENTS.md +6 -10
  33. package/number-field/index.tsx +26 -16
  34. package/package.json +13 -15
  35. package/palette.css +114 -0
  36. package/popover/AGENTS.md +4 -4
  37. package/popover/index.tsx +14 -4
  38. package/radio-group/AGENTS.md +8 -8
  39. package/radio-group/index.tsx +20 -16
  40. package/registry.json +9 -71
  41. package/select/AGENTS.md +10 -10
  42. package/select/index.tsx +46 -21
  43. package/switch/AGENTS.md +4 -4
  44. package/switch/index.tsx +13 -13
  45. package/table/AGENTS.md +9 -9
  46. package/table/index.tsx +16 -6
  47. package/tabs/AGENTS.md +5 -4
  48. package/tabs/index.module.css +2 -0
  49. package/tabs/index.tsx +22 -11
  50. package/tailwind.css +3 -0
  51. package/textarea/AGENTS.md +4 -4
  52. package/textarea/index.tsx +5 -5
  53. package/toast/AGENTS.md +5 -13
  54. package/toast/index.tsx +27 -33
  55. package/toggle/AGENTS.md +4 -4
  56. package/toggle/index.tsx +8 -7
  57. package/tokens.css +272 -0
  58. package/tooltip/AGENTS.md +2 -2
  59. package/tooltip/index.tsx +14 -4
  60. package/tv.ts +0 -1
  61. package/utilities.css +119 -0
  62. package/code-block/AGENTS.md +0 -60
  63. package/code-block/index.module.css +0 -46
  64. package/code-block/index.tsx +0 -127
  65. package/copy-button/AGENTS.md +0 -43
  66. package/copy-button/index.tsx +0 -119
  67. package/press.css +0 -37
  68. package/styles.css +0 -347
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  받기 npx @pantoia/ui add accordion
5
5
  층 ui
6
- 파일 accordion/index.tsx · accordion/index.module.css · accordion/AGENTS.md
6
+ 파일 accordion/index.tsx, accordion/index.module.css, accordion/AGENTS.md
7
7
  ```
8
8
 
9
9
  ## 부위
@@ -11,9 +11,9 @@
11
11
  | 이름 | props |
12
12
  |---|---|
13
13
  | `Accordion` | `AccordionProps` |
14
- | `AccordionItem` | — |
15
- | `AccordionTrigger` | — |
16
- | `AccordionContent` | — |
14
+ | `AccordionItem` | - |
15
+ | `AccordionTrigger` | - |
16
+ | `AccordionContent` | - |
17
17
 
18
18
  ### `AccordionItem`
19
19
 
@@ -57,4 +57,4 @@
57
57
 
58
58
  ## npm 의존
59
59
 
60
- `lucide-react` · `radix-ui`
60
+ `radix-ui`
@@ -1,6 +1,5 @@
1
1
  'use client'
2
2
 
3
- import { ChevronDown } from 'lucide-react'
4
3
  import { Accordion as AccordionPrimitive } from 'radix-ui'
5
4
  import type { ReactNode } from 'react'
6
5
 
@@ -17,9 +16,11 @@ export interface AccordionProps {
17
16
  children?: ReactNode
18
17
  }
19
18
 
19
+ const accordion = tv({ base: 'frame rounded-r12 overflow-hidden divide-y divide-line' })
20
+
20
21
  export function Accordion({ value, defaultValue, onValueChange, multiple, className, children }: AccordionProps) {
21
22
  const shared = {
22
- className: tv({ base: 'rounded-panel border border-line overflow-hidden divide-y divide-line' })({ className }),
23
+ className: accordion({ className }),
23
24
  children,
24
25
  }
25
26
 
@@ -58,32 +59,41 @@ export function AccordionItem({ value, disabled, className, children }: {
58
59
  )
59
60
  }
60
61
 
62
+ const accordionTrigger = tv({
63
+ base: 'text-label text-fg flex h-11 w-full items-center'
64
+ + ' gap-stack border-b border-transparent px-4 transition-state'
65
+ + ' press open:border-line enabled:hover:bg-bg-neutral-hover'
66
+ + ' disabled:text-fg-disabled disabled:cursor-not-allowed'
67
+ + ' focus-visible:outline-2 focus-visible:-outline-offset-2'
68
+ + ' focus-visible:outline-line-focus-ring',
69
+ })
70
+
61
71
  export function AccordionTrigger({ className, children }: { className?: string, children?: ReactNode }) {
62
72
  return (
63
73
  <AccordionPrimitive.Header>
64
74
  <AccordionPrimitive.Trigger
65
- className={tv({ base: 'text-label text-fg flex h-11 w-full items-center'
66
- + ' gap-stack border-b border-transparent px-4 transition-state'
67
- + ' press open:border-line enabled:hover:bg-hover'
68
- + ' disabled:text-fg-disabled disabled:cursor-not-allowed'
69
- + ' focus-visible:outline-2 focus-visible:-outline-offset-2'
70
- + ' focus-visible:outline-ring' })({ className })}
75
+ className={accordionTrigger({ className })}
71
76
  >
72
77
  <span className="flex min-w-0 grow items-center gap-tight">{children}</span>
73
78
 
74
- <ChevronDown
79
+ <svg
80
+ viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"
75
81
  className="text-fg-subtle size-4 shrink-0 transition-transform open:rotate-180
76
82
  motion-reduce:transition-none"
77
- />
83
+ >
84
+ <path d="m6 9 6 6 6-6" />
85
+ </svg>
78
86
  </AccordionPrimitive.Trigger>
79
87
  </AccordionPrimitive.Header>
80
88
  )
81
89
  }
82
90
 
91
+ const accordionContent = tv({ base: 'bg-bg-well text-caption text-fg-muted px-4 py-3' })
92
+
83
93
  export function AccordionContent({ className, children }: { className?: string, children?: ReactNode }) {
84
94
  return (
85
95
  <AccordionPrimitive.Content className={s.panel}>
86
- <div className={tv({ base: 'bg-well text-caption text-fg-muted px-4 py-3' })({ className })}>
96
+ <div className={accordionContent({ className })}>
87
97
  {children}
88
98
  </div>
89
99
  </AccordionPrimitive.Content>
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  받기 npx @pantoia/ui add alert-dialog
5
5
  층 ui
6
- 파일 alert-dialog/index.tsx · alert-dialog/AGENTS.md
6
+ 파일 alert-dialog/index.tsx, alert-dialog/AGENTS.md
7
7
  ```
8
8
 
9
9
  ## 부위
@@ -11,14 +11,14 @@
11
11
  | 이름 | props |
12
12
  |---|---|
13
13
  | `AlertDialog` | `AlertDialogProps` |
14
- | `AlertDialogTrigger` | — |
14
+ | `AlertDialogTrigger` | - |
15
15
  | `AlertDialogContent` | `ComponentProps<typeof AlertDialogPrimitive.Content>` |
16
16
  | `AlertDialogTitle` | `ComponentProps<typeof AlertDialogPrimitive.Title>` |
17
17
  | `AlertDialogDescription` | `ComponentProps<typeof AlertDialogPrimitive.Description>` |
18
18
  | `AlertDialogHeader` | `AlertDialogHeaderProps` |
19
- | `AlertDialogFooter` | — |
20
- | `AlertDialogAction` | — |
21
- | `AlertDialogCancel` | — |
19
+ | `AlertDialogFooter` | - |
20
+ | `AlertDialogAction` | - |
21
+ | `AlertDialogCancel` | - |
22
22
 
23
23
  ### `AlertDialogTrigger`
24
24
 
@@ -37,7 +37,7 @@
37
37
 
38
38
  | 이름 | 타입 | 필수 |
39
39
  |---|---|---|
40
- | `color` | `'neutral' \| 'primary' \| 'danger'` | |
40
+ | `color` | `'neutral' \| 'brand' \| 'danger'` | |
41
41
  | `onClick` | `() => void` | |
42
42
  | `className` | `string` | |
43
43
  | `children` | `ReactNode` | |
@@ -71,7 +71,7 @@
71
71
 
72
72
  ## 함께 받는 것
73
73
 
74
- `button` · `tv`
74
+ `button`, `tv`
75
75
 
76
76
  ## npm 의존
77
77
 
@@ -25,18 +25,22 @@ export function AlertDialogTrigger({ children }: { children: ReactNode }) {
25
25
  return <AlertDialogPrimitive.Trigger asChild>{children}</AlertDialogPrimitive.Trigger>
26
26
  }
27
27
 
28
+ const alertDialogContent = tv({
29
+ base: 'sheet text-fg z-overlay fixed left-1/2 top-1/2'
30
+ + ' w-full max-w-112 -translate-x-1/2 -translate-y-1/2'
31
+ + ' rounded-r20 p-6 flex flex-col gap-stack overflow-y-auto'
32
+ + ' open:animate-fade-in closed:animate-fade-out'
33
+ + ' focus-visible:outline-none',
34
+ })
35
+
28
36
  export function AlertDialogContent({ className, children, ...rest }: ComponentProps<typeof AlertDialogPrimitive.Content>) {
29
37
  return (
30
38
  <AlertDialogPrimitive.Portal>
31
- <AlertDialogPrimitive.Overlay className="bg-overlay z-overlay fixed inset-0 open:animate-fade-in closed:animate-fade-out" />
39
+ <AlertDialogPrimitive.Overlay className="bg-bg-overlay z-overlay fixed inset-0 open:animate-fade-in closed:animate-fade-out" />
32
40
 
33
41
  <AlertDialogPrimitive.Content
34
42
  {...rest}
35
- className={tv({ base: 'bg-float text-fg z-overlay fixed left-1/2 top-1/2'
36
- + ' w-full max-w-112 -translate-x-1/2 -translate-y-1/2'
37
- + ' rounded-r20 p-6 flex flex-col gap-stack overflow-y-auto'
38
- + ' open:animate-fade-in closed:animate-fade-out'
39
- + ' focus-visible:outline-none' })({ className })}
43
+ className={alertDialogContent({ className })}
40
44
  >
41
45
  {children}
42
46
  </AlertDialogPrimitive.Content>
@@ -44,15 +48,19 @@ export function AlertDialogContent({ className, children, ...rest }: ComponentPr
44
48
  )
45
49
  }
46
50
 
51
+ const alertDialogTitle = tv({ base: 'text-section' })
52
+
47
53
  export function AlertDialogTitle({ className, ...rest }: ComponentProps<typeof AlertDialogPrimitive.Title>) {
48
- return <AlertDialogPrimitive.Title {...rest} className={tv({ base: 'text-section' })({ className })} />
54
+ return <AlertDialogPrimitive.Title {...rest} className={alertDialogTitle({ className })} />
49
55
  }
50
56
 
57
+ const alertDialogDescription = tv({ base: 'text-prose text-fg-muted' })
58
+
51
59
  export function AlertDialogDescription({ className, ...rest }: ComponentProps<typeof AlertDialogPrimitive.Description>) {
52
60
  return (
53
61
  <AlertDialogPrimitive.Description
54
62
  {...rest}
55
- className={tv({ base: 'text-prose text-fg-muted' })({ className })}
63
+ className={alertDialogDescription({ className })}
56
64
  />
57
65
  )
58
66
  }
@@ -85,16 +93,18 @@ export function AlertDialogHeader({ lead, trail, className, children }: AlertDia
85
93
  )
86
94
  }
87
95
 
96
+ const alertDialogFooter = tv({ base: 'flex justify-end gap-2' })
97
+
88
98
  export function AlertDialogFooter({ className, children }: { className?: string, children?: ReactNode }) {
89
99
  return (
90
- <div className={tv({ base: 'flex justify-end gap-2' })({ className })}>
100
+ <div className={alertDialogFooter({ className })}>
91
101
  {children}
92
102
  </div>
93
103
  )
94
104
  }
95
105
 
96
106
  export function AlertDialogAction({ color = 'neutral', onClick, className, children }: {
97
- color?: 'neutral' | 'primary' | 'danger'
107
+ color?: 'neutral' | 'brand' | 'danger'
98
108
  onClick?: () => void
99
109
  className?: string
100
110
  children?: ReactNode
package/badge/AGENTS.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  받기 npx @pantoia/ui add badge
5
5
  층 ui
6
- 파일 badge/index.tsx · badge/AGENTS.md
6
+ 파일 badge/index.tsx, badge/AGENTS.md
7
7
  ```
8
8
 
9
9
  ## 부위
@@ -20,15 +20,15 @@
20
20
 
21
21
  | 이름 | 타입 | 필수 |
22
22
  |---|---|---|
23
- | `color` | `'neutral' \| 'primary' \| 'info' \| 'success' \| 'warning' \| 'danger'` | |
23
+ | `color` | `'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'danger'` | |
24
24
  | `shape` | `'square' \| 'pill'` | |
25
25
 
26
- ## 변형 — `badge`
26
+ ## 변형 - `badge`
27
27
 
28
28
  | 축 | 값 | 기본 |
29
29
  |---|---|---|
30
- | `color` | `neutral` · `primary` · `info` · `success` · `warning` · `danger` | `neutral` |
31
- | `shape` | `square` · `pill` | `square` |
30
+ | `color` | `neutral`, `brand`, `info`, `success`, `warning`, `danger` | `neutral` |
31
+ | `shape` | `square`, `pill` | `square` |
32
32
 
33
33
  ## 함께 받는 것
34
34
 
package/badge/index.tsx CHANGED
@@ -8,15 +8,15 @@ export const badge = tv({
8
8
 
9
9
  variants: {
10
10
  color: {
11
- neutral: 'bg-well text-fg-muted',
12
- primary: 'bg-primary-weak text-primary-on-weak',
13
- info: 'bg-info-weak text-info-on-weak',
14
- success: 'bg-success-weak text-success-on-weak',
15
- warning: 'bg-warning-weak text-warning-on-weak',
16
- danger: 'bg-danger-weak text-danger-on-weak',
11
+ neutral: 'bg-bg-well text-fg-muted',
12
+ brand: 'bg-bg-brand-weak text-fg-brand-contrast',
13
+ info: 'bg-bg-info-weak text-fg-info-contrast',
14
+ success: 'bg-bg-success-weak text-fg-success-contrast',
15
+ warning: 'bg-bg-warning-weak text-fg-warning-contrast',
16
+ danger: 'bg-bg-danger-weak text-fg-danger-contrast',
17
17
  },
18
18
  shape: {
19
- square: 'rounded-mark',
19
+ square: 'rounded-r4',
20
20
  pill: 'rounded-full',
21
21
  },
22
22
  },
@@ -25,7 +25,7 @@ export const badge = tv({
25
25
  })
26
26
 
27
27
  export interface BadgeProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'color'> {
28
- color?: 'neutral' | 'primary' | 'info' | 'success' | 'warning' | 'danger'
28
+ color?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'danger'
29
29
  shape?: 'square' | 'pill'
30
30
  }
31
31
 
package/button/AGENTS.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  받기 npx @pantoia/ui add button
5
5
  층 ui
6
- 파일 button/index.tsx · button/AGENTS.md
6
+ 파일 button/index.tsx, button/AGENTS.md
7
7
  ```
8
8
 
9
9
  ## 부위
@@ -20,19 +20,19 @@
20
20
 
21
21
  | 이름 | 타입 | 필수 |
22
22
  |---|---|---|
23
- | `color` | `'primary' \| 'neutral' \| 'danger'` | 예 |
23
+ | `color` | `'brand' \| 'neutral' \| 'danger'` | 예 |
24
24
  | `emphasis` | `'solid' \| 'weak' \| 'outline' \| 'ghost'` | 예 |
25
25
  | `size` | `'sm' \| 'md' \| 'lg'` | |
26
26
  | `shape` | `'rect' \| 'square' \| 'pill' \| 'circle'` | |
27
27
 
28
- ## 변형 — `button`
28
+ ## 변형 - `button`
29
29
 
30
30
  | 축 | 값 | 기본 |
31
31
  |---|---|---|
32
- | `color` | `primary` · `neutral` · `danger` | — |
33
- | `emphasis` | `solid` · `weak` · `outline` · `ghost` | — |
34
- | `size` | `sm` · `md` · `lg` | `md` |
35
- | `shape` | `rect` · `square` · `pill` · `circle` | `rect` |
32
+ | `color` | `brand`, `neutral`, `danger` | - |
33
+ | `emphasis` | `solid`, `weak`, `outline`, `ghost` | - |
34
+ | `size` | `sm`, `md`, `lg` | `md` |
35
+ | `shape` | `rect`, `square`, `pill`, `circle` | `rect` |
36
36
 
37
37
  ## 함께 받는 것
38
38
 
package/button/index.tsx CHANGED
@@ -6,11 +6,11 @@ export const button = tv({
6
6
  base: 'inline-flex shrink-0 items-center justify-center gap-tight whitespace-nowrap'
7
7
  + ' rounded-r8 text-label'
8
8
  + ' transition-state press press-shrink'
9
- + ' focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring'
9
+ + ' focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-line-focus-ring'
10
10
  + ' disabled:text-fg-disabled disabled:cursor-not-allowed',
11
11
 
12
12
  variants: {
13
- color: { primary: '', neutral: '', danger: '' },
13
+ color: { brand: '', neutral: '', danger: '' },
14
14
  emphasis: { solid: '', weak: '', outline: '', ghost: '' },
15
15
  size: {
16
16
  sm: 'h-8 [&_svg]:size-4',
@@ -26,48 +26,48 @@ export const button = tv({
26
26
  },
27
27
 
28
28
  compoundVariants: [
29
- { color: 'primary', emphasis: 'solid',
30
- class: 'bg-primary-solid text-fg-on-solid'
31
- + ' enabled:hover:bg-primary-solid-hover'
32
- + ' disabled:bg-primary-solid/20' },
33
- { color: 'primary', emphasis: 'weak',
34
- class: 'bg-primary-weak text-primary-on-weak disabled:text-primary-on-weak/40'
35
- + ' enabled:hover:bg-primary-solid/10' },
36
- { color: 'primary', emphasis: 'outline',
37
- class: 'text-primary-on-weak disabled:text-primary-on-weak/40'
38
- + ' ring-1 ring-inset ring-primary-stroke disabled:ring-line'
39
- + ' enabled:hover:bg-primary-solid/10' },
40
- { color: 'primary', emphasis: 'ghost',
41
- class: 'text-primary-on-weak disabled:text-primary-on-weak/40'
42
- + ' enabled:hover:bg-primary-solid/10' },
29
+ { color: 'brand', emphasis: 'solid',
30
+ class: 'bg-bg-brand-solid text-fg-brand-solid-contrast'
31
+ + ' enabled:hover:bg-bg-brand-solid-hover'
32
+ + ' disabled:bg-bg-brand-solid/20' },
33
+ { color: 'brand', emphasis: 'weak',
34
+ class: 'bg-bg-brand-weak text-fg-brand-contrast disabled:text-fg-brand-contrast/40'
35
+ + ' enabled:hover:bg-bg-brand-solid/10' },
36
+ { color: 'brand', emphasis: 'outline',
37
+ class: 'text-fg-brand-contrast disabled:text-fg-brand-contrast/40'
38
+ + ' ring-1 ring-inset ring-line-brand-weak disabled:ring-line'
39
+ + ' enabled:hover:bg-bg-brand-solid/10' },
40
+ { color: 'brand', emphasis: 'ghost',
41
+ class: 'text-fg-brand-contrast disabled:text-fg-brand-contrast/40'
42
+ + ' enabled:hover:bg-bg-brand-solid/10' },
43
43
 
44
44
  { color: 'neutral', emphasis: 'solid',
45
- class: 'bg-neutral-solid text-fg-on-control'
46
- + ' enabled:hover:bg-neutral-solid-hover'
47
- + ' disabled:bg-neutral-solid/20' },
45
+ class: 'bg-bg-neutral-solid text-fg-neutral-solid-contrast'
46
+ + ' enabled:hover:bg-bg-neutral-solid-hover'
47
+ + ' disabled:bg-bg-neutral-solid/20' },
48
48
  { color: 'neutral', emphasis: 'weak',
49
- class: 'bg-well text-fg'
50
- + ' enabled:hover:bg-fg-muted/10' },
49
+ class: 'bg-bg-well text-fg'
50
+ + ' enabled:hover:bg-bg-neutral-solid/10' },
51
51
  { color: 'neutral', emphasis: 'outline',
52
52
  class: 'text-fg ring-1 ring-inset ring-line-strong disabled:ring-line'
53
- + ' enabled:hover:bg-hover' },
53
+ + ' enabled:hover:bg-bg-neutral-hover' },
54
54
  { color: 'neutral', emphasis: 'ghost',
55
- class: 'text-fg enabled:hover:bg-hover' },
55
+ class: 'text-fg enabled:hover:bg-bg-neutral-hover' },
56
56
 
57
57
  { color: 'danger', emphasis: 'solid',
58
- class: 'bg-danger-solid text-fg-on-solid'
59
- + ' enabled:hover:bg-danger-solid-hover'
60
- + ' disabled:bg-danger-solid/20' },
58
+ class: 'bg-bg-danger-solid text-white'
59
+ + ' enabled:hover:bg-bg-danger-solid-hover'
60
+ + ' disabled:bg-bg-danger-solid/20' },
61
61
  { color: 'danger', emphasis: 'weak',
62
- class: 'bg-danger-weak text-danger-on-weak disabled:text-danger-on-weak/40'
63
- + ' enabled:hover:bg-danger/10' },
62
+ class: 'bg-bg-danger-weak text-fg-danger-contrast disabled:text-fg-danger-contrast/40'
63
+ + ' enabled:hover:bg-bg-danger-solid/10' },
64
64
  { color: 'danger', emphasis: 'outline',
65
- class: 'text-danger-on-weak disabled:text-danger-on-weak/40'
66
- + ' ring-1 ring-inset ring-danger-stroke disabled:ring-line'
67
- + ' enabled:hover:bg-danger/10' },
65
+ class: 'text-fg-danger-contrast disabled:text-fg-danger-contrast/40'
66
+ + ' ring-1 ring-inset ring-line-danger-weak disabled:ring-line'
67
+ + ' enabled:hover:bg-bg-danger-solid/10' },
68
68
  { color: 'danger', emphasis: 'ghost',
69
- class: 'text-danger-on-weak disabled:text-danger-on-weak/40'
70
- + ' enabled:hover:bg-danger/10' },
69
+ class: 'text-fg-danger-contrast disabled:text-fg-danger-contrast/40'
70
+ + ' enabled:hover:bg-bg-danger-solid/10' },
71
71
 
72
72
  { shape: ['rect', 'pill'], size: 'sm', class: 'px-3' },
73
73
  { shape: ['rect', 'pill'], size: 'md', class: 'px-3.5' },
@@ -81,7 +81,7 @@ export const button = tv({
81
81
  })
82
82
 
83
83
  export interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'color'> {
84
- color: 'primary' | 'neutral' | 'danger'
84
+ color: 'brand' | 'neutral' | 'danger'
85
85
  emphasis: 'solid' | 'weak' | 'outline' | 'ghost'
86
86
  size?: 'sm' | 'md' | 'lg'
87
87
  shape?: 'rect' | 'square' | 'pill' | 'circle'
package/callout/AGENTS.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  받기 npx @pantoia/ui add callout
5
5
  층 ui
6
- 파일 callout/index.tsx · callout/AGENTS.md
6
+ 파일 callout/index.tsx, callout/AGENTS.md
7
7
  ```
8
8
 
9
9
  ## 부위
@@ -19,24 +19,19 @@
19
19
  | 이름 | 타입 | 필수 |
20
20
  |---|---|---|
21
21
  | `color` | `'info' \| 'success' \| 'warning' \| 'danger'` | |
22
- | `live` | `boolean` | |
23
22
  | `icon` | `ReactNode` | |
24
23
  | `title` | `ReactNode` | |
25
24
  | `className` | `string` | |
26
25
  | `children` | `ReactNode` | |
27
26
 
28
- ## 변형 — `callout`
27
+ ## 변형 - `callout`
29
28
 
30
- 슬롯 `root` · `icon` · `title` · `body` · `text`
29
+ 슬롯 `root`, `icon`, `title`, `body`, `text`
31
30
 
32
31
  | 축 | 값 | 기본 |
33
32
  |---|---|---|
34
- | `color` | `info` · `success` · `warning` · `danger` | `info` |
33
+ | `color` | `info`, `success`, `warning`, `danger` | `info` |
35
34
 
36
35
  ## 함께 받는 것
37
36
 
38
37
  `tv`
39
-
40
- ## npm 의존
41
-
42
- `lucide-react`
package/callout/index.tsx CHANGED
@@ -1,34 +1,33 @@
1
- import { CircleCheck, CircleX, Info, TriangleAlert } from 'lucide-react'
2
1
  import type { ReactNode } from 'react'
3
2
 
4
3
  import { tv } from '../tv'
5
4
 
6
5
  export const callout = tv({
7
6
  slots: {
8
- root: 'flex gap-stack rounded-panel border p-4 text-prose',
7
+ root: 'flex gap-stack rounded-r12 border p-4 text-prose',
9
8
  icon: 'flex shrink-0 mt-0.5 [&_svg]:size-5',
10
9
  title: 'font-bold',
11
- body: 'flex min-w-0 flex-col gap-tight',
12
- text: 'flex flex-col gap-2',
10
+ body: 'flex min-w-0 flex-1 flex-col gap-tight',
11
+ text: 'flex flex-col items-start gap-2',
13
12
  },
14
13
 
15
14
  variants: {
16
15
  color: {
17
16
  info: {
18
- root: 'bg-info-weak text-info-on-weak border-info-stroke',
19
- icon: 'text-info',
17
+ root: 'bg-bg-info-weak text-fg-info-contrast border-line-info-weak',
18
+ icon: 'text-fg-info',
20
19
  },
21
20
  success: {
22
- root: 'bg-success-weak text-success-on-weak border-success-stroke',
23
- icon: 'text-success',
21
+ root: 'bg-bg-success-weak text-fg-success-contrast border-line-success-weak',
22
+ icon: 'text-fg-success',
24
23
  },
25
24
  warning: {
26
- root: 'bg-warning-weak text-warning-on-weak border-warning-stroke',
27
- icon: 'text-warning',
25
+ root: 'bg-bg-warning-weak text-fg-warning-contrast border-line-warning-weak',
26
+ icon: 'text-fg-warning',
28
27
  },
29
28
  danger: {
30
- root: 'bg-danger-weak text-danger-on-weak border-danger-stroke',
31
- icon: 'text-danger',
29
+ root: 'bg-bg-danger-weak text-fg-danger-contrast border-line-danger-weak',
30
+ icon: 'text-fg-danger',
32
31
  },
33
32
  },
34
33
  },
@@ -37,33 +36,54 @@ export const callout = tv({
37
36
  })
38
37
 
39
38
  const ICONS = {
40
- info: Info,
41
- success: CircleCheck,
42
- warning: TriangleAlert,
43
- danger: CircleX,
39
+ info: (
40
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
41
+ <circle cx="12" cy="12" r="10" />
42
+ <path d="M12 16v-4" />
43
+ <path d="M12 8h.01" />
44
+ </svg>
45
+ ),
46
+ success: (
47
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
48
+ <circle cx="12" cy="12" r="10" />
49
+ <path d="m16 9-5.5 5.5L8 12" />
50
+ </svg>
51
+ ),
52
+ warning: (
53
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
54
+ <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" />
55
+ <path d="M12 9v4" />
56
+ <path d="M12 17h.01" />
57
+ </svg>
58
+ ),
59
+ danger: (
60
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
61
+ <circle cx="12" cy="12" r="10" />
62
+ <path d="m15 9-6 6" />
63
+ <path d="m9 9 6 6" />
64
+ </svg>
65
+ ),
44
66
  } as const
45
67
 
46
68
  export interface CalloutProps {
47
69
  color?: 'info' | 'success' | 'warning' | 'danger'
48
- live?: boolean
49
70
  icon?: ReactNode
50
71
  title?: ReactNode
51
72
  className?: string
52
73
  children?: ReactNode
53
74
  }
54
75
 
55
- export function Callout({ color, live, icon, title, className, children }: CalloutProps) {
76
+ export function Callout({ color, icon, title, className, children }: CalloutProps) {
56
77
  const ui = callout({ color })
57
- const Fallback = ICONS[color ?? 'info']
58
78
 
59
79
  return (
60
- <div className={ui.root({ className })} role={live ? 'alert' : 'note'}>
80
+ <div className={ui.root({ className })} role="alert">
61
81
  <span className={ui.icon()}>
62
- {icon ?? <Fallback />}
82
+ {icon ?? ICONS[color ?? 'info']}
63
83
  </span>
64
84
  <div className={ui.body()}>
65
85
  {title && <span className={ui.title()}>{title}</span>}
66
- <div className={ui.text()}>{children}</div>
86
+ {children && <div className={ui.text()}>{children}</div>}
67
87
  </div>
68
88
  </div>
69
89
  )
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  받기 npx @pantoia/ui add checkbox
5
5
  층 ui
6
- 파일 checkbox/index.tsx · checkbox/AGENTS.md
6
+ 파일 checkbox/index.tsx, checkbox/AGENTS.md
7
7
  ```
8
8
 
9
9
  ## 부위
@@ -37,13 +37,13 @@
37
37
  | `onCheckedChange` | `(checked: boolean) => void` | |
38
38
  | `indeterminate` | `boolean` | |
39
39
  | `onIndeterminateChange` | `(indeterminate: boolean) => void` | |
40
- | `color` | `'control' \| 'info' \| 'success' \| 'warning' \| 'danger'` | |
40
+ | `color` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'danger'` | |
41
41
 
42
- ## 변형 — `checkbox`
42
+ ## 변형 - `checkbox`
43
43
 
44
44
  | 축 | 값 | 기본 |
45
45
  |---|---|---|
46
- | `color` | `control` · `info` · `success` · `warning` · `danger` | `control` |
46
+ | `color` | `neutral`, `info`, `success`, `warning`, `danger` | `neutral` |
47
47
 
48
48
  ## 함께 받는 것
49
49
 
@@ -51,4 +51,4 @@
51
51
 
52
52
  ## npm 의존
53
53
 
54
- `lucide-react` · `radix-ui`
54
+ `radix-ui`