@suphark/ui 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.
- package/CHANGELOG.md +36 -0
- package/LICENSE +21 -0
- package/README.md +120 -0
- package/components.json +21 -0
- package/package.json +108 -0
- package/scripts/audit-base-ui-props.mjs +179 -0
- package/scripts/audit-tailwind-typography.mjs +100 -0
- package/src/components/design-system/design-system-showcase.tsx +138 -0
- package/src/components/design-system/sections/showcase-data-display.tsx +454 -0
- package/src/components/design-system/sections/showcase-feedback.tsx +273 -0
- package/src/components/design-system/sections/showcase-forms.tsx +373 -0
- package/src/components/design-system/sections/showcase-foundations.tsx +384 -0
- package/src/components/design-system/sections/showcase-guidelines-recipes.tsx +397 -0
- package/src/components/design-system/sections/showcase-overlays-navigation.tsx +479 -0
- package/src/components/design-system/sections/showcase-overview.tsx +368 -0
- package/src/components/design-system/sections/showcase-primitives.tsx +463 -0
- package/src/components/shared/__tests__/multi-select-combobox.test.tsx +180 -0
- package/src/components/shared/__tests__/name-id-fields.test.ts +24 -0
- package/src/components/shared/button/add-new-button.tsx +19 -0
- package/src/components/shared/button/base/action-button.tsx +134 -0
- package/src/components/shared/button/base/link-button.tsx +130 -0
- package/src/components/shared/button/cancel-button.tsx +27 -0
- package/src/components/shared/button/confirm-button.tsx +26 -0
- package/src/components/shared/button/delete-button.tsx +36 -0
- package/src/components/shared/button/floating-save-button.tsx +89 -0
- package/src/components/shared/button/index.ts +13 -0
- package/src/components/shared/button/print-button.tsx +67 -0
- package/src/components/shared/button/refresh-button.tsx +63 -0
- package/src/components/shared/button/save-button.tsx +29 -0
- package/src/components/shared/button/submit-button.tsx +58 -0
- package/src/components/shared/client-redirect.tsx +11 -0
- package/src/components/shared/combobox.tsx +116 -0
- package/src/components/shared/data-list.tsx +65 -0
- package/src/components/shared/date/date-range-picker.tsx +106 -0
- package/src/components/shared/description-list.tsx +27 -0
- package/src/components/shared/empty-row.tsx +13 -0
- package/src/components/shared/empty-state.tsx +31 -0
- package/src/components/shared/env-snippet.tsx +62 -0
- package/src/components/shared/form/__tests__/simple-select.test.tsx +72 -0
- package/src/components/shared/form/form-field-boolean.tsx +93 -0
- package/src/components/shared/form/form-field-color-select.tsx +86 -0
- package/src/components/shared/form/form-field-combobox.tsx +167 -0
- package/src/components/shared/form/form-field-date.tsx +55 -0
- package/src/components/shared/form/form-field-formatted-number.tsx +103 -0
- package/src/components/shared/form/form-field-input.tsx +372 -0
- package/src/components/shared/form/form-field-radio-cards.tsx +127 -0
- package/src/components/shared/form/form-field-radio-group.tsx +56 -0
- package/src/components/shared/form/form-field-select.tsx +312 -0
- package/src/components/shared/form/simple-select.tsx +152 -0
- package/src/components/shared/form-dialog.tsx +109 -0
- package/src/components/shared/form-message.tsx +30 -0
- package/src/components/shared/initials.tsx +33 -0
- package/src/components/shared/layout/error-state.tsx +160 -0
- package/src/components/shared/layout/page-shell.tsx +57 -0
- package/src/components/shared/link/transition-link.tsx +72 -0
- package/src/components/shared/multi-select-combobox.tsx +392 -0
- package/src/components/shared/name-id-fields.tsx +133 -0
- package/src/components/shared/navigation/page-breadcrumb.tsx +100 -0
- package/src/components/shared/notice.tsx +35 -0
- package/src/components/shared/number/formatted-number.tsx +133 -0
- package/src/components/shared/page-header.tsx +25 -0
- package/src/components/shared/page-skeleton.tsx +18 -0
- package/src/components/shared/row-actions.tsx +93 -0
- package/src/components/shared/row-menu.tsx +55 -0
- package/src/components/shared/secret-reveal.tsx +53 -0
- package/src/components/shared/section-card.tsx +44 -0
- package/src/components/shared/stat.tsx +26 -0
- package/src/components/shared/status-badge.tsx +47 -0
- package/src/components/shared/text/primary-secondary-text.tsx +186 -0
- package/src/components/shared/theme/index.ts +4 -0
- package/src/components/shared/theme/theme-menu-items.tsx +43 -0
- package/src/components/shared/theme/theme-provider.tsx +39 -0
- package/src/components/shared/theme/theme-switch.tsx +36 -0
- package/src/components/shared/theme/theme-toggle.tsx +76 -0
- package/src/components/shared/time/client-date-formatter.tsx +188 -0
- package/src/components/shared/ui-text.tsx +47 -0
- package/src/components/ui/__tests__/combobox.test.tsx +40 -0
- package/src/components/ui/__tests__/date-picker.test.tsx +53 -0
- package/src/components/ui/__tests__/slider.test.tsx +18 -0
- package/src/components/ui/__tests__/tabs.test.tsx +33 -0
- package/src/components/ui/accordion.tsx +69 -0
- package/src/components/ui/alert-dialog.tsx +161 -0
- package/src/components/ui/alert.tsx +68 -0
- package/src/components/ui/aspect-ratio.tsx +22 -0
- package/src/components/ui/attachment.tsx +194 -0
- package/src/components/ui/avatar.tsx +92 -0
- package/src/components/ui/badge.tsx +48 -0
- package/src/components/ui/breadcrumb.tsx +102 -0
- package/src/components/ui/button-group.tsx +77 -0
- package/src/components/ui/button.tsx +57 -0
- package/src/components/ui/calendar.tsx +184 -0
- package/src/components/ui/card.tsx +87 -0
- package/src/components/ui/carousel.tsx +230 -0
- package/src/components/ui/chart.tsx +338 -0
- package/src/components/ui/checkbox.tsx +27 -0
- package/src/components/ui/collapsible.tsx +17 -0
- package/src/components/ui/combobox.tsx +272 -0
- package/src/components/ui/command.tsx +180 -0
- package/src/components/ui/context-menu.tsx +244 -0
- package/src/components/ui/date-picker.tsx +308 -0
- package/src/components/ui/dialog.tsx +137 -0
- package/src/components/ui/drawer.tsx +208 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/empty.tsx +93 -0
- package/src/components/ui/field.tsx +223 -0
- package/src/components/ui/form.tsx +161 -0
- package/src/components/ui/hover-card.tsx +46 -0
- package/src/components/ui/input-group.tsx +145 -0
- package/src/components/ui/input-otp.tsx +85 -0
- package/src/components/ui/input.tsx +19 -0
- package/src/components/ui/item.tsx +187 -0
- package/src/components/ui/kbd.tsx +26 -0
- package/src/components/ui/label.tsx +19 -0
- package/src/components/ui/menubar.tsx +266 -0
- package/src/components/ui/navigation-menu.tsx +160 -0
- package/src/components/ui/pagination.tsx +117 -0
- package/src/components/ui/popover.tsx +76 -0
- package/src/components/ui/progress.tsx +66 -0
- package/src/components/ui/radio-group.tsx +38 -0
- package/src/components/ui/relative-date.tsx +40 -0
- package/src/components/ui/resizable.tsx +41 -0
- package/src/components/ui/scroll-area.tsx +67 -0
- package/src/components/ui/searchable-select.tsx +124 -0
- package/src/components/ui/select.tsx +189 -0
- package/src/components/ui/separator.tsx +21 -0
- package/src/components/ui/sheet.tsx +124 -0
- package/src/components/ui/sidebar.tsx +691 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/slider.tsx +55 -0
- package/src/components/ui/sonner.tsx +45 -0
- package/src/components/ui/spinner.tsx +16 -0
- package/src/components/ui/switch.tsx +32 -0
- package/src/components/ui/table.tsx +95 -0
- package/src/components/ui/tabs.tsx +79 -0
- package/src/components/ui/textarea.tsx +17 -0
- package/src/components/ui/toggle-group.tsx +86 -0
- package/src/components/ui/toggle.tsx +44 -0
- package/src/components/ui/tooltip.tsx +54 -0
- package/src/hooks/use-copy-to-clipboard.ts +27 -0
- package/src/hooks/use-mobile.ts +21 -0
- package/src/index.ts +156 -0
- package/src/lib/formatters.ts +44 -0
- package/src/lib/permission.ts +75 -0
- package/src/lib/status-colors.ts +52 -0
- package/src/lib/utils.ts +6 -0
- package/src/next.ts +15 -0
- package/src/styles.css +214 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Dialog,
|
|
5
|
+
DialogContent,
|
|
6
|
+
DialogDescription,
|
|
7
|
+
DialogHeader,
|
|
8
|
+
DialogTitle,
|
|
9
|
+
} from "@suphark/ui/components/ui/dialog";
|
|
10
|
+
import { InputGroup, InputGroupAddon } from "@suphark/ui/components/ui/input-group";
|
|
11
|
+
import { cn } from "@suphark/ui/lib/utils";
|
|
12
|
+
import { Command as CommandPrimitive } from "cmdk";
|
|
13
|
+
import { CheckIcon, SearchIcon } from "lucide-react";
|
|
14
|
+
import type * as React from "react";
|
|
15
|
+
|
|
16
|
+
function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {
|
|
17
|
+
return (
|
|
18
|
+
<CommandPrimitive
|
|
19
|
+
data-slot="command"
|
|
20
|
+
className={cn(
|
|
21
|
+
"flex size-full flex-col overflow-hidden rounded-xl! bg-popover p-1 text-popover-foreground",
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function CommandDialog({
|
|
30
|
+
title = "Command Palette",
|
|
31
|
+
description = "Search for a command to run...",
|
|
32
|
+
children,
|
|
33
|
+
className,
|
|
34
|
+
showCloseButton = false,
|
|
35
|
+
...props
|
|
36
|
+
}: Omit<React.ComponentProps<typeof Dialog>, "children"> & {
|
|
37
|
+
title?: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
className?: string;
|
|
40
|
+
showCloseButton?: boolean;
|
|
41
|
+
children: React.ReactNode;
|
|
42
|
+
}) {
|
|
43
|
+
return (
|
|
44
|
+
<Dialog {...props}>
|
|
45
|
+
<DialogHeader className="sr-only">
|
|
46
|
+
<DialogTitle>{title}</DialogTitle>
|
|
47
|
+
<DialogDescription>{description}</DialogDescription>
|
|
48
|
+
</DialogHeader>
|
|
49
|
+
<DialogContent
|
|
50
|
+
className={cn("top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0", className)}
|
|
51
|
+
showCloseButton={showCloseButton}
|
|
52
|
+
>
|
|
53
|
+
{children}
|
|
54
|
+
</DialogContent>
|
|
55
|
+
</Dialog>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function CommandInput({
|
|
60
|
+
className,
|
|
61
|
+
...props
|
|
62
|
+
}: React.ComponentProps<typeof CommandPrimitive.Input>) {
|
|
63
|
+
return (
|
|
64
|
+
<div data-slot="command-input-wrapper" className="p-1 pb-0">
|
|
65
|
+
<InputGroup className="h-8! rounded-lg! border-input/30 bg-input/30 shadow-none! *:data-[slot=input-group-addon]:pl-2!">
|
|
66
|
+
<CommandPrimitive.Input
|
|
67
|
+
data-slot="command-input"
|
|
68
|
+
className={cn(
|
|
69
|
+
"w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
|
|
70
|
+
className,
|
|
71
|
+
)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
<InputGroupAddon>
|
|
75
|
+
<SearchIcon className="size-4 shrink-0 opacity-50" />
|
|
76
|
+
</InputGroupAddon>
|
|
77
|
+
</InputGroup>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
|
|
83
|
+
return (
|
|
84
|
+
<CommandPrimitive.List
|
|
85
|
+
data-slot="command-list"
|
|
86
|
+
className={cn(
|
|
87
|
+
"no-scrollbar max-h-72 scroll-py-1 overflow-y-auto overflow-x-hidden outline-none",
|
|
88
|
+
className,
|
|
89
|
+
)}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function CommandEmpty({
|
|
96
|
+
className,
|
|
97
|
+
...props
|
|
98
|
+
}: React.ComponentProps<typeof CommandPrimitive.Empty>) {
|
|
99
|
+
return (
|
|
100
|
+
<CommandPrimitive.Empty
|
|
101
|
+
data-slot="command-empty"
|
|
102
|
+
className={cn("py-6 text-center text-sm", className)}
|
|
103
|
+
{...props}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function CommandGroup({
|
|
109
|
+
className,
|
|
110
|
+
...props
|
|
111
|
+
}: React.ComponentProps<typeof CommandPrimitive.Group>) {
|
|
112
|
+
return (
|
|
113
|
+
<CommandPrimitive.Group
|
|
114
|
+
data-slot="command-group"
|
|
115
|
+
className={cn(
|
|
116
|
+
"overflow-hidden p-1 text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground **:[[cmdk-group-heading]]:text-xs",
|
|
117
|
+
className,
|
|
118
|
+
)}
|
|
119
|
+
{...props}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function CommandSeparator({
|
|
125
|
+
className,
|
|
126
|
+
...props
|
|
127
|
+
}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
|
|
128
|
+
return (
|
|
129
|
+
<CommandPrimitive.Separator
|
|
130
|
+
data-slot="command-separator"
|
|
131
|
+
className={cn("-mx-1 h-px bg-border", className)}
|
|
132
|
+
{...props}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function CommandItem({
|
|
138
|
+
className,
|
|
139
|
+
children,
|
|
140
|
+
...props
|
|
141
|
+
}: React.ComponentProps<typeof CommandPrimitive.Item>) {
|
|
142
|
+
return (
|
|
143
|
+
<CommandPrimitive.Item
|
|
144
|
+
data-slot="command-item"
|
|
145
|
+
className={cn(
|
|
146
|
+
"group/command-item relative flex cursor-default select-none items-center gap-2 in-data-[slot=dialog-content]:rounded-lg! rounded-sm px-2 py-1.5 text-sm outline-hidden data-[disabled=true]:pointer-events-none data-selected:bg-muted data-selected:text-foreground data-[disabled=true]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 data-selected:*:[svg]:text-foreground",
|
|
147
|
+
className,
|
|
148
|
+
)}
|
|
149
|
+
{...props}
|
|
150
|
+
>
|
|
151
|
+
{children}
|
|
152
|
+
<CheckIcon className="ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" />
|
|
153
|
+
</CommandPrimitive.Item>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function CommandShortcut({ className, ...props }: React.ComponentProps<"span">) {
|
|
158
|
+
return (
|
|
159
|
+
<span
|
|
160
|
+
data-slot="command-shortcut"
|
|
161
|
+
className={cn(
|
|
162
|
+
"ml-auto text-muted-foreground text-xs tracking-widest group-data-selected/command-item:text-foreground",
|
|
163
|
+
className,
|
|
164
|
+
)}
|
|
165
|
+
{...props}
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export {
|
|
171
|
+
Command,
|
|
172
|
+
CommandDialog,
|
|
173
|
+
CommandEmpty,
|
|
174
|
+
CommandGroup,
|
|
175
|
+
CommandInput,
|
|
176
|
+
CommandItem,
|
|
177
|
+
CommandList,
|
|
178
|
+
CommandSeparator,
|
|
179
|
+
CommandShortcut,
|
|
180
|
+
};
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ContextMenu as ContextMenuPrimitive } from "@base-ui/react/context-menu";
|
|
4
|
+
import { cn } from "@suphark/ui/lib/utils";
|
|
5
|
+
import { CheckIcon, ChevronRightIcon } from "lucide-react";
|
|
6
|
+
import type * as React from "react";
|
|
7
|
+
|
|
8
|
+
function ContextMenu({ ...props }: ContextMenuPrimitive.Root.Props) {
|
|
9
|
+
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function ContextMenuPortal({ ...props }: ContextMenuPrimitive.Portal.Props) {
|
|
13
|
+
return <ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function ContextMenuTrigger({ className, ...props }: ContextMenuPrimitive.Trigger.Props) {
|
|
17
|
+
return (
|
|
18
|
+
<ContextMenuPrimitive.Trigger
|
|
19
|
+
data-slot="context-menu-trigger"
|
|
20
|
+
className={cn("select-none", className)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function ContextMenuContent({
|
|
27
|
+
className,
|
|
28
|
+
align = "start",
|
|
29
|
+
alignOffset = 4,
|
|
30
|
+
side = "right",
|
|
31
|
+
sideOffset = 0,
|
|
32
|
+
...props
|
|
33
|
+
}: ContextMenuPrimitive.Popup.Props &
|
|
34
|
+
Pick<ContextMenuPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">) {
|
|
35
|
+
return (
|
|
36
|
+
<ContextMenuPrimitive.Portal>
|
|
37
|
+
<ContextMenuPrimitive.Positioner
|
|
38
|
+
className="isolate z-50 outline-none"
|
|
39
|
+
align={align}
|
|
40
|
+
alignOffset={alignOffset}
|
|
41
|
+
side={side}
|
|
42
|
+
sideOffset={sideOffset}
|
|
43
|
+
>
|
|
44
|
+
<ContextMenuPrimitive.Popup
|
|
45
|
+
data-slot="context-menu-content"
|
|
46
|
+
className={cn(
|
|
47
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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:fade-in-0 data-open:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 z-50 max-h-(--available-height) min-w-36 origin-(--transform-origin) overflow-y-auto overflow-x-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-md outline-none ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-open:animate-in",
|
|
48
|
+
className,
|
|
49
|
+
)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
</ContextMenuPrimitive.Positioner>
|
|
53
|
+
</ContextMenuPrimitive.Portal>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function ContextMenuGroup({ ...props }: ContextMenuPrimitive.Group.Props) {
|
|
58
|
+
return <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function ContextMenuLabel({
|
|
62
|
+
className,
|
|
63
|
+
inset,
|
|
64
|
+
...props
|
|
65
|
+
}: ContextMenuPrimitive.GroupLabel.Props & {
|
|
66
|
+
inset?: boolean;
|
|
67
|
+
}) {
|
|
68
|
+
return (
|
|
69
|
+
<ContextMenuPrimitive.GroupLabel
|
|
70
|
+
data-slot="context-menu-label"
|
|
71
|
+
data-inset={inset}
|
|
72
|
+
className={cn(
|
|
73
|
+
"px-1.5 py-1 font-medium text-muted-foreground text-xs data-inset:pl-7",
|
|
74
|
+
className,
|
|
75
|
+
)}
|
|
76
|
+
{...props}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function ContextMenuItem({
|
|
82
|
+
className,
|
|
83
|
+
inset,
|
|
84
|
+
variant = "default",
|
|
85
|
+
...props
|
|
86
|
+
}: ContextMenuPrimitive.Item.Props & {
|
|
87
|
+
inset?: boolean;
|
|
88
|
+
variant?: "default" | "destructive";
|
|
89
|
+
}) {
|
|
90
|
+
return (
|
|
91
|
+
<ContextMenuPrimitive.Item
|
|
92
|
+
data-slot="context-menu-item"
|
|
93
|
+
data-inset={inset}
|
|
94
|
+
data-variant={variant}
|
|
95
|
+
className={cn(
|
|
96
|
+
"group/context-menu-item relative flex cursor-default select-none items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-inset:pl-7 data-[variant=destructive]:text-destructive data-disabled:opacity-50 data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 focus:*:[svg]:text-accent-foreground data-[variant=destructive]:*:[svg]:text-destructive",
|
|
97
|
+
className,
|
|
98
|
+
)}
|
|
99
|
+
{...props}
|
|
100
|
+
/>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function ContextMenuSub({ ...props }: ContextMenuPrimitive.SubmenuRoot.Props) {
|
|
105
|
+
return <ContextMenuPrimitive.SubmenuRoot data-slot="context-menu-sub" {...props} />;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function ContextMenuSubTrigger({
|
|
109
|
+
className,
|
|
110
|
+
inset,
|
|
111
|
+
children,
|
|
112
|
+
...props
|
|
113
|
+
}: ContextMenuPrimitive.SubmenuTrigger.Props & {
|
|
114
|
+
inset?: boolean;
|
|
115
|
+
}) {
|
|
116
|
+
return (
|
|
117
|
+
<ContextMenuPrimitive.SubmenuTrigger
|
|
118
|
+
data-slot="context-menu-sub-trigger"
|
|
119
|
+
data-inset={inset}
|
|
120
|
+
className={cn(
|
|
121
|
+
"flex cursor-default select-none items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-inset:pl-7 data-open:text-accent-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
122
|
+
className,
|
|
123
|
+
)}
|
|
124
|
+
{...props}
|
|
125
|
+
>
|
|
126
|
+
{children}
|
|
127
|
+
<ChevronRightIcon className="ml-auto" />
|
|
128
|
+
</ContextMenuPrimitive.SubmenuTrigger>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function ContextMenuSubContent({ ...props }: React.ComponentProps<typeof ContextMenuContent>) {
|
|
133
|
+
return (
|
|
134
|
+
<ContextMenuContent
|
|
135
|
+
data-slot="context-menu-sub-content"
|
|
136
|
+
className="shadow-lg"
|
|
137
|
+
side="right"
|
|
138
|
+
{...props}
|
|
139
|
+
/>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function ContextMenuCheckboxItem({
|
|
144
|
+
className,
|
|
145
|
+
children,
|
|
146
|
+
checked,
|
|
147
|
+
inset,
|
|
148
|
+
...props
|
|
149
|
+
}: ContextMenuPrimitive.CheckboxItem.Props & {
|
|
150
|
+
inset?: boolean;
|
|
151
|
+
}) {
|
|
152
|
+
return (
|
|
153
|
+
<ContextMenuPrimitive.CheckboxItem
|
|
154
|
+
data-slot="context-menu-checkbox-item"
|
|
155
|
+
data-inset={inset}
|
|
156
|
+
className={cn(
|
|
157
|
+
"relative flex cursor-default select-none items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-inset:pl-7 data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
158
|
+
className,
|
|
159
|
+
)}
|
|
160
|
+
checked={checked}
|
|
161
|
+
{...props}
|
|
162
|
+
>
|
|
163
|
+
<span className="pointer-events-none absolute right-2">
|
|
164
|
+
<ContextMenuPrimitive.CheckboxItemIndicator>
|
|
165
|
+
<CheckIcon />
|
|
166
|
+
</ContextMenuPrimitive.CheckboxItemIndicator>
|
|
167
|
+
</span>
|
|
168
|
+
{children}
|
|
169
|
+
</ContextMenuPrimitive.CheckboxItem>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function ContextMenuRadioGroup({ ...props }: ContextMenuPrimitive.RadioGroup.Props) {
|
|
174
|
+
return <ContextMenuPrimitive.RadioGroup data-slot="context-menu-radio-group" {...props} />;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function ContextMenuRadioItem({
|
|
178
|
+
className,
|
|
179
|
+
children,
|
|
180
|
+
inset,
|
|
181
|
+
...props
|
|
182
|
+
}: ContextMenuPrimitive.RadioItem.Props & {
|
|
183
|
+
inset?: boolean;
|
|
184
|
+
}) {
|
|
185
|
+
return (
|
|
186
|
+
<ContextMenuPrimitive.RadioItem
|
|
187
|
+
data-slot="context-menu-radio-item"
|
|
188
|
+
data-inset={inset}
|
|
189
|
+
className={cn(
|
|
190
|
+
"relative flex cursor-default select-none items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-inset:pl-7 data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
191
|
+
className,
|
|
192
|
+
)}
|
|
193
|
+
{...props}
|
|
194
|
+
>
|
|
195
|
+
<span className="pointer-events-none absolute right-2">
|
|
196
|
+
<ContextMenuPrimitive.RadioItemIndicator>
|
|
197
|
+
<CheckIcon />
|
|
198
|
+
</ContextMenuPrimitive.RadioItemIndicator>
|
|
199
|
+
</span>
|
|
200
|
+
{children}
|
|
201
|
+
</ContextMenuPrimitive.RadioItem>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function ContextMenuSeparator({ className, ...props }: ContextMenuPrimitive.Separator.Props) {
|
|
206
|
+
return (
|
|
207
|
+
<ContextMenuPrimitive.Separator
|
|
208
|
+
data-slot="context-menu-separator"
|
|
209
|
+
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
|
210
|
+
{...props}
|
|
211
|
+
/>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function ContextMenuShortcut({ className, ...props }: React.ComponentProps<"span">) {
|
|
216
|
+
return (
|
|
217
|
+
<span
|
|
218
|
+
data-slot="context-menu-shortcut"
|
|
219
|
+
className={cn(
|
|
220
|
+
"ml-auto text-muted-foreground text-xs tracking-widest group-focus/context-menu-item:text-accent-foreground",
|
|
221
|
+
className,
|
|
222
|
+
)}
|
|
223
|
+
{...props}
|
|
224
|
+
/>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export {
|
|
229
|
+
ContextMenu,
|
|
230
|
+
ContextMenuCheckboxItem,
|
|
231
|
+
ContextMenuContent,
|
|
232
|
+
ContextMenuGroup,
|
|
233
|
+
ContextMenuItem,
|
|
234
|
+
ContextMenuLabel,
|
|
235
|
+
ContextMenuPortal,
|
|
236
|
+
ContextMenuRadioGroup,
|
|
237
|
+
ContextMenuRadioItem,
|
|
238
|
+
ContextMenuSeparator,
|
|
239
|
+
ContextMenuShortcut,
|
|
240
|
+
ContextMenuSub,
|
|
241
|
+
ContextMenuSubContent,
|
|
242
|
+
ContextMenuSubTrigger,
|
|
243
|
+
ContextMenuTrigger,
|
|
244
|
+
};
|