@oppulence/design-system 1.0.2

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 (80) hide show
  1. package/README.md +115 -0
  2. package/components.json +21 -0
  3. package/hooks/use-mobile.tsx +21 -0
  4. package/lib/utils.ts +6 -0
  5. package/package.json +104 -0
  6. package/postcss.config.mjs +8 -0
  7. package/src/components/atoms/aspect-ratio.tsx +21 -0
  8. package/src/components/atoms/avatar.tsx +91 -0
  9. package/src/components/atoms/badge.tsx +47 -0
  10. package/src/components/atoms/button.tsx +128 -0
  11. package/src/components/atoms/checkbox.tsx +24 -0
  12. package/src/components/atoms/container.tsx +42 -0
  13. package/src/components/atoms/heading.tsx +56 -0
  14. package/src/components/atoms/index.ts +21 -0
  15. package/src/components/atoms/input.tsx +18 -0
  16. package/src/components/atoms/kbd.tsx +23 -0
  17. package/src/components/atoms/label.tsx +15 -0
  18. package/src/components/atoms/logo.tsx +52 -0
  19. package/src/components/atoms/progress.tsx +79 -0
  20. package/src/components/atoms/separator.tsx +17 -0
  21. package/src/components/atoms/skeleton.tsx +13 -0
  22. package/src/components/atoms/slider.tsx +56 -0
  23. package/src/components/atoms/spinner.tsx +14 -0
  24. package/src/components/atoms/stack.tsx +126 -0
  25. package/src/components/atoms/switch.tsx +26 -0
  26. package/src/components/atoms/text.tsx +69 -0
  27. package/src/components/atoms/textarea.tsx +19 -0
  28. package/src/components/atoms/toggle.tsx +40 -0
  29. package/src/components/molecules/accordion.tsx +72 -0
  30. package/src/components/molecules/ai-chat.tsx +251 -0
  31. package/src/components/molecules/alert.tsx +131 -0
  32. package/src/components/molecules/breadcrumb.tsx +301 -0
  33. package/src/components/molecules/button-group.tsx +96 -0
  34. package/src/components/molecules/card.tsx +184 -0
  35. package/src/components/molecules/collapsible.tsx +21 -0
  36. package/src/components/molecules/command-search.tsx +148 -0
  37. package/src/components/molecules/empty.tsx +98 -0
  38. package/src/components/molecules/field.tsx +217 -0
  39. package/src/components/molecules/grid.tsx +141 -0
  40. package/src/components/molecules/hover-card.tsx +45 -0
  41. package/src/components/molecules/index.ts +29 -0
  42. package/src/components/molecules/input-group.tsx +151 -0
  43. package/src/components/molecules/input-otp.tsx +74 -0
  44. package/src/components/molecules/item.tsx +194 -0
  45. package/src/components/molecules/page-header.tsx +89 -0
  46. package/src/components/molecules/pagination.tsx +130 -0
  47. package/src/components/molecules/popover.tsx +96 -0
  48. package/src/components/molecules/radio-group.tsx +37 -0
  49. package/src/components/molecules/resizable.tsx +52 -0
  50. package/src/components/molecules/scroll-area.tsx +45 -0
  51. package/src/components/molecules/section.tsx +108 -0
  52. package/src/components/molecules/select.tsx +201 -0
  53. package/src/components/molecules/settings.tsx +197 -0
  54. package/src/components/molecules/table.tsx +111 -0
  55. package/src/components/molecules/tabs.tsx +74 -0
  56. package/src/components/molecules/theme-switcher.tsx +187 -0
  57. package/src/components/molecules/toggle-group.tsx +89 -0
  58. package/src/components/molecules/tooltip.tsx +66 -0
  59. package/src/components/organisms/alert-dialog.tsx +152 -0
  60. package/src/components/organisms/app-shell.tsx +939 -0
  61. package/src/components/organisms/calendar.tsx +212 -0
  62. package/src/components/organisms/carousel.tsx +230 -0
  63. package/src/components/organisms/chart.tsx +333 -0
  64. package/src/components/organisms/combobox.tsx +274 -0
  65. package/src/components/organisms/command.tsx +200 -0
  66. package/src/components/organisms/context-menu.tsx +229 -0
  67. package/src/components/organisms/dialog.tsx +134 -0
  68. package/src/components/organisms/drawer.tsx +123 -0
  69. package/src/components/organisms/dropdown-menu.tsx +256 -0
  70. package/src/components/organisms/index.ts +17 -0
  71. package/src/components/organisms/menubar.tsx +203 -0
  72. package/src/components/organisms/navigation-menu.tsx +143 -0
  73. package/src/components/organisms/page-layout.tsx +105 -0
  74. package/src/components/organisms/sheet.tsx +126 -0
  75. package/src/components/organisms/sidebar.tsx +723 -0
  76. package/src/components/organisms/sonner.tsx +41 -0
  77. package/src/components/ui/index.ts +3 -0
  78. package/src/index.ts +3 -0
  79. package/src/styles/globals.css +297 -0
  80. package/tailwind.config.ts +77 -0
@@ -0,0 +1,96 @@
1
+ import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
2
+ import * as React from "react";
3
+
4
+ import { cn } from "../../../lib/utils";
5
+
6
+ function Popover({ ...props }: PopoverPrimitive.Root.Props) {
7
+ return <PopoverPrimitive.Root data-slot="popover" {...props} />;
8
+ }
9
+
10
+ function PopoverTrigger({
11
+ className,
12
+ ...props
13
+ }: PopoverPrimitive.Trigger.Props) {
14
+ return (
15
+ <PopoverPrimitive.Trigger
16
+ data-slot="popover-trigger"
17
+ className={cn(className)}
18
+ {...props}
19
+ />
20
+ );
21
+ }
22
+
23
+ function PopoverContent({
24
+ align = "center",
25
+ alignOffset = 0,
26
+ side = "bottom",
27
+ sideOffset = 4,
28
+ ...props
29
+ }: Omit<PopoverPrimitive.Popup.Props, "className"> &
30
+ Pick<
31
+ PopoverPrimitive.Positioner.Props,
32
+ "align" | "alignOffset" | "side" | "sideOffset"
33
+ >) {
34
+ return (
35
+ <PopoverPrimitive.Portal>
36
+ <PopoverPrimitive.Positioner
37
+ align={align}
38
+ alignOffset={alignOffset}
39
+ side={side}
40
+ sideOffset={sideOffset}
41
+ className="isolate z-50"
42
+ >
43
+ <PopoverPrimitive.Popup
44
+ data-slot="popover-content"
45
+ className="bg-popover text-popover-foreground 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 flex flex-col gap-2.5 rounded-lg p-2.5 text-sm shadow-md ring-1 duration-100 z-50 w-72 origin-(--transform-origin) outline-hidden"
46
+ {...props}
47
+ />
48
+ </PopoverPrimitive.Positioner>
49
+ </PopoverPrimitive.Portal>
50
+ );
51
+ }
52
+
53
+ function PopoverHeader({
54
+ ...props
55
+ }: Omit<React.ComponentProps<"div">, "className">) {
56
+ return (
57
+ <div
58
+ data-slot="popover-header"
59
+ className="flex flex-col gap-0.5 text-sm"
60
+ {...props}
61
+ />
62
+ );
63
+ }
64
+
65
+ function PopoverTitle({
66
+ ...props
67
+ }: Omit<PopoverPrimitive.Title.Props, "className">) {
68
+ return (
69
+ <PopoverPrimitive.Title
70
+ data-slot="popover-title"
71
+ className="font-medium"
72
+ {...props}
73
+ />
74
+ );
75
+ }
76
+
77
+ function PopoverDescription({
78
+ ...props
79
+ }: Omit<PopoverPrimitive.Description.Props, "className">) {
80
+ return (
81
+ <PopoverPrimitive.Description
82
+ data-slot="popover-description"
83
+ className="text-muted-foreground"
84
+ {...props}
85
+ />
86
+ );
87
+ }
88
+
89
+ export {
90
+ Popover,
91
+ PopoverContent,
92
+ PopoverDescription,
93
+ PopoverHeader,
94
+ PopoverTitle,
95
+ PopoverTrigger,
96
+ };
@@ -0,0 +1,37 @@
1
+ import { Radio as RadioPrimitive } from "@base-ui/react/radio";
2
+ import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group";
3
+
4
+ import { CircleIcon } from "lucide-react";
5
+
6
+ function RadioGroup({
7
+ ...props
8
+ }: Omit<RadioGroupPrimitive.Props, "className">) {
9
+ return (
10
+ <RadioGroupPrimitive
11
+ data-slot="radio-group"
12
+ className="grid gap-2 w-full"
13
+ {...props}
14
+ />
15
+ );
16
+ }
17
+
18
+ function RadioGroupItem({
19
+ ...props
20
+ }: Omit<RadioPrimitive.Root.Props, "className">) {
21
+ return (
22
+ <RadioPrimitive.Root
23
+ data-slot="radio-group-item"
24
+ className="border-input text-primary dark:bg-input/30 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 flex size-4 rounded-full shadow-xs focus-visible:ring-[3px] aria-invalid:ring-[3px] group/radio-group-item peer relative aspect-square shrink-0 border outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50"
25
+ {...props}
26
+ >
27
+ <RadioPrimitive.Indicator
28
+ data-slot="radio-group-indicator"
29
+ className="group-aria-invalid/radio-group-item:text-destructive text-primary flex size-4 items-center justify-center"
30
+ >
31
+ <CircleIcon className="absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 fill-current" />
32
+ </RadioPrimitive.Indicator>
33
+ </RadioPrimitive.Root>
34
+ );
35
+ }
36
+
37
+ export { RadioGroup, RadioGroupItem };
@@ -0,0 +1,52 @@
1
+ "use client";
2
+
3
+ import * as ResizablePrimitive from "react-resizable-panels";
4
+
5
+ type ResizablePanelGroupProps = Omit<
6
+ ResizablePrimitive.GroupProps,
7
+ "className"
8
+ >;
9
+
10
+ function ResizablePanelGroup({
11
+ orientation = "horizontal",
12
+ ...props
13
+ }: ResizablePanelGroupProps) {
14
+ return (
15
+ <ResizablePrimitive.Group
16
+ data-slot="resizable-panel-group"
17
+ data-orientation={orientation}
18
+ orientation={orientation}
19
+ className="flex h-full w-full data-[orientation=vertical]:flex-col"
20
+ {...props}
21
+ />
22
+ );
23
+ }
24
+
25
+ type ResizablePanelProps = Omit<ResizablePrimitive.PanelProps, "className">;
26
+
27
+ function ResizablePanel({ ...props }: ResizablePanelProps) {
28
+ return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
29
+ }
30
+
31
+ type ResizableHandleProps = Omit<
32
+ ResizablePrimitive.SeparatorProps,
33
+ "className"
34
+ > & {
35
+ withHandle?: boolean;
36
+ };
37
+
38
+ function ResizableHandle({ withHandle, ...props }: ResizableHandleProps) {
39
+ return (
40
+ <ResizablePrimitive.Separator
41
+ data-slot="resizable-handle"
42
+ className="bg-border hover:bg-muted-foreground/20 focus-visible:ring-ring relative flex w-px items-center justify-center transition-colors after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]>div]:rotate-90"
43
+ {...props}
44
+ >
45
+ {withHandle && (
46
+ <div className="bg-border z-10 flex h-4 w-1 shrink-0 rounded-full" />
47
+ )}
48
+ </ResizablePrimitive.Separator>
49
+ );
50
+ }
51
+
52
+ export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
@@ -0,0 +1,45 @@
1
+ import { ScrollArea as ScrollAreaPrimitive } from "@base-ui/react/scroll-area";
2
+
3
+ function ScrollArea({
4
+ children,
5
+ ...props
6
+ }: Omit<ScrollAreaPrimitive.Root.Props, "className">) {
7
+ return (
8
+ <ScrollAreaPrimitive.Root
9
+ data-slot="scroll-area"
10
+ className="relative overflow-hidden size-full"
11
+ {...props}
12
+ >
13
+ <ScrollAreaPrimitive.Viewport
14
+ data-slot="scroll-area-viewport"
15
+ className="focus-visible:ring-ring/50 size-full overflow-auto rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
16
+ >
17
+ {children}
18
+ </ScrollAreaPrimitive.Viewport>
19
+ <ScrollBar />
20
+ <ScrollAreaPrimitive.Corner />
21
+ </ScrollAreaPrimitive.Root>
22
+ );
23
+ }
24
+
25
+ function ScrollBar({
26
+ orientation = "vertical",
27
+ ...props
28
+ }: Omit<ScrollAreaPrimitive.Scrollbar.Props, "className">) {
29
+ return (
30
+ <ScrollAreaPrimitive.Scrollbar
31
+ data-slot="scroll-area-scrollbar"
32
+ data-orientation={orientation}
33
+ orientation={orientation}
34
+ className="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-l data-vertical:border-l-transparent flex touch-none p-px transition-colors select-none"
35
+ {...props}
36
+ >
37
+ <ScrollAreaPrimitive.Thumb
38
+ data-slot="scroll-area-thumb"
39
+ className="rounded-full bg-border relative flex-1"
40
+ />
41
+ </ScrollAreaPrimitive.Scrollbar>
42
+ );
43
+ }
44
+
45
+ export { ScrollArea, ScrollBar };
@@ -0,0 +1,108 @@
1
+ import * as React from "react";
2
+
3
+ import { Heading } from "../atoms/heading";
4
+ import { Text } from "../atoms/text";
5
+ import { Stack } from "../atoms/stack";
6
+
7
+ interface SectionProps extends Omit<
8
+ React.ComponentProps<"section">,
9
+ "className"
10
+ > {
11
+ title?: string;
12
+ description?: string;
13
+ actions?: React.ReactNode;
14
+ /** Gap between header and content. Default is "4" */
15
+ gap?: "2" | "3" | "4" | "6" | "8";
16
+ }
17
+
18
+ function Section({
19
+ title,
20
+ description,
21
+ actions,
22
+ gap = "4",
23
+ children,
24
+ ...props
25
+ }: SectionProps) {
26
+ const hasHeader = title || description || actions;
27
+
28
+ return (
29
+ <section data-slot="section" className="w-full" {...props}>
30
+ <Stack gap={gap}>
31
+ {hasHeader && (
32
+ <div className="flex items-start justify-between gap-4">
33
+ <Stack gap="1">
34
+ {title && <Heading level="3">{title}</Heading>}
35
+ {description && (
36
+ <Text size="sm" variant="muted">
37
+ {description}
38
+ </Text>
39
+ )}
40
+ </Stack>
41
+ {actions && (
42
+ <div className="flex shrink-0 items-center gap-2">{actions}</div>
43
+ )}
44
+ </div>
45
+ )}
46
+ {children}
47
+ </Stack>
48
+ </section>
49
+ );
50
+ }
51
+
52
+ function SectionHeader({
53
+ ...props
54
+ }: Omit<React.ComponentProps<"div">, "className">) {
55
+ return (
56
+ <div
57
+ data-slot="section-header"
58
+ className="flex items-start justify-between gap-4"
59
+ {...props}
60
+ />
61
+ );
62
+ }
63
+
64
+ function SectionTitle({
65
+ ...props
66
+ }: Omit<React.ComponentProps<typeof Heading>, "className">) {
67
+ return <Heading data-slot="section-title" level="3" {...props} />;
68
+ }
69
+
70
+ function SectionDescription({
71
+ ...props
72
+ }: Omit<React.ComponentProps<typeof Text>, "className">) {
73
+ return (
74
+ <Text
75
+ data-slot="section-description"
76
+ size="sm"
77
+ variant="muted"
78
+ {...props}
79
+ />
80
+ );
81
+ }
82
+
83
+ function SectionActions({
84
+ ...props
85
+ }: Omit<React.ComponentProps<"div">, "className">) {
86
+ return (
87
+ <div
88
+ data-slot="section-actions"
89
+ className="flex shrink-0 items-center gap-2"
90
+ {...props}
91
+ />
92
+ );
93
+ }
94
+
95
+ function SectionContent({
96
+ ...props
97
+ }: Omit<React.ComponentProps<"div">, "className">) {
98
+ return <div data-slot="section-content" className="w-full" {...props} />;
99
+ }
100
+
101
+ export {
102
+ Section,
103
+ SectionActions,
104
+ SectionContent,
105
+ SectionDescription,
106
+ SectionHeader,
107
+ SectionTitle,
108
+ };
@@ -0,0 +1,201 @@
1
+ "use client";
2
+
3
+ import { Select as SelectPrimitive } from "@base-ui/react/select";
4
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
5
+ import * as React from "react";
6
+
7
+ const Select = SelectPrimitive.Root;
8
+
9
+ function SelectGroup({
10
+ ...props
11
+ }: Omit<SelectPrimitive.Group.Props, "className">) {
12
+ return (
13
+ <SelectPrimitive.Group
14
+ data-slot="select-group"
15
+ className="scroll-my-1 p-1"
16
+ {...props}
17
+ />
18
+ );
19
+ }
20
+
21
+ function SelectValue({
22
+ placeholder,
23
+ ...props
24
+ }: Omit<SelectPrimitive.Value.Props, "className"> & {
25
+ /** Text to show when no value is selected */
26
+ placeholder?: string;
27
+ }) {
28
+ return (
29
+ <>
30
+ <SelectPrimitive.Value
31
+ data-slot="select-value"
32
+ className="flex-1 text-left data-[placeholder]:hidden"
33
+ {...props}
34
+ />
35
+ {placeholder && (
36
+ <span
37
+ data-slot="select-placeholder"
38
+ className="text-muted-foreground [[data-slot=select-value]:not([data-placeholder])~&]:hidden"
39
+ >
40
+ {placeholder}
41
+ </span>
42
+ )}
43
+ </>
44
+ );
45
+ }
46
+
47
+ function SelectTrigger({
48
+ size = "default",
49
+ children,
50
+ ...props
51
+ }: Omit<SelectPrimitive.Trigger.Props, "className"> & {
52
+ size?: "sm" | "default";
53
+ }) {
54
+ return (
55
+ <SelectPrimitive.Trigger
56
+ data-slot="select-trigger"
57
+ data-size={size}
58
+ className="border-input data-[placeholder]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 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 gap-1.5 rounded-lg border bg-transparent py-2 pr-2 pl-2.5 text-sm transition-colors select-none focus-visible:ring-[3px] aria-invalid:ring-[3px] data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:flex *:data-[slot=select-value]:data-[placeholder]:absolute *:data-[slot=select-value]:data-[placeholder]:w-0 *:data-[slot=select-value]:data-[placeholder]:overflow-hidden *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4 flex w-full items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0"
59
+ {...props}
60
+ >
61
+ {children}
62
+ <SelectPrimitive.Icon
63
+ render={
64
+ <ChevronDownIcon className="text-muted-foreground size-4 pointer-events-none" />
65
+ }
66
+ />
67
+ </SelectPrimitive.Trigger>
68
+ );
69
+ }
70
+
71
+ function SelectContent({
72
+ children,
73
+ side = "bottom",
74
+ sideOffset = 4,
75
+ align = "center",
76
+ alignOffset = 0,
77
+ alignItemWithTrigger = true,
78
+ ...props
79
+ }: Omit<SelectPrimitive.Popup.Props, "className"> &
80
+ Pick<
81
+ SelectPrimitive.Positioner.Props,
82
+ "align" | "alignOffset" | "side" | "sideOffset" | "alignItemWithTrigger"
83
+ >) {
84
+ return (
85
+ <SelectPrimitive.Portal>
86
+ <SelectPrimitive.Positioner
87
+ side={side}
88
+ sideOffset={sideOffset}
89
+ align={align}
90
+ alignOffset={alignOffset}
91
+ alignItemWithTrigger={alignItemWithTrigger}
92
+ className="isolate z-50"
93
+ >
94
+ <SelectPrimitive.Popup
95
+ data-slot="select-content"
96
+ className="bg-popover text-popover-foreground 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 min-w-(--anchor-width) max-w-80 rounded-lg p-1 shadow-md ring-1 duration-100 relative isolate z-50 max-h-(--available-height) origin-(--transform-origin) overflow-x-hidden overflow-y-auto"
97
+ {...props}
98
+ >
99
+ <SelectScrollUpButton />
100
+ <SelectPrimitive.List>{children}</SelectPrimitive.List>
101
+ <SelectScrollDownButton />
102
+ </SelectPrimitive.Popup>
103
+ </SelectPrimitive.Positioner>
104
+ </SelectPrimitive.Portal>
105
+ );
106
+ }
107
+
108
+ function SelectLabel({
109
+ ...props
110
+ }: Omit<SelectPrimitive.GroupLabel.Props, "className">) {
111
+ return (
112
+ <SelectPrimitive.GroupLabel
113
+ data-slot="select-label"
114
+ className="text-muted-foreground px-1.5 py-1 text-xs"
115
+ {...props}
116
+ />
117
+ );
118
+ }
119
+
120
+ function SelectItem({
121
+ children,
122
+ ...props
123
+ }: Omit<SelectPrimitive.Item.Props, "className">) {
124
+ return (
125
+ <SelectPrimitive.Item
126
+ data-slot="select-item"
127
+ className="focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0"
128
+ {...props}
129
+ >
130
+ <SelectPrimitive.ItemText className="flex flex-1 gap-2 shrink-0 whitespace-nowrap">
131
+ {children}
132
+ </SelectPrimitive.ItemText>
133
+ <SelectPrimitive.ItemIndicator
134
+ render={
135
+ <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />
136
+ }
137
+ >
138
+ <CheckIcon className="pointer-events-none" />
139
+ </SelectPrimitive.ItemIndicator>
140
+ </SelectPrimitive.Item>
141
+ );
142
+ }
143
+
144
+ function SelectSeparator({
145
+ ...props
146
+ }: Omit<SelectPrimitive.Separator.Props, "className">) {
147
+ return (
148
+ <SelectPrimitive.Separator
149
+ data-slot="select-separator"
150
+ className="bg-border -mx-1 my-1 h-px pointer-events-none"
151
+ {...props}
152
+ />
153
+ );
154
+ }
155
+
156
+ function SelectScrollUpButton({
157
+ ...props
158
+ }: Omit<
159
+ React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>,
160
+ "className"
161
+ >) {
162
+ return (
163
+ <SelectPrimitive.ScrollUpArrow
164
+ data-slot="select-scroll-up-button"
165
+ className="bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4 top-0 w-full"
166
+ {...props}
167
+ >
168
+ <ChevronUpIcon />
169
+ </SelectPrimitive.ScrollUpArrow>
170
+ );
171
+ }
172
+
173
+ function SelectScrollDownButton({
174
+ ...props
175
+ }: Omit<
176
+ React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>,
177
+ "className"
178
+ >) {
179
+ return (
180
+ <SelectPrimitive.ScrollDownArrow
181
+ data-slot="select-scroll-down-button"
182
+ className="bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4 bottom-0 w-full"
183
+ {...props}
184
+ >
185
+ <ChevronDownIcon />
186
+ </SelectPrimitive.ScrollDownArrow>
187
+ );
188
+ }
189
+
190
+ export {
191
+ Select,
192
+ SelectContent,
193
+ SelectGroup,
194
+ SelectItem,
195
+ SelectLabel,
196
+ SelectScrollDownButton,
197
+ SelectScrollUpButton,
198
+ SelectSeparator,
199
+ SelectTrigger,
200
+ SelectValue,
201
+ };