@beemafrica/ui 0.1.14 → 0.1.15
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.
- package/package.json +3 -1
- package/src/components/calendar.tsx +222 -0
- package/src/components/dropdown-menu.tsx +268 -0
- package/src/components/popover.tsx +88 -0
- package/src/components/scroll-area.tsx +54 -0
- package/src/components/select.tsx +191 -0
- package/src/components/skeleton.tsx +13 -0
- package/src/components/tooltip.tsx +56 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beemafrica/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "Shared Beem UI components built on shadcn/Radix",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -24,9 +24,11 @@
|
|
|
24
24
|
"clsx": "^2.1.1",
|
|
25
25
|
"cmdk": "^1.1.1",
|
|
26
26
|
"cn": "^0.2.6",
|
|
27
|
+
"date-fns": "^4.4.0",
|
|
27
28
|
"lucide-react": "^1.31.0",
|
|
28
29
|
"next-themes": "^0.4.6",
|
|
29
30
|
"radix-ui": "^1.6.7",
|
|
31
|
+
"react-day-picker": "^10.0.1",
|
|
30
32
|
"recharts": "^3.8.0",
|
|
31
33
|
"shadcn": "^4.16.2",
|
|
32
34
|
"tailwind-merge": "^3.6.0",
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "cn"
|
|
5
|
+
import {
|
|
6
|
+
DayPicker,
|
|
7
|
+
getDefaultClassNames,
|
|
8
|
+
type DayButton,
|
|
9
|
+
type Locale,
|
|
10
|
+
} from "react-day-picker"
|
|
11
|
+
|
|
12
|
+
import { Button, buttonVariants } from "@beemafrica/ui/components/button"
|
|
13
|
+
import { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from "lucide-react"
|
|
14
|
+
|
|
15
|
+
function Calendar({
|
|
16
|
+
className,
|
|
17
|
+
classNames,
|
|
18
|
+
showOutsideDays = true,
|
|
19
|
+
captionLayout = "label",
|
|
20
|
+
buttonVariant = "ghost",
|
|
21
|
+
locale,
|
|
22
|
+
formatters,
|
|
23
|
+
components,
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<typeof DayPicker> & {
|
|
26
|
+
buttonVariant?: React.ComponentProps<typeof Button>["variant"]
|
|
27
|
+
}) {
|
|
28
|
+
const defaultClassNames = getDefaultClassNames()
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<DayPicker
|
|
32
|
+
showOutsideDays={showOutsideDays}
|
|
33
|
+
className={cn(
|
|
34
|
+
"group/calendar bg-background p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent",
|
|
35
|
+
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
36
|
+
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
37
|
+
className
|
|
38
|
+
)}
|
|
39
|
+
captionLayout={captionLayout}
|
|
40
|
+
locale={locale}
|
|
41
|
+
formatters={{
|
|
42
|
+
formatMonthDropdown: (date) =>
|
|
43
|
+
date.toLocaleString(locale?.code, { month: "short" }),
|
|
44
|
+
...formatters,
|
|
45
|
+
}}
|
|
46
|
+
classNames={{
|
|
47
|
+
root: cn("w-fit", defaultClassNames.root),
|
|
48
|
+
months: cn(
|
|
49
|
+
"relative flex flex-col gap-4 md:flex-row",
|
|
50
|
+
defaultClassNames.months
|
|
51
|
+
),
|
|
52
|
+
month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
|
|
53
|
+
nav: cn(
|
|
54
|
+
"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
|
|
55
|
+
defaultClassNames.nav
|
|
56
|
+
),
|
|
57
|
+
button_previous: cn(
|
|
58
|
+
buttonVariants({ variant: buttonVariant }),
|
|
59
|
+
"size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
|
|
60
|
+
defaultClassNames.button_previous
|
|
61
|
+
),
|
|
62
|
+
button_next: cn(
|
|
63
|
+
buttonVariants({ variant: buttonVariant }),
|
|
64
|
+
"size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
|
|
65
|
+
defaultClassNames.button_next
|
|
66
|
+
),
|
|
67
|
+
month_caption: cn(
|
|
68
|
+
"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
|
|
69
|
+
defaultClassNames.month_caption
|
|
70
|
+
),
|
|
71
|
+
dropdowns: cn(
|
|
72
|
+
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
|
|
73
|
+
defaultClassNames.dropdowns
|
|
74
|
+
),
|
|
75
|
+
dropdown_root: cn(
|
|
76
|
+
"relative rounded-(--cell-radius)",
|
|
77
|
+
defaultClassNames.dropdown_root
|
|
78
|
+
),
|
|
79
|
+
dropdown: cn(
|
|
80
|
+
"absolute inset-0 bg-popover opacity-0",
|
|
81
|
+
defaultClassNames.dropdown
|
|
82
|
+
),
|
|
83
|
+
caption_label: cn(
|
|
84
|
+
"font-medium select-none",
|
|
85
|
+
captionLayout === "label"
|
|
86
|
+
? "text-sm"
|
|
87
|
+
: "flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
|
|
88
|
+
defaultClassNames.caption_label
|
|
89
|
+
),
|
|
90
|
+
month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
|
|
91
|
+
weekdays: cn("flex", defaultClassNames.weekdays),
|
|
92
|
+
weekday: cn(
|
|
93
|
+
"flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none",
|
|
94
|
+
defaultClassNames.weekday
|
|
95
|
+
),
|
|
96
|
+
week: cn("mt-2 flex w-full", defaultClassNames.week),
|
|
97
|
+
week_number_header: cn(
|
|
98
|
+
"w-(--cell-size) select-none",
|
|
99
|
+
defaultClassNames.week_number_header
|
|
100
|
+
),
|
|
101
|
+
week_number: cn(
|
|
102
|
+
"text-[0.8rem] text-muted-foreground select-none",
|
|
103
|
+
defaultClassNames.week_number
|
|
104
|
+
),
|
|
105
|
+
day: cn(
|
|
106
|
+
"group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-e-(--cell-radius)",
|
|
107
|
+
props.showWeekNumber
|
|
108
|
+
? "[&:nth-child(2)[data-selected=true]_button]:rounded-s-(--cell-radius)"
|
|
109
|
+
: "[&:first-child[data-selected=true]_button]:rounded-s-(--cell-radius)",
|
|
110
|
+
defaultClassNames.day
|
|
111
|
+
),
|
|
112
|
+
range_start: cn(
|
|
113
|
+
"relative isolate z-0 rounded-s-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:end-0 after:w-4 after:bg-muted",
|
|
114
|
+
defaultClassNames.range_start
|
|
115
|
+
),
|
|
116
|
+
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
|
117
|
+
range_end: cn(
|
|
118
|
+
"relative isolate z-0 rounded-e-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:start-0 after:w-4 after:bg-muted",
|
|
119
|
+
defaultClassNames.range_end
|
|
120
|
+
),
|
|
121
|
+
today: cn(
|
|
122
|
+
"rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none",
|
|
123
|
+
defaultClassNames.today
|
|
124
|
+
),
|
|
125
|
+
outside: cn(
|
|
126
|
+
"text-muted-foreground aria-selected:text-muted-foreground",
|
|
127
|
+
defaultClassNames.outside
|
|
128
|
+
),
|
|
129
|
+
disabled: cn(
|
|
130
|
+
"text-muted-foreground opacity-50",
|
|
131
|
+
defaultClassNames.disabled
|
|
132
|
+
),
|
|
133
|
+
hidden: cn("invisible", defaultClassNames.hidden),
|
|
134
|
+
...classNames,
|
|
135
|
+
}}
|
|
136
|
+
components={{
|
|
137
|
+
Root: ({ className, rootRef, ...props }) => {
|
|
138
|
+
return (
|
|
139
|
+
<div
|
|
140
|
+
data-slot="calendar"
|
|
141
|
+
ref={rootRef}
|
|
142
|
+
className={cn(className)}
|
|
143
|
+
{...props}
|
|
144
|
+
/>
|
|
145
|
+
)
|
|
146
|
+
},
|
|
147
|
+
Chevron: ({ className, orientation, ...props }) => {
|
|
148
|
+
if (orientation === "left") {
|
|
149
|
+
return (
|
|
150
|
+
<ChevronLeftIcon className={cn("rtl:rotate-180 size-4", className)} {...props} />
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (orientation === "right") {
|
|
155
|
+
return (
|
|
156
|
+
<ChevronRightIcon className={cn("rtl:rotate-180 size-4", className)} {...props} />
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<ChevronDownIcon className={cn("size-4", className)} {...props} />
|
|
162
|
+
)
|
|
163
|
+
},
|
|
164
|
+
DayButton: ({ ...props }) => (
|
|
165
|
+
<CalendarDayButton locale={locale} {...props} />
|
|
166
|
+
),
|
|
167
|
+
WeekNumber: ({ children, ...props }) => {
|
|
168
|
+
return (
|
|
169
|
+
<td {...props}>
|
|
170
|
+
<div className="flex size-(--cell-size) items-center justify-center text-center">
|
|
171
|
+
{children}
|
|
172
|
+
</div>
|
|
173
|
+
</td>
|
|
174
|
+
)
|
|
175
|
+
},
|
|
176
|
+
...components,
|
|
177
|
+
}}
|
|
178
|
+
{...props}
|
|
179
|
+
/>
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function CalendarDayButton({
|
|
184
|
+
className,
|
|
185
|
+
day,
|
|
186
|
+
modifiers,
|
|
187
|
+
locale,
|
|
188
|
+
...props
|
|
189
|
+
}: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {
|
|
190
|
+
const defaultClassNames = getDefaultClassNames()
|
|
191
|
+
|
|
192
|
+
const ref = React.useRef<HTMLButtonElement>(null)
|
|
193
|
+
React.useEffect(() => {
|
|
194
|
+
if (modifiers.focused) ref.current?.focus()
|
|
195
|
+
}, [modifiers.focused])
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<Button
|
|
199
|
+
ref={ref}
|
|
200
|
+
variant="ghost"
|
|
201
|
+
size="icon"
|
|
202
|
+
data-day={day.date.toLocaleDateString(locale?.code)}
|
|
203
|
+
data-selected-single={
|
|
204
|
+
modifiers.selected &&
|
|
205
|
+
!modifiers.range_start &&
|
|
206
|
+
!modifiers.range_end &&
|
|
207
|
+
!modifiers.range_middle
|
|
208
|
+
}
|
|
209
|
+
data-range-start={modifiers.range_start}
|
|
210
|
+
data-range-end={modifiers.range_end}
|
|
211
|
+
data-range-middle={modifiers.range_middle}
|
|
212
|
+
className={cn(
|
|
213
|
+
"relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-e-(--cell-radius) data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-s-(--cell-radius) data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70",
|
|
214
|
+
defaultClassNames.day,
|
|
215
|
+
className
|
|
216
|
+
)}
|
|
217
|
+
{...props}
|
|
218
|
+
/>
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export { Calendar, CalendarDayButton }
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "cn"
|
|
5
|
+
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui"
|
|
6
|
+
import { CheckIcon, ChevronRightIcon } from "lucide-react"
|
|
7
|
+
|
|
8
|
+
function DropdownMenu({
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
|
11
|
+
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function DropdownMenuPortal({
|
|
15
|
+
...props
|
|
16
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
|
|
17
|
+
return (
|
|
18
|
+
<DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function DropdownMenuTrigger({
|
|
23
|
+
...props
|
|
24
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
|
|
25
|
+
return (
|
|
26
|
+
<DropdownMenuPrimitive.Trigger
|
|
27
|
+
data-slot="dropdown-menu-trigger"
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function DropdownMenuContent({
|
|
34
|
+
className,
|
|
35
|
+
align = "start",
|
|
36
|
+
sideOffset = 4,
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
|
39
|
+
return (
|
|
40
|
+
<DropdownMenuPrimitive.Portal>
|
|
41
|
+
<DropdownMenuPrimitive.Content
|
|
42
|
+
data-slot="dropdown-menu-content"
|
|
43
|
+
sideOffset={sideOffset}
|
|
44
|
+
align={align}
|
|
45
|
+
className={cn("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 )}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
</DropdownMenuPrimitive.Portal>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function DropdownMenuGroup({
|
|
53
|
+
...props
|
|
54
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
|
|
55
|
+
return (
|
|
56
|
+
<DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function DropdownMenuItem({
|
|
61
|
+
className,
|
|
62
|
+
inset,
|
|
63
|
+
variant = "default",
|
|
64
|
+
...props
|
|
65
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
|
66
|
+
inset?: boolean
|
|
67
|
+
variant?: "default" | "destructive"
|
|
68
|
+
}) {
|
|
69
|
+
return (
|
|
70
|
+
<DropdownMenuPrimitive.Item
|
|
71
|
+
data-slot="dropdown-menu-item"
|
|
72
|
+
data-inset={inset}
|
|
73
|
+
data-variant={variant}
|
|
74
|
+
className={cn(
|
|
75
|
+
"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:ps-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",
|
|
76
|
+
className
|
|
77
|
+
)}
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function DropdownMenuCheckboxItem({
|
|
84
|
+
className,
|
|
85
|
+
children,
|
|
86
|
+
checked,
|
|
87
|
+
inset,
|
|
88
|
+
...props
|
|
89
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
|
|
90
|
+
inset?: boolean
|
|
91
|
+
}) {
|
|
92
|
+
return (
|
|
93
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
94
|
+
data-slot="dropdown-menu-checkbox-item"
|
|
95
|
+
data-inset={inset}
|
|
96
|
+
className={cn(
|
|
97
|
+
"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pe-8 ps-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:ps-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
98
|
+
className
|
|
99
|
+
)}
|
|
100
|
+
checked={checked}
|
|
101
|
+
{...props}
|
|
102
|
+
>
|
|
103
|
+
<span
|
|
104
|
+
className="pointer-events-none absolute end-2 flex items-center justify-center"
|
|
105
|
+
data-slot="dropdown-menu-checkbox-item-indicator"
|
|
106
|
+
>
|
|
107
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
108
|
+
<CheckIcon
|
|
109
|
+
/>
|
|
110
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
111
|
+
</span>
|
|
112
|
+
{children}
|
|
113
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function DropdownMenuRadioGroup({
|
|
118
|
+
...props
|
|
119
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
|
|
120
|
+
return (
|
|
121
|
+
<DropdownMenuPrimitive.RadioGroup
|
|
122
|
+
data-slot="dropdown-menu-radio-group"
|
|
123
|
+
{...props}
|
|
124
|
+
/>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function DropdownMenuRadioItem({
|
|
129
|
+
className,
|
|
130
|
+
children,
|
|
131
|
+
inset,
|
|
132
|
+
...props
|
|
133
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
|
|
134
|
+
inset?: boolean
|
|
135
|
+
}) {
|
|
136
|
+
return (
|
|
137
|
+
<DropdownMenuPrimitive.RadioItem
|
|
138
|
+
data-slot="dropdown-menu-radio-item"
|
|
139
|
+
data-inset={inset}
|
|
140
|
+
className={cn(
|
|
141
|
+
"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pe-8 ps-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:ps-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
142
|
+
className
|
|
143
|
+
)}
|
|
144
|
+
{...props}
|
|
145
|
+
>
|
|
146
|
+
<span
|
|
147
|
+
className="pointer-events-none absolute end-2 flex items-center justify-center"
|
|
148
|
+
data-slot="dropdown-menu-radio-item-indicator"
|
|
149
|
+
>
|
|
150
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
151
|
+
<CheckIcon
|
|
152
|
+
/>
|
|
153
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
154
|
+
</span>
|
|
155
|
+
{children}
|
|
156
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function DropdownMenuLabel({
|
|
161
|
+
className,
|
|
162
|
+
inset,
|
|
163
|
+
...props
|
|
164
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
|
|
165
|
+
inset?: boolean
|
|
166
|
+
}) {
|
|
167
|
+
return (
|
|
168
|
+
<DropdownMenuPrimitive.Label
|
|
169
|
+
data-slot="dropdown-menu-label"
|
|
170
|
+
data-inset={inset}
|
|
171
|
+
className={cn(
|
|
172
|
+
"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:ps-7",
|
|
173
|
+
className
|
|
174
|
+
)}
|
|
175
|
+
{...props}
|
|
176
|
+
/>
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function DropdownMenuSeparator({
|
|
181
|
+
className,
|
|
182
|
+
...props
|
|
183
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
|
184
|
+
return (
|
|
185
|
+
<DropdownMenuPrimitive.Separator
|
|
186
|
+
data-slot="dropdown-menu-separator"
|
|
187
|
+
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
|
188
|
+
{...props}
|
|
189
|
+
/>
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function DropdownMenuShortcut({
|
|
194
|
+
className,
|
|
195
|
+
...props
|
|
196
|
+
}: React.ComponentProps<"span">) {
|
|
197
|
+
return (
|
|
198
|
+
<span
|
|
199
|
+
data-slot="dropdown-menu-shortcut"
|
|
200
|
+
className={cn(
|
|
201
|
+
"ms-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
|
|
202
|
+
className
|
|
203
|
+
)}
|
|
204
|
+
{...props}
|
|
205
|
+
/>
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function DropdownMenuSub({
|
|
210
|
+
...props
|
|
211
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
|
|
212
|
+
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function DropdownMenuSubTrigger({
|
|
216
|
+
className,
|
|
217
|
+
inset,
|
|
218
|
+
children,
|
|
219
|
+
...props
|
|
220
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
221
|
+
inset?: boolean
|
|
222
|
+
}) {
|
|
223
|
+
return (
|
|
224
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
225
|
+
data-slot="dropdown-menu-sub-trigger"
|
|
226
|
+
data-inset={inset}
|
|
227
|
+
className={cn(
|
|
228
|
+
"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:ps-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
229
|
+
className
|
|
230
|
+
)}
|
|
231
|
+
{...props}
|
|
232
|
+
>
|
|
233
|
+
{children}
|
|
234
|
+
<ChevronRightIcon className="rtl:rotate-180 ms-auto" />
|
|
235
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function DropdownMenuSubContent({
|
|
240
|
+
className,
|
|
241
|
+
...props
|
|
242
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
|
|
243
|
+
return (
|
|
244
|
+
<DropdownMenuPrimitive.SubContent
|
|
245
|
+
data-slot="dropdown-menu-sub-content"
|
|
246
|
+
className={cn("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 )}
|
|
247
|
+
{...props}
|
|
248
|
+
/>
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export {
|
|
253
|
+
DropdownMenu,
|
|
254
|
+
DropdownMenuPortal,
|
|
255
|
+
DropdownMenuTrigger,
|
|
256
|
+
DropdownMenuContent,
|
|
257
|
+
DropdownMenuGroup,
|
|
258
|
+
DropdownMenuLabel,
|
|
259
|
+
DropdownMenuItem,
|
|
260
|
+
DropdownMenuCheckboxItem,
|
|
261
|
+
DropdownMenuRadioGroup,
|
|
262
|
+
DropdownMenuRadioItem,
|
|
263
|
+
DropdownMenuSeparator,
|
|
264
|
+
DropdownMenuShortcut,
|
|
265
|
+
DropdownMenuSub,
|
|
266
|
+
DropdownMenuSubTrigger,
|
|
267
|
+
DropdownMenuSubContent,
|
|
268
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "cn"
|
|
5
|
+
import { Popover as PopoverPrimitive } from "radix-ui"
|
|
6
|
+
|
|
7
|
+
function Popover({
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
|
10
|
+
return <PopoverPrimitive.Root data-slot="popover" {...props} />
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function PopoverTrigger({
|
|
14
|
+
...props
|
|
15
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
16
|
+
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function PopoverContent({
|
|
20
|
+
className,
|
|
21
|
+
align = "center",
|
|
22
|
+
sideOffset = 4,
|
|
23
|
+
...props
|
|
24
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
|
25
|
+
return (
|
|
26
|
+
<PopoverPrimitive.Portal>
|
|
27
|
+
<PopoverPrimitive.Content
|
|
28
|
+
data-slot="popover-content"
|
|
29
|
+
align={align}
|
|
30
|
+
sideOffset={sideOffset}
|
|
31
|
+
className={cn(
|
|
32
|
+
"z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden 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",
|
|
33
|
+
className
|
|
34
|
+
)}
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
</PopoverPrimitive.Portal>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function PopoverAnchor({
|
|
42
|
+
...props
|
|
43
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
|
|
44
|
+
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function PopoverHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
48
|
+
return (
|
|
49
|
+
<div
|
|
50
|
+
data-slot="popover-header"
|
|
51
|
+
className={cn("flex flex-col gap-0.5 text-sm", className)}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function PopoverTitle({ className, ...props }: React.ComponentProps<"h2">) {
|
|
58
|
+
return (
|
|
59
|
+
<div
|
|
60
|
+
data-slot="popover-title"
|
|
61
|
+
className={cn("font-medium", className)}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function PopoverDescription({
|
|
68
|
+
className,
|
|
69
|
+
...props
|
|
70
|
+
}: React.ComponentProps<"p">) {
|
|
71
|
+
return (
|
|
72
|
+
<p
|
|
73
|
+
data-slot="popover-description"
|
|
74
|
+
className={cn("text-muted-foreground", className)}
|
|
75
|
+
{...props}
|
|
76
|
+
/>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export {
|
|
81
|
+
Popover,
|
|
82
|
+
PopoverAnchor,
|
|
83
|
+
PopoverContent,
|
|
84
|
+
PopoverDescription,
|
|
85
|
+
PopoverHeader,
|
|
86
|
+
PopoverTitle,
|
|
87
|
+
PopoverTrigger,
|
|
88
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "cn"
|
|
5
|
+
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui"
|
|
6
|
+
|
|
7
|
+
function ScrollArea({
|
|
8
|
+
className,
|
|
9
|
+
children,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<ScrollAreaPrimitive.Root
|
|
14
|
+
data-slot="scroll-area"
|
|
15
|
+
className={cn("relative", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<ScrollAreaPrimitive.Viewport
|
|
19
|
+
data-slot="scroll-area-viewport"
|
|
20
|
+
className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</ScrollAreaPrimitive.Viewport>
|
|
24
|
+
<ScrollBar />
|
|
25
|
+
<ScrollAreaPrimitive.Corner />
|
|
26
|
+
</ScrollAreaPrimitive.Root>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function ScrollBar({
|
|
31
|
+
className,
|
|
32
|
+
orientation = "vertical",
|
|
33
|
+
...props
|
|
34
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
|
35
|
+
return (
|
|
36
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
37
|
+
data-slot="scroll-area-scrollbar"
|
|
38
|
+
data-orientation={orientation}
|
|
39
|
+
orientation={orientation}
|
|
40
|
+
className={cn(
|
|
41
|
+
"flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-s data-vertical:border-s-transparent",
|
|
42
|
+
className
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
<ScrollAreaPrimitive.ScrollAreaThumb
|
|
47
|
+
data-slot="scroll-area-thumb"
|
|
48
|
+
className="relative flex-1 rounded-full bg-border"
|
|
49
|
+
/>
|
|
50
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { ScrollArea, ScrollBar }
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "cn"
|
|
5
|
+
import { Select as SelectPrimitive } from "radix-ui"
|
|
6
|
+
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
|
|
7
|
+
|
|
8
|
+
function Select({
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
|
11
|
+
return <SelectPrimitive.Root data-slot="select" {...props} />
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function SelectGroup({
|
|
15
|
+
className,
|
|
16
|
+
...props
|
|
17
|
+
}: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
|
18
|
+
return (
|
|
19
|
+
<SelectPrimitive.Group
|
|
20
|
+
data-slot="select-group"
|
|
21
|
+
className={cn("scroll-my-1 p-1", className)}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function SelectValue({
|
|
28
|
+
...props
|
|
29
|
+
}: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
|
30
|
+
return <SelectPrimitive.Value data-slot="select-value" {...props} />
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function SelectTrigger({
|
|
34
|
+
className,
|
|
35
|
+
size = "default",
|
|
36
|
+
children,
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
|
39
|
+
size?: "sm" | "default"
|
|
40
|
+
}) {
|
|
41
|
+
return (
|
|
42
|
+
<SelectPrimitive.Trigger
|
|
43
|
+
data-slot="select-trigger"
|
|
44
|
+
data-size={size}
|
|
45
|
+
className={cn(
|
|
46
|
+
"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pe-2 ps-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",
|
|
47
|
+
className
|
|
48
|
+
)}
|
|
49
|
+
{...props}
|
|
50
|
+
>
|
|
51
|
+
{children}
|
|
52
|
+
<SelectPrimitive.Icon asChild>
|
|
53
|
+
<ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
|
|
54
|
+
</SelectPrimitive.Icon>
|
|
55
|
+
</SelectPrimitive.Trigger>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function SelectContent({
|
|
60
|
+
className,
|
|
61
|
+
children,
|
|
62
|
+
position = "item-aligned",
|
|
63
|
+
align = "center",
|
|
64
|
+
...props
|
|
65
|
+
}: React.ComponentProps<typeof SelectPrimitive.Content>) {
|
|
66
|
+
return (
|
|
67
|
+
<SelectPrimitive.Portal>
|
|
68
|
+
<SelectPrimitive.Content
|
|
69
|
+
data-slot="select-content"
|
|
70
|
+
data-align-trigger={position === "item-aligned"}
|
|
71
|
+
className={cn("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 rtl:data-[side=left]:translate-x-1 data-[side=right]:translate-x-1 rtl:data-[side=right]:-translate-x-1 data-[side=top]:-translate-y-1", className )}
|
|
72
|
+
position={position}
|
|
73
|
+
align={align}
|
|
74
|
+
{...props}
|
|
75
|
+
>
|
|
76
|
+
<SelectScrollUpButton />
|
|
77
|
+
<SelectPrimitive.Viewport
|
|
78
|
+
data-position={position}
|
|
79
|
+
className={cn(
|
|
80
|
+
"data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
|
|
81
|
+
position === "popper" && ""
|
|
82
|
+
)}
|
|
83
|
+
>
|
|
84
|
+
{children}
|
|
85
|
+
</SelectPrimitive.Viewport>
|
|
86
|
+
<SelectScrollDownButton />
|
|
87
|
+
</SelectPrimitive.Content>
|
|
88
|
+
</SelectPrimitive.Portal>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function SelectLabel({
|
|
93
|
+
className,
|
|
94
|
+
...props
|
|
95
|
+
}: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
|
96
|
+
return (
|
|
97
|
+
<SelectPrimitive.Label
|
|
98
|
+
data-slot="select-label"
|
|
99
|
+
className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function SelectItem({
|
|
106
|
+
className,
|
|
107
|
+
children,
|
|
108
|
+
...props
|
|
109
|
+
}: React.ComponentProps<typeof SelectPrimitive.Item>) {
|
|
110
|
+
return (
|
|
111
|
+
<SelectPrimitive.Item
|
|
112
|
+
data-slot="select-item"
|
|
113
|
+
className={cn(
|
|
114
|
+
"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pe-8 ps-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",
|
|
115
|
+
className
|
|
116
|
+
)}
|
|
117
|
+
{...props}
|
|
118
|
+
>
|
|
119
|
+
<span className="pointer-events-none absolute end-2 flex size-4 items-center justify-center">
|
|
120
|
+
<SelectPrimitive.ItemIndicator>
|
|
121
|
+
<CheckIcon className="pointer-events-none" />
|
|
122
|
+
</SelectPrimitive.ItemIndicator>
|
|
123
|
+
</span>
|
|
124
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
125
|
+
</SelectPrimitive.Item>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function SelectSeparator({
|
|
130
|
+
className,
|
|
131
|
+
...props
|
|
132
|
+
}: React.ComponentProps<typeof SelectPrimitive.Separator>) {
|
|
133
|
+
return (
|
|
134
|
+
<SelectPrimitive.Separator
|
|
135
|
+
data-slot="select-separator"
|
|
136
|
+
className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
|
|
137
|
+
{...props}
|
|
138
|
+
/>
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function SelectScrollUpButton({
|
|
143
|
+
className,
|
|
144
|
+
...props
|
|
145
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
|
|
146
|
+
return (
|
|
147
|
+
<SelectPrimitive.ScrollUpButton
|
|
148
|
+
data-slot="select-scroll-up-button"
|
|
149
|
+
className={cn(
|
|
150
|
+
"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
151
|
+
className
|
|
152
|
+
)}
|
|
153
|
+
{...props}
|
|
154
|
+
>
|
|
155
|
+
<ChevronUpIcon
|
|
156
|
+
/>
|
|
157
|
+
</SelectPrimitive.ScrollUpButton>
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function SelectScrollDownButton({
|
|
162
|
+
className,
|
|
163
|
+
...props
|
|
164
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
|
|
165
|
+
return (
|
|
166
|
+
<SelectPrimitive.ScrollDownButton
|
|
167
|
+
data-slot="select-scroll-down-button"
|
|
168
|
+
className={cn(
|
|
169
|
+
"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
170
|
+
className
|
|
171
|
+
)}
|
|
172
|
+
{...props}
|
|
173
|
+
>
|
|
174
|
+
<ChevronDownIcon
|
|
175
|
+
/>
|
|
176
|
+
</SelectPrimitive.ScrollDownButton>
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export {
|
|
181
|
+
Select,
|
|
182
|
+
SelectContent,
|
|
183
|
+
SelectGroup,
|
|
184
|
+
SelectItem,
|
|
185
|
+
SelectLabel,
|
|
186
|
+
SelectScrollDownButton,
|
|
187
|
+
SelectScrollUpButton,
|
|
188
|
+
SelectSeparator,
|
|
189
|
+
SelectTrigger,
|
|
190
|
+
SelectValue,
|
|
191
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { cn } from "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,56 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "cn"
|
|
5
|
+
import { Tooltip as TooltipPrimitive } from "radix-ui"
|
|
6
|
+
|
|
7
|
+
function TooltipProvider({
|
|
8
|
+
delayDuration = 0,
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
|
11
|
+
return (
|
|
12
|
+
<TooltipPrimitive.Provider
|
|
13
|
+
data-slot="tooltip-provider"
|
|
14
|
+
delayDuration={delayDuration}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function Tooltip({
|
|
21
|
+
...props
|
|
22
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
|
23
|
+
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function TooltipTrigger({
|
|
27
|
+
...props
|
|
28
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
|
29
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function TooltipContent({
|
|
33
|
+
className,
|
|
34
|
+
sideOffset = 0,
|
|
35
|
+
children,
|
|
36
|
+
...props
|
|
37
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
|
|
38
|
+
return (
|
|
39
|
+
<TooltipPrimitive.Portal>
|
|
40
|
+
<TooltipPrimitive.Content
|
|
41
|
+
data-slot="tooltip-content"
|
|
42
|
+
sideOffset={sideOffset}
|
|
43
|
+
className={cn(
|
|
44
|
+
"z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 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-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 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",
|
|
45
|
+
className
|
|
46
|
+
)}
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
{children}
|
|
50
|
+
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
|
|
51
|
+
</TooltipPrimitive.Content>
|
|
52
|
+
</TooltipPrimitive.Portal>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }
|