@bytespell/shella 0.2.4 → 0.2.6

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