@luanthnh/cntt-ui 0.1.5
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/.storybook/globals.d.ts +1 -0
- package/.storybook/main.ts +29 -0
- package/.storybook/preview.ts +32 -0
- package/README.md +86 -0
- package/assets/fonts/Montserrat-Black.eot +0 -0
- package/assets/fonts/Montserrat-Black.ttf +0 -0
- package/assets/fonts/Montserrat-Black.woff +0 -0
- package/assets/fonts/Montserrat-Black.woff2 +0 -0
- package/assets/fonts/Montserrat-BlackItalic.eot +0 -0
- package/assets/fonts/Montserrat-BlackItalic.ttf +0 -0
- package/assets/fonts/Montserrat-BlackItalic.woff +0 -0
- package/assets/fonts/Montserrat-BlackItalic.woff2 +0 -0
- package/assets/fonts/Montserrat-Bold.eot +0 -0
- package/assets/fonts/Montserrat-Bold.ttf +0 -0
- package/assets/fonts/Montserrat-Bold.woff +0 -0
- package/assets/fonts/Montserrat-Bold.woff2 +0 -0
- package/assets/fonts/Montserrat-BoldItalic.eot +0 -0
- package/assets/fonts/Montserrat-BoldItalic.ttf +0 -0
- package/assets/fonts/Montserrat-BoldItalic.woff +0 -0
- package/assets/fonts/Montserrat-BoldItalic.woff2 +0 -0
- package/assets/fonts/Montserrat-ExtraBold.eot +0 -0
- package/assets/fonts/Montserrat-ExtraBold.ttf +0 -0
- package/assets/fonts/Montserrat-ExtraBold.woff +0 -0
- package/assets/fonts/Montserrat-ExtraBold.woff2 +0 -0
- package/assets/fonts/Montserrat-ExtraBoldItalic.eot +0 -0
- package/assets/fonts/Montserrat-ExtraBoldItalic.ttf +0 -0
- package/assets/fonts/Montserrat-ExtraBoldItalic.woff +0 -0
- package/assets/fonts/Montserrat-ExtraBoldItalic.woff2 +0 -0
- package/assets/fonts/Montserrat-ExtraLight.eot +0 -0
- package/assets/fonts/Montserrat-ExtraLight.ttf +0 -0
- package/assets/fonts/Montserrat-ExtraLight.woff +0 -0
- package/assets/fonts/Montserrat-ExtraLight.woff2 +0 -0
- package/assets/fonts/Montserrat-ExtraLightItalic.eot +0 -0
- package/assets/fonts/Montserrat-ExtraLightItalic.ttf +0 -0
- package/assets/fonts/Montserrat-ExtraLightItalic.woff +0 -0
- package/assets/fonts/Montserrat-ExtraLightItalic.woff2 +0 -0
- package/assets/fonts/Montserrat-Italic.eot +0 -0
- package/assets/fonts/Montserrat-Italic.ttf +0 -0
- package/assets/fonts/Montserrat-Italic.woff +0 -0
- package/assets/fonts/Montserrat-Italic.woff2 +0 -0
- package/assets/fonts/Montserrat-Light.eot +0 -0
- package/assets/fonts/Montserrat-Light.ttf +0 -0
- package/assets/fonts/Montserrat-Light.woff +0 -0
- package/assets/fonts/Montserrat-Light.woff2 +0 -0
- package/assets/fonts/Montserrat-LightItalic.eot +0 -0
- package/assets/fonts/Montserrat-LightItalic.ttf +0 -0
- package/assets/fonts/Montserrat-LightItalic.woff +0 -0
- package/assets/fonts/Montserrat-LightItalic.woff2 +0 -0
- package/assets/fonts/Montserrat-Medium.eot +0 -0
- package/assets/fonts/Montserrat-Medium.ttf +0 -0
- package/assets/fonts/Montserrat-Medium.woff +0 -0
- package/assets/fonts/Montserrat-Medium.woff2 +0 -0
- package/assets/fonts/Montserrat-MediumItalic.eot +0 -0
- package/assets/fonts/Montserrat-MediumItalic.ttf +0 -0
- package/assets/fonts/Montserrat-MediumItalic.woff +0 -0
- package/assets/fonts/Montserrat-MediumItalic.woff2 +0 -0
- package/assets/fonts/Montserrat-Regular.eot +0 -0
- package/assets/fonts/Montserrat-Regular.ttf +0 -0
- package/assets/fonts/Montserrat-Regular.woff +0 -0
- package/assets/fonts/Montserrat-Regular.woff2 +0 -0
- package/assets/fonts/Montserrat-SemiBold.eot +0 -0
- package/assets/fonts/Montserrat-SemiBold.ttf +0 -0
- package/assets/fonts/Montserrat-SemiBold.woff +0 -0
- package/assets/fonts/Montserrat-SemiBold.woff2 +0 -0
- package/assets/fonts/Montserrat-SemiBoldItalic.eot +0 -0
- package/assets/fonts/Montserrat-SemiBoldItalic.ttf +0 -0
- package/assets/fonts/Montserrat-SemiBoldItalic.woff +0 -0
- package/assets/fonts/Montserrat-SemiBoldItalic.woff2 +0 -0
- package/assets/fonts/Montserrat-Thin.eot +0 -0
- package/assets/fonts/Montserrat-Thin.ttf +0 -0
- package/assets/fonts/Montserrat-Thin.woff +0 -0
- package/assets/fonts/Montserrat-Thin.woff2 +0 -0
- package/assets/fonts/Montserrat-ThinItalic.eot +0 -0
- package/assets/fonts/Montserrat-ThinItalic.ttf +0 -0
- package/assets/fonts/Montserrat-ThinItalic.woff +0 -0
- package/assets/fonts/Montserrat-ThinItalic.woff2 +0 -0
- package/assets/fonts/Montserrat-Variable.eot +0 -0
- package/assets/fonts/Montserrat-Variable.ttf +0 -0
- package/assets/fonts/Montserrat-Variable.woff +0 -0
- package/assets/fonts/Montserrat-Variable.woff2 +0 -0
- package/assets/fonts/Montserrat-VariableItalic.eot +0 -0
- package/assets/fonts/Montserrat-VariableItalic.ttf +0 -0
- package/assets/fonts/Montserrat-VariableItalic.woff +0 -0
- package/assets/fonts/Montserrat-VariableItalic.woff2 +0 -0
- package/assets/icons/arrow-left.svg +1 -0
- package/assets/icons/file.svg +1 -0
- package/assets/icons/globe.svg +1 -0
- package/assets/icons/logo-line.svg +1 -0
- package/assets/icons/next.svg +1 -0
- package/assets/icons/panel-left-expand.svg +1 -0
- package/assets/icons/placeholder.svg +57 -0
- package/assets/icons/vercel.svg +1 -0
- package/assets/icons/window.svg +1 -0
- package/assets/lotties/error-404.json +19642 -0
- package/assets/lotties/error.json +2414 -0
- package/assets/lotties/loader.json +305 -0
- package/components/Welcome.mdx +74 -0
- package/components/lenis/index.tsx +48 -0
- package/components/motion/auto-height.tsx +56 -0
- package/components/motion/cursor.tsx +108 -0
- package/components/motion/highlight.tsx +605 -0
- package/components/motion/number-ticker.tsx +55 -0
- package/components/motion/slot.tsx +106 -0
- package/components/motion/waves.tsx +417 -0
- package/components/primitives/tabs.tsx +174 -0
- package/components/ui/Accordion/index.stories.tsx +39 -0
- package/components/ui/Accordion/index.tsx +170 -0
- package/components/ui/Alert/index.stories.tsx +39 -0
- package/components/ui/Alert/index.tsx +60 -0
- package/components/ui/AlertDialog/index.stories.tsx +47 -0
- package/components/ui/AlertDialog/index.tsx +172 -0
- package/components/ui/AspectRatio/index.stories.tsx +40 -0
- package/components/ui/AspectRatio/index.tsx +9 -0
- package/components/ui/Avatar/index.stories.tsx +39 -0
- package/components/ui/Avatar/index.tsx +44 -0
- package/components/ui/Badge/index.stories.tsx +64 -0
- package/components/ui/Badge/index.tsx +46 -0
- package/components/ui/Breadcrumb/index.stories.tsx +64 -0
- package/components/ui/Breadcrumb/index.tsx +102 -0
- package/components/ui/Button/index.stories.tsx +232 -0
- package/components/ui/Button/index.tsx +114 -0
- package/components/ui/Calendar/index.stories.tsx +20 -0
- package/components/ui/Calendar/index.tsx +149 -0
- package/components/ui/Card/index.stories.tsx +39 -0
- package/components/ui/Card/index.tsx +65 -0
- package/components/ui/Carousel/index.stories.tsx +37 -0
- package/components/ui/Carousel/index.tsx +242 -0
- package/components/ui/Chart/index.stories.tsx +53 -0
- package/components/ui/Chart/index.tsx +322 -0
- package/components/ui/Checkbox/index.stories.tsx +56 -0
- package/components/ui/Checkbox/index.tsx +167 -0
- package/components/ui/CircleProcess/index.stories.tsx +29 -0
- package/components/ui/CircleProcess/index.tsx +50 -0
- package/components/ui/Collapsible/index.stories.tsx +33 -0
- package/components/ui/Collapsible/index.tsx +124 -0
- package/components/ui/Command/index.stories.tsx +65 -0
- package/components/ui/Command/index.tsx +161 -0
- package/components/ui/Container/index.stories.tsx +22 -0
- package/components/ui/Container/index.tsx +30 -0
- package/components/ui/ContextMenu/index.stories.tsx +51 -0
- package/components/ui/ContextMenu/index.tsx +224 -0
- package/components/ui/Dialog/index.stories.tsx +44 -0
- package/components/ui/Dialog/index.tsx +156 -0
- package/components/ui/Drawer/index.stories.tsx +54 -0
- package/components/ui/Drawer/index.tsx +124 -0
- package/components/ui/DropdownMenu/index.stories.tsx +83 -0
- package/components/ui/DropdownMenu/index.tsx +231 -0
- package/components/ui/Dropzone/index.stories.tsx +18 -0
- package/components/ui/Dropzone/index.tsx +47 -0
- package/components/ui/Form/date-field.tsx +77 -0
- package/components/ui/Form/index.stories.tsx +67 -0
- package/components/ui/Form/index.tsx +188 -0
- package/components/ui/Form/select-field.tsx +55 -0
- package/components/ui/Form/text-area-field.tsx +37 -0
- package/components/ui/Form/text-field.tsx +72 -0
- package/components/ui/HStack/index.stories.tsx +48 -0
- package/components/ui/HStack/index.tsx +73 -0
- package/components/ui/HoverCard/index.stories.tsx +38 -0
- package/components/ui/HoverCard/index.tsx +38 -0
- package/components/ui/Icons/index.stories.tsx +27 -0
- package/components/ui/Icons/index.tsx +33 -0
- package/components/ui/ImageWithFallback/index.stories.tsx +32 -0
- package/components/ui/ImageWithFallback/index.tsx +34 -0
- package/components/ui/Input/index.stories.tsx +47 -0
- package/components/ui/Input/index.tsx +21 -0
- package/components/ui/InputOtp/index.stories.tsx +35 -0
- package/components/ui/InputOtp/index.tsx +70 -0
- package/components/ui/Label/index.stories.tsx +18 -0
- package/components/ui/Label/index.tsx +21 -0
- package/components/ui/Marquee/index.stories.tsx +71 -0
- package/components/ui/Marquee/index.tsx +65 -0
- package/components/ui/Menubar/index.stories.tsx +116 -0
- package/components/ui/Menubar/index.tsx +252 -0
- package/components/ui/NavigationMenu/index.stories.tsx +112 -0
- package/components/ui/NavigationMenu/index.tsx +185 -0
- package/components/ui/NoData/index.stories.tsx +24 -0
- package/components/ui/NoData/index.tsx +19 -0
- package/components/ui/Pagination/index.stories.tsx +53 -0
- package/components/ui/Pagination/index.tsx +114 -0
- package/components/ui/Popover/index.stories.tsx +31 -0
- package/components/ui/Popover/index.tsx +42 -0
- package/components/ui/Progress/index.stories.tsx +35 -0
- package/components/ui/Progress/index.tsx +28 -0
- package/components/ui/RadioGroup/index.stories.tsx +28 -0
- package/components/ui/RadioGroup/index.tsx +45 -0
- package/components/ui/Resizable/index.stories.tsx +44 -0
- package/components/ui/Resizable/index.tsx +54 -0
- package/components/ui/ScrollArea/index.stories.tsx +31 -0
- package/components/ui/ScrollArea/index.tsx +56 -0
- package/components/ui/Select/index.stories.tsx +64 -0
- package/components/ui/Select/index.tsx +170 -0
- package/components/ui/Separator/index.stories.tsx +31 -0
- package/components/ui/Separator/index.tsx +28 -0
- package/components/ui/Sheet/index.stories.tsx +45 -0
- package/components/ui/Sheet/index.tsx +130 -0
- package/components/ui/Sidebar/index.stories.tsx +82 -0
- package/components/ui/Sidebar/index.tsx +676 -0
- package/components/ui/Skeleton/index.stories.tsx +36 -0
- package/components/ui/Skeleton/index.tsx +13 -0
- package/components/ui/Slider/index.stories.tsx +48 -0
- package/components/ui/Slider/index.tsx +82 -0
- package/components/ui/Slot/index.stories.tsx +29 -0
- package/components/ui/Slot/index.tsx +106 -0
- package/components/ui/Sonner/index.stories.tsx +36 -0
- package/components/ui/Sonner/index.tsx +31 -0
- package/components/ui/Switch/index.stories.tsx +33 -0
- package/components/ui/Switch/index.tsx +28 -0
- package/components/ui/Table/index.stories.tsx +74 -0
- package/components/ui/Table/index.tsx +95 -0
- package/components/ui/Tabs/index.stories.tsx +38 -0
- package/components/ui/Tabs/index.tsx +78 -0
- package/components/ui/Text/index.stories.tsx +53 -0
- package/components/ui/Text/index.tsx +138 -0
- package/components/ui/Textarea/index.stories.tsx +25 -0
- package/components/ui/Textarea/index.tsx +18 -0
- package/components/ui/Toggle/index.stories.tsx +52 -0
- package/components/ui/Toggle/index.tsx +46 -0
- package/components/ui/ToggleGroup/index.stories.tsx +52 -0
- package/components/ui/ToggleGroup/index.tsx +69 -0
- package/components/ui/Tooltip/index.stories.tsx +29 -0
- package/components/ui/Tooltip/index.tsx +35 -0
- package/components/ui/VStack/index.stories.tsx +45 -0
- package/components/ui/VStack/index.tsx +69 -0
- package/components/ui/colors.stories.tsx +148 -0
- package/dist/arrow-left-46B4CAEY.svg +1 -0
- package/dist/file-4IXBJF4J.svg +1 -0
- package/dist/globe-KVAXBN2U.svg +1 -0
- package/dist/index.cjs +6001 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +693 -0
- package/dist/index.d.ts +693 -0
- package/dist/index.js +5714 -0
- package/dist/index.js.map +1 -0
- package/dist/logo-line-QLUD5DAV.svg +1 -0
- package/dist/next-HOXZBJQP.svg +1 -0
- package/dist/panel-left-expand-SIPFBG4J.svg +1 -0
- package/dist/placeholder-H3V4XYVI.svg +57 -0
- package/dist/vercel-KFYFHF3A.svg +1 -0
- package/dist/window-JNUL4Q2E.svg +1 -0
- package/eslint.config.js +10 -0
- package/globals.css +994 -0
- package/hooks/index.ts +3 -0
- package/hooks/use-auto-height.tsx +99 -0
- package/hooks/use-controlled-state.tsx +32 -0
- package/hooks/use-mobile.ts +19 -0
- package/index.ts +58 -0
- package/lib/get-strict-context.ts +15 -0
- package/lib/utils.ts +10 -0
- package/package.json +107 -0
- package/scripts/generate-exports.ts +32 -0
- package/tsconfig.json +12 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsup.config.ts +11 -0
- package/types/svg.d.ts +10 -0
- package/vercel.json +5 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { Button } from '@/components/ui/Button';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Dialog,
|
|
7
|
+
DialogContent,
|
|
8
|
+
DialogDescription,
|
|
9
|
+
DialogFooter,
|
|
10
|
+
DialogHeader,
|
|
11
|
+
DialogTitle,
|
|
12
|
+
DialogTrigger,
|
|
13
|
+
} from './index';
|
|
14
|
+
|
|
15
|
+
const meta: Meta<typeof Dialog> = {
|
|
16
|
+
title: 'UI/Dialog',
|
|
17
|
+
component: Dialog,
|
|
18
|
+
tags: ['autodocs'],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof Dialog>;
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
render: (args) => (
|
|
26
|
+
<Dialog {...args}>
|
|
27
|
+
<DialogTrigger asChild>
|
|
28
|
+
<Button variant="outline">Open Dialog</Button>
|
|
29
|
+
</DialogTrigger>
|
|
30
|
+
<DialogContent>
|
|
31
|
+
<DialogHeader>
|
|
32
|
+
<DialogTitle>Are you absolutely sure?</DialogTitle>
|
|
33
|
+
<DialogDescription>
|
|
34
|
+
This action cannot be undone. This will permanently delete your account and remove your
|
|
35
|
+
data from our servers.
|
|
36
|
+
</DialogDescription>
|
|
37
|
+
</DialogHeader>
|
|
38
|
+
<DialogFooter>
|
|
39
|
+
<Button type="submit">Confirm</Button>
|
|
40
|
+
</DialogFooter>
|
|
41
|
+
</DialogContent>
|
|
42
|
+
</Dialog>
|
|
43
|
+
),
|
|
44
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
5
|
+
import { useLenis } from 'lenis/react';
|
|
6
|
+
import { XIcon } from 'lucide-react';
|
|
7
|
+
|
|
8
|
+
import { cn } from '@/lib/utils';
|
|
9
|
+
import { useControlledState } from '@/hooks/use-controlled-state';
|
|
10
|
+
|
|
11
|
+
function Dialog({
|
|
12
|
+
open: openProp,
|
|
13
|
+
defaultOpen = false,
|
|
14
|
+
onOpenChange,
|
|
15
|
+
...props
|
|
16
|
+
}: React.ComponentProps<typeof DialogPrimitive.Root> & {
|
|
17
|
+
open?: boolean;
|
|
18
|
+
defaultOpen?: boolean;
|
|
19
|
+
onOpenChange?: (open: boolean) => void;
|
|
20
|
+
}) {
|
|
21
|
+
const [open, setOpen] = useControlledState<boolean>({
|
|
22
|
+
value: openProp,
|
|
23
|
+
defaultValue: defaultOpen,
|
|
24
|
+
onChange: onOpenChange,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const lenis = useLenis();
|
|
28
|
+
|
|
29
|
+
React.useEffect(() => {
|
|
30
|
+
if (open) {
|
|
31
|
+
lenis?.stop();
|
|
32
|
+
} else {
|
|
33
|
+
lenis?.start();
|
|
34
|
+
}
|
|
35
|
+
}, [open, lenis]);
|
|
36
|
+
|
|
37
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} open={open} onOpenChange={setOpen} />;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
41
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
45
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
49
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function DialogOverlay({
|
|
53
|
+
className,
|
|
54
|
+
...props
|
|
55
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
56
|
+
return (
|
|
57
|
+
<DialogPrimitive.Overlay
|
|
58
|
+
data-slot="dialog-overlay"
|
|
59
|
+
className={cn(
|
|
60
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
|
|
61
|
+
className,
|
|
62
|
+
)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function DialogContent({
|
|
69
|
+
className,
|
|
70
|
+
children,
|
|
71
|
+
showCloseButton = true,
|
|
72
|
+
...props
|
|
73
|
+
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
|
74
|
+
showCloseButton?: boolean;
|
|
75
|
+
}) {
|
|
76
|
+
return (
|
|
77
|
+
<DialogPortal data-slot="dialog-portal">
|
|
78
|
+
<DialogOverlay />
|
|
79
|
+
<DialogPrimitive.Content
|
|
80
|
+
data-slot="dialog-content"
|
|
81
|
+
className={cn(
|
|
82
|
+
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-2xl border p-6 shadow-lg duration-200 sm:max-w-lg',
|
|
83
|
+
className,
|
|
84
|
+
)}
|
|
85
|
+
{...props}
|
|
86
|
+
>
|
|
87
|
+
{children}
|
|
88
|
+
{showCloseButton && (
|
|
89
|
+
<DialogPrimitive.Close
|
|
90
|
+
data-slot="dialog-close"
|
|
91
|
+
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
92
|
+
>
|
|
93
|
+
<XIcon />
|
|
94
|
+
<span className="sr-only">Close</span>
|
|
95
|
+
</DialogPrimitive.Close>
|
|
96
|
+
)}
|
|
97
|
+
</DialogPrimitive.Content>
|
|
98
|
+
</DialogPortal>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
103
|
+
return (
|
|
104
|
+
<div
|
|
105
|
+
data-slot="dialog-header"
|
|
106
|
+
className={cn('flex flex-col gap-2 text-center sm:text-left', className)}
|
|
107
|
+
{...props}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
113
|
+
return (
|
|
114
|
+
<div
|
|
115
|
+
data-slot="dialog-footer"
|
|
116
|
+
className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
|
|
117
|
+
{...props}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
123
|
+
return (
|
|
124
|
+
<DialogPrimitive.Title
|
|
125
|
+
data-slot="dialog-title"
|
|
126
|
+
className={cn('text-lg leading-none font-semibold', className)}
|
|
127
|
+
{...props}
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function DialogDescription({
|
|
133
|
+
className,
|
|
134
|
+
...props
|
|
135
|
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
136
|
+
return (
|
|
137
|
+
<DialogPrimitive.Description
|
|
138
|
+
data-slot="dialog-description"
|
|
139
|
+
className={cn('text-muted-foreground text-sm', className)}
|
|
140
|
+
{...props}
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
Dialog,
|
|
147
|
+
DialogClose,
|
|
148
|
+
DialogContent,
|
|
149
|
+
DialogDescription,
|
|
150
|
+
DialogFooter,
|
|
151
|
+
DialogHeader,
|
|
152
|
+
DialogOverlay,
|
|
153
|
+
DialogPortal,
|
|
154
|
+
DialogTitle,
|
|
155
|
+
DialogTrigger,
|
|
156
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { Button } from '../Button';
|
|
4
|
+
import {
|
|
5
|
+
Drawer,
|
|
6
|
+
DrawerClose,
|
|
7
|
+
DrawerContent,
|
|
8
|
+
DrawerDescription,
|
|
9
|
+
DrawerFooter,
|
|
10
|
+
DrawerHeader,
|
|
11
|
+
DrawerTitle,
|
|
12
|
+
DrawerTrigger,
|
|
13
|
+
} from './index';
|
|
14
|
+
|
|
15
|
+
const meta: Meta<typeof Drawer> = {
|
|
16
|
+
title: 'UI/Drawer',
|
|
17
|
+
component: Drawer,
|
|
18
|
+
tags: ['autodocs'],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof Drawer>;
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
render: (args) => (
|
|
26
|
+
<Drawer {...args}>
|
|
27
|
+
<DrawerTrigger asChild>
|
|
28
|
+
<Button variant="outline">Open Drawer</Button>
|
|
29
|
+
</DrawerTrigger>
|
|
30
|
+
<DrawerContent>
|
|
31
|
+
<div className="mx-auto w-full max-w-sm">
|
|
32
|
+
<DrawerHeader>
|
|
33
|
+
<DrawerTitle>Move Goal</DrawerTitle>
|
|
34
|
+
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
|
|
35
|
+
</DrawerHeader>
|
|
36
|
+
<div className="p-4 pb-0">
|
|
37
|
+
<div className="flex items-center justify-center space-x-2">
|
|
38
|
+
<div className="flex-1 text-center">
|
|
39
|
+
<div className="text-7xl font-bold tracking-tighter">350</div>
|
|
40
|
+
<div className="text-muted-foreground text-[0.70rem] uppercase">Calories/day</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
<DrawerFooter>
|
|
45
|
+
<Button>Submit</Button>
|
|
46
|
+
<DrawerClose asChild>
|
|
47
|
+
<Button variant="outline">Cancel</Button>
|
|
48
|
+
</DrawerClose>
|
|
49
|
+
</DrawerFooter>
|
|
50
|
+
</div>
|
|
51
|
+
</DrawerContent>
|
|
52
|
+
</Drawer>
|
|
53
|
+
),
|
|
54
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Drawer as DrawerPrimitive } from 'vaul';
|
|
5
|
+
|
|
6
|
+
import { cn } from '@/lib/utils';
|
|
7
|
+
|
|
8
|
+
function Drawer({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Root>) {
|
|
9
|
+
return <DrawerPrimitive.Root data-slot="drawer" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function DrawerTrigger({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
|
|
13
|
+
return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function DrawerPortal({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
|
|
17
|
+
return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function DrawerClose({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
|
|
21
|
+
return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function DrawerOverlay({
|
|
25
|
+
className,
|
|
26
|
+
...props
|
|
27
|
+
}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
|
|
28
|
+
return (
|
|
29
|
+
<DrawerPrimitive.Overlay
|
|
30
|
+
data-slot="drawer-overlay"
|
|
31
|
+
className={cn(
|
|
32
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
|
|
33
|
+
className,
|
|
34
|
+
)}
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function DrawerContent({
|
|
41
|
+
className,
|
|
42
|
+
children,
|
|
43
|
+
...props
|
|
44
|
+
}: React.ComponentProps<typeof DrawerPrimitive.Content>) {
|
|
45
|
+
return (
|
|
46
|
+
<DrawerPortal data-slot="drawer-portal">
|
|
47
|
+
<DrawerOverlay />
|
|
48
|
+
<DrawerPrimitive.Content
|
|
49
|
+
data-slot="drawer-content"
|
|
50
|
+
className={cn(
|
|
51
|
+
'group/drawer-content bg-background fixed z-50 flex h-auto flex-col',
|
|
52
|
+
'data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b',
|
|
53
|
+
'data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t',
|
|
54
|
+
'data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm',
|
|
55
|
+
'data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm',
|
|
56
|
+
className,
|
|
57
|
+
)}
|
|
58
|
+
{...props}
|
|
59
|
+
>
|
|
60
|
+
<div className="bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
|
|
61
|
+
{children}
|
|
62
|
+
</DrawerPrimitive.Content>
|
|
63
|
+
</DrawerPortal>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
data-slot="drawer-header"
|
|
71
|
+
className={cn(
|
|
72
|
+
'flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left',
|
|
73
|
+
className,
|
|
74
|
+
)}
|
|
75
|
+
{...props}
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
81
|
+
return (
|
|
82
|
+
<div
|
|
83
|
+
data-slot="drawer-footer"
|
|
84
|
+
className={cn('mt-auto flex flex-col gap-2 p-4', className)}
|
|
85
|
+
{...props}
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function DrawerTitle({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
|
|
91
|
+
return (
|
|
92
|
+
<DrawerPrimitive.Title
|
|
93
|
+
data-slot="drawer-title"
|
|
94
|
+
className={cn('text-foreground font-semibold', className)}
|
|
95
|
+
{...props}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function DrawerDescription({
|
|
101
|
+
className,
|
|
102
|
+
...props
|
|
103
|
+
}: React.ComponentProps<typeof DrawerPrimitive.Description>) {
|
|
104
|
+
return (
|
|
105
|
+
<DrawerPrimitive.Description
|
|
106
|
+
data-slot="drawer-description"
|
|
107
|
+
className={cn('text-muted-foreground text-sm', className)}
|
|
108
|
+
{...props}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export {
|
|
114
|
+
Drawer,
|
|
115
|
+
DrawerPortal,
|
|
116
|
+
DrawerOverlay,
|
|
117
|
+
DrawerTrigger,
|
|
118
|
+
DrawerClose,
|
|
119
|
+
DrawerContent,
|
|
120
|
+
DrawerHeader,
|
|
121
|
+
DrawerFooter,
|
|
122
|
+
DrawerTitle,
|
|
123
|
+
DrawerDescription,
|
|
124
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { Button } from '../Button';
|
|
4
|
+
import {
|
|
5
|
+
DropdownMenu,
|
|
6
|
+
DropdownMenuContent,
|
|
7
|
+
DropdownMenuGroup,
|
|
8
|
+
DropdownMenuItem,
|
|
9
|
+
DropdownMenuLabel,
|
|
10
|
+
DropdownMenuSeparator,
|
|
11
|
+
DropdownMenuShortcut,
|
|
12
|
+
DropdownMenuSub,
|
|
13
|
+
DropdownMenuSubContent,
|
|
14
|
+
DropdownMenuSubTrigger,
|
|
15
|
+
DropdownMenuTrigger,
|
|
16
|
+
} from './index';
|
|
17
|
+
|
|
18
|
+
const meta: Meta<typeof DropdownMenu> = {
|
|
19
|
+
title: 'UI/DropdownMenu',
|
|
20
|
+
component: DropdownMenu,
|
|
21
|
+
tags: ['autodocs'],
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default meta;
|
|
25
|
+
type Story = StoryObj<typeof DropdownMenu>;
|
|
26
|
+
|
|
27
|
+
export const Default: Story = {
|
|
28
|
+
render: (args) => (
|
|
29
|
+
<DropdownMenu {...args}>
|
|
30
|
+
<DropdownMenuTrigger asChild>
|
|
31
|
+
<Button variant="outline">Open Menu</Button>
|
|
32
|
+
</DropdownMenuTrigger>
|
|
33
|
+
<DropdownMenuContent className="w-56">
|
|
34
|
+
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
|
35
|
+
<DropdownMenuSeparator />
|
|
36
|
+
<DropdownMenuGroup>
|
|
37
|
+
<DropdownMenuItem>
|
|
38
|
+
Profile
|
|
39
|
+
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
|
|
40
|
+
</DropdownMenuItem>
|
|
41
|
+
<DropdownMenuItem>
|
|
42
|
+
Billing
|
|
43
|
+
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
|
|
44
|
+
</DropdownMenuItem>
|
|
45
|
+
<DropdownMenuItem>
|
|
46
|
+
Settings
|
|
47
|
+
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
|
|
48
|
+
</DropdownMenuItem>
|
|
49
|
+
<DropdownMenuItem>
|
|
50
|
+
Keyboard shortcuts
|
|
51
|
+
<DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
|
|
52
|
+
</DropdownMenuItem>
|
|
53
|
+
</DropdownMenuGroup>
|
|
54
|
+
<DropdownMenuSeparator />
|
|
55
|
+
<DropdownMenuGroup>
|
|
56
|
+
<DropdownMenuItem>Team</DropdownMenuItem>
|
|
57
|
+
<DropdownMenuSub>
|
|
58
|
+
<DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>
|
|
59
|
+
<DropdownMenuSubContent>
|
|
60
|
+
<DropdownMenuItem>Email</DropdownMenuItem>
|
|
61
|
+
<DropdownMenuItem>Message</DropdownMenuItem>
|
|
62
|
+
<DropdownMenuSeparator />
|
|
63
|
+
<DropdownMenuItem>More...</DropdownMenuItem>
|
|
64
|
+
</DropdownMenuSubContent>
|
|
65
|
+
</DropdownMenuSub>
|
|
66
|
+
<DropdownMenuItem>
|
|
67
|
+
New Team
|
|
68
|
+
<DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
|
|
69
|
+
</DropdownMenuItem>
|
|
70
|
+
</DropdownMenuGroup>
|
|
71
|
+
<DropdownMenuSeparator />
|
|
72
|
+
<DropdownMenuItem>GitHub</DropdownMenuItem>
|
|
73
|
+
<DropdownMenuItem>Support</DropdownMenuItem>
|
|
74
|
+
<DropdownMenuItem disabled>API</DropdownMenuItem>
|
|
75
|
+
<DropdownMenuSeparator />
|
|
76
|
+
<DropdownMenuItem variant="destructive">
|
|
77
|
+
Log out
|
|
78
|
+
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
|
|
79
|
+
</DropdownMenuItem>
|
|
80
|
+
</DropdownMenuContent>
|
|
81
|
+
</DropdownMenu>
|
|
82
|
+
),
|
|
83
|
+
};
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
5
|
+
import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
import { cn } from '@/lib/utils';
|
|
8
|
+
|
|
9
|
+
function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
|
10
|
+
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function DropdownMenuPortal({
|
|
14
|
+
...props
|
|
15
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
|
|
16
|
+
return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const DropdownMenuTrigger = React.forwardRef<
|
|
20
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,
|
|
21
|
+
React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>
|
|
22
|
+
>(({ ...props }, ref) => {
|
|
23
|
+
return <DropdownMenuPrimitive.Trigger ref={ref} data-slot="dropdown-menu-trigger" {...props} />;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
DropdownMenuTrigger.displayName = 'DropdownMenuTrigger';
|
|
27
|
+
|
|
28
|
+
function DropdownMenuContent({
|
|
29
|
+
className,
|
|
30
|
+
sideOffset = 4,
|
|
31
|
+
...props
|
|
32
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
|
33
|
+
return (
|
|
34
|
+
<DropdownMenuPrimitive.Portal>
|
|
35
|
+
<DropdownMenuPrimitive.Content
|
|
36
|
+
data-slot="dropdown-menu-content"
|
|
37
|
+
sideOffset={sideOffset}
|
|
38
|
+
className={cn(
|
|
39
|
+
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=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 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-2xl border border-gray-100 p-1 shadow-sm dark:border-gray-800',
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
</DropdownMenuPrimitive.Portal>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
|
|
49
|
+
return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function DropdownMenuItem({
|
|
53
|
+
className,
|
|
54
|
+
inset,
|
|
55
|
+
variant = 'default',
|
|
56
|
+
...props
|
|
57
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
|
58
|
+
inset?: boolean;
|
|
59
|
+
variant?: 'default' | 'destructive';
|
|
60
|
+
}) {
|
|
61
|
+
return (
|
|
62
|
+
<DropdownMenuPrimitive.Item
|
|
63
|
+
data-slot="dropdown-menu-item"
|
|
64
|
+
data-inset={inset}
|
|
65
|
+
data-variant={variant}
|
|
66
|
+
className={cn(
|
|
67
|
+
"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 [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-pointer items-center gap-2 rounded-xl px-2 py-1.5 text-base !ring-offset-0 outline-hidden !outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
68
|
+
className,
|
|
69
|
+
)}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function DropdownMenuCheckboxItem({
|
|
76
|
+
className,
|
|
77
|
+
children,
|
|
78
|
+
checked,
|
|
79
|
+
...props
|
|
80
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
|
|
81
|
+
return (
|
|
82
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
83
|
+
data-slot="dropdown-menu-checkbox-item"
|
|
84
|
+
className={cn(
|
|
85
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-pointer items-center gap-2 rounded-xl py-1.5 pr-2 pl-8 text-base !ring-offset-0 outline-hidden !outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
86
|
+
className,
|
|
87
|
+
)}
|
|
88
|
+
checked={checked}
|
|
89
|
+
{...props}
|
|
90
|
+
>
|
|
91
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
92
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
93
|
+
<CheckIcon className="size-4" />
|
|
94
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
95
|
+
</span>
|
|
96
|
+
{children}
|
|
97
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function DropdownMenuRadioGroup({
|
|
102
|
+
...props
|
|
103
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
|
|
104
|
+
return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function DropdownMenuRadioItem({
|
|
108
|
+
className,
|
|
109
|
+
children,
|
|
110
|
+
...props
|
|
111
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
|
|
112
|
+
return (
|
|
113
|
+
<DropdownMenuPrimitive.RadioItem
|
|
114
|
+
data-slot="dropdown-menu-radio-item"
|
|
115
|
+
className={cn(
|
|
116
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-pointer items-center gap-2 rounded-xl py-1.5 pr-2 pl-8 text-base !ring-offset-0 outline-hidden !outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
117
|
+
className,
|
|
118
|
+
)}
|
|
119
|
+
{...props}
|
|
120
|
+
>
|
|
121
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
122
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
123
|
+
<CircleIcon className="size-2 fill-current" />
|
|
124
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
125
|
+
</span>
|
|
126
|
+
{children}
|
|
127
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function DropdownMenuLabel({
|
|
132
|
+
className,
|
|
133
|
+
inset,
|
|
134
|
+
...props
|
|
135
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
|
|
136
|
+
inset?: boolean;
|
|
137
|
+
}) {
|
|
138
|
+
return (
|
|
139
|
+
<DropdownMenuPrimitive.Label
|
|
140
|
+
data-slot="dropdown-menu-label"
|
|
141
|
+
data-inset={inset}
|
|
142
|
+
className={cn('px-2 py-1.5 text-base font-medium data-[inset]:pl-8', className)}
|
|
143
|
+
{...props}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function DropdownMenuSeparator({
|
|
149
|
+
className,
|
|
150
|
+
...props
|
|
151
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
|
152
|
+
return (
|
|
153
|
+
<DropdownMenuPrimitive.Separator
|
|
154
|
+
data-slot="dropdown-menu-separator"
|
|
155
|
+
className={cn('-mx-1 my-1 h-px bg-gray-100 dark:bg-gray-800', className)}
|
|
156
|
+
{...props}
|
|
157
|
+
/>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
|
|
162
|
+
return (
|
|
163
|
+
<span
|
|
164
|
+
data-slot="dropdown-menu-shortcut"
|
|
165
|
+
className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}
|
|
166
|
+
{...props}
|
|
167
|
+
/>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
|
|
172
|
+
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function DropdownMenuSubTrigger({
|
|
176
|
+
className,
|
|
177
|
+
inset,
|
|
178
|
+
children,
|
|
179
|
+
...props
|
|
180
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
181
|
+
inset?: boolean;
|
|
182
|
+
}) {
|
|
183
|
+
return (
|
|
184
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
185
|
+
data-slot="dropdown-menu-sub-trigger"
|
|
186
|
+
data-inset={inset}
|
|
187
|
+
className={cn(
|
|
188
|
+
'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-xl px-2 py-1.5 text-base outline-hidden select-none data-[inset]:pl-8',
|
|
189
|
+
className,
|
|
190
|
+
)}
|
|
191
|
+
{...props}
|
|
192
|
+
>
|
|
193
|
+
{children}
|
|
194
|
+
<ChevronRightIcon className="ml-auto size-4" />
|
|
195
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function DropdownMenuSubContent({
|
|
200
|
+
className,
|
|
201
|
+
...props
|
|
202
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
|
|
203
|
+
return (
|
|
204
|
+
<DropdownMenuPrimitive.SubContent
|
|
205
|
+
data-slot="dropdown-menu-sub-content"
|
|
206
|
+
className={cn(
|
|
207
|
+
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=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 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-2xl border border-gray-100 p-1 shadow-lg !ring-0 !ring-offset-0 !outline-none dark:border-gray-800',
|
|
208
|
+
className,
|
|
209
|
+
)}
|
|
210
|
+
{...props}
|
|
211
|
+
/>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export {
|
|
216
|
+
DropdownMenu,
|
|
217
|
+
DropdownMenuPortal,
|
|
218
|
+
DropdownMenuTrigger,
|
|
219
|
+
DropdownMenuContent,
|
|
220
|
+
DropdownMenuGroup,
|
|
221
|
+
DropdownMenuLabel,
|
|
222
|
+
DropdownMenuItem,
|
|
223
|
+
DropdownMenuCheckboxItem,
|
|
224
|
+
DropdownMenuRadioGroup,
|
|
225
|
+
DropdownMenuRadioItem,
|
|
226
|
+
DropdownMenuSeparator,
|
|
227
|
+
DropdownMenuShortcut,
|
|
228
|
+
DropdownMenuSub,
|
|
229
|
+
DropdownMenuSubTrigger,
|
|
230
|
+
DropdownMenuSubContent,
|
|
231
|
+
};
|