@trycompai/design-system 1.0.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/README.md +110 -0
- package/components.json +21 -0
- package/hooks/use-mobile.tsx +19 -0
- package/lib/utils.ts +6 -0
- package/package.json +103 -0
- package/postcss.config.mjs +8 -0
- package/src/components/ui/accordion.tsx +60 -0
- package/src/components/ui/alert-dialog.tsx +161 -0
- package/src/components/ui/alert.tsx +109 -0
- package/src/components/ui/aspect-ratio.tsx +21 -0
- package/src/components/ui/avatar.tsx +74 -0
- package/src/components/ui/badge.tsx +48 -0
- package/src/components/ui/breadcrumb.tsx +254 -0
- package/src/components/ui/button-group.tsx +89 -0
- package/src/components/ui/button.tsx +122 -0
- package/src/components/ui/calendar.tsx +190 -0
- package/src/components/ui/card.tsx +155 -0
- package/src/components/ui/carousel.tsx +216 -0
- package/src/components/ui/chart.tsx +325 -0
- package/src/components/ui/checkbox.tsx +22 -0
- package/src/components/ui/collapsible.tsx +17 -0
- package/src/components/ui/combobox.tsx +248 -0
- package/src/components/ui/command.tsx +189 -0
- package/src/components/ui/container.tsx +34 -0
- package/src/components/ui/context-menu.tsx +235 -0
- package/src/components/ui/dialog.tsx +122 -0
- package/src/components/ui/drawer.tsx +102 -0
- package/src/components/ui/dropdown-menu.tsx +242 -0
- package/src/components/ui/empty.tsx +94 -0
- package/src/components/ui/field.tsx +215 -0
- package/src/components/ui/grid.tsx +135 -0
- package/src/components/ui/heading.tsx +56 -0
- package/src/components/ui/hover-card.tsx +46 -0
- package/src/components/ui/index.ts +61 -0
- package/src/components/ui/input-group.tsx +128 -0
- package/src/components/ui/input-otp.tsx +84 -0
- package/src/components/ui/input.tsx +15 -0
- package/src/components/ui/item.tsx +188 -0
- package/src/components/ui/kbd.tsx +26 -0
- package/src/components/ui/label.tsx +15 -0
- package/src/components/ui/menubar.tsx +163 -0
- package/src/components/ui/navigation-menu.tsx +147 -0
- package/src/components/ui/page-header.tsx +51 -0
- package/src/components/ui/page-layout.tsx +65 -0
- package/src/components/ui/pagination.tsx +104 -0
- package/src/components/ui/popover.tsx +57 -0
- package/src/components/ui/progress.tsx +61 -0
- package/src/components/ui/radio-group.tsx +37 -0
- package/src/components/ui/resizable.tsx +41 -0
- package/src/components/ui/scroll-area.tsx +48 -0
- package/src/components/ui/section.tsx +64 -0
- package/src/components/ui/select.tsx +166 -0
- package/src/components/ui/separator.tsx +17 -0
- package/src/components/ui/sheet.tsx +104 -0
- package/src/components/ui/sidebar.tsx +707 -0
- package/src/components/ui/skeleton.tsx +5 -0
- package/src/components/ui/slider.tsx +51 -0
- package/src/components/ui/sonner.tsx +43 -0
- package/src/components/ui/spinner.tsx +14 -0
- package/src/components/ui/stack.tsx +72 -0
- package/src/components/ui/switch.tsx +26 -0
- package/src/components/ui/table.tsx +65 -0
- package/src/components/ui/tabs.tsx +69 -0
- package/src/components/ui/text.tsx +59 -0
- package/src/components/ui/textarea.tsx +13 -0
- package/src/components/ui/toggle-group.tsx +87 -0
- package/src/components/ui/toggle.tsx +42 -0
- package/src/components/ui/tooltip.tsx +52 -0
- package/src/index.ts +3 -0
- package/src/styles/globals.css +122 -0
- package/tailwind.config.ts +59 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as ResizablePrimitive from 'react-resizable-panels';
|
|
4
|
+
|
|
5
|
+
type ResizablePanelGroupProps = Omit<ResizablePrimitive.GroupProps, 'className'>;
|
|
6
|
+
|
|
7
|
+
function ResizablePanelGroup({ orientation = 'horizontal', ...props }: ResizablePanelGroupProps) {
|
|
8
|
+
return (
|
|
9
|
+
<ResizablePrimitive.Group
|
|
10
|
+
data-slot="resizable-panel-group"
|
|
11
|
+
data-orientation={orientation}
|
|
12
|
+
orientation={orientation}
|
|
13
|
+
className="flex h-full w-full data-[orientation=vertical]:flex-col"
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type ResizablePanelProps = Omit<ResizablePrimitive.PanelProps, 'className'>;
|
|
20
|
+
|
|
21
|
+
function ResizablePanel({ ...props }: ResizablePanelProps) {
|
|
22
|
+
return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type ResizableHandleProps = Omit<ResizablePrimitive.SeparatorProps, 'className'> & {
|
|
26
|
+
withHandle?: boolean;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function ResizableHandle({ withHandle, ...props }: ResizableHandleProps) {
|
|
30
|
+
return (
|
|
31
|
+
<ResizablePrimitive.Separator
|
|
32
|
+
data-slot="resizable-handle"
|
|
33
|
+
className="bg-border hover:bg-muted-foreground/20 focus-visible:ring-ring relative flex w-px items-center justify-center transition-colors after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]>div]:rotate-90"
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
36
|
+
{withHandle && <div className="bg-border z-10 flex h-4 w-1 shrink-0 rounded-full" />}
|
|
37
|
+
</ResizablePrimitive.Separator>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ScrollArea as ScrollAreaPrimitive } from '@base-ui/react/scroll-area';
|
|
2
|
+
|
|
3
|
+
import { cn } from '../../../lib/utils';
|
|
4
|
+
|
|
5
|
+
function ScrollArea({ className, children, ...props }: ScrollAreaPrimitive.Root.Props) {
|
|
6
|
+
return (
|
|
7
|
+
<ScrollAreaPrimitive.Root
|
|
8
|
+
data-slot="scroll-area"
|
|
9
|
+
className={cn('relative', className)}
|
|
10
|
+
{...props}
|
|
11
|
+
>
|
|
12
|
+
<ScrollAreaPrimitive.Viewport
|
|
13
|
+
data-slot="scroll-area-viewport"
|
|
14
|
+
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
|
15
|
+
>
|
|
16
|
+
{children}
|
|
17
|
+
</ScrollAreaPrimitive.Viewport>
|
|
18
|
+
<ScrollBar />
|
|
19
|
+
<ScrollAreaPrimitive.Corner />
|
|
20
|
+
</ScrollAreaPrimitive.Root>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function ScrollBar({
|
|
25
|
+
className,
|
|
26
|
+
orientation = 'vertical',
|
|
27
|
+
...props
|
|
28
|
+
}: ScrollAreaPrimitive.Scrollbar.Props) {
|
|
29
|
+
return (
|
|
30
|
+
<ScrollAreaPrimitive.Scrollbar
|
|
31
|
+
data-slot="scroll-area-scrollbar"
|
|
32
|
+
data-orientation={orientation}
|
|
33
|
+
orientation={orientation}
|
|
34
|
+
className={cn(
|
|
35
|
+
'data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent flex touch-none p-px transition-colors select-none',
|
|
36
|
+
className,
|
|
37
|
+
)}
|
|
38
|
+
{...props}
|
|
39
|
+
>
|
|
40
|
+
<ScrollAreaPrimitive.Thumb
|
|
41
|
+
data-slot="scroll-area-thumb"
|
|
42
|
+
className="rounded-full bg-border relative flex-1"
|
|
43
|
+
/>
|
|
44
|
+
</ScrollAreaPrimitive.Scrollbar>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { ScrollArea, ScrollBar };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { Heading } from './heading';
|
|
4
|
+
import { Stack } from './stack';
|
|
5
|
+
import { Text } from './text';
|
|
6
|
+
|
|
7
|
+
interface SectionProps extends Omit<React.ComponentProps<'section'>, 'className'> {
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
actions?: React.ReactNode;
|
|
11
|
+
/** Gap between header and content. Default is "4" */
|
|
12
|
+
gap?: '2' | '3' | '4' | '6' | '8';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function Section({ title, description, actions, gap = '4', children, ...props }: SectionProps) {
|
|
16
|
+
const hasHeader = title || description || actions;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<section data-slot="section" className="w-full" {...props}>
|
|
20
|
+
<Stack gap={gap}>
|
|
21
|
+
{hasHeader && (
|
|
22
|
+
<div className="flex items-start justify-between gap-4">
|
|
23
|
+
<Stack gap="1">
|
|
24
|
+
{title && <Heading level="3">{title}</Heading>}
|
|
25
|
+
{description && (
|
|
26
|
+
<Text size="sm" variant="muted">
|
|
27
|
+
{description}
|
|
28
|
+
</Text>
|
|
29
|
+
)}
|
|
30
|
+
</Stack>
|
|
31
|
+
{actions && <div className="flex shrink-0 items-center gap-2">{actions}</div>}
|
|
32
|
+
</div>
|
|
33
|
+
)}
|
|
34
|
+
{children}
|
|
35
|
+
</Stack>
|
|
36
|
+
</section>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function SectionHeader({ ...props }: Omit<React.ComponentProps<'div'>, 'className'>) {
|
|
41
|
+
return (
|
|
42
|
+
<div data-slot="section-header" className="flex items-start justify-between gap-4" {...props} />
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function SectionTitle({ ...props }: Omit<React.ComponentProps<typeof Heading>, 'className'>) {
|
|
47
|
+
return <Heading data-slot="section-title" level="3" {...props} />;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function SectionDescription({ ...props }: Omit<React.ComponentProps<typeof Text>, 'className'>) {
|
|
51
|
+
return <Text data-slot="section-description" size="sm" variant="muted" {...props} />;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function SectionActions({ ...props }: Omit<React.ComponentProps<'div'>, 'className'>) {
|
|
55
|
+
return (
|
|
56
|
+
<div data-slot="section-actions" className="flex shrink-0 items-center gap-2" {...props} />
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function SectionContent({ ...props }: Omit<React.ComponentProps<'div'>, 'className'>) {
|
|
61
|
+
return <div data-slot="section-content" className="w-full" {...props} />;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { Section, SectionActions, SectionContent, SectionDescription, SectionHeader, SectionTitle };
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Select as SelectPrimitive } from '@base-ui/react/select';
|
|
4
|
+
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
|
|
7
|
+
const Select = SelectPrimitive.Root;
|
|
8
|
+
|
|
9
|
+
function SelectGroup({ ...props }: Omit<SelectPrimitive.Group.Props, 'className'>) {
|
|
10
|
+
return <SelectPrimitive.Group data-slot="select-group" className="scroll-my-1 p-1" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function SelectValue({
|
|
14
|
+
placeholder,
|
|
15
|
+
...props
|
|
16
|
+
}: Omit<SelectPrimitive.Value.Props, 'className'> & {
|
|
17
|
+
/** Text to show when no value is selected */
|
|
18
|
+
placeholder?: string;
|
|
19
|
+
}) {
|
|
20
|
+
return (
|
|
21
|
+
<SelectPrimitive.Value data-slot="select-value" className="flex flex-1 text-left" {...props}>
|
|
22
|
+
{placeholder}
|
|
23
|
+
</SelectPrimitive.Value>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function SelectTrigger({
|
|
28
|
+
size = 'default',
|
|
29
|
+
children,
|
|
30
|
+
...props
|
|
31
|
+
}: Omit<SelectPrimitive.Trigger.Props, 'className'> & {
|
|
32
|
+
size?: 'sm' | 'default';
|
|
33
|
+
}) {
|
|
34
|
+
return (
|
|
35
|
+
<SelectPrimitive.Trigger
|
|
36
|
+
data-slot="select-trigger"
|
|
37
|
+
data-size={size}
|
|
38
|
+
className="border-input data-[placeholder]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 gap-1.5 rounded-lg border bg-transparent py-2 pr-2 pl-2.5 text-sm transition-colors select-none focus-visible:ring-[3px] aria-invalid:ring-[3px] data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:flex *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
<SelectPrimitive.Icon
|
|
43
|
+
render={<ChevronDownIcon className="text-muted-foreground size-4 pointer-events-none" />}
|
|
44
|
+
/>
|
|
45
|
+
</SelectPrimitive.Trigger>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function SelectContent({
|
|
50
|
+
children,
|
|
51
|
+
side = 'bottom',
|
|
52
|
+
sideOffset = 4,
|
|
53
|
+
align = 'center',
|
|
54
|
+
alignOffset = 0,
|
|
55
|
+
alignItemWithTrigger = true,
|
|
56
|
+
...props
|
|
57
|
+
}: Omit<SelectPrimitive.Popup.Props, 'className'> &
|
|
58
|
+
Pick<
|
|
59
|
+
SelectPrimitive.Positioner.Props,
|
|
60
|
+
'align' | 'alignOffset' | 'side' | 'sideOffset' | 'alignItemWithTrigger'
|
|
61
|
+
>) {
|
|
62
|
+
return (
|
|
63
|
+
<SelectPrimitive.Portal>
|
|
64
|
+
<SelectPrimitive.Positioner
|
|
65
|
+
side={side}
|
|
66
|
+
sideOffset={sideOffset}
|
|
67
|
+
align={align}
|
|
68
|
+
alignOffset={alignOffset}
|
|
69
|
+
alignItemWithTrigger={alignItemWithTrigger}
|
|
70
|
+
className="isolate z-50"
|
|
71
|
+
>
|
|
72
|
+
<SelectPrimitive.Popup
|
|
73
|
+
data-slot="select-content"
|
|
74
|
+
className="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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-36 rounded-lg shadow-md ring-1 duration-100 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto"
|
|
75
|
+
{...props}
|
|
76
|
+
>
|
|
77
|
+
<SelectScrollUpButton />
|
|
78
|
+
<SelectPrimitive.List>{children}</SelectPrimitive.List>
|
|
79
|
+
<SelectScrollDownButton />
|
|
80
|
+
</SelectPrimitive.Popup>
|
|
81
|
+
</SelectPrimitive.Positioner>
|
|
82
|
+
</SelectPrimitive.Portal>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function SelectLabel({ ...props }: Omit<SelectPrimitive.GroupLabel.Props, 'className'>) {
|
|
87
|
+
return (
|
|
88
|
+
<SelectPrimitive.GroupLabel
|
|
89
|
+
data-slot="select-label"
|
|
90
|
+
className="text-muted-foreground px-1.5 py-1 text-xs"
|
|
91
|
+
{...props}
|
|
92
|
+
/>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function SelectItem({ children, ...props }: Omit<SelectPrimitive.Item.Props, 'className'>) {
|
|
97
|
+
return (
|
|
98
|
+
<SelectPrimitive.Item
|
|
99
|
+
data-slot="select-item"
|
|
100
|
+
className="focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
101
|
+
{...props}
|
|
102
|
+
>
|
|
103
|
+
<SelectPrimitive.ItemText className="flex flex-1 gap-2 shrink-0 whitespace-nowrap">
|
|
104
|
+
{children}
|
|
105
|
+
</SelectPrimitive.ItemText>
|
|
106
|
+
<SelectPrimitive.ItemIndicator
|
|
107
|
+
render={
|
|
108
|
+
<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />
|
|
109
|
+
}
|
|
110
|
+
>
|
|
111
|
+
<CheckIcon className="pointer-events-none" />
|
|
112
|
+
</SelectPrimitive.ItemIndicator>
|
|
113
|
+
</SelectPrimitive.Item>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function SelectSeparator({ ...props }: Omit<SelectPrimitive.Separator.Props, 'className'>) {
|
|
118
|
+
return (
|
|
119
|
+
<SelectPrimitive.Separator
|
|
120
|
+
data-slot="select-separator"
|
|
121
|
+
className="bg-border -mx-1 my-1 h-px pointer-events-none"
|
|
122
|
+
{...props}
|
|
123
|
+
/>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function SelectScrollUpButton({
|
|
128
|
+
...props
|
|
129
|
+
}: Omit<React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>, 'className'>) {
|
|
130
|
+
return (
|
|
131
|
+
<SelectPrimitive.ScrollUpArrow
|
|
132
|
+
data-slot="select-scroll-up-button"
|
|
133
|
+
className="bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4 top-0 w-full"
|
|
134
|
+
{...props}
|
|
135
|
+
>
|
|
136
|
+
<ChevronUpIcon />
|
|
137
|
+
</SelectPrimitive.ScrollUpArrow>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function SelectScrollDownButton({
|
|
142
|
+
...props
|
|
143
|
+
}: Omit<React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>, 'className'>) {
|
|
144
|
+
return (
|
|
145
|
+
<SelectPrimitive.ScrollDownArrow
|
|
146
|
+
data-slot="select-scroll-down-button"
|
|
147
|
+
className="bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4 bottom-0 w-full"
|
|
148
|
+
{...props}
|
|
149
|
+
>
|
|
150
|
+
<ChevronDownIcon />
|
|
151
|
+
</SelectPrimitive.ScrollDownArrow>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
Select,
|
|
157
|
+
SelectContent,
|
|
158
|
+
SelectGroup,
|
|
159
|
+
SelectItem,
|
|
160
|
+
SelectLabel,
|
|
161
|
+
SelectScrollDownButton,
|
|
162
|
+
SelectScrollUpButton,
|
|
163
|
+
SelectSeparator,
|
|
164
|
+
SelectTrigger,
|
|
165
|
+
SelectValue,
|
|
166
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Separator as SeparatorPrimitive } from '@base-ui/react/separator';
|
|
2
|
+
|
|
3
|
+
function Separator({
|
|
4
|
+
orientation = 'horizontal',
|
|
5
|
+
...props
|
|
6
|
+
}: Omit<SeparatorPrimitive.Props, 'className'>) {
|
|
7
|
+
return (
|
|
8
|
+
<SeparatorPrimitive
|
|
9
|
+
data-slot="separator"
|
|
10
|
+
orientation={orientation}
|
|
11
|
+
className="bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch"
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { Separator };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Dialog as SheetPrimitive } from '@base-ui/react/dialog';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
import { XIcon } from 'lucide-react';
|
|
5
|
+
import { Button } from './button';
|
|
6
|
+
|
|
7
|
+
function Sheet({ ...props }: SheetPrimitive.Root.Props) {
|
|
8
|
+
return <SheetPrimitive.Root data-slot="sheet" {...props} />;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {
|
|
12
|
+
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function SheetClose({ ...props }: SheetPrimitive.Close.Props) {
|
|
16
|
+
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {
|
|
20
|
+
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function SheetOverlay({ ...props }: Omit<SheetPrimitive.Backdrop.Props, 'className'>) {
|
|
24
|
+
return (
|
|
25
|
+
<SheetPrimitive.Backdrop
|
|
26
|
+
data-slot="sheet-overlay"
|
|
27
|
+
className="data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50"
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function SheetContent({
|
|
34
|
+
children,
|
|
35
|
+
side = 'right',
|
|
36
|
+
showCloseButton = true,
|
|
37
|
+
...props
|
|
38
|
+
}: Omit<SheetPrimitive.Popup.Props, 'className'> & {
|
|
39
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
40
|
+
showCloseButton?: boolean;
|
|
41
|
+
}) {
|
|
42
|
+
return (
|
|
43
|
+
<SheetPortal>
|
|
44
|
+
<SheetOverlay />
|
|
45
|
+
<SheetPrimitive.Popup
|
|
46
|
+
data-slot="sheet-content"
|
|
47
|
+
data-side={side}
|
|
48
|
+
className="bg-background data-open:animate-in data-closed:animate-out data-[side=right]:data-closed:slide-out-to-right-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=top]:data-closed:slide-out-to-top-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:fade-out-0 data-open:fade-in-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=bottom]:data-open:slide-in-from-bottom-10 fixed z-50 flex flex-col gap-4 bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm"
|
|
49
|
+
{...props}
|
|
50
|
+
>
|
|
51
|
+
{children}
|
|
52
|
+
{showCloseButton && (
|
|
53
|
+
<SheetPrimitive.Close
|
|
54
|
+
data-slot="sheet-close"
|
|
55
|
+
render={<Button variant="ghost" size="icon-sm" />}
|
|
56
|
+
className="absolute top-3 right-3"
|
|
57
|
+
>
|
|
58
|
+
<XIcon />
|
|
59
|
+
<span className="sr-only">Close</span>
|
|
60
|
+
</SheetPrimitive.Close>
|
|
61
|
+
)}
|
|
62
|
+
</SheetPrimitive.Popup>
|
|
63
|
+
</SheetPortal>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function SheetHeader({ ...props }: Omit<React.ComponentProps<'div'>, 'className'>) {
|
|
68
|
+
return <div data-slot="sheet-header" className="gap-0.5 p-4 flex flex-col" {...props} />;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function SheetFooter({ ...props }: Omit<React.ComponentProps<'div'>, 'className'>) {
|
|
72
|
+
return <div data-slot="sheet-footer" className="gap-2 p-4 mt-auto flex flex-col" {...props} />;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function SheetTitle({ ...props }: Omit<SheetPrimitive.Title.Props, 'className'>) {
|
|
76
|
+
return (
|
|
77
|
+
<SheetPrimitive.Title
|
|
78
|
+
data-slot="sheet-title"
|
|
79
|
+
className="text-foreground text-base font-medium"
|
|
80
|
+
{...props}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function SheetDescription({ ...props }: Omit<SheetPrimitive.Description.Props, 'className'>) {
|
|
86
|
+
return (
|
|
87
|
+
<SheetPrimitive.Description
|
|
88
|
+
data-slot="sheet-description"
|
|
89
|
+
className="text-muted-foreground text-sm"
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
Sheet,
|
|
97
|
+
SheetClose,
|
|
98
|
+
SheetContent,
|
|
99
|
+
SheetDescription,
|
|
100
|
+
SheetFooter,
|
|
101
|
+
SheetHeader,
|
|
102
|
+
SheetTitle,
|
|
103
|
+
SheetTrigger,
|
|
104
|
+
};
|