@ponti-studios/ui 0.1.2 → 0.3.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/LICENSE +21 -0
- package/README.md +7 -7
- package/THIRD_PARTY_NOTICES.md +17 -0
- package/dist/index.js +1028 -638
- package/dist/index.js.map +1 -1
- package/package.json +30 -32
- package/src/animations.css +16 -434
- package/src/components/data-display/accordion.tsx +10 -7
- package/src/components/data-display/filter-chip.tsx +2 -2
- package/src/components/data-display/index.ts +5 -0
- package/src/components/data-display/metric-card.stories.tsx +48 -0
- package/src/components/data-display/metric-card.tsx +20 -0
- package/src/components/data-display/sort-controls.stories.tsx +45 -0
- package/src/components/data-display/sort-controls.tsx +99 -0
- package/src/components/data-display/sort-row.tsx +74 -0
- package/src/components/data-display/table.tsx +5 -5
- package/src/components/feedback/alert.tsx +4 -4
- package/src/components/feedback/empty-state.tsx +6 -6
- package/src/components/feedback/file-upload-status-badge.stories.tsx +28 -0
- package/src/components/feedback/file-upload-status-badge.tsx +33 -0
- package/src/components/feedback/file-upload-status.stories.tsx +57 -0
- package/src/components/feedback/file-upload-status.tsx +152 -0
- package/src/components/feedback/index.ts +9 -0
- package/src/components/feedback/progress-bar.stories.tsx +39 -0
- package/src/components/feedback/progress-bar.tsx +21 -0
- package/src/components/feedback/progress.stories.tsx +8 -6
- package/src/components/feedback/progress.tsx +1 -1
- package/src/components/feedback/skeleton.stories.tsx +36 -0
- package/src/components/feedback/skeleton.tsx +7 -0
- package/src/components/feedback/spinner.tsx +2 -2
- package/src/components/feedback/update-guard.stories.tsx +32 -0
- package/src/components/feedback/update-guard.tsx +280 -0
- package/src/components/forms/calendar.tsx +11 -11
- package/src/components/forms/date-month-select.stories.tsx +26 -0
- package/src/components/forms/date-month-select.tsx +70 -0
- package/src/components/forms/date-picker.tsx +3 -3
- package/src/components/forms/drop-zone.stories.tsx +56 -0
- package/src/components/forms/drop-zone.tsx +146 -0
- package/src/components/forms/entity-select.stories.tsx +65 -0
- package/src/components/forms/entity-select.tsx +79 -0
- package/src/components/forms/field.tsx +3 -3
- package/src/components/forms/group-by-select.stories.tsx +26 -0
- package/src/components/forms/group-by-select.tsx +47 -0
- package/src/components/forms/index.ts +10 -0
- package/src/components/forms/input.stories.tsx +4 -4
- package/src/components/forms/input.tsx +1 -1
- package/src/components/forms/passkey-management.stories.tsx +81 -0
- package/src/components/forms/passkey-management.tsx +138 -0
- package/src/components/forms/radio-group.tsx +14 -13
- package/src/components/forms/select.stories.tsx +4 -4
- package/src/components/forms/select.tsx +45 -53
- package/src/components/forms/slider.stories.tsx +5 -2
- package/src/components/forms/slider.tsx +27 -17
- package/src/components/forms/stepper.tsx +4 -4
- package/src/components/forms/switch.stories.tsx +1 -1
- package/src/components/forms/switch.tsx +2 -2
- package/src/components/forms/textarea.stories.tsx +2 -2
- package/src/components/forms/textarea.tsx +1 -1
- package/src/components/layout/index.ts +3 -0
- package/src/components/layout/scroll-area.stories.tsx +4 -4
- package/src/components/layout/scroll-area.tsx +23 -21
- package/src/components/layout/section-intro.stories.tsx +29 -0
- package/src/components/layout/section-intro.tsx +31 -0
- package/src/components/layout/surface-panel.stories.tsx +32 -0
- package/src/components/layout/surface-panel.tsx +15 -0
- package/src/components/navigation/app-navigation.stories.tsx +2 -2
- package/src/components/navigation/app-navigation.tsx +13 -13
- package/src/components/navigation/index.ts +4 -0
- package/src/components/navigation/pagination-controls.stories.tsx +41 -0
- package/src/components/navigation/pagination-controls.tsx +50 -0
- package/src/components/navigation/route-link.stories.tsx +30 -0
- package/src/components/navigation/route-link.tsx +42 -0
- package/src/components/navigation/tabs.stories.tsx +5 -5
- package/src/components/navigation/tabs.tsx +7 -7
- package/src/components/overlays/alert-dialog.tsx +21 -46
- package/src/components/overlays/command.tsx +51 -82
- package/src/components/overlays/dialog.tsx +5 -5
- package/src/components/overlays/dropdown-menu.stories.tsx +0 -5
- package/src/components/overlays/dropdown-menu.tsx +44 -142
- package/src/components/overlays/popover.stories.tsx +2 -2
- package/src/components/overlays/popover.tsx +34 -16
- package/src/components/overlays/sheet.stories.tsx +2 -2
- package/src/components/overlays/sheet.tsx +35 -17
- package/src/components/primitives/avatar.tsx +3 -3
- package/src/components/primitives/badge.tsx +7 -11
- package/src/components/primitives/button.tsx +41 -13
- package/src/components/primitives/card.stories.tsx +2 -2
- package/src/components/primitives/card.tsx +2 -2
- package/src/components/primitives/index.ts +2 -0
- package/src/components/primitives/label.stories.tsx +1 -1
- package/src/components/primitives/label.tsx +5 -6
- package/src/components/primitives/status-badge.stories.tsx +52 -0
- package/src/components/primitives/status-badge.tsx +33 -0
- package/src/constants/chart-colors.ts +5 -5
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-sort.ts +20 -0
- package/src/index.ts +30 -11
- package/src/styles.css +76 -1040
- package/src/tokens/color-systems.stories.tsx +9 -119
- package/src/tokens/foundations.stories.tsx +21 -113
- package/src/tokens/generated/dark.colors.generated.ts +56 -0
- package/src/tokens/generated/dark.css +54 -0
- package/src/tokens/generated/foundations.css +148 -0
- package/src/tokens/generated/foundations.generated.ts +443 -0
- package/src/tokens/generated/light.colors.generated.ts +56 -0
- package/src/tokens/generated/light.css +54 -0
- package/src/tokens/index.ts +74 -16
- package/src/tokens/layout.stories.tsx +3 -108
- package/src/tokens/colors.ts +0 -156
- package/src/tokens/motion.ts +0 -51
- package/src/tokens/radii.ts +0 -10
- package/src/tokens/shadows.ts +0 -34
- package/src/tokens/spacing.ts +0 -30
- package/src/tokens/typography.ts +0 -42
|
@@ -1,130 +1,99 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Combobox as CommandPrimitive } from "@base-ui/react/combobox";
|
|
2
2
|
import { SearchIcon } from "lucide-react";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
5
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./dialog";
|
|
6
6
|
|
|
7
|
-
function Command(props: React.ComponentProps<typeof CommandPrimitive>) {
|
|
7
|
+
function Command({ className, children, ...props }: Omit<React.ComponentProps<typeof CommandPrimitive.Root<string>>, "className"> & { className?: string }) {
|
|
8
8
|
return (
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
{...props}
|
|
13
|
-
/>
|
|
9
|
+
<div data-slot="command" className={`bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md ${className ?? ""}`}>
|
|
10
|
+
<CommandPrimitive.Root {...props}>{children}</CommandPrimitive.Root>
|
|
11
|
+
</div>
|
|
14
12
|
);
|
|
15
13
|
}
|
|
16
14
|
|
|
17
|
-
function CommandDialog({
|
|
18
|
-
title = "Command Palette",
|
|
19
|
-
description = "Search for a command to run...",
|
|
20
|
-
children,
|
|
21
|
-
showCloseButton = true,
|
|
22
|
-
...props
|
|
23
|
-
}: Omit<React.ComponentProps<typeof Dialog>, "children"> & {
|
|
24
|
-
title?: string;
|
|
25
|
-
description?: string;
|
|
26
|
-
showCloseButton?: boolean;
|
|
27
|
-
children?: React.ReactNode;
|
|
28
|
-
}) {
|
|
15
|
+
function CommandDialog({ title = "Command Palette", description = "Search for a command to run...", children, showCloseButton = true, ...props }: Omit<React.ComponentProps<typeof Dialog>, "children"> & { title?: string; description?: string; showCloseButton?: boolean; children?: React.ReactNode }) {
|
|
29
16
|
return (
|
|
30
17
|
<Dialog {...props}>
|
|
31
|
-
<DialogHeader className="sr-only">
|
|
32
|
-
|
|
33
|
-
<DialogDescription>{description}</DialogDescription>
|
|
34
|
-
</DialogHeader>
|
|
35
|
-
<DialogContent className="overflow-hidden p-0" showCloseButton={showCloseButton}>
|
|
36
|
-
<Command>{children}</Command>
|
|
37
|
-
</DialogContent>
|
|
18
|
+
<DialogHeader className="sr-only"><DialogTitle>{title}</DialogTitle><DialogDescription>{description}</DialogDescription></DialogHeader>
|
|
19
|
+
<DialogContent className="overflow-hidden p-0" showCloseButton={showCloseButton}><Command>{children}</Command></DialogContent>
|
|
38
20
|
</Dialog>
|
|
39
21
|
);
|
|
40
22
|
}
|
|
41
23
|
|
|
42
|
-
|
|
24
|
+
type CommandInputProps = React.ComponentProps<typeof CommandPrimitive.Input> & { onValueChange?: (value: string) => void };
|
|
25
|
+
|
|
26
|
+
function CommandInput({ className, onValueChange, onChange, "aria-label": ariaLabel = "Search commands", ...props }: CommandInputProps) {
|
|
43
27
|
return (
|
|
44
28
|
<div data-slot="command-input-wrapper" className="flex h-9 items-center gap-2 border-b px-3">
|
|
45
29
|
<SearchIcon className="size-4 shrink-0 opacity-50" />
|
|
46
30
|
<CommandPrimitive.Input
|
|
47
31
|
data-slot="command-input"
|
|
48
|
-
|
|
32
|
+
aria-label={ariaLabel}
|
|
33
|
+
className={`placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50 ${className ?? ""}`}
|
|
34
|
+
onChange={(event) => { onChange?.(event); onValueChange?.(event.currentTarget.value); }}
|
|
49
35
|
{...props}
|
|
50
36
|
/>
|
|
51
37
|
</div>
|
|
52
38
|
);
|
|
53
39
|
}
|
|
54
40
|
|
|
55
|
-
function CommandList(props: React.ComponentProps<typeof CommandPrimitive.List>) {
|
|
41
|
+
function CommandList({ children, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
|
|
42
|
+
if (typeof children === "function") {
|
|
43
|
+
return (
|
|
44
|
+
<CommandPrimitive.List data-slot="command-list" aria-label="Command results" tabIndex={0} className="max-h-75 scroll-py-1 overflow-x-hidden overflow-y-auto" {...props}>
|
|
45
|
+
{children}
|
|
46
|
+
</CommandPrimitive.List>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const listChildren: React.ReactNode[] = [];
|
|
51
|
+
const emptyChildren: React.ReactNode[] = [];
|
|
52
|
+
|
|
53
|
+
React.Children.forEach(children, (child) => {
|
|
54
|
+
if (React.isValidElement(child) && child.type === CommandEmpty) emptyChildren.push(child);
|
|
55
|
+
else listChildren.push(child);
|
|
56
|
+
});
|
|
57
|
+
|
|
56
58
|
return (
|
|
57
|
-
<
|
|
58
|
-
data-slot="command-list"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
<div data-slot="command-list-container" className="relative">
|
|
60
|
+
<CommandPrimitive.List data-slot="command-list" aria-label="Command results" tabIndex={0} className="max-h-75 scroll-py-1 overflow-x-hidden overflow-y-auto" {...props}>
|
|
61
|
+
{listChildren}
|
|
62
|
+
</CommandPrimitive.List>
|
|
63
|
+
{emptyChildren}
|
|
64
|
+
</div>
|
|
62
65
|
);
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
function CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {
|
|
66
|
-
return
|
|
67
|
-
<CommandPrimitive.Empty
|
|
68
|
-
data-slot="command-empty"
|
|
69
|
-
className="py-6 text-center text-sm"
|
|
70
|
-
{...props}
|
|
71
|
-
/>
|
|
72
|
-
);
|
|
69
|
+
return <CommandPrimitive.Empty data-slot="command-empty" className="py-6 text-center text-sm" {...props} />;
|
|
73
70
|
}
|
|
74
71
|
|
|
75
|
-
function CommandGroup(props: React.ComponentProps<typeof CommandPrimitive.Group>) {
|
|
72
|
+
function CommandGroup({ className, heading, children, ...props }: React.ComponentProps<typeof CommandPrimitive.Group> & { heading?: React.ReactNode }) {
|
|
76
73
|
return (
|
|
77
|
-
<CommandPrimitive.Group
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
/>
|
|
74
|
+
<CommandPrimitive.Group data-slot="command-group" className={`text-foreground overflow-hidden p-1 ${className ?? ""}`} {...props}>
|
|
75
|
+
{heading ? <CommandPrimitive.GroupLabel className="text-muted-foreground px-2 py-1.5 text-xs font-medium">{heading}</CommandPrimitive.GroupLabel> : null}
|
|
76
|
+
{children}
|
|
77
|
+
</CommandPrimitive.Group>
|
|
82
78
|
);
|
|
83
79
|
}
|
|
84
80
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
className="bg-border -mx-1 h-px"
|
|
90
|
-
{...props}
|
|
91
|
-
/>
|
|
92
|
-
);
|
|
81
|
+
type CommandItemProps = React.ComponentProps<typeof CommandPrimitive.Item> & { onSelect?: () => void };
|
|
82
|
+
|
|
83
|
+
function CommandItem({ className, onSelect, onClick, ...props }: CommandItemProps) {
|
|
84
|
+
return <CommandPrimitive.Item data-slot="command-item" className={`data-highlighted:bg-accent data-highlighted:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 ${className ?? ""}`} onClick={(event) => { onClick?.(event); onSelect?.(); }} {...props} />;
|
|
93
85
|
}
|
|
94
86
|
|
|
95
|
-
function
|
|
96
|
-
return
|
|
97
|
-
<CommandPrimitive.Item
|
|
98
|
-
data-slot="command-item"
|
|
99
|
-
className="data-[selected=true]:bg-accent data-[selected=true]:text-on-accent [&_svg:not([class*='text-'])]:text-secondary relative flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
100
|
-
{...props}
|
|
101
|
-
/>
|
|
102
|
-
);
|
|
87
|
+
function CommandSeparator({ className, ...props }: React.ComponentProps<"div">) {
|
|
88
|
+
return <div data-slot="command-separator" aria-hidden="true" className={`bg-border -mx-1 h-px ${className ?? ""}`} {...props} />;
|
|
103
89
|
}
|
|
104
90
|
|
|
105
91
|
function CommandShortcut(props: React.ComponentProps<"span">) {
|
|
106
|
-
return
|
|
107
|
-
<span
|
|
108
|
-
data-slot="command-shortcut"
|
|
109
|
-
className="text-secondary ml-auto text-xs tracking-widest"
|
|
110
|
-
{...props}
|
|
111
|
-
/>
|
|
112
|
-
);
|
|
92
|
+
return <span data-slot="command-shortcut" className="text-muted-foreground ml-auto text-xs tracking-widest" {...props} />;
|
|
113
93
|
}
|
|
114
94
|
|
|
115
95
|
function CommandListLoading(props: React.ComponentProps<"div">) {
|
|
116
96
|
return <div data-slot="command-list-loading" className="py-6 text-center text-sm" {...props} />;
|
|
117
97
|
}
|
|
118
98
|
|
|
119
|
-
export {
|
|
120
|
-
Command,
|
|
121
|
-
CommandDialog,
|
|
122
|
-
CommandEmpty,
|
|
123
|
-
CommandGroup,
|
|
124
|
-
CommandInput,
|
|
125
|
-
CommandItem,
|
|
126
|
-
CommandList,
|
|
127
|
-
CommandListLoading,
|
|
128
|
-
CommandSeparator,
|
|
129
|
-
CommandShortcut,
|
|
130
|
-
};
|
|
99
|
+
export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandListLoading, CommandSeparator, CommandShortcut };
|
|
@@ -63,7 +63,7 @@ function DialogOverlay({ className, ...props }: React.ComponentProps<typeof Base
|
|
|
63
63
|
<BaseDialog.Backdrop
|
|
64
64
|
data-slot="dialog-overlay"
|
|
65
65
|
className={cn(
|
|
66
|
-
"
|
|
66
|
+
"bg-black/80 data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 fixed inset-0 z-50 transition-opacity",
|
|
67
67
|
className,
|
|
68
68
|
)}
|
|
69
69
|
{...props}
|
|
@@ -85,7 +85,7 @@ function DialogContent({
|
|
|
85
85
|
<BaseDialog.Popup
|
|
86
86
|
data-slot="dialog-content"
|
|
87
87
|
className={cn(
|
|
88
|
-
"bg-
|
|
88
|
+
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid max-h-[90dvh] w-[calc(100%-2rem)] max-w-[30rem] translate-x-[-50%] translate-y-[-50%] gap-6 overflow-y-auto rounded-lg border p-4 duration-200 outline-none sm:p-6",
|
|
89
89
|
className,
|
|
90
90
|
)}
|
|
91
91
|
{...props}
|
|
@@ -94,7 +94,7 @@ function DialogContent({
|
|
|
94
94
|
{showCloseButton && (
|
|
95
95
|
<BaseDialog.Close
|
|
96
96
|
data-slot="dialog-close"
|
|
97
|
-
className="text-
|
|
97
|
+
className="text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-ring absolute top-3 right-3 inline-flex size-11 items-center justify-center rounded-md border border-transparent opacity-100 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 disabled:pointer-events-none sm:top-4 sm:right-4 [&_svg]:pointer-events-none [&_svg]:size-4.5 [&_svg]:shrink-0"
|
|
98
98
|
>
|
|
99
99
|
<XIcon />
|
|
100
100
|
<span className="sr-only">Close</span>
|
|
@@ -129,7 +129,7 @@ function DialogTitle({ className, ...props }: React.ComponentProps<typeof BaseDi
|
|
|
129
129
|
return (
|
|
130
130
|
<BaseDialog.Title
|
|
131
131
|
data-slot="dialog-title"
|
|
132
|
-
className={cn("
|
|
132
|
+
className={cn("text-lg font-semibold leading-none tracking-tight", className)}
|
|
133
133
|
{...props}
|
|
134
134
|
/>
|
|
135
135
|
);
|
|
@@ -142,7 +142,7 @@ function DialogDescription({
|
|
|
142
142
|
return (
|
|
143
143
|
<BaseDialog.Description
|
|
144
144
|
data-slot="dialog-description"
|
|
145
|
-
className={cn("
|
|
145
|
+
className={cn("max-w-prose text-sm text-muted-foreground", className)}
|
|
146
146
|
{...props}
|
|
147
147
|
/>
|
|
148
148
|
);
|
|
@@ -31,11 +31,6 @@ const meta = {
|
|
|
31
31
|
description: "When true, interaction outside the menu is disabled while open",
|
|
32
32
|
table: { defaultValue: { summary: "true" } },
|
|
33
33
|
},
|
|
34
|
-
dir: {
|
|
35
|
-
control: "select",
|
|
36
|
-
options: ["ltr", "rtl"],
|
|
37
|
-
description: "Reading direction of the dropdown menu",
|
|
38
|
-
},
|
|
39
34
|
},
|
|
40
35
|
} satisfies Meta<typeof DropdownMenu>;
|
|
41
36
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Menu as DropdownMenuPrimitive } from "@base-ui/react/menu";
|
|
2
2
|
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
@@ -12,26 +12,33 @@ function DropdownMenuPortal(props: React.ComponentProps<typeof DropdownMenuPrimi
|
|
|
12
12
|
return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function DropdownMenuTrigger(props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
|
|
16
|
-
return
|
|
15
|
+
function DropdownMenuTrigger({ asChild, children, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger> & { asChild?: boolean }) {
|
|
16
|
+
return (
|
|
17
|
+
<DropdownMenuPrimitive.Trigger
|
|
18
|
+
data-slot="dropdown-menu-trigger"
|
|
19
|
+
{...(asChild && React.isValidElement(children) ? { render: children as React.ReactElement } : {})}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
{!asChild && children}
|
|
23
|
+
</DropdownMenuPrimitive.Trigger>
|
|
24
|
+
);
|
|
17
25
|
}
|
|
18
26
|
|
|
19
|
-
function DropdownMenuContent({
|
|
20
|
-
className,
|
|
21
|
-
sideOffset = 4,
|
|
22
|
-
...props
|
|
23
|
-
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
|
27
|
+
function DropdownMenuContent({ className, sideOffset = 4, children, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Popup> & { sideOffset?: number }) {
|
|
24
28
|
return (
|
|
25
29
|
<DropdownMenuPrimitive.Portal>
|
|
26
|
-
<DropdownMenuPrimitive.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
<DropdownMenuPrimitive.Positioner sideOffset={sideOffset}>
|
|
31
|
+
<DropdownMenuPrimitive.Popup
|
|
32
|
+
data-slot="dropdown-menu-content"
|
|
33
|
+
className={cn(
|
|
34
|
+
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 z-50 max-h-(--available-height) min-w-[8rem] origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 outline-none",
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
{children}
|
|
40
|
+
</DropdownMenuPrimitive.Popup>
|
|
41
|
+
</DropdownMenuPrimitive.Positioner>
|
|
35
42
|
</DropdownMenuPrimitive.Portal>
|
|
36
43
|
);
|
|
37
44
|
}
|
|
@@ -40,159 +47,54 @@ function DropdownMenuGroup(props: React.ComponentProps<typeof DropdownMenuPrimit
|
|
|
40
47
|
return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
function DropdownMenuLabel({
|
|
44
|
-
className,
|
|
45
|
-
inset,
|
|
46
|
-
...props
|
|
47
|
-
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & { inset?: boolean }) {
|
|
48
|
-
return (
|
|
49
|
-
<DropdownMenuPrimitive.Label
|
|
50
|
-
data-slot="dropdown-menu-label"
|
|
51
|
-
data-inset={inset}
|
|
52
|
-
className={cn("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", className)}
|
|
53
|
-
{...props}
|
|
54
|
-
/>
|
|
55
|
-
);
|
|
50
|
+
function DropdownMenuLabel({ className, inset, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.GroupLabel> & { inset?: boolean }) {
|
|
51
|
+
return <DropdownMenuPrimitive.GroupLabel data-slot="dropdown-menu-label" data-inset={inset} className={cn("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", className)} {...props} />;
|
|
56
52
|
}
|
|
57
53
|
|
|
58
|
-
function DropdownMenuItem({
|
|
59
|
-
className,
|
|
60
|
-
inset,
|
|
61
|
-
variant = "default",
|
|
62
|
-
...props
|
|
63
|
-
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
|
64
|
-
inset?: boolean;
|
|
65
|
-
variant?: "default" | "destructive";
|
|
66
|
-
}) {
|
|
67
|
-
return (
|
|
68
|
-
<DropdownMenuPrimitive.Item
|
|
69
|
-
data-slot="dropdown-menu-item"
|
|
70
|
-
data-inset={inset}
|
|
71
|
-
data-variant={variant}
|
|
72
|
-
className={cn(
|
|
73
|
-
"focus:bg-accent focus:text-on-accent data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
74
|
-
className,
|
|
75
|
-
)}
|
|
76
|
-
{...props}
|
|
77
|
-
/>
|
|
78
|
-
);
|
|
54
|
+
function DropdownMenuItem({ className, inset, variant = "default", ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & { inset?: boolean; variant?: "default" | "destructive" }) {
|
|
55
|
+
return <DropdownMenuPrimitive.Item data-slot="dropdown-menu-item" data-inset={inset} data-variant={variant} className={cn("data-highlighted:bg-accent data-highlighted:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:data-highlighted:bg-destructive/10 relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", className)} {...props} />;
|
|
79
56
|
}
|
|
80
57
|
|
|
81
|
-
function DropdownMenuCheckboxItem({
|
|
82
|
-
className,
|
|
83
|
-
children,
|
|
84
|
-
checked,
|
|
85
|
-
...props
|
|
86
|
-
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
|
|
58
|
+
function DropdownMenuCheckboxItem({ className, children, checked, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
|
|
87
59
|
return (
|
|
88
|
-
<DropdownMenuPrimitive.CheckboxItem
|
|
89
|
-
|
|
90
|
-
className={cn(
|
|
91
|
-
"focus:bg-accent focus:text-on-accent relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
92
|
-
className,
|
|
93
|
-
)}
|
|
94
|
-
checked={checked}
|
|
95
|
-
{...props}
|
|
96
|
-
>
|
|
97
|
-
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
|
98
|
-
<DropdownMenuPrimitive.ItemIndicator>
|
|
99
|
-
<CheckIcon className="size-4" />
|
|
100
|
-
</DropdownMenuPrimitive.ItemIndicator>
|
|
101
|
-
</span>
|
|
60
|
+
<DropdownMenuPrimitive.CheckboxItem data-slot="dropdown-menu-checkbox-item" className={cn("data-highlighted:bg-accent data-highlighted:text-accent-foreground relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-none select-none data-disabled:pointer-events-none data-disabled:opacity-50", className)} checked={checked} {...props}>
|
|
61
|
+
<span className="absolute left-2 flex size-3.5 items-center justify-center"><DropdownMenuPrimitive.CheckboxItemIndicator><CheckIcon className="size-4" /></DropdownMenuPrimitive.CheckboxItemIndicator></span>
|
|
102
62
|
{children}
|
|
103
63
|
</DropdownMenuPrimitive.CheckboxItem>
|
|
104
64
|
);
|
|
105
65
|
}
|
|
106
66
|
|
|
107
|
-
function DropdownMenuRadioGroup(
|
|
108
|
-
props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,
|
|
109
|
-
) {
|
|
67
|
+
function DropdownMenuRadioGroup(props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
|
|
110
68
|
return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
|
|
111
69
|
}
|
|
112
70
|
|
|
113
|
-
function DropdownMenuRadioItem({
|
|
114
|
-
className,
|
|
115
|
-
children,
|
|
116
|
-
...props
|
|
117
|
-
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
|
|
71
|
+
function DropdownMenuRadioItem({ className, children, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
|
|
118
72
|
return (
|
|
119
|
-
<DropdownMenuPrimitive.RadioItem
|
|
120
|
-
|
|
121
|
-
className={cn(
|
|
122
|
-
"focus:bg-accent focus:text-on-accent relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
123
|
-
className,
|
|
124
|
-
)}
|
|
125
|
-
{...props}
|
|
126
|
-
>
|
|
127
|
-
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
|
128
|
-
<DropdownMenuPrimitive.ItemIndicator>
|
|
129
|
-
<CircleIcon className="size-2 fill-current" />
|
|
130
|
-
</DropdownMenuPrimitive.ItemIndicator>
|
|
131
|
-
</span>
|
|
73
|
+
<DropdownMenuPrimitive.RadioItem data-slot="dropdown-menu-radio-item" className={cn("data-highlighted:bg-accent data-highlighted:text-accent-foreground relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-none select-none data-disabled:pointer-events-none data-disabled:opacity-50", className)} {...props}>
|
|
74
|
+
<span className="absolute left-2 flex size-3.5 items-center justify-center"><DropdownMenuPrimitive.RadioItemIndicator><CircleIcon className="size-2 fill-current" /></DropdownMenuPrimitive.RadioItemIndicator></span>
|
|
132
75
|
{children}
|
|
133
76
|
</DropdownMenuPrimitive.RadioItem>
|
|
134
77
|
);
|
|
135
78
|
}
|
|
136
79
|
|
|
137
|
-
function DropdownMenuSeparator({
|
|
138
|
-
className,
|
|
139
|
-
...props
|
|
140
|
-
}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
|
141
|
-
return (
|
|
142
|
-
<DropdownMenuPrimitive.Separator
|
|
143
|
-
data-slot="dropdown-menu-separator"
|
|
144
|
-
className={cn("bg-border -mx-1 my-1 h-px", className)}
|
|
145
|
-
{...props}
|
|
146
|
-
/>
|
|
147
|
-
);
|
|
80
|
+
function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
|
81
|
+
return <DropdownMenuPrimitive.Separator data-slot="dropdown-menu-separator" className={cn("bg-border -mx-1 my-1 h-px", className)} {...props} />;
|
|
148
82
|
}
|
|
149
83
|
|
|
150
84
|
function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">) {
|
|
151
|
-
return (
|
|
152
|
-
<span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />
|
|
153
|
-
);
|
|
85
|
+
return <span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />;
|
|
154
86
|
}
|
|
155
87
|
|
|
156
|
-
function DropdownMenuSub(props: React.ComponentProps<typeof DropdownMenuPrimitive.
|
|
157
|
-
return <DropdownMenuPrimitive.
|
|
88
|
+
function DropdownMenuSub(props: React.ComponentProps<typeof DropdownMenuPrimitive.SubmenuRoot>) {
|
|
89
|
+
return <DropdownMenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />;
|
|
158
90
|
}
|
|
159
91
|
|
|
160
|
-
function DropdownMenuSubTrigger({
|
|
161
|
-
className,
|
|
162
|
-
inset,
|
|
163
|
-
children,
|
|
164
|
-
...props
|
|
165
|
-
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & { inset?: boolean }) {
|
|
166
|
-
return (
|
|
167
|
-
<DropdownMenuPrimitive.SubTrigger
|
|
168
|
-
data-slot="dropdown-menu-sub-trigger"
|
|
169
|
-
data-inset={inset}
|
|
170
|
-
className={cn(
|
|
171
|
-
"focus:bg-accent focus:text-on-accent data-[state=open]:bg-accent data-[state=open]:text-on-accent flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8",
|
|
172
|
-
className,
|
|
173
|
-
)}
|
|
174
|
-
{...props}
|
|
175
|
-
>
|
|
176
|
-
{children}
|
|
177
|
-
<ChevronRightIcon className="ml-auto size-4" />
|
|
178
|
-
</DropdownMenuPrimitive.SubTrigger>
|
|
179
|
-
);
|
|
92
|
+
function DropdownMenuSubTrigger({ className, inset, children, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.SubmenuTrigger> & { inset?: boolean }) {
|
|
93
|
+
return <DropdownMenuPrimitive.SubmenuTrigger data-slot="dropdown-menu-sub-trigger" data-inset={inset} className={cn("data-highlighted:bg-accent data-highlighted:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8", className)} {...props}>{children}<ChevronRightIcon className="ml-auto size-4" /></DropdownMenuPrimitive.SubmenuTrigger>;
|
|
180
94
|
}
|
|
181
95
|
|
|
182
|
-
function DropdownMenuSubContent({
|
|
183
|
-
className,
|
|
184
|
-
...props
|
|
185
|
-
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
|
|
186
|
-
return (
|
|
187
|
-
<DropdownMenuPrimitive.SubContent
|
|
188
|
-
data-slot="dropdown-menu-sub-content"
|
|
189
|
-
className={cn(
|
|
190
|
-
"bg-raised text-primary 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 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg",
|
|
191
|
-
className,
|
|
192
|
-
)}
|
|
193
|
-
{...props}
|
|
194
|
-
/>
|
|
195
|
-
);
|
|
96
|
+
function DropdownMenuSubContent({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Popup>) {
|
|
97
|
+
return <DropdownMenuPrimitive.Popup data-slot="dropdown-menu-sub-content" className={cn("bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg outline-none", className)} {...props} />;
|
|
196
98
|
}
|
|
197
99
|
|
|
198
100
|
export {
|
|
@@ -20,8 +20,8 @@ export const Default: Story = {
|
|
|
20
20
|
</PopoverTrigger>
|
|
21
21
|
<PopoverContent>
|
|
22
22
|
<div className="grid gap-1.5">
|
|
23
|
-
<h4 className="text-
|
|
24
|
-
<p className="text-
|
|
23
|
+
<h4 className="text-foreground leading-none font-medium">Dimensions</h4>
|
|
24
|
+
<p className="text-muted-foreground text-sm">Set the dimensions for the layer.</p>
|
|
25
25
|
</div>
|
|
26
26
|
<div className="grid gap-4 pt-4">
|
|
27
27
|
<div className="grid grid-cols-3 items-center gap-4">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
4
|
import { cn } from "../../lib/utils";
|
|
@@ -7,34 +7,52 @@ function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root
|
|
|
7
7
|
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
11
|
-
return
|
|
10
|
+
function PopoverTrigger({ asChild, children, ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger> & { asChild?: boolean }) {
|
|
11
|
+
return (
|
|
12
|
+
<PopoverPrimitive.Trigger
|
|
13
|
+
data-slot="popover-trigger"
|
|
14
|
+
{...(asChild && React.isValidElement(children) ? { render: children as React.ReactElement } : {})}
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
{!asChild && children}
|
|
18
|
+
</PopoverPrimitive.Trigger>
|
|
19
|
+
);
|
|
12
20
|
}
|
|
13
21
|
|
|
14
22
|
function PopoverContent({
|
|
15
23
|
className,
|
|
16
24
|
align = "center",
|
|
17
25
|
sideOffset = 4,
|
|
26
|
+
children,
|
|
27
|
+
side = "bottom",
|
|
28
|
+
avoidCollisions = true,
|
|
18
29
|
...props
|
|
19
|
-
}: React.ComponentProps<typeof PopoverPrimitive.
|
|
30
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Popup> & {
|
|
31
|
+
align?: "start" | "center" | "end";
|
|
32
|
+
sideOffset?: number;
|
|
33
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
34
|
+
avoidCollisions?: boolean;
|
|
35
|
+
}) {
|
|
20
36
|
return (
|
|
21
37
|
<PopoverPrimitive.Portal>
|
|
22
|
-
<PopoverPrimitive.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
<PopoverPrimitive.Positioner align={align} side={side} sideOffset={sideOffset} collisionAvoidance={avoidCollisions ? undefined : { side: "none", align: "none" }}>
|
|
39
|
+
<PopoverPrimitive.Popup
|
|
40
|
+
data-slot="popover-content"
|
|
41
|
+
className={cn(
|
|
42
|
+
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 z-50 w-72 origin-(--transform-origin) rounded-md border p-4 outline-hidden",
|
|
43
|
+
className,
|
|
44
|
+
)}
|
|
45
|
+
{...props}
|
|
46
|
+
>
|
|
47
|
+
{children}
|
|
48
|
+
</PopoverPrimitive.Popup>
|
|
49
|
+
</PopoverPrimitive.Positioner>
|
|
32
50
|
</PopoverPrimitive.Portal>
|
|
33
51
|
);
|
|
34
52
|
}
|
|
35
53
|
|
|
36
|
-
function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.
|
|
37
|
-
return <PopoverPrimitive.
|
|
54
|
+
function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
55
|
+
return <PopoverPrimitive.Trigger data-slot="popover-anchor" {...props} />;
|
|
38
56
|
}
|
|
39
57
|
|
|
40
58
|
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
|
|
@@ -38,14 +38,14 @@ const SheetDemo = () => (
|
|
|
38
38
|
<div className="flex flex-col gap-2">
|
|
39
39
|
<span className="text-sm font-medium">Name</span>
|
|
40
40
|
<input
|
|
41
|
-
className="border-
|
|
41
|
+
className="border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:ring-1 focus-visible:outline-none"
|
|
42
42
|
placeholder="Jane Doe"
|
|
43
43
|
/>
|
|
44
44
|
</div>
|
|
45
45
|
<div className="flex flex-col gap-2">
|
|
46
46
|
<span className="text-sm font-medium">Email</span>
|
|
47
47
|
<input
|
|
48
|
-
className="border-
|
|
48
|
+
className="border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:ring-1 focus-visible:outline-none"
|
|
49
49
|
placeholder="jane@example.com"
|
|
50
50
|
type="email"
|
|
51
51
|
/>
|