@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.
- package/README.md +115 -0
- package/components.json +21 -0
- package/hooks/use-mobile.tsx +21 -0
- package/lib/utils.ts +6 -0
- package/package.json +104 -0
- package/postcss.config.mjs +8 -0
- package/src/components/atoms/aspect-ratio.tsx +21 -0
- package/src/components/atoms/avatar.tsx +91 -0
- package/src/components/atoms/badge.tsx +47 -0
- package/src/components/atoms/button.tsx +128 -0
- package/src/components/atoms/checkbox.tsx +24 -0
- package/src/components/atoms/container.tsx +42 -0
- package/src/components/atoms/heading.tsx +56 -0
- package/src/components/atoms/index.ts +21 -0
- package/src/components/atoms/input.tsx +18 -0
- package/src/components/atoms/kbd.tsx +23 -0
- package/src/components/atoms/label.tsx +15 -0
- package/src/components/atoms/logo.tsx +52 -0
- package/src/components/atoms/progress.tsx +79 -0
- package/src/components/atoms/separator.tsx +17 -0
- package/src/components/atoms/skeleton.tsx +13 -0
- package/src/components/atoms/slider.tsx +56 -0
- package/src/components/atoms/spinner.tsx +14 -0
- package/src/components/atoms/stack.tsx +126 -0
- package/src/components/atoms/switch.tsx +26 -0
- package/src/components/atoms/text.tsx +69 -0
- package/src/components/atoms/textarea.tsx +19 -0
- package/src/components/atoms/toggle.tsx +40 -0
- package/src/components/molecules/accordion.tsx +72 -0
- package/src/components/molecules/ai-chat.tsx +251 -0
- package/src/components/molecules/alert.tsx +131 -0
- package/src/components/molecules/breadcrumb.tsx +301 -0
- package/src/components/molecules/button-group.tsx +96 -0
- package/src/components/molecules/card.tsx +184 -0
- package/src/components/molecules/collapsible.tsx +21 -0
- package/src/components/molecules/command-search.tsx +148 -0
- package/src/components/molecules/empty.tsx +98 -0
- package/src/components/molecules/field.tsx +217 -0
- package/src/components/molecules/grid.tsx +141 -0
- package/src/components/molecules/hover-card.tsx +45 -0
- package/src/components/molecules/index.ts +29 -0
- package/src/components/molecules/input-group.tsx +151 -0
- package/src/components/molecules/input-otp.tsx +74 -0
- package/src/components/molecules/item.tsx +194 -0
- package/src/components/molecules/page-header.tsx +89 -0
- package/src/components/molecules/pagination.tsx +130 -0
- package/src/components/molecules/popover.tsx +96 -0
- package/src/components/molecules/radio-group.tsx +37 -0
- package/src/components/molecules/resizable.tsx +52 -0
- package/src/components/molecules/scroll-area.tsx +45 -0
- package/src/components/molecules/section.tsx +108 -0
- package/src/components/molecules/select.tsx +201 -0
- package/src/components/molecules/settings.tsx +197 -0
- package/src/components/molecules/table.tsx +111 -0
- package/src/components/molecules/tabs.tsx +74 -0
- package/src/components/molecules/theme-switcher.tsx +187 -0
- package/src/components/molecules/toggle-group.tsx +89 -0
- package/src/components/molecules/tooltip.tsx +66 -0
- package/src/components/organisms/alert-dialog.tsx +152 -0
- package/src/components/organisms/app-shell.tsx +939 -0
- package/src/components/organisms/calendar.tsx +212 -0
- package/src/components/organisms/carousel.tsx +230 -0
- package/src/components/organisms/chart.tsx +333 -0
- package/src/components/organisms/combobox.tsx +274 -0
- package/src/components/organisms/command.tsx +200 -0
- package/src/components/organisms/context-menu.tsx +229 -0
- package/src/components/organisms/dialog.tsx +134 -0
- package/src/components/organisms/drawer.tsx +123 -0
- package/src/components/organisms/dropdown-menu.tsx +256 -0
- package/src/components/organisms/index.ts +17 -0
- package/src/components/organisms/menubar.tsx +203 -0
- package/src/components/organisms/navigation-menu.tsx +143 -0
- package/src/components/organisms/page-layout.tsx +105 -0
- package/src/components/organisms/sheet.tsx +126 -0
- package/src/components/organisms/sidebar.tsx +723 -0
- package/src/components/organisms/sonner.tsx +41 -0
- package/src/components/ui/index.ts +3 -0
- package/src/index.ts +3 -0
- package/src/styles/globals.css +297 -0
- package/tailwind.config.ts +77 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import { CheckIcon, ChevronRightIcon } from "lucide-react";
|
|
6
|
+
import { cn } from "../../../lib/utils";
|
|
7
|
+
|
|
8
|
+
function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {
|
|
9
|
+
return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
|
|
13
|
+
return <MenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const dropdownMenuTriggerVariants = cva("", {
|
|
17
|
+
variants: {
|
|
18
|
+
variant: {
|
|
19
|
+
default: "", // Uses render prop for custom trigger styling
|
|
20
|
+
menubar:
|
|
21
|
+
"hover:bg-muted aria-expanded:bg-muted rounded-sm px-2 py-1 text-sm font-medium flex items-center outline-hidden select-none",
|
|
22
|
+
ellipsis:
|
|
23
|
+
"size-5 [&>svg]:size-4 flex items-center justify-center cursor-pointer hover:text-foreground transition-colors rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
variant: "default",
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function DropdownMenuTrigger({
|
|
32
|
+
variant = "default",
|
|
33
|
+
className,
|
|
34
|
+
...props
|
|
35
|
+
}: MenuPrimitive.Trigger.Props &
|
|
36
|
+
VariantProps<typeof dropdownMenuTriggerVariants>) {
|
|
37
|
+
return (
|
|
38
|
+
<MenuPrimitive.Trigger
|
|
39
|
+
data-slot="dropdown-menu-trigger"
|
|
40
|
+
className={cn(dropdownMenuTriggerVariants({ variant }), className)}
|
|
41
|
+
{...props}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function DropdownMenuContent({
|
|
47
|
+
align = "start",
|
|
48
|
+
alignOffset = 0,
|
|
49
|
+
side = "bottom",
|
|
50
|
+
sideOffset = 4,
|
|
51
|
+
...props
|
|
52
|
+
}: Omit<MenuPrimitive.Popup.Props, "className"> &
|
|
53
|
+
Pick<
|
|
54
|
+
MenuPrimitive.Positioner.Props,
|
|
55
|
+
"align" | "alignOffset" | "side" | "sideOffset"
|
|
56
|
+
>) {
|
|
57
|
+
return (
|
|
58
|
+
<MenuPrimitive.Portal>
|
|
59
|
+
<MenuPrimitive.Positioner
|
|
60
|
+
className="isolate z-50 outline-none"
|
|
61
|
+
align={align}
|
|
62
|
+
alignOffset={alignOffset}
|
|
63
|
+
side={side}
|
|
64
|
+
sideOffset={sideOffset}
|
|
65
|
+
>
|
|
66
|
+
<MenuPrimitive.Popup
|
|
67
|
+
data-slot="dropdown-menu-content"
|
|
68
|
+
className="data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-lg p-1 shadow-md ring-1 duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden"
|
|
69
|
+
{...props}
|
|
70
|
+
/>
|
|
71
|
+
</MenuPrimitive.Positioner>
|
|
72
|
+
</MenuPrimitive.Portal>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {
|
|
77
|
+
return <MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function DropdownMenuLabel({
|
|
81
|
+
inset,
|
|
82
|
+
...props
|
|
83
|
+
}: Omit<MenuPrimitive.GroupLabel.Props, "className"> & {
|
|
84
|
+
inset?: boolean;
|
|
85
|
+
}) {
|
|
86
|
+
return (
|
|
87
|
+
<MenuPrimitive.GroupLabel
|
|
88
|
+
data-slot="dropdown-menu-label"
|
|
89
|
+
data-inset={inset}
|
|
90
|
+
className="text-muted-foreground px-1.5 py-1 text-xs font-medium data-[inset]:pl-8"
|
|
91
|
+
{...props}
|
|
92
|
+
/>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function DropdownMenuItem({
|
|
97
|
+
inset,
|
|
98
|
+
variant = "default",
|
|
99
|
+
...props
|
|
100
|
+
}: Omit<MenuPrimitive.Item.Props, "className"> & {
|
|
101
|
+
inset?: boolean;
|
|
102
|
+
variant?: "default" | "destructive";
|
|
103
|
+
}) {
|
|
104
|
+
return (
|
|
105
|
+
<MenuPrimitive.Item
|
|
106
|
+
data-slot="dropdown-menu-item"
|
|
107
|
+
data-inset={inset}
|
|
108
|
+
data-variant={variant}
|
|
109
|
+
className="focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
|
|
116
|
+
return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function DropdownMenuSubTrigger({
|
|
120
|
+
inset,
|
|
121
|
+
children,
|
|
122
|
+
...props
|
|
123
|
+
}: Omit<MenuPrimitive.SubmenuTrigger.Props, "className"> & {
|
|
124
|
+
inset?: boolean;
|
|
125
|
+
}) {
|
|
126
|
+
return (
|
|
127
|
+
<MenuPrimitive.SubmenuTrigger
|
|
128
|
+
data-slot="dropdown-menu-sub-trigger"
|
|
129
|
+
data-inset={inset}
|
|
130
|
+
className="focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm [&_svg:not([class*='size-'])]:size-4 flex cursor-default items-center outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
131
|
+
{...props}
|
|
132
|
+
>
|
|
133
|
+
{children}
|
|
134
|
+
<ChevronRightIcon className="ml-auto" />
|
|
135
|
+
</MenuPrimitive.SubmenuTrigger>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function DropdownMenuSubContent({
|
|
140
|
+
align = "start",
|
|
141
|
+
alignOffset = -3,
|
|
142
|
+
side = "right",
|
|
143
|
+
sideOffset = 0,
|
|
144
|
+
...props
|
|
145
|
+
}: React.ComponentProps<typeof DropdownMenuContent>) {
|
|
146
|
+
return (
|
|
147
|
+
<DropdownMenuContent
|
|
148
|
+
data-slot="dropdown-menu-sub-content"
|
|
149
|
+
align={align}
|
|
150
|
+
alignOffset={alignOffset}
|
|
151
|
+
side={side}
|
|
152
|
+
sideOffset={sideOffset}
|
|
153
|
+
{...props}
|
|
154
|
+
/>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function DropdownMenuCheckboxItem({
|
|
159
|
+
children,
|
|
160
|
+
checked,
|
|
161
|
+
...props
|
|
162
|
+
}: Omit<MenuPrimitive.CheckboxItem.Props, "className">) {
|
|
163
|
+
return (
|
|
164
|
+
<MenuPrimitive.CheckboxItem
|
|
165
|
+
data-slot="dropdown-menu-checkbox-item"
|
|
166
|
+
className="focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
167
|
+
checked={checked}
|
|
168
|
+
{...props}
|
|
169
|
+
>
|
|
170
|
+
<span
|
|
171
|
+
className="pointer-events-none absolute right-2 flex size-4 items-center justify-center"
|
|
172
|
+
data-slot="dropdown-menu-checkbox-item-indicator"
|
|
173
|
+
>
|
|
174
|
+
<MenuPrimitive.CheckboxItemIndicator>
|
|
175
|
+
<CheckIcon className="size-4" />
|
|
176
|
+
</MenuPrimitive.CheckboxItemIndicator>
|
|
177
|
+
</span>
|
|
178
|
+
{children}
|
|
179
|
+
</MenuPrimitive.CheckboxItem>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
|
|
184
|
+
return (
|
|
185
|
+
<MenuPrimitive.RadioGroup
|
|
186
|
+
data-slot="dropdown-menu-radio-group"
|
|
187
|
+
{...props}
|
|
188
|
+
/>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function DropdownMenuRadioItem({
|
|
193
|
+
children,
|
|
194
|
+
...props
|
|
195
|
+
}: Omit<MenuPrimitive.RadioItem.Props, "className">) {
|
|
196
|
+
return (
|
|
197
|
+
<MenuPrimitive.RadioItem
|
|
198
|
+
data-slot="dropdown-menu-radio-item"
|
|
199
|
+
className="focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
200
|
+
{...props}
|
|
201
|
+
>
|
|
202
|
+
<span
|
|
203
|
+
className="pointer-events-none absolute right-2 flex size-4 items-center justify-center"
|
|
204
|
+
data-slot="dropdown-menu-radio-item-indicator"
|
|
205
|
+
>
|
|
206
|
+
<MenuPrimitive.RadioItemIndicator>
|
|
207
|
+
<CheckIcon className="size-4" />
|
|
208
|
+
</MenuPrimitive.RadioItemIndicator>
|
|
209
|
+
</span>
|
|
210
|
+
{children}
|
|
211
|
+
</MenuPrimitive.RadioItem>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function DropdownMenuSeparator({
|
|
216
|
+
...props
|
|
217
|
+
}: Omit<MenuPrimitive.Separator.Props, "className">) {
|
|
218
|
+
return (
|
|
219
|
+
<MenuPrimitive.Separator
|
|
220
|
+
data-slot="dropdown-menu-separator"
|
|
221
|
+
className="bg-border -mx-1 my-1 h-px"
|
|
222
|
+
{...props}
|
|
223
|
+
/>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function DropdownMenuShortcut({
|
|
228
|
+
...props
|
|
229
|
+
}: Omit<React.ComponentProps<"span">, "className">) {
|
|
230
|
+
return (
|
|
231
|
+
<span
|
|
232
|
+
data-slot="dropdown-menu-shortcut"
|
|
233
|
+
className="text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ml-auto text-xs tracking-widest"
|
|
234
|
+
{...props}
|
|
235
|
+
/>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export {
|
|
240
|
+
DropdownMenu,
|
|
241
|
+
DropdownMenuCheckboxItem,
|
|
242
|
+
DropdownMenuContent,
|
|
243
|
+
DropdownMenuGroup,
|
|
244
|
+
DropdownMenuItem,
|
|
245
|
+
DropdownMenuLabel,
|
|
246
|
+
DropdownMenuPortal,
|
|
247
|
+
DropdownMenuRadioGroup,
|
|
248
|
+
DropdownMenuRadioItem,
|
|
249
|
+
DropdownMenuSeparator,
|
|
250
|
+
DropdownMenuShortcut,
|
|
251
|
+
DropdownMenuSub,
|
|
252
|
+
DropdownMenuSubContent,
|
|
253
|
+
DropdownMenuSubTrigger,
|
|
254
|
+
DropdownMenuTrigger,
|
|
255
|
+
dropdownMenuTriggerVariants,
|
|
256
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export * from "./alert-dialog";
|
|
2
|
+
export * from "./app-shell";
|
|
3
|
+
export * from "./calendar";
|
|
4
|
+
export * from "./carousel";
|
|
5
|
+
export * from "./chart";
|
|
6
|
+
export * from "./combobox";
|
|
7
|
+
export * from "./command";
|
|
8
|
+
export * from "./context-menu";
|
|
9
|
+
export * from "./dialog";
|
|
10
|
+
export * from "./drawer";
|
|
11
|
+
export * from "./dropdown-menu";
|
|
12
|
+
export * from "./menubar";
|
|
13
|
+
export * from "./navigation-menu";
|
|
14
|
+
export * from "./page-layout";
|
|
15
|
+
export * from "./sheet";
|
|
16
|
+
export * from "./sidebar";
|
|
17
|
+
export * from "./sonner";
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
2
|
+
import { Menubar as MenubarPrimitive } from "@base-ui/react/menubar";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import { CheckIcon } from "lucide-react";
|
|
6
|
+
import {
|
|
7
|
+
DropdownMenu,
|
|
8
|
+
DropdownMenuContent,
|
|
9
|
+
DropdownMenuGroup,
|
|
10
|
+
DropdownMenuItem,
|
|
11
|
+
DropdownMenuLabel,
|
|
12
|
+
DropdownMenuPortal,
|
|
13
|
+
DropdownMenuRadioGroup,
|
|
14
|
+
DropdownMenuSeparator,
|
|
15
|
+
DropdownMenuShortcut,
|
|
16
|
+
DropdownMenuSub,
|
|
17
|
+
DropdownMenuSubContent,
|
|
18
|
+
DropdownMenuSubTrigger,
|
|
19
|
+
DropdownMenuTrigger,
|
|
20
|
+
} from "./dropdown-menu";
|
|
21
|
+
|
|
22
|
+
function Menubar({ ...props }: Omit<MenubarPrimitive.Props, "className">) {
|
|
23
|
+
return (
|
|
24
|
+
<MenubarPrimitive
|
|
25
|
+
data-slot="menubar"
|
|
26
|
+
className="bg-background h-9 gap-1 rounded-md border p-1 shadow-xs flex items-center"
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function MenubarMenu({ ...props }: React.ComponentProps<typeof DropdownMenu>) {
|
|
33
|
+
return <DropdownMenu data-slot="menubar-menu" {...props} />;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function MenubarGroup({
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<typeof DropdownMenuGroup>) {
|
|
39
|
+
return <DropdownMenuGroup data-slot="menubar-group" {...props} />;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function MenubarPortal({
|
|
43
|
+
...props
|
|
44
|
+
}: React.ComponentProps<typeof DropdownMenuPortal>) {
|
|
45
|
+
return <DropdownMenuPortal data-slot="menubar-portal" {...props} />;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function MenubarTrigger({
|
|
49
|
+
...props
|
|
50
|
+
}: React.ComponentProps<typeof DropdownMenuTrigger>) {
|
|
51
|
+
return (
|
|
52
|
+
<DropdownMenuTrigger
|
|
53
|
+
data-slot="menubar-trigger"
|
|
54
|
+
variant="menubar"
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function MenubarContent({
|
|
61
|
+
align = "start",
|
|
62
|
+
alignOffset = -4,
|
|
63
|
+
sideOffset = 8,
|
|
64
|
+
...props
|
|
65
|
+
}: React.ComponentProps<typeof DropdownMenuContent>) {
|
|
66
|
+
return (
|
|
67
|
+
<DropdownMenuContent
|
|
68
|
+
data-slot="menubar-content"
|
|
69
|
+
align={align}
|
|
70
|
+
alignOffset={alignOffset}
|
|
71
|
+
sideOffset={sideOffset}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function MenubarItem({
|
|
78
|
+
inset,
|
|
79
|
+
variant = "default",
|
|
80
|
+
...props
|
|
81
|
+
}: React.ComponentProps<typeof DropdownMenuItem>) {
|
|
82
|
+
return (
|
|
83
|
+
<DropdownMenuItem
|
|
84
|
+
data-slot="menubar-item"
|
|
85
|
+
inset={inset}
|
|
86
|
+
variant={variant}
|
|
87
|
+
{...props}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function MenubarCheckboxItem({
|
|
93
|
+
children,
|
|
94
|
+
checked,
|
|
95
|
+
...props
|
|
96
|
+
}: Omit<MenuPrimitive.CheckboxItem.Props, "className">) {
|
|
97
|
+
return (
|
|
98
|
+
<MenuPrimitive.CheckboxItem
|
|
99
|
+
data-slot="menubar-checkbox-item"
|
|
100
|
+
className="focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-md py-1.5 pr-2 pl-8 text-sm data-disabled:opacity-50 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
101
|
+
checked={checked}
|
|
102
|
+
{...props}
|
|
103
|
+
>
|
|
104
|
+
<span className="left-2 size-4 [&_svg:not([class*='size-'])]:size-4 pointer-events-none absolute flex items-center justify-center">
|
|
105
|
+
<MenuPrimitive.CheckboxItemIndicator>
|
|
106
|
+
<CheckIcon />
|
|
107
|
+
</MenuPrimitive.CheckboxItemIndicator>
|
|
108
|
+
</span>
|
|
109
|
+
{children}
|
|
110
|
+
</MenuPrimitive.CheckboxItem>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function MenubarRadioGroup({
|
|
115
|
+
...props
|
|
116
|
+
}: React.ComponentProps<typeof DropdownMenuRadioGroup>) {
|
|
117
|
+
return <DropdownMenuRadioGroup data-slot="menubar-radio-group" {...props} />;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function MenubarRadioItem({
|
|
121
|
+
children,
|
|
122
|
+
...props
|
|
123
|
+
}: Omit<MenuPrimitive.RadioItem.Props, "className">) {
|
|
124
|
+
return (
|
|
125
|
+
<MenuPrimitive.RadioItem
|
|
126
|
+
data-slot="menubar-radio-item"
|
|
127
|
+
className="focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-md py-1.5 pr-2 pl-8 text-sm data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
128
|
+
{...props}
|
|
129
|
+
>
|
|
130
|
+
<span className="left-2 size-4 [&_svg:not([class*='size-'])]:size-4 pointer-events-none absolute flex items-center justify-center">
|
|
131
|
+
<MenuPrimitive.RadioItemIndicator>
|
|
132
|
+
<CheckIcon />
|
|
133
|
+
</MenuPrimitive.RadioItemIndicator>
|
|
134
|
+
</span>
|
|
135
|
+
{children}
|
|
136
|
+
</MenuPrimitive.RadioItem>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function MenubarLabel({
|
|
141
|
+
inset,
|
|
142
|
+
...props
|
|
143
|
+
}: React.ComponentProps<typeof DropdownMenuLabel>) {
|
|
144
|
+
return (
|
|
145
|
+
<DropdownMenuLabel data-slot="menubar-label" inset={inset} {...props} />
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function MenubarSeparator({
|
|
150
|
+
...props
|
|
151
|
+
}: React.ComponentProps<typeof DropdownMenuSeparator>) {
|
|
152
|
+
return <DropdownMenuSeparator data-slot="menubar-separator" {...props} />;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function MenubarShortcut({
|
|
156
|
+
...props
|
|
157
|
+
}: React.ComponentProps<typeof DropdownMenuShortcut>) {
|
|
158
|
+
return <DropdownMenuShortcut data-slot="menubar-shortcut" {...props} />;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function MenubarSub({
|
|
162
|
+
...props
|
|
163
|
+
}: React.ComponentProps<typeof DropdownMenuSub>) {
|
|
164
|
+
return <DropdownMenuSub data-slot="menubar-sub" {...props} />;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function MenubarSubTrigger({
|
|
168
|
+
inset,
|
|
169
|
+
...props
|
|
170
|
+
}: React.ComponentProps<typeof DropdownMenuSubTrigger>) {
|
|
171
|
+
return (
|
|
172
|
+
<DropdownMenuSubTrigger
|
|
173
|
+
data-slot="menubar-sub-trigger"
|
|
174
|
+
inset={inset}
|
|
175
|
+
{...props}
|
|
176
|
+
/>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function MenubarSubContent({
|
|
181
|
+
...props
|
|
182
|
+
}: React.ComponentProps<typeof DropdownMenuSubContent>) {
|
|
183
|
+
return <DropdownMenuSubContent data-slot="menubar-sub-content" {...props} />;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export {
|
|
187
|
+
Menubar,
|
|
188
|
+
MenubarCheckboxItem,
|
|
189
|
+
MenubarContent,
|
|
190
|
+
MenubarGroup,
|
|
191
|
+
MenubarItem,
|
|
192
|
+
MenubarLabel,
|
|
193
|
+
MenubarMenu,
|
|
194
|
+
MenubarPortal,
|
|
195
|
+
MenubarRadioGroup,
|
|
196
|
+
MenubarRadioItem,
|
|
197
|
+
MenubarSeparator,
|
|
198
|
+
MenubarShortcut,
|
|
199
|
+
MenubarSub,
|
|
200
|
+
MenubarSubContent,
|
|
201
|
+
MenubarSubTrigger,
|
|
202
|
+
MenubarTrigger,
|
|
203
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { NavigationMenu as NavigationMenuPrimitive } from "@base-ui/react/navigation-menu";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
import { ChevronDownIcon } from "lucide-react";
|
|
5
|
+
import { cn } from "../../../lib/utils";
|
|
6
|
+
|
|
7
|
+
function NavigationMenu({
|
|
8
|
+
children,
|
|
9
|
+
...props
|
|
10
|
+
}: Omit<NavigationMenuPrimitive.Root.Props, "className">) {
|
|
11
|
+
return (
|
|
12
|
+
<NavigationMenuPrimitive.Root
|
|
13
|
+
data-slot="navigation-menu"
|
|
14
|
+
className="max-w-max group/navigation-menu relative flex max-w-max flex-1 items-center justify-center"
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
{children}
|
|
18
|
+
<NavigationMenuPositioner />
|
|
19
|
+
</NavigationMenuPrimitive.Root>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function NavigationMenuList({
|
|
24
|
+
...props
|
|
25
|
+
}: Omit<NavigationMenuPrimitive.List.Props, "className">) {
|
|
26
|
+
return (
|
|
27
|
+
<NavigationMenuPrimitive.List
|
|
28
|
+
data-slot="navigation-menu-list"
|
|
29
|
+
className="gap-0 group flex flex-1 list-none items-center justify-center"
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function NavigationMenuItem({
|
|
36
|
+
...props
|
|
37
|
+
}: Omit<NavigationMenuPrimitive.Item.Props, "className">) {
|
|
38
|
+
return (
|
|
39
|
+
<NavigationMenuPrimitive.Item
|
|
40
|
+
data-slot="navigation-menu-item"
|
|
41
|
+
className="relative"
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const navigationMenuTriggerStyle = cva(
|
|
48
|
+
"bg-background hover:bg-muted focus:bg-muted data-open:hover:bg-muted data-open:focus:bg-muted data-open:bg-muted/50 focus-visible:ring-ring/50 data-popup-open:bg-muted/50 data-popup-open:hover:bg-muted rounded-md px-4 py-2 text-sm font-medium transition-all focus-visible:ring-[3px] focus-visible:outline-1 disabled:opacity-50 group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center disabled:pointer-events-none outline-none",
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
function NavigationMenuTrigger({
|
|
52
|
+
children,
|
|
53
|
+
...props
|
|
54
|
+
}: Omit<NavigationMenuPrimitive.Trigger.Props, "className">) {
|
|
55
|
+
return (
|
|
56
|
+
<NavigationMenuPrimitive.Trigger
|
|
57
|
+
data-slot="navigation-menu-trigger"
|
|
58
|
+
className={cn(navigationMenuTriggerStyle(), "group")}
|
|
59
|
+
{...props}
|
|
60
|
+
>
|
|
61
|
+
{children}{" "}
|
|
62
|
+
<ChevronDownIcon
|
|
63
|
+
className="relative top-[1px] ml-1 size-3 transition duration-300 group-data-open/navigation-menu-trigger:rotate-180 group-data-popup-open/navigation-menu-trigger:rotate-180"
|
|
64
|
+
aria-hidden="true"
|
|
65
|
+
/>
|
|
66
|
+
</NavigationMenuPrimitive.Trigger>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function NavigationMenuContent({
|
|
71
|
+
...props
|
|
72
|
+
}: Omit<NavigationMenuPrimitive.Content.Props, "className">) {
|
|
73
|
+
return (
|
|
74
|
+
<NavigationMenuPrimitive.Content
|
|
75
|
+
data-slot="navigation-menu-content"
|
|
76
|
+
className="data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-open:animate-in group-data-[viewport=false]/navigation-menu:data-closed:animate-out group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 group-data-[viewport=false]/navigation-menu:ring-foreground/10 p-2 pr-2.5 ease-[cubic-bezier(0.22,1,0.36,1)] group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:ring-1 group-data-[viewport=false]/navigation-menu:duration-300 h-full w-auto **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none"
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function NavigationMenuPositioner({
|
|
83
|
+
side = "bottom",
|
|
84
|
+
sideOffset = 8,
|
|
85
|
+
align = "start",
|
|
86
|
+
alignOffset = 0,
|
|
87
|
+
...props
|
|
88
|
+
}: Omit<NavigationMenuPrimitive.Positioner.Props, "className">) {
|
|
89
|
+
return (
|
|
90
|
+
<NavigationMenuPrimitive.Portal>
|
|
91
|
+
<NavigationMenuPrimitive.Positioner
|
|
92
|
+
side={side}
|
|
93
|
+
sideOffset={sideOffset}
|
|
94
|
+
align={align}
|
|
95
|
+
alignOffset={alignOffset}
|
|
96
|
+
className="transition-[top,left,right,bottom] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0 isolate z-50 h-[var(--positioner-height)] w-[var(--positioner-width)] max-w-[var(--available-width)] data-[instant]:transition-none"
|
|
97
|
+
{...props}
|
|
98
|
+
>
|
|
99
|
+
<NavigationMenuPrimitive.Popup className="bg-popover text-popover-foreground ring-foreground/10 rounded-lg shadow ring-1 transition-all ease-[cubic-bezier(0.22,1,0.36,1)] outline-none data-[ending-style]:scale-90 data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:scale-90 data-[starting-style]:opacity-0 xs:w-(--popup-width) relative h-(--popup-height) w-(--popup-width) origin-(--transform-origin)">
|
|
100
|
+
<NavigationMenuPrimitive.Viewport className="relative size-full overflow-hidden" />
|
|
101
|
+
</NavigationMenuPrimitive.Popup>
|
|
102
|
+
</NavigationMenuPrimitive.Positioner>
|
|
103
|
+
</NavigationMenuPrimitive.Portal>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function NavigationMenuLink({
|
|
108
|
+
...props
|
|
109
|
+
}: Omit<NavigationMenuPrimitive.Link.Props, "className">) {
|
|
110
|
+
return (
|
|
111
|
+
<NavigationMenuPrimitive.Link
|
|
112
|
+
data-slot="navigation-menu-link"
|
|
113
|
+
className="data-[active=true]:focus:bg-muted data-[active=true]:hover:bg-muted data-[active=true]:bg-muted/50 focus-visible:ring-ring/50 hover:bg-muted focus:bg-muted flex items-center gap-1.5 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4"
|
|
114
|
+
{...props}
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function NavigationMenuIndicator({
|
|
120
|
+
...props
|
|
121
|
+
}: Omit<NavigationMenuPrimitive.Icon.Props, "className">) {
|
|
122
|
+
return (
|
|
123
|
+
<NavigationMenuPrimitive.Icon
|
|
124
|
+
data-slot="navigation-menu-indicator"
|
|
125
|
+
className="data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden"
|
|
126
|
+
{...props}
|
|
127
|
+
>
|
|
128
|
+
<div className="bg-border rounded-tl-sm shadow-md relative top-[60%] h-2 w-2 rotate-45" />
|
|
129
|
+
</NavigationMenuPrimitive.Icon>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export {
|
|
134
|
+
NavigationMenu,
|
|
135
|
+
NavigationMenuContent,
|
|
136
|
+
NavigationMenuIndicator,
|
|
137
|
+
NavigationMenuItem,
|
|
138
|
+
NavigationMenuLink,
|
|
139
|
+
NavigationMenuList,
|
|
140
|
+
NavigationMenuPositioner,
|
|
141
|
+
NavigationMenuTrigger,
|
|
142
|
+
navigationMenuTriggerStyle,
|
|
143
|
+
};
|