@robomous/ui-core 0.1.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 (126) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +38 -0
  3. package/components.json +13 -0
  4. package/dist/index.d.ts +44 -0
  5. package/dist/index.js +47 -0
  6. package/dist/lib/button.d.ts +1 -0
  7. package/dist/lib/button.js +4 -0
  8. package/dist/lib/cn.d.ts +18 -0
  9. package/dist/lib/cn.js +21 -0
  10. package/dist/lib/menu.d.ts +1 -0
  11. package/dist/lib/menu.js +16 -0
  12. package/dist/lib/progress.d.ts +3 -0
  13. package/dist/lib/progress.js +6 -0
  14. package/dist/lib/select.d.ts +1 -0
  15. package/dist/lib/select.js +3 -0
  16. package/dist/primitives/alert.d.ts +10 -0
  17. package/dist/primitives/alert.js +27 -0
  18. package/dist/primitives/badge.d.ts +9 -0
  19. package/dist/primitives/badge.js +28 -0
  20. package/dist/primitives/button.d.ts +10 -0
  21. package/dist/primitives/button.js +35 -0
  22. package/dist/primitives/card.d.ts +11 -0
  23. package/dist/primitives/card.js +24 -0
  24. package/dist/primitives/combobox.d.ts +24 -0
  25. package/dist/primitives/combobox.js +58 -0
  26. package/dist/primitives/dialog.d.ts +17 -0
  27. package/dist/primitives/dialog.js +36 -0
  28. package/dist/primitives/dropdown-menu.d.ts +29 -0
  29. package/dist/primitives/dropdown-menu.js +50 -0
  30. package/dist/primitives/field.d.ts +24 -0
  31. package/dist/primitives/field.js +67 -0
  32. package/dist/primitives/input-group.d.ts +16 -0
  33. package/dist/primitives/input-group.js +56 -0
  34. package/dist/primitives/input.d.ts +3 -0
  35. package/dist/primitives/input.js +6 -0
  36. package/dist/primitives/label.d.ts +4 -0
  37. package/dist/primitives/label.js +7 -0
  38. package/dist/primitives/progress.d.ts +4 -0
  39. package/dist/primitives/progress.js +7 -0
  40. package/dist/primitives/select.d.ts +15 -0
  41. package/dist/primitives/select.js +35 -0
  42. package/dist/primitives/separator.d.ts +4 -0
  43. package/dist/primitives/separator.js +8 -0
  44. package/dist/primitives/sheet.d.ts +14 -0
  45. package/dist/primitives/sheet.js +36 -0
  46. package/dist/primitives/skeleton.d.ts +2 -0
  47. package/dist/primitives/skeleton.js +6 -0
  48. package/dist/primitives/sonner.d.ts +4 -0
  49. package/dist/primitives/sonner.js +40 -0
  50. package/dist/primitives/table.d.ts +10 -0
  51. package/dist/primitives/table.js +27 -0
  52. package/dist/primitives/tabs.d.ts +11 -0
  53. package/dist/primitives/tabs.js +28 -0
  54. package/dist/primitives/textarea.d.ts +3 -0
  55. package/dist/primitives/textarea.js +6 -0
  56. package/dist/primitives/tooltip.d.ts +7 -0
  57. package/dist/primitives/tooltip.js +17 -0
  58. package/dist/statusTone.d.ts +37 -0
  59. package/dist/statusTone.js +38 -0
  60. package/dist/tokens.d.ts +26 -0
  61. package/dist/tokens.js +96 -0
  62. package/gates/canonical.test.mjs +71 -0
  63. package/gates/extensions.test.mjs +373 -0
  64. package/gates/index.d.mts +51 -0
  65. package/gates/index.mjs +514 -0
  66. package/gates/tokens.test.mjs +276 -0
  67. package/package.json +60 -0
  68. package/shadcn/README.md +13 -0
  69. package/shadcn/alert.tsx +76 -0
  70. package/shadcn/badge.tsx +49 -0
  71. package/shadcn/button.tsx +67 -0
  72. package/shadcn/card.tsx +103 -0
  73. package/shadcn/combobox.tsx +299 -0
  74. package/shadcn/dialog.tsx +166 -0
  75. package/shadcn/dropdown-menu.tsx +267 -0
  76. package/shadcn/field.tsx +236 -0
  77. package/shadcn/input-group.tsx +154 -0
  78. package/shadcn/input.tsx +19 -0
  79. package/shadcn/label.tsx +22 -0
  80. package/shadcn/progress.tsx +29 -0
  81. package/shadcn/select.tsx +190 -0
  82. package/shadcn/separator.tsx +28 -0
  83. package/shadcn/sheet.tsx +145 -0
  84. package/shadcn/skeleton.tsx +13 -0
  85. package/shadcn/sonner.tsx +49 -0
  86. package/shadcn/table.tsx +114 -0
  87. package/shadcn/tabs.tsx +88 -0
  88. package/shadcn/textarea.tsx +18 -0
  89. package/shadcn/tooltip.tsx +57 -0
  90. package/src/harness.test.tsx +37 -0
  91. package/src/index.ts +119 -0
  92. package/src/lib/button.ts +4 -0
  93. package/src/lib/cn.test.ts +33 -0
  94. package/src/lib/cn.ts +23 -0
  95. package/src/lib/menu.ts +16 -0
  96. package/src/lib/progress.ts +6 -0
  97. package/src/lib/select.ts +4 -0
  98. package/src/primitives/alert.tsx +76 -0
  99. package/src/primitives/badge.tsx +57 -0
  100. package/src/primitives/button.tsx +67 -0
  101. package/src/primitives/card.tsx +103 -0
  102. package/src/primitives/combobox.test.tsx +38 -0
  103. package/src/primitives/combobox.tsx +299 -0
  104. package/src/primitives/dialog.tsx +166 -0
  105. package/src/primitives/dropdown-menu.tsx +267 -0
  106. package/src/primitives/field.tsx +236 -0
  107. package/src/primitives/input-group.tsx +154 -0
  108. package/src/primitives/input.tsx +19 -0
  109. package/src/primitives/label.tsx +22 -0
  110. package/src/primitives/primitives.test.tsx +440 -0
  111. package/src/primitives/progress.tsx +29 -0
  112. package/src/primitives/select.tsx +190 -0
  113. package/src/primitives/separator.tsx +28 -0
  114. package/src/primitives/sheet.tsx +145 -0
  115. package/src/primitives/skeleton.tsx +13 -0
  116. package/src/primitives/sonner.test.tsx +41 -0
  117. package/src/primitives/sonner.tsx +65 -0
  118. package/src/primitives/table.tsx +114 -0
  119. package/src/primitives/tabs.tsx +88 -0
  120. package/src/primitives/textarea.tsx +18 -0
  121. package/src/primitives/tooltip.tsx +57 -0
  122. package/src/statusTone.test.ts +20 -0
  123. package/src/statusTone.ts +52 -0
  124. package/src/styles.css +204 -0
  125. package/src/tokens.test.ts +285 -0
  126. package/src/tokens.ts +102 -0
@@ -0,0 +1,29 @@
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 }
@@ -0,0 +1,190 @@
1
+ import * as React from "react"
2
+ import { Select as SelectPrimitive } from "radix-ui"
3
+
4
+ import { cn } from "@/lib/cn"
5
+ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
6
+
7
+ function Select({
8
+ ...props
9
+ }: React.ComponentProps<typeof SelectPrimitive.Root>) {
10
+ return <SelectPrimitive.Root data-slot="select" {...props} />
11
+ }
12
+
13
+ function SelectGroup({
14
+ className,
15
+ ...props
16
+ }: React.ComponentProps<typeof SelectPrimitive.Group>) {
17
+ return (
18
+ <SelectPrimitive.Group
19
+ data-slot="select-group"
20
+ className={cn("scroll-my-1 p-1", className)}
21
+ {...props}
22
+ />
23
+ )
24
+ }
25
+
26
+ function SelectValue({
27
+ ...props
28
+ }: React.ComponentProps<typeof SelectPrimitive.Value>) {
29
+ return <SelectPrimitive.Value data-slot="select-value" {...props} />
30
+ }
31
+
32
+ function SelectTrigger({
33
+ className,
34
+ size = "default",
35
+ children,
36
+ ...props
37
+ }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
38
+ size?: "sm" | "default"
39
+ }) {
40
+ return (
41
+ <SelectPrimitive.Trigger
42
+ data-slot="select-trigger"
43
+ data-size={size}
44
+ className={cn(
45
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
46
+ className
47
+ )}
48
+ {...props}
49
+ >
50
+ {children}
51
+ <SelectPrimitive.Icon asChild>
52
+ <ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
53
+ </SelectPrimitive.Icon>
54
+ </SelectPrimitive.Trigger>
55
+ )
56
+ }
57
+
58
+ function SelectContent({
59
+ className,
60
+ children,
61
+ position = "item-aligned",
62
+ align = "center",
63
+ ...props
64
+ }: React.ComponentProps<typeof SelectPrimitive.Content>) {
65
+ return (
66
+ <SelectPrimitive.Portal>
67
+ <SelectPrimitive.Content
68
+ data-slot="select-content"
69
+ data-align-trigger={position === "item-aligned"}
70
+ className={cn("dark relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none 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", position ==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className )}
71
+ position={position}
72
+ align={align}
73
+ {...props}
74
+ >
75
+ <SelectScrollUpButton />
76
+ <SelectPrimitive.Viewport
77
+ data-position={position}
78
+ className={cn(
79
+ "data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
80
+ position === "popper" && ""
81
+ )}
82
+ >
83
+ {children}
84
+ </SelectPrimitive.Viewport>
85
+ <SelectScrollDownButton />
86
+ </SelectPrimitive.Content>
87
+ </SelectPrimitive.Portal>
88
+ )
89
+ }
90
+
91
+ function SelectLabel({
92
+ className,
93
+ ...props
94
+ }: React.ComponentProps<typeof SelectPrimitive.Label>) {
95
+ return (
96
+ <SelectPrimitive.Label
97
+ data-slot="select-label"
98
+ className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
99
+ {...props}
100
+ />
101
+ )
102
+ }
103
+
104
+ function SelectItem({
105
+ className,
106
+ children,
107
+ ...props
108
+ }: React.ComponentProps<typeof SelectPrimitive.Item>) {
109
+ return (
110
+ <SelectPrimitive.Item
111
+ data-slot="select-item"
112
+ className={cn(
113
+ "relative flex w-full 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 not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
114
+ className
115
+ )}
116
+ {...props}
117
+ >
118
+ <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
119
+ <SelectPrimitive.ItemIndicator>
120
+ <CheckIcon className="pointer-events-none" />
121
+ </SelectPrimitive.ItemIndicator>
122
+ </span>
123
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
124
+ </SelectPrimitive.Item>
125
+ )
126
+ }
127
+
128
+ function SelectSeparator({
129
+ className,
130
+ ...props
131
+ }: React.ComponentProps<typeof SelectPrimitive.Separator>) {
132
+ return (
133
+ <SelectPrimitive.Separator
134
+ data-slot="select-separator"
135
+ className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
136
+ {...props}
137
+ />
138
+ )
139
+ }
140
+
141
+ function SelectScrollUpButton({
142
+ className,
143
+ ...props
144
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
145
+ return (
146
+ <SelectPrimitive.ScrollUpButton
147
+ data-slot="select-scroll-up-button"
148
+ className={cn(
149
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
150
+ className
151
+ )}
152
+ {...props}
153
+ >
154
+ <ChevronUpIcon
155
+ />
156
+ </SelectPrimitive.ScrollUpButton>
157
+ )
158
+ }
159
+
160
+ function SelectScrollDownButton({
161
+ className,
162
+ ...props
163
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
164
+ return (
165
+ <SelectPrimitive.ScrollDownButton
166
+ data-slot="select-scroll-down-button"
167
+ className={cn(
168
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
169
+ className
170
+ )}
171
+ {...props}
172
+ >
173
+ <ChevronDownIcon
174
+ />
175
+ </SelectPrimitive.ScrollDownButton>
176
+ )
177
+ }
178
+
179
+ export {
180
+ Select,
181
+ SelectContent,
182
+ SelectGroup,
183
+ SelectItem,
184
+ SelectLabel,
185
+ SelectScrollDownButton,
186
+ SelectScrollUpButton,
187
+ SelectSeparator,
188
+ SelectTrigger,
189
+ SelectValue,
190
+ }
@@ -0,0 +1,28 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Separator as SeparatorPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/cn"
7
+
8
+ function Separator({
9
+ className,
10
+ orientation = "horizontal",
11
+ decorative = true,
12
+ ...props
13
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
14
+ return (
15
+ <SeparatorPrimitive.Root
16
+ data-slot="separator"
17
+ decorative={decorative}
18
+ orientation={orientation}
19
+ className={cn(
20
+ "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
21
+ className
22
+ )}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ export { Separator }
@@ -0,0 +1,145 @@
1
+ import * as React from "react"
2
+ import { Dialog as SheetPrimitive } from "radix-ui"
3
+
4
+ import { cn } from "@/lib/cn"
5
+ import { Button } from "@/primitives/button"
6
+ import { XIcon } from "lucide-react"
7
+
8
+ function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
9
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />
10
+ }
11
+
12
+ function SheetTrigger({
13
+ ...props
14
+ }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
15
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
16
+ }
17
+
18
+ function SheetClose({
19
+ ...props
20
+ }: React.ComponentProps<typeof SheetPrimitive.Close>) {
21
+ return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
22
+ }
23
+
24
+ function SheetPortal({
25
+ ...props
26
+ }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
27
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
28
+ }
29
+
30
+ function SheetOverlay({
31
+ className,
32
+ ...props
33
+ }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
34
+ return (
35
+ <SheetPrimitive.Overlay
36
+ data-slot="sheet-overlay"
37
+ className={cn(
38
+ "fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
39
+ className
40
+ )}
41
+ {...props}
42
+ />
43
+ )
44
+ }
45
+
46
+ function SheetContent({
47
+ className,
48
+ children,
49
+ side = "right",
50
+ showCloseButton = true,
51
+ ...props
52
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
53
+ side?: "top" | "right" | "bottom" | "left"
54
+ showCloseButton?: boolean
55
+ }) {
56
+ return (
57
+ <SheetPortal>
58
+ <SheetOverlay />
59
+ <SheetPrimitive.Content
60
+ data-slot="sheet-content"
61
+ data-side={side}
62
+ className={cn(
63
+ "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10",
64
+ className
65
+ )}
66
+ {...props}
67
+ >
68
+ {children}
69
+ {showCloseButton && (
70
+ <SheetPrimitive.Close data-slot="sheet-close" asChild>
71
+ <Button
72
+ variant="ghost"
73
+ className="absolute top-3 right-3"
74
+ size="icon-sm"
75
+ >
76
+ <XIcon
77
+ />
78
+ <span className="sr-only">Close</span>
79
+ </Button>
80
+ </SheetPrimitive.Close>
81
+ )}
82
+ </SheetPrimitive.Content>
83
+ </SheetPortal>
84
+ )
85
+ }
86
+
87
+ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
88
+ return (
89
+ <div
90
+ data-slot="sheet-header"
91
+ className={cn("flex flex-col gap-0.5 p-4", className)}
92
+ {...props}
93
+ />
94
+ )
95
+ }
96
+
97
+ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
98
+ return (
99
+ <div
100
+ data-slot="sheet-footer"
101
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
102
+ {...props}
103
+ />
104
+ )
105
+ }
106
+
107
+ function SheetTitle({
108
+ className,
109
+ ...props
110
+ }: React.ComponentProps<typeof SheetPrimitive.Title>) {
111
+ return (
112
+ <SheetPrimitive.Title
113
+ data-slot="sheet-title"
114
+ className={cn(
115
+ "font-heading text-base font-medium text-foreground",
116
+ className
117
+ )}
118
+ {...props}
119
+ />
120
+ )
121
+ }
122
+
123
+ function SheetDescription({
124
+ className,
125
+ ...props
126
+ }: React.ComponentProps<typeof SheetPrimitive.Description>) {
127
+ return (
128
+ <SheetPrimitive.Description
129
+ data-slot="sheet-description"
130
+ className={cn("text-sm text-muted-foreground", className)}
131
+ {...props}
132
+ />
133
+ )
134
+ }
135
+
136
+ export {
137
+ Sheet,
138
+ SheetTrigger,
139
+ SheetClose,
140
+ SheetContent,
141
+ SheetHeader,
142
+ SheetFooter,
143
+ SheetTitle,
144
+ SheetDescription,
145
+ }
@@ -0,0 +1,13 @@
1
+ import { cn } from "@/lib/cn"
2
+
3
+ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
+ return (
5
+ <div
6
+ data-slot="skeleton"
7
+ className={cn("animate-pulse rounded-md bg-muted", className)}
8
+ {...props}
9
+ />
10
+ )
11
+ }
12
+
13
+ export { Skeleton }
@@ -0,0 +1,49 @@
1
+ "use client"
2
+
3
+ import { useTheme } from "next-themes"
4
+ import { Toaster as Sonner, type ToasterProps } from "sonner"
5
+ import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react"
6
+
7
+ const Toaster = ({ ...props }: ToasterProps) => {
8
+ const { theme = "system" } = useTheme()
9
+
10
+ return (
11
+ <Sonner
12
+ theme={theme as ToasterProps["theme"]}
13
+ className="toaster group"
14
+ icons={{
15
+ success: (
16
+ <CircleCheckIcon className="size-4" />
17
+ ),
18
+ info: (
19
+ <InfoIcon className="size-4" />
20
+ ),
21
+ warning: (
22
+ <TriangleAlertIcon className="size-4" />
23
+ ),
24
+ error: (
25
+ <OctagonXIcon className="size-4" />
26
+ ),
27
+ loading: (
28
+ <Loader2Icon className="size-4 animate-spin" />
29
+ ),
30
+ }}
31
+ style={
32
+ {
33
+ "--normal-bg": "var(--popover)",
34
+ "--normal-text": "var(--popover-foreground)",
35
+ "--normal-border": "var(--border)",
36
+ "--border-radius": "var(--radius)",
37
+ } as React.CSSProperties
38
+ }
39
+ toastOptions={{
40
+ classNames: {
41
+ toast: "cn-toast",
42
+ },
43
+ }}
44
+ {...props}
45
+ />
46
+ )
47
+ }
48
+
49
+ export { Toaster }
@@ -0,0 +1,114 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/cn"
4
+
5
+ function Table({ className, ...props }: React.ComponentProps<"table">) {
6
+ return (
7
+ <div
8
+ data-slot="table-container"
9
+ className="relative w-full overflow-x-auto"
10
+ >
11
+ <table
12
+ data-slot="table"
13
+ className={cn("w-full caption-bottom text-sm", className)}
14
+ {...props}
15
+ />
16
+ </div>
17
+ )
18
+ }
19
+
20
+ function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
21
+ return (
22
+ <thead
23
+ data-slot="table-header"
24
+ className={cn("[&_tr]:border-b", className)}
25
+ {...props}
26
+ />
27
+ )
28
+ }
29
+
30
+ function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
31
+ return (
32
+ <tbody
33
+ data-slot="table-body"
34
+ className={cn("[&_tr:last-child]:border-0", className)}
35
+ {...props}
36
+ />
37
+ )
38
+ }
39
+
40
+ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
41
+ return (
42
+ <tfoot
43
+ data-slot="table-footer"
44
+ className={cn(
45
+ "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
46
+ className
47
+ )}
48
+ {...props}
49
+ />
50
+ )
51
+ }
52
+
53
+ function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
54
+ return (
55
+ <tr
56
+ data-slot="table-row"
57
+ className={cn(
58
+ "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
59
+ className
60
+ )}
61
+ {...props}
62
+ />
63
+ )
64
+ }
65
+
66
+ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
67
+ return (
68
+ <th
69
+ data-slot="table-head"
70
+ className={cn(
71
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
72
+ className
73
+ )}
74
+ {...props}
75
+ />
76
+ )
77
+ }
78
+
79
+ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
80
+ return (
81
+ <td
82
+ data-slot="table-cell"
83
+ className={cn(
84
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
85
+ className
86
+ )}
87
+ {...props}
88
+ />
89
+ )
90
+ }
91
+
92
+ function TableCaption({
93
+ className,
94
+ ...props
95
+ }: React.ComponentProps<"caption">) {
96
+ return (
97
+ <caption
98
+ data-slot="table-caption"
99
+ className={cn("mt-4 text-sm text-muted-foreground", className)}
100
+ {...props}
101
+ />
102
+ )
103
+ }
104
+
105
+ export {
106
+ Table,
107
+ TableHeader,
108
+ TableBody,
109
+ TableFooter,
110
+ TableHead,
111
+ TableRow,
112
+ TableCell,
113
+ TableCaption,
114
+ }
@@ -0,0 +1,88 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { Tabs as TabsPrimitive } from "radix-ui"
4
+
5
+ import { cn } from "@/lib/cn"
6
+
7
+ function Tabs({
8
+ className,
9
+ orientation = "horizontal",
10
+ ...props
11
+ }: React.ComponentProps<typeof TabsPrimitive.Root>) {
12
+ return (
13
+ <TabsPrimitive.Root
14
+ data-slot="tabs"
15
+ data-orientation={orientation}
16
+ className={cn(
17
+ "group/tabs flex gap-2 data-horizontal:flex-col",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ const tabsListVariants = cva(
26
+ "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
27
+ {
28
+ variants: {
29
+ variant: {
30
+ default: "bg-muted",
31
+ line: "gap-1 bg-transparent",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: "default",
36
+ },
37
+ }
38
+ )
39
+
40
+ function TabsList({
41
+ className,
42
+ variant = "default",
43
+ ...props
44
+ }: React.ComponentProps<typeof TabsPrimitive.List> &
45
+ VariantProps<typeof tabsListVariants>) {
46
+ return (
47
+ <TabsPrimitive.List
48
+ data-slot="tabs-list"
49
+ data-variant={variant}
50
+ className={cn(tabsListVariants({ variant }), className)}
51
+ {...props}
52
+ />
53
+ )
54
+ }
55
+
56
+ function TabsTrigger({
57
+ className,
58
+ ...props
59
+ }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
60
+ return (
61
+ <TabsPrimitive.Trigger
62
+ data-slot="tabs-trigger"
63
+ className={cn(
64
+ "relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
65
+ "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
66
+ "data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
67
+ "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
68
+ className
69
+ )}
70
+ {...props}
71
+ />
72
+ )
73
+ }
74
+
75
+ function TabsContent({
76
+ className,
77
+ ...props
78
+ }: React.ComponentProps<typeof TabsPrimitive.Content>) {
79
+ return (
80
+ <TabsPrimitive.Content
81
+ data-slot="tabs-content"
82
+ className={cn("flex-1 text-sm outline-none", className)}
83
+ {...props}
84
+ />
85
+ )
86
+ }
87
+
88
+ export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
@@ -0,0 +1,18 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/cn"
4
+
5
+ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6
+ return (
7
+ <textarea
8
+ data-slot="textarea"
9
+ className={cn(
10
+ "flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ export { Textarea }