@robomous/ui-core 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.
Files changed (135) hide show
  1. package/README.md +19 -7
  2. package/dist/{primitives → components}/alert.js +1 -1
  3. package/dist/{primitives → components}/badge.js +1 -1
  4. package/dist/{primitives → components}/button.d.ts +1 -1
  5. package/dist/{primitives → components}/button.js +4 -1
  6. package/dist/{primitives → components}/card.d.ts +1 -1
  7. package/dist/{primitives → components}/card.js +2 -2
  8. package/dist/{primitives → components}/combobox.js +4 -4
  9. package/dist/{primitives → components}/dialog.js +1 -1
  10. package/dist/{primitives → components}/dropdown-menu.js +12 -7
  11. package/dist/{primitives → components}/field.js +2 -4
  12. package/dist/{primitives → components}/input-group.js +1 -1
  13. package/dist/{primitives → components}/input.js +1 -1
  14. package/dist/{primitives → components}/label.js +1 -1
  15. package/dist/components/progress.js +7 -0
  16. package/dist/{primitives → components}/select.d.ts +3 -1
  17. package/dist/{primitives → components}/select.js +7 -4
  18. package/dist/{primitives → components}/separator.js +1 -1
  19. package/dist/{primitives → components}/sheet.js +1 -1
  20. package/dist/{primitives → components}/skeleton.js +1 -1
  21. package/dist/{primitives → components}/sonner.js +17 -12
  22. package/dist/{primitives → components}/table.d.ts +1 -1
  23. package/dist/{primitives → components}/table.js +3 -3
  24. package/dist/{primitives → components}/tabs.js +1 -1
  25. package/dist/{primitives → components}/textarea.js +1 -1
  26. package/dist/{primitives → components}/tooltip.js +1 -1
  27. package/dist/gates/index.d.ts +28 -0
  28. package/dist/gates/index.js +142 -0
  29. package/dist/index.d.ts +31 -32
  30. package/dist/index.js +32 -33
  31. package/dist/{tokens.d.ts → theme/tokens.d.ts} +5 -5
  32. package/dist/{tokens.js → theme/tokens.js} +12 -12
  33. package/package.json +23 -12
  34. package/{shadcn → src/components}/alert.tsx +14 -21
  35. package/src/{primitives → components}/badge.tsx +15 -21
  36. package/src/{primitives → components}/button.tsx +13 -10
  37. package/{shadcn → src/components}/card.tsx +16 -31
  38. package/src/{primitives → components}/combobox.test.tsx +15 -2
  39. package/src/{primitives → components}/combobox.tsx +45 -74
  40. package/src/{primitives/primitives.test.tsx → components/components.test.tsx} +106 -69
  41. package/src/{primitives → components}/dialog.tsx +31 -54
  42. package/src/{primitives → components}/dropdown-menu.tsx +51 -65
  43. package/src/{primitives → components}/field.tsx +48 -62
  44. package/src/{primitives → components}/input-group.tsx +37 -49
  45. package/{shadcn → src/components}/input.tsx +5 -5
  46. package/{shadcn → src/components}/label.tsx +7 -10
  47. package/src/{primitives → components}/progress.tsx +7 -6
  48. package/{shadcn → src/components}/select.tsx +40 -40
  49. package/{shadcn → src/components}/separator.tsx +7 -7
  50. package/src/{primitives → components}/sheet.tsx +27 -44
  51. package/{shadcn → src/components}/skeleton.tsx +3 -3
  52. package/src/{primitives → components}/sonner.test.tsx +12 -4
  53. package/src/components/sonner.tsx +67 -0
  54. package/{shadcn → src/components}/table.tsx +17 -44
  55. package/{shadcn → src/components}/tabs.tsx +16 -26
  56. package/{shadcn → src/components}/textarea.tsx +5 -5
  57. package/{shadcn → src/components}/tooltip.tsx +12 -16
  58. package/src/gates/design.test.ts +188 -0
  59. package/src/gates/index.test.ts +11 -0
  60. package/src/gates/index.ts +165 -0
  61. package/src/gates/tokens.test.ts +215 -0
  62. package/src/harness.test.tsx +1 -1
  63. package/src/index.ts +63 -33
  64. package/src/theme/imports.test.ts +160 -0
  65. package/src/{statusTone.test.ts → theme/statusTone.test.ts} +5 -1
  66. package/src/{styles.css → theme/styles.css} +45 -31
  67. package/src/theme/tailwind.css +646 -0
  68. package/src/{tokens.test.ts → theme/tokens.test.ts} +30 -23
  69. package/src/{tokens.ts → theme/tokens.ts} +12 -12
  70. package/components.json +0 -13
  71. package/dist/lib/button.d.ts +0 -1
  72. package/dist/lib/button.js +0 -4
  73. package/dist/lib/cn.d.ts +0 -18
  74. package/dist/lib/cn.js +0 -21
  75. package/dist/lib/menu.d.ts +0 -1
  76. package/dist/lib/menu.js +0 -16
  77. package/dist/lib/progress.d.ts +0 -3
  78. package/dist/lib/progress.js +0 -6
  79. package/dist/lib/select.d.ts +0 -1
  80. package/dist/lib/select.js +0 -3
  81. package/dist/primitives/progress.js +0 -7
  82. package/gates/canonical.test.mjs +0 -71
  83. package/gates/extensions.test.mjs +0 -373
  84. package/gates/index.d.mts +0 -51
  85. package/gates/index.mjs +0 -514
  86. package/gates/tokens.test.mjs +0 -276
  87. package/shadcn/README.md +0 -13
  88. package/shadcn/badge.tsx +0 -49
  89. package/shadcn/button.tsx +0 -67
  90. package/shadcn/combobox.tsx +0 -299
  91. package/shadcn/dialog.tsx +0 -166
  92. package/shadcn/dropdown-menu.tsx +0 -267
  93. package/shadcn/field.tsx +0 -236
  94. package/shadcn/input-group.tsx +0 -154
  95. package/shadcn/progress.tsx +0 -29
  96. package/shadcn/sheet.tsx +0 -145
  97. package/shadcn/sonner.tsx +0 -49
  98. package/src/lib/button.ts +0 -4
  99. package/src/lib/cn.test.ts +0 -33
  100. package/src/lib/cn.ts +0 -23
  101. package/src/lib/menu.ts +0 -16
  102. package/src/lib/progress.ts +0 -6
  103. package/src/lib/select.ts +0 -4
  104. package/src/primitives/alert.tsx +0 -76
  105. package/src/primitives/card.tsx +0 -103
  106. package/src/primitives/input.tsx +0 -19
  107. package/src/primitives/label.tsx +0 -22
  108. package/src/primitives/select.tsx +0 -190
  109. package/src/primitives/separator.tsx +0 -28
  110. package/src/primitives/skeleton.tsx +0 -13
  111. package/src/primitives/sonner.tsx +0 -65
  112. package/src/primitives/table.tsx +0 -114
  113. package/src/primitives/tabs.tsx +0 -88
  114. package/src/primitives/textarea.tsx +0 -18
  115. package/src/primitives/tooltip.tsx +0 -57
  116. /package/dist/{primitives → components}/alert.d.ts +0 -0
  117. /package/dist/{primitives → components}/badge.d.ts +0 -0
  118. /package/dist/{primitives → components}/combobox.d.ts +0 -0
  119. /package/dist/{primitives → components}/dialog.d.ts +0 -0
  120. /package/dist/{primitives → components}/dropdown-menu.d.ts +0 -0
  121. /package/dist/{primitives → components}/field.d.ts +0 -0
  122. /package/dist/{primitives → components}/input-group.d.ts +0 -0
  123. /package/dist/{primitives → components}/input.d.ts +0 -0
  124. /package/dist/{primitives → components}/label.d.ts +0 -0
  125. /package/dist/{primitives → components}/progress.d.ts +0 -0
  126. /package/dist/{primitives → components}/separator.d.ts +0 -0
  127. /package/dist/{primitives → components}/sheet.d.ts +0 -0
  128. /package/dist/{primitives → components}/skeleton.d.ts +0 -0
  129. /package/dist/{primitives → components}/sonner.d.ts +0 -0
  130. /package/dist/{primitives → components}/tabs.d.ts +0 -0
  131. /package/dist/{primitives → components}/textarea.d.ts +0 -0
  132. /package/dist/{primitives → components}/tooltip.d.ts +0 -0
  133. /package/dist/{statusTone.d.ts → theme/statusTone.d.ts} +0 -0
  134. /package/dist/{statusTone.js → theme/statusTone.js} +0 -0
  135. /package/src/{statusTone.ts → theme/statusTone.ts} +0 -0
@@ -1,267 +0,0 @@
1
- import * as React from "react"
2
- import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui"
3
-
4
- import { cn } from "@/lib/cn"
5
- import { CheckIcon, ChevronRightIcon } from "lucide-react"
6
-
7
- function DropdownMenu({
8
- ...props
9
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
10
- return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
11
- }
12
-
13
- function DropdownMenuPortal({
14
- ...props
15
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
16
- return (
17
- <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
18
- )
19
- }
20
-
21
- function DropdownMenuTrigger({
22
- ...props
23
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
24
- return (
25
- <DropdownMenuPrimitive.Trigger
26
- data-slot="dropdown-menu-trigger"
27
- {...props}
28
- />
29
- )
30
- }
31
-
32
- function DropdownMenuContent({
33
- className,
34
- align = "start",
35
- sideOffset = 4,
36
- ...props
37
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
38
- return (
39
- <DropdownMenuPrimitive.Portal>
40
- <DropdownMenuPrimitive.Content
41
- data-slot="dropdown-menu-content"
42
- sideOffset={sideOffset}
43
- align={align}
44
- className={cn("dark z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
45
- {...props}
46
- />
47
- </DropdownMenuPrimitive.Portal>
48
- )
49
- }
50
-
51
- function DropdownMenuGroup({
52
- ...props
53
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
54
- return (
55
- <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
56
- )
57
- }
58
-
59
- function DropdownMenuItem({
60
- className,
61
- inset,
62
- variant = "default",
63
- ...props
64
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
65
- inset?: boolean
66
- variant?: "default" | "destructive"
67
- }) {
68
- return (
69
- <DropdownMenuPrimitive.Item
70
- data-slot="dropdown-menu-item"
71
- data-inset={inset}
72
- data-variant={variant}
73
- className={cn(
74
- "group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
75
- className
76
- )}
77
- {...props}
78
- />
79
- )
80
- }
81
-
82
- function DropdownMenuCheckboxItem({
83
- className,
84
- children,
85
- checked,
86
- inset,
87
- ...props
88
- }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
89
- inset?: boolean
90
- }) {
91
- return (
92
- <DropdownMenuPrimitive.CheckboxItem
93
- data-slot="dropdown-menu-checkbox-item"
94
- data-inset={inset}
95
- className={cn(
96
- "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
97
- className
98
- )}
99
- checked={checked}
100
- {...props}
101
- >
102
- <span
103
- className="pointer-events-none absolute right-2 flex items-center justify-center"
104
- data-slot="dropdown-menu-checkbox-item-indicator"
105
- >
106
- <DropdownMenuPrimitive.ItemIndicator>
107
- <CheckIcon
108
- />
109
- </DropdownMenuPrimitive.ItemIndicator>
110
- </span>
111
- {children}
112
- </DropdownMenuPrimitive.CheckboxItem>
113
- )
114
- }
115
-
116
- function DropdownMenuRadioGroup({
117
- ...props
118
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
119
- return (
120
- <DropdownMenuPrimitive.RadioGroup
121
- data-slot="dropdown-menu-radio-group"
122
- {...props}
123
- />
124
- )
125
- }
126
-
127
- function DropdownMenuRadioItem({
128
- className,
129
- children,
130
- inset,
131
- ...props
132
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
133
- inset?: boolean
134
- }) {
135
- return (
136
- <DropdownMenuPrimitive.RadioItem
137
- data-slot="dropdown-menu-radio-item"
138
- data-inset={inset}
139
- className={cn(
140
- "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
141
- className
142
- )}
143
- {...props}
144
- >
145
- <span
146
- className="pointer-events-none absolute right-2 flex items-center justify-center"
147
- data-slot="dropdown-menu-radio-item-indicator"
148
- >
149
- <DropdownMenuPrimitive.ItemIndicator>
150
- <CheckIcon
151
- />
152
- </DropdownMenuPrimitive.ItemIndicator>
153
- </span>
154
- {children}
155
- </DropdownMenuPrimitive.RadioItem>
156
- )
157
- }
158
-
159
- function DropdownMenuLabel({
160
- className,
161
- inset,
162
- ...props
163
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
164
- inset?: boolean
165
- }) {
166
- return (
167
- <DropdownMenuPrimitive.Label
168
- data-slot="dropdown-menu-label"
169
- data-inset={inset}
170
- className={cn(
171
- "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7",
172
- className
173
- )}
174
- {...props}
175
- />
176
- )
177
- }
178
-
179
- function DropdownMenuSeparator({
180
- className,
181
- ...props
182
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
183
- return (
184
- <DropdownMenuPrimitive.Separator
185
- data-slot="dropdown-menu-separator"
186
- className={cn("-mx-1 my-1 h-px bg-border", className)}
187
- {...props}
188
- />
189
- )
190
- }
191
-
192
- function DropdownMenuShortcut({
193
- className,
194
- ...props
195
- }: React.ComponentProps<"span">) {
196
- return (
197
- <span
198
- data-slot="dropdown-menu-shortcut"
199
- className={cn(
200
- "ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
201
- className
202
- )}
203
- {...props}
204
- />
205
- )
206
- }
207
-
208
- function DropdownMenuSub({
209
- ...props
210
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
211
- return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
212
- }
213
-
214
- function DropdownMenuSubTrigger({
215
- className,
216
- inset,
217
- children,
218
- ...props
219
- }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
220
- inset?: boolean
221
- }) {
222
- return (
223
- <DropdownMenuPrimitive.SubTrigger
224
- data-slot="dropdown-menu-sub-trigger"
225
- data-inset={inset}
226
- className={cn(
227
- "flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
228
- className
229
- )}
230
- {...props}
231
- >
232
- {children}
233
- <ChevronRightIcon className="ml-auto" />
234
- </DropdownMenuPrimitive.SubTrigger>
235
- )
236
- }
237
-
238
- function DropdownMenuSubContent({
239
- className,
240
- ...props
241
- }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
242
- return (
243
- <DropdownMenuPrimitive.SubContent
244
- data-slot="dropdown-menu-sub-content"
245
- className={cn("dark z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
246
- {...props}
247
- />
248
- )
249
- }
250
-
251
- export {
252
- DropdownMenu,
253
- DropdownMenuPortal,
254
- DropdownMenuTrigger,
255
- DropdownMenuContent,
256
- DropdownMenuGroup,
257
- DropdownMenuLabel,
258
- DropdownMenuItem,
259
- DropdownMenuCheckboxItem,
260
- DropdownMenuRadioGroup,
261
- DropdownMenuRadioItem,
262
- DropdownMenuSeparator,
263
- DropdownMenuShortcut,
264
- DropdownMenuSub,
265
- DropdownMenuSubTrigger,
266
- DropdownMenuSubContent,
267
- }
package/shadcn/field.tsx DELETED
@@ -1,236 +0,0 @@
1
- import { useMemo } from "react"
2
- import { cva, type VariantProps } from "class-variance-authority"
3
-
4
- import { cn } from "@/lib/cn"
5
- import { Label } from "@/primitives/label"
6
- import { Separator } from "@/primitives/separator"
7
-
8
- function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
9
- return (
10
- <fieldset
11
- data-slot="field-set"
12
- className={cn(
13
- "flex flex-col gap-4 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
14
- className
15
- )}
16
- {...props}
17
- />
18
- )
19
- }
20
-
21
- function FieldLegend({
22
- className,
23
- variant = "legend",
24
- ...props
25
- }: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
26
- return (
27
- <legend
28
- data-slot="field-legend"
29
- data-variant={variant}
30
- className={cn(
31
- "mb-1.5 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base",
32
- className
33
- )}
34
- {...props}
35
- />
36
- )
37
- }
38
-
39
- function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
40
- return (
41
- <div
42
- data-slot="field-group"
43
- className={cn(
44
- "group/field-group @container/field-group flex w-full flex-col gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",
45
- className
46
- )}
47
- {...props}
48
- />
49
- )
50
- }
51
-
52
- const fieldVariants = cva(
53
- "group/field flex w-full gap-2 data-[invalid=true]:text-destructive",
54
- {
55
- variants: {
56
- orientation: {
57
- vertical: "flex-col *:w-full [&>.sr-only]:w-auto",
58
- horizontal:
59
- "flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
60
- responsive:
61
- "flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
62
- },
63
- },
64
- defaultVariants: {
65
- orientation: "vertical",
66
- },
67
- }
68
- )
69
-
70
- function Field({
71
- className,
72
- orientation = "vertical",
73
- ...props
74
- }: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
75
- return (
76
- <div
77
- role="group"
78
- data-slot="field"
79
- data-orientation={orientation}
80
- className={cn(fieldVariants({ orientation }), className)}
81
- {...props}
82
- />
83
- )
84
- }
85
-
86
- function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
87
- return (
88
- <div
89
- data-slot="field-content"
90
- className={cn(
91
- "group/field-content flex flex-1 flex-col gap-0.5 leading-snug",
92
- className
93
- )}
94
- {...props}
95
- />
96
- )
97
- }
98
-
99
- function FieldLabel({
100
- className,
101
- ...props
102
- }: React.ComponentProps<typeof Label>) {
103
- return (
104
- <Label
105
- data-slot="field-label"
106
- className={cn(
107
- "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-muted/50 has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-3 has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/50 *:data-[slot=field]:p-2.5 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10",
108
- "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
109
- className
110
- )}
111
- {...props}
112
- />
113
- )
114
- }
115
-
116
- function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
117
- return (
118
- <div
119
- data-slot="field-label"
120
- className={cn(
121
- "flex w-fit items-center gap-2 text-sm font-medium group-data-[disabled=true]/field:opacity-50",
122
- className
123
- )}
124
- {...props}
125
- />
126
- )
127
- }
128
-
129
- function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
130
- return (
131
- <p
132
- data-slot="field-description"
133
- className={cn(
134
- "text-left text-sm leading-normal font-normal text-muted-foreground group-has-data-horizontal/field:text-balance [[data-variant=legend]+&]:-mt-1.5",
135
- "last:mt-0 nth-last-2:-mt-1",
136
- "[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
137
- className
138
- )}
139
- {...props}
140
- />
141
- )
142
- }
143
-
144
- function FieldSeparator({
145
- children,
146
- className,
147
- ...props
148
- }: React.ComponentProps<"div"> & {
149
- children?: React.ReactNode
150
- }) {
151
- return (
152
- <div
153
- data-slot="field-separator"
154
- data-content={!!children}
155
- className={cn(
156
- "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
157
- className
158
- )}
159
- {...props}
160
- >
161
- <Separator className="absolute inset-0 top-1/2" />
162
- {children && (
163
- <span
164
- className="relative mx-auto block w-fit bg-background px-2 text-muted-foreground"
165
- data-slot="field-separator-content"
166
- >
167
- {children}
168
- </span>
169
- )}
170
- </div>
171
- )
172
- }
173
-
174
- function FieldError({
175
- className,
176
- children,
177
- errors,
178
- ...props
179
- }: React.ComponentProps<"div"> & {
180
- errors?: Array<{ message?: string } | undefined>
181
- }) {
182
- const content = useMemo(() => {
183
- if (children) {
184
- return children
185
- }
186
-
187
- if (!errors?.length) {
188
- return null
189
- }
190
-
191
- const uniqueErrors = [
192
- ...new Map(errors.map((error) => [error?.message, error])).values(),
193
- ]
194
-
195
- if (uniqueErrors?.length == 1) {
196
- return uniqueErrors[0]?.message
197
- }
198
-
199
- return (
200
- <ul className="ml-4 flex list-disc flex-col gap-1">
201
- {uniqueErrors.map(
202
- (error, index) =>
203
- error?.message && <li key={index}>{error.message}</li>
204
- )}
205
- </ul>
206
- )
207
- }, [children, errors])
208
-
209
- if (!content) {
210
- return null
211
- }
212
-
213
- return (
214
- <div
215
- role="alert"
216
- data-slot="field-error"
217
- className={cn("text-sm font-normal text-destructive", className)}
218
- {...props}
219
- >
220
- {content}
221
- </div>
222
- )
223
- }
224
-
225
- export {
226
- Field,
227
- FieldLabel,
228
- FieldDescription,
229
- FieldError,
230
- FieldGroup,
231
- FieldLegend,
232
- FieldSeparator,
233
- FieldSet,
234
- FieldContent,
235
- FieldTitle,
236
- }
@@ -1,154 +0,0 @@
1
- import * as React from "react"
2
- import { cva, type VariantProps } from "class-variance-authority"
3
-
4
- import { cn } from "@/lib/cn"
5
- import { Button } from "@/primitives/button"
6
- import { Input } from "@/primitives/input"
7
- import { Textarea } from "@/primitives/textarea"
8
-
9
- function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
10
- return (
11
- <div
12
- data-slot="input-group"
13
- role="group"
14
- className={cn(
15
- "group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
16
- className
17
- )}
18
- {...props}
19
- />
20
- )
21
- }
22
-
23
- const inputGroupAddonVariants = cva(
24
- "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",
25
- {
26
- variants: {
27
- align: {
28
- "inline-start":
29
- "order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]",
30
- "inline-end":
31
- "order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]",
32
- "block-start":
33
- "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
34
- "block-end":
35
- "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2",
36
- },
37
- },
38
- defaultVariants: {
39
- align: "inline-start",
40
- },
41
- }
42
- )
43
-
44
- function InputGroupAddon({
45
- className,
46
- align = "inline-start",
47
- ...props
48
- }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
49
- return (
50
- <div
51
- role="group"
52
- data-slot="input-group-addon"
53
- data-align={align}
54
- className={cn(inputGroupAddonVariants({ align }), className)}
55
- onClick={(e) => {
56
- if ((e.target as HTMLElement).closest("button")) {
57
- return
58
- }
59
- e.currentTarget.parentElement?.querySelector("input")?.focus()
60
- }}
61
- {...props}
62
- />
63
- )
64
- }
65
-
66
- const inputGroupButtonVariants = cva(
67
- "flex items-center gap-2 text-sm shadow-none",
68
- {
69
- variants: {
70
- size: {
71
- xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
72
- sm: "",
73
- "icon-xs":
74
- "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
75
- "icon-sm": "size-8 p-0 has-[>svg]:p-0",
76
- },
77
- },
78
- defaultVariants: {
79
- size: "xs",
80
- },
81
- }
82
- )
83
-
84
- function InputGroupButton({
85
- className,
86
- type = "button",
87
- variant = "ghost",
88
- size = "xs",
89
- ...props
90
- }: Omit<React.ComponentProps<typeof Button>, "size"> &
91
- VariantProps<typeof inputGroupButtonVariants>) {
92
- return (
93
- <Button
94
- type={type}
95
- data-size={size}
96
- variant={variant}
97
- className={cn(inputGroupButtonVariants({ size }), className)}
98
- {...props}
99
- />
100
- )
101
- }
102
-
103
- function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
104
- return (
105
- <span
106
- className={cn(
107
- "flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
108
- className
109
- )}
110
- {...props}
111
- />
112
- )
113
- }
114
-
115
- function InputGroupInput({
116
- className,
117
- ...props
118
- }: React.ComponentProps<"input">) {
119
- return (
120
- <Input
121
- data-slot="input-group-control"
122
- className={cn(
123
- "flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent",
124
- className
125
- )}
126
- {...props}
127
- />
128
- )
129
- }
130
-
131
- function InputGroupTextarea({
132
- className,
133
- ...props
134
- }: React.ComponentProps<"textarea">) {
135
- return (
136
- <Textarea
137
- data-slot="input-group-control"
138
- className={cn(
139
- "flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent",
140
- className
141
- )}
142
- {...props}
143
- />
144
- )
145
- }
146
-
147
- export {
148
- InputGroup,
149
- InputGroupAddon,
150
- InputGroupButton,
151
- InputGroupText,
152
- InputGroupInput,
153
- InputGroupTextarea,
154
- }
@@ -1,29 +0,0 @@
1
- import * as React from "react"
2
- import { Progress as ProgressPrimitive } from "radix-ui"
3
-
4
- import { cn } from "@/lib/cn"
5
-
6
- function Progress({
7
- className,
8
- value,
9
- ...props
10
- }: React.ComponentProps<typeof ProgressPrimitive.Root>) {
11
- return (
12
- <ProgressPrimitive.Root
13
- data-slot="progress"
14
- className={cn(
15
- "relative flex h-1 w-full items-center overflow-x-hidden rounded-full bg-muted",
16
- className
17
- )}
18
- {...props}
19
- >
20
- <ProgressPrimitive.Indicator
21
- data-slot="progress-indicator"
22
- className="size-full flex-1 bg-primary transition-all"
23
- style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
24
- />
25
- </ProgressPrimitive.Root>
26
- )
27
- }
28
-
29
- export { Progress }