@cntyclub/ui-react 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/dist/chunk-HDGMSYQS.js +26461 -0
- package/dist/chunk-HDGMSYQS.js.map +1 -0
- package/dist/chunk-PR4QN5HX.js +39 -0
- package/dist/chunk-PR4QN5HX.js.map +1 -0
- package/dist/form.d.ts +175 -0
- package/dist/form.js +5207 -0
- package/dist/form.js.map +1 -0
- package/dist/index.d.ts +1462 -0
- package/dist/index.js +81862 -0
- package/dist/index.js.map +1 -0
- package/dist/input-CZvh825j.d.ts +24 -0
- package/dist/qr-code-styling-3Y6LZH6V.js +1123 -0
- package/dist/qr-code-styling-3Y6LZH6V.js.map +1 -0
- package/package.json +79 -0
- package/src/components/form/checkbox-group-field.tsx +101 -0
- package/src/components/form/date-field.tsx +79 -0
- package/src/components/form/date-range-field.tsx +106 -0
- package/src/components/form/form-context.ts +10 -0
- package/src/components/form/form.tsx +54 -0
- package/src/components/form/number-field.tsx +69 -0
- package/src/components/form/select-field.tsx +76 -0
- package/src/components/form/submit-button.tsx +28 -0
- package/src/components/form/text-field.tsx +107 -0
- package/src/components/layout/dashboard-header.tsx +54 -0
- package/src/components/layout/dashboard-panel.tsx +34 -0
- package/src/components/theme-provider.tsx +403 -0
- package/src/components/ui/accordion.tsx +69 -0
- package/src/components/ui/alert-dialog.tsx +169 -0
- package/src/components/ui/alert.tsx +80 -0
- package/src/components/ui/animated-theme-toggler.tsx +265 -0
- package/src/components/ui/app-store-buttons.tsx +182 -0
- package/src/components/ui/aspect-ratio.tsx +23 -0
- package/src/components/ui/autocomplete.tsx +296 -0
- package/src/components/ui/avatar-group.tsx +95 -0
- package/src/components/ui/avatar.tsx +285 -0
- package/src/components/ui/badge-group.tsx +160 -0
- package/src/components/ui/badge.tsx +172 -0
- package/src/components/ui/breadcrumb.tsx +112 -0
- package/src/components/ui/button.tsx +77 -0
- package/src/components/ui/calendar.tsx +137 -0
- package/src/components/ui/card.tsx +244 -0
- package/src/components/ui/carousel.tsx +258 -0
- package/src/components/ui/chart.tsx +379 -0
- package/src/components/ui/checkbox-group.tsx +16 -0
- package/src/components/ui/checkbox.tsx +82 -0
- package/src/components/ui/collapsible.tsx +45 -0
- package/src/components/ui/combobox.tsx +411 -0
- package/src/components/ui/command.tsx +264 -0
- package/src/components/ui/context-menu.tsx +271 -0
- package/src/components/ui/credit-card.tsx +214 -0
- package/src/components/ui/dialog.tsx +196 -0
- package/src/components/ui/drawer.tsx +135 -0
- package/src/components/ui/empty.tsx +127 -0
- package/src/components/ui/featured-icon.tsx +149 -0
- package/src/components/ui/field.tsx +88 -0
- package/src/components/ui/fieldset.tsx +29 -0
- package/src/components/ui/form.tsx +17 -0
- package/src/components/ui/frame.tsx +82 -0
- package/src/components/ui/generic-empty.tsx +142 -0
- package/src/components/ui/group.tsx +97 -0
- package/src/components/ui/horizontal-scroll-fader.tsx +228 -0
- package/src/components/ui/input-group.tsx +102 -0
- package/src/components/ui/input-otp.tsx +96 -0
- package/src/components/ui/input.tsx +66 -0
- package/src/components/ui/item.tsx +198 -0
- package/src/components/ui/kbd.tsx +30 -0
- package/src/components/ui/label.tsx +28 -0
- package/src/components/ui/menu.tsx +312 -0
- package/src/components/ui/menubar.tsx +93 -0
- package/src/components/ui/meter.tsx +67 -0
- package/src/components/ui/multi-select.tsx +308 -0
- package/src/components/ui/navigation-menu.tsx +143 -0
- package/src/components/ui/number-field.tsx +160 -0
- package/src/components/ui/pagination-controls.tsx +74 -0
- package/src/components/ui/pagination.tsx +149 -0
- package/src/components/ui/popover.tsx +119 -0
- package/src/components/ui/preview-card.tsx +55 -0
- package/src/components/ui/progress.tsx +289 -0
- package/src/components/ui/qr-code.tsx +150 -0
- package/src/components/ui/radio-group.tsx +103 -0
- package/src/components/ui/resizable.tsx +56 -0
- package/src/components/ui/scroll-area.tsx +90 -0
- package/src/components/ui/scroller.tsx +38 -0
- package/src/components/ui/section-header.tsx +118 -0
- package/src/components/ui/select.tsx +181 -0
- package/src/components/ui/separator.tsx +23 -0
- package/src/components/ui/sheet.tsx +224 -0
- package/src/components/ui/sidebar.tsx +744 -0
- package/src/components/ui/skeleton.tsx +16 -0
- package/src/components/ui/slider.tsx +108 -0
- package/src/components/ui/smooth-scroll.tsx +143 -0
- package/src/components/ui/social-button.tsx +247 -0
- package/src/components/ui/spinner-on-demand.tsx +32 -0
- package/src/components/ui/spinner.tsx +18 -0
- package/src/components/ui/stat.tsx +187 -0
- package/src/components/ui/stepper.tsx +167 -0
- package/src/components/ui/switch.tsx +56 -0
- package/src/components/ui/table.tsx +126 -0
- package/src/components/ui/tabs.tsx +90 -0
- package/src/components/ui/tag.tsx +229 -0
- package/src/components/ui/target-countdown.tsx +46 -0
- package/src/components/ui/text-editor.tsx +313 -0
- package/src/components/ui/textarea.tsx +51 -0
- package/src/components/ui/timeline.tsx +116 -0
- package/src/components/ui/toast.tsx +268 -0
- package/src/components/ui/toggle-group.tsx +101 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/components/ui/toolbar.tsx +89 -0
- package/src/components/ui/tooltip.tsx +102 -0
- package/src/components/ui/vertical-scroll-fader.tsx +250 -0
- package/src/components/ui/video-player.tsx +275 -0
- package/src/components/upload/avatar-upload-base.tsx +131 -0
- package/src/components/upload/image-upload-base.tsx +112 -0
- package/src/form.ts +17 -0
- package/src/index.ts +125 -0
- package/src/lib/hooks/use-callback-ref.ts +15 -0
- package/src/lib/hooks/use-first-render.ts +11 -0
- package/src/lib/hooks/use-hover.ts +53 -0
- package/src/lib/hooks/use-is-tab-active.ts +17 -0
- package/src/lib/hooks/use-media-query.ts +164 -0
- package/src/lib/utils/css.ts +6 -0
- package/src/styles.css +300 -0
- package/src/types/helpers.ts +24 -0
- package/src/types/react.d.ts +7 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Input as InputPrimitive } from "@base-ui/react/input";
|
|
4
|
+
import type * as React from "react";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils/css";
|
|
7
|
+
|
|
8
|
+
type InputProps = Omit<
|
|
9
|
+
InputPrimitive.Props & React.RefAttributes<HTMLInputElement>,
|
|
10
|
+
"size"
|
|
11
|
+
> & {
|
|
12
|
+
size?: "sm" | "default" | "lg" | number;
|
|
13
|
+
unstyled?: boolean;
|
|
14
|
+
nativeInput?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function Input({
|
|
18
|
+
className,
|
|
19
|
+
size = "default",
|
|
20
|
+
unstyled = false,
|
|
21
|
+
nativeInput = false,
|
|
22
|
+
...props
|
|
23
|
+
}: InputProps) {
|
|
24
|
+
const inputClassName = cn(
|
|
25
|
+
"h-8.5 w-full min-w-0 rounded-[inherit] px-[calc(--spacing(3)-1px)] leading-8.5 outline-none placeholder:text-muted-foreground/72 sm:h-7.5 sm:leading-7.5",
|
|
26
|
+
size === "sm" &&
|
|
27
|
+
"h-7.5 px-[calc(--spacing(2.5)-1px)] leading-7.5 sm:h-6.5 sm:leading-6.5",
|
|
28
|
+
size === "lg" && "h-9.5 leading-9.5 sm:h-8.5 sm:leading-8.5",
|
|
29
|
+
props.type === "search" &&
|
|
30
|
+
"[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none [&::-webkit-search-results-button]:appearance-none [&::-webkit-search-results-decoration]:appearance-none",
|
|
31
|
+
props.type === "file" &&
|
|
32
|
+
"text-muted-foreground file:me-3 file:bg-transparent file:font-medium file:text-foreground file:text-sm",
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<span
|
|
37
|
+
className={
|
|
38
|
+
cn(
|
|
39
|
+
!unstyled &&
|
|
40
|
+
"relative inline-flex w-full rounded-lg border border-input bg-background not-dark:bg-clip-padding text-base text-foreground shadow-xs/5 ring-ring/24 transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] not-has-disabled:not-has-focus-visible:not-has-aria-invalid:before:shadow-[0_1px_--theme(--color-black/6%)] has-focus-visible:has-aria-invalid:border-destructive/64 has-focus-visible:has-aria-invalid:ring-destructive/16 has-aria-invalid:border-destructive/36 has-focus-visible:border-ring has-disabled:opacity-64 has-[:disabled,:focus-visible,[aria-invalid]]:shadow-none has-focus-visible:ring-[3px] sm:text-sm dark:bg-input/32 dark:has-aria-invalid:ring-destructive/24 dark:not-has-disabled:not-has-focus-visible:not-has-aria-invalid:before:shadow-[0_-1px_--theme(--color-white/6%)]",
|
|
41
|
+
className,
|
|
42
|
+
) || undefined
|
|
43
|
+
}
|
|
44
|
+
data-size={size}
|
|
45
|
+
data-slot="input-control"
|
|
46
|
+
>
|
|
47
|
+
{nativeInput ? (
|
|
48
|
+
<input
|
|
49
|
+
className={inputClassName}
|
|
50
|
+
data-slot="input"
|
|
51
|
+
size={typeof size === "number" ? size : undefined}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
) : (
|
|
55
|
+
<InputPrimitive
|
|
56
|
+
className={inputClassName}
|
|
57
|
+
data-slot="input"
|
|
58
|
+
size={typeof size === "number" ? size : undefined}
|
|
59
|
+
{...props}
|
|
60
|
+
/>
|
|
61
|
+
)}
|
|
62
|
+
</span>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { Input, type InputProps };
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
6
|
+
import type * as React from "react";
|
|
7
|
+
|
|
8
|
+
import { cn } from "../../lib/utils/css";
|
|
9
|
+
import { Separator } from "./separator";
|
|
10
|
+
|
|
11
|
+
function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
12
|
+
return (
|
|
13
|
+
<div
|
|
14
|
+
className={cn("group/item-group flex flex-col", className)}
|
|
15
|
+
data-slot="item-group"
|
|
16
|
+
role="list"
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function ItemSeparator({
|
|
23
|
+
className,
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<typeof Separator>) {
|
|
26
|
+
return (
|
|
27
|
+
<Separator
|
|
28
|
+
className={cn("my-0", className)}
|
|
29
|
+
data-slot="item-separator"
|
|
30
|
+
orientation="horizontal"
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const itemVariants = cva(
|
|
37
|
+
"group/item flex flex-wrap items-center rounded-lg border border-transparent text-base outline-none transition-colors duration-100 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background sm:text-sm [a]:transition-colors [a]:hover:bg-accent/50",
|
|
38
|
+
{
|
|
39
|
+
defaultVariants: {
|
|
40
|
+
size: "default",
|
|
41
|
+
variant: "default",
|
|
42
|
+
},
|
|
43
|
+
variants: {
|
|
44
|
+
size: {
|
|
45
|
+
default: "gap-4 p-4",
|
|
46
|
+
sm: "gap-2.5 px-4 py-3",
|
|
47
|
+
},
|
|
48
|
+
variant: {
|
|
49
|
+
default: "bg-transparent",
|
|
50
|
+
muted: "bg-muted/50",
|
|
51
|
+
outline:
|
|
52
|
+
"border-border bg-card not-dark:bg-clip-padding shadow-xs/5 dark:bg-input/32",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
interface ItemProps extends useRender.ComponentProps<"div"> {
|
|
59
|
+
variant?: VariantProps<typeof itemVariants>["variant"];
|
|
60
|
+
size?: VariantProps<typeof itemVariants>["size"];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function Item({ className, variant, size, render, ...props }: ItemProps) {
|
|
64
|
+
const defaultProps = {
|
|
65
|
+
className: cn(itemVariants({ className, size, variant })),
|
|
66
|
+
"data-size": size ?? "default",
|
|
67
|
+
"data-slot": "item",
|
|
68
|
+
"data-variant": variant ?? "default",
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return useRender({
|
|
72
|
+
defaultTagName: "div",
|
|
73
|
+
props: mergeProps<"div">(defaultProps, props),
|
|
74
|
+
render,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const itemMediaVariants = cva(
|
|
79
|
+
"flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none",
|
|
80
|
+
{
|
|
81
|
+
defaultVariants: {
|
|
82
|
+
variant: "default",
|
|
83
|
+
},
|
|
84
|
+
variants: {
|
|
85
|
+
variant: {
|
|
86
|
+
default: "bg-transparent",
|
|
87
|
+
icon: "size-8 rounded-sm border bg-muted [&_svg:not([class*='size-'])]:size-4",
|
|
88
|
+
image:
|
|
89
|
+
"size-10 overflow-hidden rounded-sm [&_img]:size-full [&_img]:object-cover",
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
function ItemMedia({
|
|
96
|
+
className,
|
|
97
|
+
variant = "default",
|
|
98
|
+
...props
|
|
99
|
+
}: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>) {
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
className={cn(itemMediaVariants({ className, variant }))}
|
|
103
|
+
data-slot="item-media"
|
|
104
|
+
data-variant={variant}
|
|
105
|
+
{...props}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function ItemContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
111
|
+
return (
|
|
112
|
+
<div
|
|
113
|
+
className={cn(
|
|
114
|
+
"flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none",
|
|
115
|
+
className,
|
|
116
|
+
)}
|
|
117
|
+
data-slot="item-content"
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
124
|
+
return (
|
|
125
|
+
<div
|
|
126
|
+
className={cn(
|
|
127
|
+
"flex w-fit items-center gap-2 font-medium leading-snug",
|
|
128
|
+
className,
|
|
129
|
+
)}
|
|
130
|
+
data-slot="item-title"
|
|
131
|
+
{...props}
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
137
|
+
return (
|
|
138
|
+
<p
|
|
139
|
+
className={cn(
|
|
140
|
+
"line-clamp-2 text-balance font-normal text-muted-foreground text-sm leading-normal sm:text-xs",
|
|
141
|
+
"[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
|
|
142
|
+
className,
|
|
143
|
+
)}
|
|
144
|
+
data-slot="item-description"
|
|
145
|
+
{...props}
|
|
146
|
+
/>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function ItemActions({ className, ...props }: React.ComponentProps<"div">) {
|
|
151
|
+
return (
|
|
152
|
+
<div
|
|
153
|
+
className={cn("flex items-center gap-2", className)}
|
|
154
|
+
data-slot="item-actions"
|
|
155
|
+
{...props}
|
|
156
|
+
/>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
161
|
+
return (
|
|
162
|
+
<div
|
|
163
|
+
className={cn(
|
|
164
|
+
"flex basis-full items-center justify-between gap-2",
|
|
165
|
+
className,
|
|
166
|
+
)}
|
|
167
|
+
data-slot="item-header"
|
|
168
|
+
{...props}
|
|
169
|
+
/>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
174
|
+
return (
|
|
175
|
+
<div
|
|
176
|
+
className={cn(
|
|
177
|
+
"flex basis-full items-center justify-between gap-2",
|
|
178
|
+
className,
|
|
179
|
+
)}
|
|
180
|
+
data-slot="item-footer"
|
|
181
|
+
{...props}
|
|
182
|
+
/>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export {
|
|
187
|
+
Item,
|
|
188
|
+
ItemMedia,
|
|
189
|
+
ItemContent,
|
|
190
|
+
ItemActions,
|
|
191
|
+
ItemGroup,
|
|
192
|
+
ItemSeparator,
|
|
193
|
+
ItemTitle,
|
|
194
|
+
ItemDescription,
|
|
195
|
+
ItemHeader,
|
|
196
|
+
ItemFooter,
|
|
197
|
+
itemVariants,
|
|
198
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type * as React from "react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils/css";
|
|
6
|
+
|
|
7
|
+
function Kbd({ className, ...props }: React.ComponentProps<"kbd">) {
|
|
8
|
+
return (
|
|
9
|
+
<kbd
|
|
10
|
+
className={cn(
|
|
11
|
+
"pointer-events-none inline-flex h-5 min-w-5 select-none items-center justify-center gap-1 rounded bg-muted px-1 font-medium font-sans text-muted-foreground text-xs [&_svg:not([class*='size-'])]:size-3",
|
|
12
|
+
className,
|
|
13
|
+
)}
|
|
14
|
+
data-slot="kbd"
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function KbdGroup({ className, ...props }: React.ComponentProps<"kbd">) {
|
|
21
|
+
return (
|
|
22
|
+
<kbd
|
|
23
|
+
className={cn("inline-flex items-center gap-1", className)}
|
|
24
|
+
data-slot="kbd-group"
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { Kbd, KbdGroup };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils/css";
|
|
7
|
+
|
|
8
|
+
function Label({
|
|
9
|
+
className,
|
|
10
|
+
render,
|
|
11
|
+
...props
|
|
12
|
+
}: useRender.ComponentProps<"label">) {
|
|
13
|
+
const defaultProps = {
|
|
14
|
+
className: cn(
|
|
15
|
+
"inline-flex items-center gap-2 text-base/4.5 sm:text-sm/4 font-medium text-foreground",
|
|
16
|
+
className,
|
|
17
|
+
),
|
|
18
|
+
"data-slot": "label",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
return useRender({
|
|
22
|
+
defaultTagName: "label",
|
|
23
|
+
props: mergeProps<"label">(defaultProps, props),
|
|
24
|
+
render,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { Label };
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
4
|
+
import { ChevronRightIcon } from "lucide-react";
|
|
5
|
+
import type * as React from "react";
|
|
6
|
+
import { cn } from "../../lib/utils/css";
|
|
7
|
+
|
|
8
|
+
const MenuCreateHandle = MenuPrimitive.createHandle;
|
|
9
|
+
|
|
10
|
+
const Menu = MenuPrimitive.Root;
|
|
11
|
+
|
|
12
|
+
const MenuPortal = MenuPrimitive.Portal;
|
|
13
|
+
|
|
14
|
+
function MenuTrigger(props: MenuPrimitive.Trigger.Props) {
|
|
15
|
+
return <MenuPrimitive.Trigger data-slot="menu-trigger" {...props} />;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function MenuPopup({
|
|
19
|
+
children,
|
|
20
|
+
className,
|
|
21
|
+
sideOffset = 4,
|
|
22
|
+
align = "center",
|
|
23
|
+
alignOffset,
|
|
24
|
+
side = "bottom",
|
|
25
|
+
...props
|
|
26
|
+
}: MenuPrimitive.Popup.Props & {
|
|
27
|
+
align?: MenuPrimitive.Positioner.Props["align"];
|
|
28
|
+
sideOffset?: MenuPrimitive.Positioner.Props["sideOffset"];
|
|
29
|
+
alignOffset?: MenuPrimitive.Positioner.Props["alignOffset"];
|
|
30
|
+
side?: MenuPrimitive.Positioner.Props["side"];
|
|
31
|
+
}) {
|
|
32
|
+
return (
|
|
33
|
+
<MenuPrimitive.Portal>
|
|
34
|
+
<MenuPrimitive.Positioner
|
|
35
|
+
align={align}
|
|
36
|
+
alignOffset={alignOffset}
|
|
37
|
+
className="z-50"
|
|
38
|
+
data-slot="menu-positioner"
|
|
39
|
+
side={side}
|
|
40
|
+
sideOffset={sideOffset}
|
|
41
|
+
>
|
|
42
|
+
<MenuPrimitive.Popup
|
|
43
|
+
className={cn(
|
|
44
|
+
"relative flex not-[class*='w-']:min-w-32 origin-(--transform-origin) rounded-lg border bg-popover not-dark:bg-clip-padding shadow-lg/5 outline-none transition-[transform,scale,opacity] duration-150 ease-out before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] before:shadow-[0_1px_--theme(--color-black/6%)] focus:outline-none data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
|
|
45
|
+
className,
|
|
46
|
+
)}
|
|
47
|
+
data-slot="menu-popup"
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
<div className="max-h-(--available-height) w-full overflow-y-auto p-1">
|
|
51
|
+
{children}
|
|
52
|
+
</div>
|
|
53
|
+
</MenuPrimitive.Popup>
|
|
54
|
+
</MenuPrimitive.Positioner>
|
|
55
|
+
</MenuPrimitive.Portal>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function MenuGroup(props: MenuPrimitive.Group.Props) {
|
|
60
|
+
return <MenuPrimitive.Group data-slot="menu-group" {...props} />;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function MenuItem({
|
|
64
|
+
className,
|
|
65
|
+
inset,
|
|
66
|
+
variant = "default",
|
|
67
|
+
...props
|
|
68
|
+
}: MenuPrimitive.Item.Props & {
|
|
69
|
+
inset?: boolean;
|
|
70
|
+
variant?: "default" | "destructive";
|
|
71
|
+
}) {
|
|
72
|
+
return (
|
|
73
|
+
<MenuPrimitive.Item
|
|
74
|
+
className={cn(
|
|
75
|
+
"[&>svg]:-mx-0.5 flex min-h-8 cursor-default select-none items-center gap-2 rounded-sm px-2 py-1 text-base text-foreground outline-none data-disabled:pointer-events-none data-highlighted:bg-accent data-inset:ps-8 data-[variant=destructive]:text-destructive-foreground data-highlighted:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&>svg:not([class*='opacity-'])]:opacity-80 [&>svg:not([class*='size-'])]:size-4.5 sm:[&>svg:not([class*='size-'])]:size-4 [&>svg]:pointer-events-none [&>svg]:shrink-0",
|
|
76
|
+
className,
|
|
77
|
+
)}
|
|
78
|
+
data-inset={inset}
|
|
79
|
+
data-slot="menu-item"
|
|
80
|
+
data-variant={variant}
|
|
81
|
+
{...props}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function MenuCheckboxItem({
|
|
87
|
+
className,
|
|
88
|
+
children,
|
|
89
|
+
checked,
|
|
90
|
+
variant = "default",
|
|
91
|
+
...props
|
|
92
|
+
}: MenuPrimitive.CheckboxItem.Props & {
|
|
93
|
+
variant?: "default" | "switch";
|
|
94
|
+
}) {
|
|
95
|
+
return (
|
|
96
|
+
<MenuPrimitive.CheckboxItem
|
|
97
|
+
checked={checked}
|
|
98
|
+
className={cn(
|
|
99
|
+
"grid min-h-8 in-data-[side=none]:min-w-[calc(var(--anchor-width)+1.25rem)] cursor-default items-center gap-2 rounded-sm py-1 ps-2 text-base text-foreground outline-none data-disabled:pointer-events-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
100
|
+
variant === "switch"
|
|
101
|
+
? "grid-cols-[1fr_auto] gap-4 pe-1.5"
|
|
102
|
+
: "grid-cols-[1rem_1fr] pe-4",
|
|
103
|
+
className,
|
|
104
|
+
)}
|
|
105
|
+
data-slot="menu-checkbox-item"
|
|
106
|
+
{...props}
|
|
107
|
+
>
|
|
108
|
+
{variant === "switch" ? (
|
|
109
|
+
<>
|
|
110
|
+
<span className="col-start-1">{children}</span>
|
|
111
|
+
<MenuPrimitive.CheckboxItemIndicator
|
|
112
|
+
className="inset-shadow-[0_1px_--theme(--color-black/6%)] inline-flex h-[calc(var(--thumb-size)+2px)] w-[calc(var(--thumb-size)*2-2px)] shrink-0 items-center rounded-full p-px outline-none transition-[background-color,box-shadow] duration-200 [--thumb-size:--spacing(4)] focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background data-checked:bg-primary data-unchecked:bg-input data-disabled:opacity-64 sm:[--thumb-size:--spacing(3)]"
|
|
113
|
+
keepMounted
|
|
114
|
+
>
|
|
115
|
+
<span className="pointer-events-none block aspect-square h-full in-[[data-slot=menu-checkbox-item][data-checked]]:origin-[var(--thumb-size)_50%] origin-left in-[[data-slot=menu-checkbox-item][data-checked]]:translate-x-[calc(var(--thumb-size)-4px)] in-[[data-slot=menu-checkbox-item]:active]:not-data-disabled:scale-x-110 in-[[data-slot=menu-checkbox-item]:active]:rounded-[var(--thumb-size)/calc(var(--thumb-size)*1.10)] rounded-(--thumb-size) bg-background shadow-sm/5 will-change-transform [transition:translate_.15s,border-radius_.15s,scale_.1s_.1s,transform-origin_.15s]" />
|
|
116
|
+
</MenuPrimitive.CheckboxItemIndicator>
|
|
117
|
+
</>
|
|
118
|
+
) : (
|
|
119
|
+
<>
|
|
120
|
+
<MenuPrimitive.CheckboxItemIndicator className="col-start-1">
|
|
121
|
+
<svg
|
|
122
|
+
fill="none"
|
|
123
|
+
height="24"
|
|
124
|
+
stroke="currentColor"
|
|
125
|
+
strokeLinecap="round"
|
|
126
|
+
strokeLinejoin="round"
|
|
127
|
+
strokeWidth="2"
|
|
128
|
+
viewBox="0 0 24 24"
|
|
129
|
+
width="24"
|
|
130
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
131
|
+
>
|
|
132
|
+
<title>Check</title>
|
|
133
|
+
<path d="M5.252 12.7 10.2 18.63 18.748 5.37" />
|
|
134
|
+
</svg>
|
|
135
|
+
</MenuPrimitive.CheckboxItemIndicator>
|
|
136
|
+
<span className="col-start-2">{children}</span>
|
|
137
|
+
</>
|
|
138
|
+
)}
|
|
139
|
+
</MenuPrimitive.CheckboxItem>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function MenuRadioGroup(props: MenuPrimitive.RadioGroup.Props) {
|
|
144
|
+
return <MenuPrimitive.RadioGroup data-slot="menu-radio-group" {...props} />;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function MenuRadioItem({
|
|
148
|
+
className,
|
|
149
|
+
children,
|
|
150
|
+
...props
|
|
151
|
+
}: MenuPrimitive.RadioItem.Props) {
|
|
152
|
+
return (
|
|
153
|
+
<MenuPrimitive.RadioItem
|
|
154
|
+
className={cn(
|
|
155
|
+
"grid min-h-8 in-data-[side=none]:min-w-[calc(var(--anchor-width)+1.25rem)] cursor-default grid-cols-[1rem_1fr] items-center gap-2 rounded-sm py-1 ps-2 pe-4 text-base text-foreground outline-none data-disabled:pointer-events-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
156
|
+
className,
|
|
157
|
+
)}
|
|
158
|
+
data-slot="menu-radio-item"
|
|
159
|
+
{...props}
|
|
160
|
+
>
|
|
161
|
+
<MenuPrimitive.RadioItemIndicator className="col-start-1">
|
|
162
|
+
<svg
|
|
163
|
+
fill="none"
|
|
164
|
+
height="24"
|
|
165
|
+
stroke="currentColor"
|
|
166
|
+
strokeLinecap="round"
|
|
167
|
+
strokeLinejoin="round"
|
|
168
|
+
strokeWidth="2"
|
|
169
|
+
viewBox="0 0 24 24"
|
|
170
|
+
width="24"
|
|
171
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
172
|
+
>
|
|
173
|
+
<title>Check</title>
|
|
174
|
+
<path d="M5.252 12.7 10.2 18.63 18.748 5.37" />
|
|
175
|
+
</svg>
|
|
176
|
+
</MenuPrimitive.RadioItemIndicator>
|
|
177
|
+
<span className="col-start-2">{children}</span>
|
|
178
|
+
</MenuPrimitive.RadioItem>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function MenuGroupLabel({
|
|
183
|
+
className,
|
|
184
|
+
inset,
|
|
185
|
+
...props
|
|
186
|
+
}: MenuPrimitive.GroupLabel.Props & {
|
|
187
|
+
inset?: boolean;
|
|
188
|
+
}) {
|
|
189
|
+
return (
|
|
190
|
+
<MenuPrimitive.GroupLabel
|
|
191
|
+
className={cn(
|
|
192
|
+
"px-2 py-1.5 font-medium text-muted-foreground text-xs data-inset:ps-9 sm:data-inset:ps-8",
|
|
193
|
+
className,
|
|
194
|
+
)}
|
|
195
|
+
data-inset={inset}
|
|
196
|
+
data-slot="menu-label"
|
|
197
|
+
{...props}
|
|
198
|
+
/>
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function MenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {
|
|
203
|
+
return (
|
|
204
|
+
<MenuPrimitive.Separator
|
|
205
|
+
className={cn("mx-2 my-1 h-px bg-border", className)}
|
|
206
|
+
data-slot="menu-separator"
|
|
207
|
+
{...props}
|
|
208
|
+
/>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function MenuShortcut({ className, ...props }: React.ComponentProps<"kbd">) {
|
|
213
|
+
return (
|
|
214
|
+
<kbd
|
|
215
|
+
className={cn(
|
|
216
|
+
"ms-auto font-medium font-sans text-muted-foreground/72 text-xs tracking-widest",
|
|
217
|
+
className,
|
|
218
|
+
)}
|
|
219
|
+
data-slot="menu-shortcut"
|
|
220
|
+
{...props}
|
|
221
|
+
/>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function MenuSub(props: MenuPrimitive.SubmenuRoot.Props) {
|
|
226
|
+
return <MenuPrimitive.SubmenuRoot data-slot="menu-sub" {...props} />;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function MenuSubTrigger({
|
|
230
|
+
className,
|
|
231
|
+
inset,
|
|
232
|
+
children,
|
|
233
|
+
...props
|
|
234
|
+
}: MenuPrimitive.SubmenuTrigger.Props & {
|
|
235
|
+
inset?: boolean;
|
|
236
|
+
}) {
|
|
237
|
+
return (
|
|
238
|
+
<MenuPrimitive.SubmenuTrigger
|
|
239
|
+
className={cn(
|
|
240
|
+
"flex min-h-8 items-center gap-2 rounded-sm px-2 py-1 text-base text-foreground outline-none data-disabled:pointer-events-none data-highlighted:bg-accent data-popup-open:bg-accent data-inset:ps-8 data-highlighted:text-accent-foreground data-popup-open:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
|
|
241
|
+
className,
|
|
242
|
+
)}
|
|
243
|
+
data-inset={inset}
|
|
244
|
+
data-slot="menu-sub-trigger"
|
|
245
|
+
{...props}
|
|
246
|
+
>
|
|
247
|
+
{children}
|
|
248
|
+
<ChevronRightIcon className="-me-0.5 ms-auto opacity-80" />
|
|
249
|
+
</MenuPrimitive.SubmenuTrigger>
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function MenuSubPopup({
|
|
254
|
+
className,
|
|
255
|
+
sideOffset = 0,
|
|
256
|
+
alignOffset,
|
|
257
|
+
align = "start",
|
|
258
|
+
...props
|
|
259
|
+
}: MenuPrimitive.Popup.Props & {
|
|
260
|
+
align?: MenuPrimitive.Positioner.Props["align"];
|
|
261
|
+
sideOffset?: MenuPrimitive.Positioner.Props["sideOffset"];
|
|
262
|
+
alignOffset?: MenuPrimitive.Positioner.Props["alignOffset"];
|
|
263
|
+
}) {
|
|
264
|
+
const defaultAlignOffset = align !== "center" ? -5 : undefined;
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<MenuPopup
|
|
268
|
+
align={align}
|
|
269
|
+
alignOffset={alignOffset ?? defaultAlignOffset}
|
|
270
|
+
className={className}
|
|
271
|
+
data-slot="menu-sub-content"
|
|
272
|
+
side="inline-end"
|
|
273
|
+
sideOffset={sideOffset}
|
|
274
|
+
{...props}
|
|
275
|
+
/>
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export {
|
|
280
|
+
MenuCreateHandle,
|
|
281
|
+
MenuCreateHandle as DropdownMenuCreateHandle,
|
|
282
|
+
Menu,
|
|
283
|
+
Menu as DropdownMenu,
|
|
284
|
+
MenuPortal,
|
|
285
|
+
MenuPortal as DropdownMenuPortal,
|
|
286
|
+
MenuTrigger,
|
|
287
|
+
MenuTrigger as DropdownMenuTrigger,
|
|
288
|
+
MenuPopup,
|
|
289
|
+
MenuPopup as DropdownMenuContent,
|
|
290
|
+
MenuGroup,
|
|
291
|
+
MenuGroup as DropdownMenuGroup,
|
|
292
|
+
MenuItem,
|
|
293
|
+
MenuItem as DropdownMenuItem,
|
|
294
|
+
MenuCheckboxItem,
|
|
295
|
+
MenuCheckboxItem as DropdownMenuCheckboxItem,
|
|
296
|
+
MenuRadioGroup,
|
|
297
|
+
MenuRadioGroup as DropdownMenuRadioGroup,
|
|
298
|
+
MenuRadioItem,
|
|
299
|
+
MenuRadioItem as DropdownMenuRadioItem,
|
|
300
|
+
MenuGroupLabel,
|
|
301
|
+
MenuGroupLabel as DropdownMenuLabel,
|
|
302
|
+
MenuSeparator,
|
|
303
|
+
MenuSeparator as DropdownMenuSeparator,
|
|
304
|
+
MenuShortcut,
|
|
305
|
+
MenuShortcut as DropdownMenuShortcut,
|
|
306
|
+
MenuSub,
|
|
307
|
+
MenuSub as DropdownMenuSub,
|
|
308
|
+
MenuSubTrigger,
|
|
309
|
+
MenuSubTrigger as DropdownMenuSubTrigger,
|
|
310
|
+
MenuSubPopup,
|
|
311
|
+
MenuSubPopup as DropdownMenuSubContent,
|
|
312
|
+
};
|