parthenon-ui 1.0.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 (36) hide show
  1. package/package.json +74 -0
  2. package/src/components/.gitkeep +0 -0
  3. package/src/components/avatar.tsx +109 -0
  4. package/src/components/badge.tsx +52 -0
  5. package/src/components/button.tsx +122 -0
  6. package/src/components/card.tsx +108 -0
  7. package/src/components/checkbox.tsx +37 -0
  8. package/src/components/collapsible.tsx +21 -0
  9. package/src/components/color-picker.tsx +270 -0
  10. package/src/components/command.tsx +195 -0
  11. package/src/components/context-menu.tsx +270 -0
  12. package/src/components/dialog.tsx +169 -0
  13. package/src/components/dropdown-menu.tsx +279 -0
  14. package/src/components/empty.tsx +104 -0
  15. package/src/components/index.ts +27 -0
  16. package/src/components/input-group.tsx +155 -0
  17. package/src/components/input.tsx +27 -0
  18. package/src/components/label.tsx +18 -0
  19. package/src/components/popover.tsx +88 -0
  20. package/src/components/scroll-area.tsx +55 -0
  21. package/src/components/select.tsx +201 -0
  22. package/src/components/separator.tsx +23 -0
  23. package/src/components/sheet.tsx +138 -0
  24. package/src/components/sidebar.tsx +729 -0
  25. package/src/components/skeleton.tsx +13 -0
  26. package/src/components/sonner.tsx +59 -0
  27. package/src/components/switch.tsx +51 -0
  28. package/src/components/table.tsx +375 -0
  29. package/src/components/tabs.tsx +80 -0
  30. package/src/components/textarea.tsx +18 -0
  31. package/src/components/tooltip.tsx +64 -0
  32. package/src/hooks/.gitkeep +0 -0
  33. package/src/hooks/use-mobile.ts +19 -0
  34. package/src/lib/.gitkeep +0 -0
  35. package/src/lib/utils.ts +6 -0
  36. package/src/styles/globals.css +654 -0
@@ -0,0 +1,279 @@
1
+ import * as React from "react"
2
+ import { Menu as MenuPrimitive } from "@base-ui/react/menu"
3
+
4
+ import { cn } from "@workspace/ui/lib/utils"
5
+ import { HugeiconsIcon } from "@hugeicons/react"
6
+ import { ArrowRight01Icon, Tick02Icon } from "@hugeicons/core-free-icons"
7
+
8
+ function DropdownMenu({ children, ...props }: MenuPrimitive.Root.Props) {
9
+ return (
10
+ <MenuPrimitive.Root data-slot="dropdown-menu" {...props}>
11
+ {children}
12
+ </MenuPrimitive.Root>
13
+ )
14
+ }
15
+
16
+ function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
17
+ return <MenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
18
+ }
19
+
20
+ function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {
21
+ return <MenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />
22
+ }
23
+
24
+ function DropdownMenuContent({
25
+ align = "start",
26
+ alignOffset = 0,
27
+ side = "bottom",
28
+ sideOffset = 4,
29
+ className,
30
+ ...props
31
+ }: MenuPrimitive.Popup.Props &
32
+ Pick<
33
+ MenuPrimitive.Positioner.Props,
34
+ "align" | "alignOffset" | "side" | "sideOffset"
35
+ >) {
36
+ return (
37
+ <MenuPrimitive.Portal>
38
+ <MenuPrimitive.Positioner
39
+ className="z-[100] outline-none"
40
+ align={align}
41
+ alignOffset={alignOffset}
42
+ side={side}
43
+ sideOffset={sideOffset}
44
+ >
45
+ <MenuPrimitive.Popup
46
+ data-slot="dropdown-menu-content"
47
+ className={cn(
48
+ "z-[100] max-h-(--available-height) w-(--anchor-width) min-w-48 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-2xl bg-popover p-1 text-popover-foreground shadow-2xl ring-1 ring-foreground/5 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-start-2 data-[side=inline-start]:slide-in-from-end-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 dark:ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95",
49
+ className
50
+ )}
51
+ {...props}
52
+ />
53
+ </MenuPrimitive.Positioner>
54
+ </MenuPrimitive.Portal>
55
+ )
56
+ }
57
+
58
+ function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {
59
+ return <MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
60
+ }
61
+
62
+ function DropdownMenuLabel({
63
+ className,
64
+ inset,
65
+ ...props
66
+ }: MenuPrimitive.GroupLabel.Props & {
67
+ inset?: boolean
68
+ }) {
69
+ return (
70
+ <MenuPrimitive.GroupLabel
71
+ data-slot="dropdown-menu-label"
72
+ data-inset={inset}
73
+ className={cn(
74
+ "px-3 py-2.5 text-xs text-muted-foreground data-inset:ps-9.5",
75
+ className
76
+ )}
77
+ {...props}
78
+ />
79
+ )
80
+ }
81
+
82
+ function DropdownMenuItem({
83
+ className,
84
+ inset,
85
+ variant = "default",
86
+ ...props
87
+ }: MenuPrimitive.Item.Props & {
88
+ inset?: boolean
89
+ variant?: "default" | "destructive"
90
+ }) {
91
+ return (
92
+ <MenuPrimitive.Item
93
+ data-slot="dropdown-menu-item"
94
+ data-inset={inset}
95
+ data-variant={variant}
96
+ className={cn(
97
+ "group/dropdown-menu-item relative flex cursor-default items-center gap-2.5 rounded-xl px-3 py-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:ps-9.5 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",
98
+ className
99
+ )}
100
+ {...props}
101
+ />
102
+ )
103
+ }
104
+
105
+ function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
106
+ return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />
107
+ }
108
+
109
+ function DropdownMenuSubTrigger({
110
+ className,
111
+ inset,
112
+ children,
113
+ ...props
114
+ }: MenuPrimitive.SubmenuTrigger.Props & {
115
+ inset?: boolean
116
+ }) {
117
+ return (
118
+ <MenuPrimitive.SubmenuTrigger
119
+ data-slot="dropdown-menu-sub-trigger"
120
+ data-inset={inset}
121
+ className={cn(
122
+ "flex cursor-default items-center gap-2 rounded-xl px-3 py-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:ps-9.5 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
123
+ className
124
+ )}
125
+ {...props}
126
+ >
127
+ {children}
128
+ <HugeiconsIcon
129
+ icon={ArrowRight01Icon}
130
+ strokeWidth={2}
131
+ className="rtl:rotate-180 ms-auto"
132
+ />
133
+ </MenuPrimitive.SubmenuTrigger>
134
+ )
135
+ }
136
+
137
+ function DropdownMenuSubContent({
138
+ align = "start",
139
+ alignOffset = -3,
140
+ side = "inline-end",
141
+ sideOffset = 0,
142
+ className,
143
+ ...props
144
+ }: React.ComponentProps<typeof DropdownMenuContent>) {
145
+ return (
146
+ <DropdownMenuContent
147
+ data-slot="dropdown-menu-sub-content"
148
+ className={cn(
149
+ "w-auto min-w-36 rounded-2xl bg-popover p-1 text-popover-foreground shadow-2xl ring-1 ring-foreground/5 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",
150
+ className
151
+ )}
152
+ align={align}
153
+ alignOffset={alignOffset}
154
+ side={side}
155
+ sideOffset={sideOffset}
156
+ {...props}
157
+ />
158
+ )
159
+ }
160
+
161
+ function DropdownMenuCheckboxItem({
162
+ className,
163
+ children,
164
+ checked,
165
+ inset,
166
+ ...props
167
+ }: MenuPrimitive.CheckboxItem.Props & {
168
+ inset?: boolean
169
+ }) {
170
+ return (
171
+ <MenuPrimitive.CheckboxItem
172
+ data-slot="dropdown-menu-checkbox-item"
173
+ data-inset={inset}
174
+ className={cn(
175
+ "relative flex cursor-default items-center gap-2.5 rounded-xl py-2 pe-8 ps-3 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:ps-9.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
176
+ className
177
+ )}
178
+ checked={checked}
179
+ {...props}
180
+ >
181
+ <span
182
+ className="pointer-events-none absolute end-2 flex items-center justify-center"
183
+ data-slot="dropdown-menu-checkbox-item-indicator"
184
+ >
185
+ <MenuPrimitive.CheckboxItemIndicator>
186
+ <HugeiconsIcon icon={Tick02Icon} strokeWidth={2} />
187
+ </MenuPrimitive.CheckboxItemIndicator>
188
+ </span>
189
+ {children}
190
+ </MenuPrimitive.CheckboxItem>
191
+ )
192
+ }
193
+
194
+ function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
195
+ return (
196
+ <MenuPrimitive.RadioGroup
197
+ data-slot="dropdown-menu-radio-group"
198
+ {...props}
199
+ />
200
+ )
201
+ }
202
+
203
+ function DropdownMenuRadioItem({
204
+ className,
205
+ children,
206
+ inset,
207
+ ...props
208
+ }: MenuPrimitive.RadioItem.Props & {
209
+ inset?: boolean
210
+ }) {
211
+ return (
212
+ <MenuPrimitive.RadioItem
213
+ data-slot="dropdown-menu-radio-item"
214
+ data-inset={inset}
215
+ className={cn(
216
+ "relative flex cursor-default items-center gap-2.5 rounded-xl py-2 pe-8 ps-3 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:ps-9.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
217
+ className
218
+ )}
219
+ {...props}
220
+ >
221
+ <span
222
+ className="pointer-events-none absolute end-2 flex items-center justify-center"
223
+ data-slot="dropdown-menu-radio-item-indicator"
224
+ >
225
+ <MenuPrimitive.RadioItemIndicator>
226
+ <HugeiconsIcon icon={Tick02Icon} strokeWidth={2} />
227
+ </MenuPrimitive.RadioItemIndicator>
228
+ </span>
229
+ {children}
230
+ </MenuPrimitive.RadioItem>
231
+ )
232
+ }
233
+
234
+ function DropdownMenuSeparator({
235
+ className,
236
+ ...props
237
+ }: MenuPrimitive.Separator.Props) {
238
+ return (
239
+ <MenuPrimitive.Separator
240
+ data-slot="dropdown-menu-separator"
241
+ className={cn("-mx-1 my-1 h-px bg-border/50", className)}
242
+ {...props}
243
+ />
244
+ )
245
+ }
246
+
247
+ function DropdownMenuShortcut({
248
+ className,
249
+ ...props
250
+ }: React.ComponentProps<"span">) {
251
+ return (
252
+ <span
253
+ data-slot="dropdown-menu-shortcut"
254
+ className={cn(
255
+ "ms-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
256
+ className
257
+ )}
258
+ {...props}
259
+ />
260
+ )
261
+ }
262
+
263
+ export {
264
+ DropdownMenu,
265
+ DropdownMenuPortal,
266
+ DropdownMenuTrigger,
267
+ DropdownMenuContent,
268
+ DropdownMenuGroup,
269
+ DropdownMenuLabel,
270
+ DropdownMenuItem,
271
+ DropdownMenuCheckboxItem,
272
+ DropdownMenuRadioGroup,
273
+ DropdownMenuRadioItem,
274
+ DropdownMenuSeparator,
275
+ DropdownMenuShortcut,
276
+ DropdownMenuSub,
277
+ DropdownMenuSubTrigger,
278
+ DropdownMenuSubContent,
279
+ }
@@ -0,0 +1,104 @@
1
+ import { cva, type VariantProps } from "class-variance-authority"
2
+
3
+ import { cn } from "@workspace/ui/lib/utils"
4
+
5
+ function Empty({ className, ...props }: React.ComponentProps<"div">) {
6
+ return (
7
+ <div
8
+ data-slot="empty"
9
+ className={cn(
10
+ "flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-lg border-dashed p-12 text-center text-balance",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+ return (
20
+ <div
21
+ data-slot="empty-header"
22
+ className={cn("flex max-w-sm flex-col items-center gap-2", className)}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ const emptyMediaVariants = cva(
29
+ "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
30
+ {
31
+ variants: {
32
+ variant: {
33
+ default: "bg-transparent",
34
+ icon: "flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-6",
35
+ },
36
+ },
37
+ defaultVariants: {
38
+ variant: "default",
39
+ },
40
+ }
41
+ )
42
+
43
+ function EmptyMedia({
44
+ className,
45
+ variant = "default",
46
+ ...props
47
+ }: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
48
+ return (
49
+ <div
50
+ data-slot="empty-icon"
51
+ data-variant={variant}
52
+ className={cn(emptyMediaVariants({ variant, className }))}
53
+ {...props}
54
+ />
55
+ )
56
+ }
57
+
58
+ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
59
+ return (
60
+ <div
61
+ data-slot="empty-title"
62
+ className={cn(
63
+ "font-heading text-lg font-medium tracking-tight",
64
+ className
65
+ )}
66
+ {...props}
67
+ />
68
+ )
69
+ }
70
+
71
+ function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
72
+ return (
73
+ <div
74
+ data-slot="empty-description"
75
+ className={cn(
76
+ "text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="empty-content"
88
+ className={cn(
89
+ "flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance",
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ )
95
+ }
96
+
97
+ export {
98
+ Empty,
99
+ EmptyHeader,
100
+ EmptyTitle,
101
+ EmptyDescription,
102
+ EmptyContent,
103
+ EmptyMedia,
104
+ }
@@ -0,0 +1,27 @@
1
+ export * from "./avatar";
2
+ export * from "./badge";
3
+ export * from "./button";
4
+ export * from "./card";
5
+ export * from "./checkbox";
6
+ export * from "./collapsible";
7
+ export * from "./command";
8
+ export * from "./context-menu";
9
+ export * from "./dialog";
10
+ export * from "./dropdown-menu";
11
+ export * from "./empty";
12
+ export * from "./input-group";
13
+ export * from "./input";
14
+ export * from "./label";
15
+ export * from "./popover";
16
+ export * from "./scroll-area";
17
+ export * from "./select";
18
+ export * from "./separator";
19
+ export * from "./sheet";
20
+ export * from "./sidebar";
21
+ export * from "./skeleton";
22
+ export * from "./sonner";
23
+ export * from "./switch";
24
+ export * from "./table";
25
+ export * from "./tabs";
26
+ export * from "./textarea";
27
+ export * from "./tooltip";
@@ -0,0 +1,155 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+ import { cn } from "@workspace/ui/lib/utils"
5
+ import { Button } from "@workspace/ui/components/button"
6
+ import { Input } from "@workspace/ui/components/input"
7
+ import { Textarea } from "@workspace/ui/components/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-9 w-full min-w-0 items-center rounded-4xl border border-input bg-input/30 transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-data-[align=block-end]:rounded-2xl has-data-[align=block-start]:rounded-2xl has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-[3px] 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-[3px] has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[textarea]:rounded-xl 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: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]:pe-1.5 has-[>[data-align=inline-start]]:[&>input]:ps-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-2 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 **:data-[slot=kbd]:rounded-4xl **:data-[slot=kbd]:bg-muted-foreground/10 **:data-[slot=kbd]:px-1.5 [&>svg:not([class*='size-'])]:size-4",
25
+ {
26
+ variants: {
27
+ align: {
28
+ "inline-start":
29
+ "order-first ps-3 has-[>button]:-ms-1 has-[>kbd]:ms-[-0.15rem]",
30
+ "inline-end":
31
+ "order-last pe-3 has-[>button]:-me-1 has-[>kbd]:me-[-0.15rem]",
32
+ "block-start":
33
+ "order-first w-full justify-start px-3 pt-3 group-has-[>input]/input-group:pt-3 [.border-b]:pb-3",
34
+ "block-end":
35
+ "order-last w-full justify-start px-3 pb-3 group-has-[>input]/input-group:pb-3 [.border-t]:pt-3",
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 rounded-4xl text-sm shadow-none",
68
+ {
69
+ variants: {
70
+ size: {
71
+ xs: "h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
72
+ sm: "",
73
+ "icon-xs": "size-6 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" | "type"> &
90
+ VariantProps<typeof inputGroupButtonVariants> & {
91
+ type?: "button" | "submit" | "reset"
92
+ }) {
93
+ return (
94
+ <Button
95
+ type={type}
96
+ data-size={size}
97
+ variant={variant}
98
+ className={cn(inputGroupButtonVariants({ size }), className)}
99
+ {...props}
100
+ />
101
+ )
102
+ }
103
+
104
+ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
105
+ return (
106
+ <span
107
+ className={cn(
108
+ "flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
109
+ className
110
+ )}
111
+ {...props}
112
+ />
113
+ )
114
+ }
115
+
116
+ function InputGroupInput({
117
+ className,
118
+ ...props
119
+ }: React.ComponentProps<"input">) {
120
+ return (
121
+ <Input
122
+ data-slot="input-group-control"
123
+ className={cn(
124
+ "flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
125
+ className
126
+ )}
127
+ {...props}
128
+ />
129
+ )
130
+ }
131
+
132
+ function InputGroupTextarea({
133
+ className,
134
+ ...props
135
+ }: React.ComponentProps<"textarea">) {
136
+ return (
137
+ <Textarea
138
+ data-slot="input-group-control"
139
+ className={cn(
140
+ "flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
141
+ className
142
+ )}
143
+ {...props}
144
+ />
145
+ )
146
+ }
147
+
148
+ export {
149
+ InputGroup,
150
+ InputGroupAddon,
151
+ InputGroupButton,
152
+ InputGroupText,
153
+ InputGroupInput,
154
+ InputGroupTextarea,
155
+ }
@@ -0,0 +1,27 @@
1
+ import * as React from "react"
2
+ import { Input as InputPrimitive } from "@base-ui/react/input"
3
+
4
+ import { cn } from "@workspace/ui/lib/utils"
5
+
6
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
7
+ return (
8
+ <div className="relative">
9
+ <InputPrimitive
10
+ type={type}
11
+ data-slot="input"
12
+ className={cn(
13
+ "h-9 w-full min-w-0 rounded-4xl border border-input bg-input/30 px-3 py-1 text-base transition-all duration-150 outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground",
14
+ "shadow-[0_1px_1px_0_rgba(0,0,0,0.24),0_2px_3px_0_rgba(0,0,0,0.20),inset_0_1px_1px_0_rgba(255,255,255,0.07),0_0_0_1px_var(--input)]",
15
+ "before:absolute before:inset-0 before:rounded-4xl before:bg-linear-[180deg,rgba(255,255,255,0.1)_0%,rgba(255,255,255,0)_100%] before:content-[''] before:pointer-events-none",
16
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:shadow-[0_1px_1px_0_rgba(0,0,0,0.24),0_2px_3px_0_rgba(0,0,0,0.20),inset_0_1px_1px_0_rgba(255,255,255,0.07),0_0_0_1px_var(--ring)]",
17
+ "focus-visible:before:bg-linear-[180deg,rgba(255,255,255,0)_0%,rgba(255,255,255,0.1)_100%]",
18
+ "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] aria-invalid:ring-destructive/20 md:text-sm dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
19
+ className
20
+ )}
21
+ {...props}
22
+ />
23
+ </div>
24
+ )
25
+ }
26
+
27
+ export { Input }
@@ -0,0 +1,18 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@workspace/ui/lib/utils"
4
+
5
+ function Label({ className, ...props }: React.ComponentProps<"label">) {
6
+ return (
7
+ <label
8
+ data-slot="label"
9
+ className={cn(
10
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ export { Label }
@@ -0,0 +1,88 @@
1
+ import * as React from "react"
2
+ import { Popover as PopoverPrimitive } from "@base-ui/react/popover"
3
+
4
+ import { cn } from "@workspace/ui/lib/utils"
5
+
6
+ function Popover({ ...props }: PopoverPrimitive.Root.Props) {
7
+ return <PopoverPrimitive.Root data-slot="popover" {...props} />
8
+ }
9
+
10
+ function PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {
11
+ return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
12
+ }
13
+
14
+ function PopoverContent({
15
+ className,
16
+ align = "center",
17
+ alignOffset = 0,
18
+ side = "bottom",
19
+ sideOffset = 4,
20
+ ...props
21
+ }: PopoverPrimitive.Popup.Props &
22
+ Pick<
23
+ PopoverPrimitive.Positioner.Props,
24
+ "align" | "alignOffset" | "side" | "sideOffset"
25
+ >) {
26
+ return (
27
+ <PopoverPrimitive.Portal>
28
+ <PopoverPrimitive.Positioner
29
+ align={align}
30
+ alignOffset={alignOffset}
31
+ side={side}
32
+ sideOffset={sideOffset}
33
+ className="isolate z-50"
34
+ >
35
+ <PopoverPrimitive.Popup
36
+ data-slot="popover-content"
37
+ className={cn(
38
+ "z-50 flex w-72 origin-(--transform-origin) flex-col gap-4 rounded-2xl bg-popover p-4 text-sm text-popover-foreground shadow-2xl ring-1 ring-foreground/5 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-start-2 data-[side=inline-start]:slide-in-from-end-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",
39
+ className
40
+ )}
41
+ {...props}
42
+ />
43
+ </PopoverPrimitive.Positioner>
44
+ </PopoverPrimitive.Portal>
45
+ )
46
+ }
47
+
48
+ function PopoverHeader({ className, ...props }: React.ComponentProps<"div">) {
49
+ return (
50
+ <div
51
+ data-slot="popover-header"
52
+ className={cn("flex flex-col gap-1 text-sm", className)}
53
+ {...props}
54
+ />
55
+ )
56
+ }
57
+
58
+ function PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {
59
+ return (
60
+ <PopoverPrimitive.Title
61
+ data-slot="popover-title"
62
+ className={cn("text-base font-medium", className)}
63
+ {...props}
64
+ />
65
+ )
66
+ }
67
+
68
+ function PopoverDescription({
69
+ className,
70
+ ...props
71
+ }: PopoverPrimitive.Description.Props) {
72
+ return (
73
+ <PopoverPrimitive.Description
74
+ data-slot="popover-description"
75
+ className={cn("text-muted-foreground", className)}
76
+ {...props}
77
+ />
78
+ )
79
+ }
80
+
81
+ export {
82
+ Popover,
83
+ PopoverContent,
84
+ PopoverDescription,
85
+ PopoverHeader,
86
+ PopoverTitle,
87
+ PopoverTrigger,
88
+ }