shapes-ui 0.4.2 → 0.6.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/.github/ISSUE_TEMPLATE/bug_report.yml +47 -0
- package/.github/ISSUE_TEMPLATE/config.yml +1 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +31 -0
- package/.github/pull_request_template.md +14 -0
- package/.github/workflows/pr-preview.yml +75 -0
- package/.github/workflows/release.yml +8 -0
- package/CHANGELOG.md +30 -0
- package/CODE_OF_CONDUCT.md +41 -0
- package/CONTRIBUTING.md +52 -0
- package/README.md +18 -0
- package/SECURITY.md +0 -0
- package/content/components/accordion.mdx +13 -0
- package/content/components/alert-dialog.mdx +34 -0
- package/content/components/autocomplete.mdx +62 -0
- package/content/components/avatar.mdx +11 -0
- package/content/components/button.mdx +8 -0
- package/content/components/checkbox.mdx +11 -0
- package/content/components/collapsible.mdx +11 -0
- package/content/components/combobox.mdx +33 -0
- package/content/components/context-menu.mdx +29 -0
- package/content/components/dialog.mdx +33 -0
- package/content/components/drawer.mdx +38 -0
- package/content/components/field.mdx +23 -2
- package/content/components/fieldset.mdx +11 -1
- package/content/components/form.mdx +8 -0
- package/content/components/input.mdx +4 -0
- package/content/components/menu.mdx +27 -0
- package/content/components/menubar.mdx +31 -0
- package/content/components/meter.mdx +14 -0
- package/content/components/navigation-menu.mdx +28 -0
- package/content/components/number-field.mdx +25 -0
- package/content/components/popover.mdx +22 -0
- package/content/components/preview-card.mdx +14 -2
- package/content/components/progress.mdx +15 -1
- package/content/components/radio.mdx +31 -0
- package/content/components/scroll-area.mdx +23 -0
- package/content/components/select.mdx +57 -0
- package/content/components/separator.mdx +29 -0
- package/content/components/slider.mdx +52 -0
- package/content/components/switch.mdx +30 -0
- package/content/components/tabs.mdx +47 -0
- package/content/components/toast.mdx +70 -0
- package/content/components/toggle-group.mdx +37 -0
- package/content/components/toggle.mdx +46 -2
- package/content/components/toolbar.mdx +48 -0
- package/content/components/tooltip.mdx +38 -0
- package/content/docs/installation.mdx +30 -0
- package/content-collections.ts +65 -1
- package/dist/cli.js +947 -101
- package/examples/__index.tsx +320 -66
- package/examples/autocomplete-align.tsx +39 -0
- package/examples/autocomplete-controlled.tsx +44 -0
- package/examples/autocomplete-groups.tsx +65 -0
- package/examples/autocomplete-no-clear.tsx +40 -0
- package/examples/avatar-demo.tsx +3 -3
- package/examples/checkbox-demo.tsx +1 -1
- package/examples/checkbox-form.tsx +3 -3
- package/examples/field-custom-control.tsx +33 -9
- package/examples/form-demo.tsx +5 -10
- package/examples/input-group-with-button.tsx +1 -1
- package/examples/menu-advanced.tsx +1 -3
- package/examples/menu-align.tsx +19 -16
- package/examples/menu-checkbox.tsx +2 -3
- package/examples/menu-demo.tsx +1 -3
- package/examples/menu-group.tsx +1 -3
- package/examples/menu-radio.tsx +1 -3
- package/examples/menu-submenu.tsx +2 -3
- package/examples/meter-demo.tsx +10 -2
- package/examples/meter-flip.tsx +8 -8
- package/examples/meter-no-label.tsx +9 -2
- package/examples/meter-no-value.tsx +7 -8
- package/examples/radio-card.tsx +28 -0
- package/examples/radio-demo.tsx +19 -1
- package/examples/radio-description.tsx +26 -0
- package/examples/radio-orientation.tsx +21 -0
- package/examples/select-alignment.tsx +51 -0
- package/examples/select-demo.tsx +36 -1
- package/examples/select-disabled.tsx +38 -0
- package/examples/select-groups.tsx +54 -0
- package/examples/select-invalid.tsx +41 -0
- package/examples/select-scrollable.tsx +112 -0
- package/examples/separator-demo.tsx +13 -0
- package/examples/separator-horizontal.tsx +18 -0
- package/examples/slider-controlled.tsx +28 -0
- package/examples/slider-demo.tsx +3 -1
- package/examples/slider-disabled.tsx +7 -0
- package/examples/slider-edge.tsx +13 -0
- package/examples/slider-multiple.tsx +7 -0
- package/examples/slider-range.tsx +5 -0
- package/examples/slider-vertical.tsx +10 -0
- package/examples/switch-demo.tsx +19 -1
- package/examples/switch-disabled.tsx +20 -0
- package/examples/switch-sizes.tsx +24 -0
- package/examples/switch-with-label.tsx +16 -0
- package/examples/tabs-demo.tsx +14 -1
- package/examples/tabs-disabled.tsx +21 -0
- package/examples/tabs-line.tsx +18 -0
- package/examples/tabs-vertical.tsx +13 -0
- package/examples/toast-action.tsx +39 -0
- package/examples/toast-anchored.tsx +36 -0
- package/examples/toast-demo.tsx +27 -1
- package/examples/toast-positions.tsx +54 -0
- package/examples/toast-promise.tsx +51 -0
- package/examples/toast-stacked.tsx +30 -0
- package/examples/toast-timeout.tsx +43 -0
- package/examples/toast-update.tsx +38 -0
- package/examples/toast-variants.tsx +54 -0
- package/examples/toggle-controlled.tsx +20 -0
- package/examples/toggle-demo.tsx +7 -51
- package/examples/toggle-group-demo.tsx +19 -0
- package/examples/toggle-group-multiple.tsx +19 -0
- package/examples/toggle-icon-fill.tsx +12 -0
- package/examples/toolbar-demo.tsx +45 -21
- package/examples/toolbar-input-link.tsx +35 -0
- package/examples/toolbar-menu.tsx +53 -0
- package/examples/tooltip-demo.tsx +48 -0
- package/examples/tooltip-positions.tsx +60 -0
- package/package.json +19 -18
- package/public/base-ui.svg +1 -0
- package/public/r/drawer.json +1 -1
- package/public/r/field.json +1 -1
- package/public/r/meter.json +1 -1
- package/public/r/number-field.json +1 -1
- package/public/r/progress.json +1 -1
- package/public/r/radio.json +1 -1
- package/public/r/select.json +1 -1
- package/public/r/slider.json +1 -1
- package/public/r/switch.json +1 -1
- package/public/r/tabs.json +1 -1
- package/public/r/toast.json +2 -1
- package/public/r/toggle.json +1 -1
- package/public/r/toolbar.json +1 -1
- package/public/r/tooltip.json +15 -0
- package/src/assets/base-ui.svg +1 -0
- package/src/commands/add.ts +79 -38
- package/src/commands/cli.ts +50 -3
- package/src/commands/create.ts +262 -0
- package/src/commands/init.ts +45 -12
- package/src/commands/palette.ts +55 -0
- package/src/components/docs/layout/footer.tsx +2 -2
- package/src/components/docs/layout/header.tsx +7 -19
- package/src/components/docs/layout/mobile-menu.tsx +26 -78
- package/src/components/docs/layout/nav-list.tsx +27 -21
- package/src/components/docs/layout/page-header.tsx +52 -7
- package/src/components/docs/layout/split-layout.tsx +11 -9
- package/src/components/docs/layout/table-of-content.tsx +145 -0
- package/src/components/docs/markdown/components.tsx +142 -29
- package/src/components/docs/markdown/copy-button.tsx +41 -0
- package/src/components/docs/markdown/installation-block.tsx +5 -24
- package/src/components/docs/markdown/render-preview.tsx +1 -1
- package/src/components/ui/badge.tsx +1 -1
- package/src/components/ui/button-group.tsx +1 -1
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/drawer.tsx +1 -1
- package/src/components/ui/field.tsx +9 -28
- package/src/components/ui/form.tsx +1 -1
- package/src/components/ui/meter.tsx +12 -26
- package/src/components/ui/number-field.tsx +1 -1
- package/src/components/ui/radio.tsx +32 -19
- package/src/components/ui/scroll-area.tsx +11 -2
- package/src/components/ui/select.tsx +6 -6
- package/src/components/ui/slider.tsx +8 -5
- package/src/components/ui/switch.tsx +13 -17
- package/src/components/ui/tabs.tsx +23 -10
- package/src/components/ui/toast.tsx +190 -29
- package/src/components/ui/toggle.tsx +1 -1
- package/src/components/ui/toolbar.tsx +17 -4
- package/src/components/ui/tooltip.tsx +54 -0
- package/src/lib/docs-headings.ts +72 -0
- package/src/routeTree.gen.ts +60 -3
- package/src/routes/__root.tsx +3 -5
- package/src/routes/components.$slug.tsx +20 -4
- package/src/routes/docs.$slug.tsx +78 -0
- package/src/routes/docs.tsx +15 -0
- package/src/styles/styles.css +1 -1
- package/src/utils/cli-utils.ts +8 -8
- package/src/utils/dependency-installer.ts +30 -0
- package/src/utils/package-manager.ts +4 -4
- package/src/utils/palette.ts +666 -0
- package/src/utils/schema.ts +6 -0
|
@@ -41,7 +41,7 @@ function SelectTrigger({
|
|
|
41
41
|
data-slot="select-trigger"
|
|
42
42
|
data-size={size}
|
|
43
43
|
className={cn(
|
|
44
|
-
"flex w-fit items-center justify-between gap-1.5 border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-
|
|
44
|
+
"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
45
45
|
className,
|
|
46
46
|
)}
|
|
47
47
|
{...props}
|
|
@@ -79,10 +79,10 @@ function SelectPopup({
|
|
|
79
79
|
className="isolate z-50"
|
|
80
80
|
>
|
|
81
81
|
<SelectPrimitive.Popup
|
|
82
|
-
data-slot="select-
|
|
82
|
+
data-slot="select-popup"
|
|
83
83
|
data-align-trigger={alignItemWithTrigger}
|
|
84
84
|
className={cn(
|
|
85
|
-
"
|
|
85
|
+
"relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popup text-popup-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
86
86
|
className,
|
|
87
87
|
)}
|
|
88
88
|
{...props}
|
|
@@ -111,7 +111,7 @@ function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Prop
|
|
|
111
111
|
<SelectPrimitive.Item
|
|
112
112
|
data-slot="select-item"
|
|
113
113
|
className={cn(
|
|
114
|
-
"relative flex w-full cursor-default items-center gap-1.5 py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
114
|
+
"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
115
115
|
className,
|
|
116
116
|
)}
|
|
117
117
|
{...props}
|
|
@@ -148,7 +148,7 @@ function SelectScrollUpButton({
|
|
|
148
148
|
<SelectPrimitive.ScrollUpArrow
|
|
149
149
|
data-slot="select-scroll-up-button"
|
|
150
150
|
className={cn(
|
|
151
|
-
"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popup py-1 [&_svg:not([class*='size-'])]:size-
|
|
151
|
+
"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popup py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
152
152
|
className,
|
|
153
153
|
)}
|
|
154
154
|
{...props}
|
|
@@ -166,7 +166,7 @@ function SelectScrollDownButton({
|
|
|
166
166
|
<SelectPrimitive.ScrollDownArrow
|
|
167
167
|
data-slot="select-scroll-down-button"
|
|
168
168
|
className={cn(
|
|
169
|
-
"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popup py-1 [&_svg:not([class*='size-'])]:size-
|
|
169
|
+
"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popup py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
170
170
|
className,
|
|
171
171
|
)}
|
|
172
172
|
{...props}
|
|
@@ -20,7 +20,10 @@ function Slider({
|
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<SliderPrimitive.Root
|
|
23
|
-
className={cn(
|
|
23
|
+
className={cn(
|
|
24
|
+
"data-horizontal:w-full data-vertical:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full",
|
|
25
|
+
className,
|
|
26
|
+
)}
|
|
24
27
|
data-slot="slider"
|
|
25
28
|
defaultValue={defaultValue}
|
|
26
29
|
value={value}
|
|
@@ -29,14 +32,14 @@ function Slider({
|
|
|
29
32
|
thumbAlignment="edge"
|
|
30
33
|
{...props}
|
|
31
34
|
>
|
|
32
|
-
<SliderPrimitive.Control className="relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col">
|
|
33
|
-
<SliderPrimitive.Track className="relative h-1.5 grow overflow-hidden border bg-muted select-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1">
|
|
34
|
-
<SliderPrimitive.Indicator className="bg-primary select-none data-horizontal:h-full data-vertical:w-full" />
|
|
35
|
+
<SliderPrimitive.Control className="relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-40 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col">
|
|
36
|
+
<SliderPrimitive.Track className="relative h-1.5 grow overflow-hidden rounded-full border bg-muted select-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1 data-[orientation=horizontal]:h-1 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1">
|
|
37
|
+
<SliderPrimitive.Indicator className="bg-primary select-none data-horizontal:h-full data-vertical:w-full data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full" />
|
|
35
38
|
</SliderPrimitive.Track>
|
|
36
39
|
{Array.from({ length: _values.length }, (_, index) => (
|
|
37
40
|
<SliderPrimitive.Thumb
|
|
38
41
|
key={index}
|
|
39
|
-
className="relative block size-3.5 shrink-0 border border-ring bg-
|
|
42
|
+
className="relative block size-3.5 shrink-0 rounded-full border border-ring bg-primary ring-ring/50 transition-[color,box-shadow] select-none after:absolute after:-inset-2 hover:ring-[3px] focus-visible:ring-[3px] focus-visible:outline-hidden active:ring-[3px] disabled:pointer-events-none disabled:opacity-50"
|
|
40
43
|
/>
|
|
41
44
|
))}
|
|
42
45
|
</SliderPrimitive.Control>
|
|
@@ -5,7 +5,6 @@ import { Switch as SwitchPrimitive } from "@base-ui/react/switch";
|
|
|
5
5
|
import { cn } from "@/lib/utils";
|
|
6
6
|
|
|
7
7
|
function Switch({
|
|
8
|
-
children,
|
|
9
8
|
className,
|
|
10
9
|
size = "default",
|
|
11
10
|
...props
|
|
@@ -13,23 +12,20 @@ function Switch({
|
|
|
13
12
|
size?: "sm" | "default";
|
|
14
13
|
}) {
|
|
15
14
|
return (
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
className={cn(
|
|
15
|
+
<SwitchPrimitive.Root
|
|
16
|
+
data-slot="switch"
|
|
17
|
+
data-size={size}
|
|
18
|
+
className={cn(
|
|
19
|
+
"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-checked:bg-primary data-disabled:cursor-not-allowed data-disabled:opacity-50 data-unchecked:bg-input data-[size=default]:h-[18.4px] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 dark:data-unchecked:bg-input/80",
|
|
20
|
+
className,
|
|
21
|
+
)}
|
|
22
|
+
{...props}
|
|
20
23
|
>
|
|
21
|
-
<SwitchPrimitive.
|
|
22
|
-
data-
|
|
23
|
-
className=
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
)}
|
|
27
|
-
{...props}
|
|
28
|
-
>
|
|
29
|
-
<SwitchPrimitive.Thumb className="pointer-events-none block bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-checked:bg-primary-foreground dark:data-unchecked:bg-foreground" />
|
|
30
|
-
</SwitchPrimitive.Root>
|
|
31
|
-
{children}
|
|
32
|
-
</label>
|
|
24
|
+
<SwitchPrimitive.Thumb
|
|
25
|
+
data-slot="switch-thumb"
|
|
26
|
+
className="pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-checked:bg-primary-foreground dark:data-unchecked:bg-foreground"
|
|
27
|
+
/>
|
|
28
|
+
</SwitchPrimitive.Root>
|
|
33
29
|
);
|
|
34
30
|
}
|
|
35
31
|
|
|
@@ -10,14 +10,17 @@ function Tabs({ className, orientation = "horizontal", ...props }: TabsPrimitive
|
|
|
10
10
|
<TabsPrimitive.Root
|
|
11
11
|
data-slot="tabs"
|
|
12
12
|
data-orientation={orientation}
|
|
13
|
-
className={cn(
|
|
13
|
+
className={cn(
|
|
14
|
+
"group/tabs flex gap-2 data-[orientation=horizontal]:flex-col data-[orientation=vertical]:flex-row data-[orientation=horizontal]:**:data-[slot=tabs-list]:h-8 data-[orientation=horizontal]:**:data-[slot=tabs-list]:flex-row data-[orientation=vertical]:**:data-[slot=tabs-list]:h-fit data-[orientation=vertical]:**:data-[slot=tabs-list]:flex-col",
|
|
15
|
+
className,
|
|
16
|
+
)}
|
|
14
17
|
{...props}
|
|
15
18
|
/>
|
|
16
19
|
);
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
const tabsListVariants = cva(
|
|
20
|
-
"group/tabs-list inline-flex w-
|
|
23
|
+
"group/tabs-list relative inline-flex w-max overflow-hidden rounded-2xl p-0.5 text-muted-foreground group-data-[orientation=horizontal]/tabs:items-center group-data-[orientation=horizontal]/tabs:justify-center group-data-[orientation=vertical]/tabs:items-stretch group-data-[orientation=vertical]/tabs:justify-start data-[orientation=horizontal]:items-center data-[orientation=horizontal]:justify-center data-[orientation=vertical]:items-stretch data-[orientation=vertical]:justify-start data-[variant=line]:rounded-none",
|
|
21
24
|
{
|
|
22
25
|
variants: {
|
|
23
26
|
variant: {
|
|
@@ -32,6 +35,7 @@ const tabsListVariants = cva(
|
|
|
32
35
|
);
|
|
33
36
|
|
|
34
37
|
function TabsList({
|
|
38
|
+
children,
|
|
35
39
|
className,
|
|
36
40
|
variant = "default",
|
|
37
41
|
...props
|
|
@@ -42,7 +46,19 @@ function TabsList({
|
|
|
42
46
|
data-variant={variant}
|
|
43
47
|
className={cn(tabsListVariants({ variant }), className)}
|
|
44
48
|
{...props}
|
|
45
|
-
|
|
49
|
+
>
|
|
50
|
+
{children}
|
|
51
|
+
<TabsPrimitive.Indicator
|
|
52
|
+
className={cn(
|
|
53
|
+
"pointer-events-none absolute rounded-xl border border-input bg-card shadow-sm transition-[left,right,top,bottom,width,height,transform] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]",
|
|
54
|
+
"data-[orientation=horizontal]:top-(--active-tab-top) data-[orientation=horizontal]:left-(--active-tab-left) data-[orientation=horizontal]:h-(--active-tab-height) data-[orientation=horizontal]:w-(--active-tab-width)",
|
|
55
|
+
"data-[orientation=vertical]:top-(--active-tab-top) data-[orientation=vertical]:left-(--active-tab-left) data-[orientation=vertical]:h-(--active-tab-height) data-[orientation=vertical]:w-(--active-tab-width)",
|
|
56
|
+
"group-data-[variant=line]/tabs-list:rounded-none group-data-[variant=line]/tabs-list:border-0 group-data-[variant=line]/tabs-list:bg-foreground group-data-[variant=line]/tabs-list:shadow-none",
|
|
57
|
+
"group-data-[variant=line]/tabs-list:data-[orientation=horizontal]:top-auto group-data-[variant=line]/tabs-list:data-[orientation=horizontal]:bottom-0 group-data-[variant=line]/tabs-list:data-[orientation=horizontal]:h-0.5",
|
|
58
|
+
"group-data-[variant=line]/tabs-list:data-[orientation=vertical]:right-auto group-data-[variant=line]/tabs-list:data-[orientation=vertical]:left-0 group-data-[variant=line]/tabs-list:data-[orientation=vertical]:w-0.5",
|
|
59
|
+
)}
|
|
60
|
+
/>
|
|
61
|
+
</TabsPrimitive.List>
|
|
46
62
|
);
|
|
47
63
|
}
|
|
48
64
|
|
|
@@ -51,10 +67,7 @@ function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {
|
|
|
51
67
|
<TabsPrimitive.Tab
|
|
52
68
|
data-slot="tabs-trigger"
|
|
53
69
|
className={cn(
|
|
54
|
-
"relative inline-flex h-
|
|
55
|
-
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
|
|
56
|
-
"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
|
|
57
|
-
"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
|
|
70
|
+
"relative z-10 inline-flex h-7 flex-none items-center justify-center rounded-xl border border-transparent px-2 py-0.5 text-center text-sm font-medium whitespace-nowrap text-muted-foreground transition-[color,transform,opacity] duration-200 ease-out group-data-[orientation=vertical]/tabs:w-full group-data-[variant=line]/tabs-list:rounded-none group-data-[variant=line]/tabs-list:border-0 group-data-[variant=line]/tabs-list:bg-transparent hover:text-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring group-data-[variant=line]/tabs-list:focus-visible:border-transparent group-data-[variant=line]/tabs-list:focus-visible:ring-0 group-data-[variant=line]/tabs-list:focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:text-card-foreground data-[orientation=vertical]:h-fit data-[orientation=vertical]:w-full [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
58
71
|
className,
|
|
59
72
|
)}
|
|
60
73
|
{...props}
|
|
@@ -62,14 +75,14 @@ function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {
|
|
|
62
75
|
);
|
|
63
76
|
}
|
|
64
77
|
|
|
65
|
-
function
|
|
78
|
+
function TabsPanel({ className, ...props }: TabsPrimitive.Panel.Props) {
|
|
66
79
|
return (
|
|
67
80
|
<TabsPrimitive.Panel
|
|
68
|
-
data-slot="tabs-
|
|
81
|
+
data-slot="tabs-panel"
|
|
69
82
|
className={cn("flex-1 text-sm outline-none", className)}
|
|
70
83
|
{...props}
|
|
71
84
|
/>
|
|
72
85
|
);
|
|
73
86
|
}
|
|
74
87
|
|
|
75
|
-
export { Tabs, TabsList, TabsTrigger,
|
|
88
|
+
export { Tabs, TabsList, TabsTrigger, TabsPanel, tabsListVariants };
|
|
@@ -1,48 +1,191 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { Toast as ToastPrimitive } from "@base-ui/react/toast";
|
|
4
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
5
|
import { AlertCircle, CheckCircle2 } from "lucide-react";
|
|
6
|
+
import * as React from "react";
|
|
5
7
|
|
|
6
8
|
import { cn } from "@/lib/utils";
|
|
7
9
|
|
|
8
10
|
type ToastTypes = "default" | "success" | "error";
|
|
9
11
|
|
|
12
|
+
const toastViewportVariants = cva("fixed z-50 w-80 outline-none", {
|
|
13
|
+
variants: {
|
|
14
|
+
position: {
|
|
15
|
+
"top-left": "top-4 right-auto bottom-auto left-4",
|
|
16
|
+
"top-center": "top-4 right-0 bottom-auto left-0 mx-auto",
|
|
17
|
+
"top-right": "top-4 right-4 bottom-auto left-auto",
|
|
18
|
+
"bottom-left": "top-auto right-auto bottom-4 left-4",
|
|
19
|
+
"bottom-center": "top-auto right-0 bottom-4 left-0 mx-auto",
|
|
20
|
+
"bottom-right": "top-auto right-4 bottom-4 left-auto",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
position: "bottom-right",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const stackedToastVariants = cva(
|
|
29
|
+
"absolute z-[calc(1000-var(--toast-index))] h-(--height) w-full rounded-lg border bg-popup bg-clip-padding p-4 select-none [--gap:0.75rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))] [transition:transform_0.5s_cubic-bezier(0.22,1,0.36,1),opacity_0.5s,height_0.15s] after:absolute after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-[''] data-ending-style:opacity-0 data-expanded:h-(--toast-height) data-limited:opacity-0 data-ending-style:data-[swipe-direction=down]:transform-[translateY(calc(var(--toast-swipe-movement-y)+150%))] data-expanded:data-ending-style:data-[swipe-direction=down]:transform-[translateY(calc(var(--toast-swipe-movement-y)+150%))] data-ending-style:data-[swipe-direction=left]:transform-[translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))] data-expanded:data-ending-style:data-[swipe-direction=left]:transform-[translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))] data-ending-style:data-[swipe-direction=right]:transform-[translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))] data-expanded:data-ending-style:data-[swipe-direction=right]:transform-[translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))] data-ending-style:data-[swipe-direction=up]:transform-[translateY(calc(var(--toast-swipe-movement-y)-150%))] data-expanded:data-ending-style:data-[swipe-direction=up]:transform-[translateY(calc(var(--toast-swipe-movement-y)-150%))]",
|
|
30
|
+
{
|
|
31
|
+
variants: {
|
|
32
|
+
vertical: {
|
|
33
|
+
top: "top-0 origin-top [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)+(var(--toast-index)*var(--peek))+(var(--shrink)*var(--height))))_scale(var(--scale))] [--offset-y:calc(var(--toast-offset-y)+(var(--toast-index)*var(--gap))+var(--toast-swipe-movement-y))] after:bottom-full data-expanded:transform-[translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--offset-y)))] data-starting-style:transform-[translateY(-150%)] [&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:transform-[translateY(-150%)]",
|
|
34
|
+
bottom:
|
|
35
|
+
"bottom-0 origin-bottom [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] after:top-full data-expanded:transform-[translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--offset-y)))] data-starting-style:transform-[translateY(150%)] [&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:transform-[translateY(150%)]",
|
|
36
|
+
},
|
|
37
|
+
horizontal: {
|
|
38
|
+
left: "right-auto left-0",
|
|
39
|
+
center: "right-0 left-0 mx-auto",
|
|
40
|
+
right: "right-0 left-auto",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
defaultVariants: {
|
|
44
|
+
vertical: "bottom",
|
|
45
|
+
horizontal: "right",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const anchoredToastVariants = cva(
|
|
51
|
+
"pointer-events-auto w-80 rounded-lg border bg-popup bg-clip-padding p-4 data-ending-style:opacity-0 data-starting-style:opacity-0",
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const toastContentVariants = cva(
|
|
55
|
+
"overflow-hidden transition-opacity duration-250 data-behind:pointer-events-none data-behind:opacity-0 data-expanded:pointer-events-auto data-expanded:opacity-100",
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const toastBodyVariants = cva("flex items-center gap-3");
|
|
59
|
+
|
|
60
|
+
type ToastPosition = NonNullable<VariantProps<typeof toastViewportVariants>["position"]>;
|
|
61
|
+
type StackVertical = NonNullable<VariantProps<typeof stackedToastVariants>["vertical"]>;
|
|
62
|
+
type StackHorizontal = NonNullable<VariantProps<typeof stackedToastVariants>["horizontal"]>;
|
|
63
|
+
type ToastManager = ReturnType<typeof ToastPrimitive.createToastManager>;
|
|
64
|
+
|
|
65
|
+
interface ToastProviderProps {
|
|
66
|
+
children: React.ReactNode;
|
|
67
|
+
position?: ToastPosition;
|
|
68
|
+
limit?: number;
|
|
69
|
+
timeout?: number;
|
|
70
|
+
toastManager?: ToastManager;
|
|
71
|
+
}
|
|
72
|
+
|
|
10
73
|
const globalToastManager = ToastPrimitive.createToastManager();
|
|
11
|
-
export const
|
|
74
|
+
export const globalToast = globalToastManager;
|
|
75
|
+
|
|
76
|
+
export function ToastProvider({
|
|
77
|
+
children,
|
|
78
|
+
position = "bottom-right",
|
|
79
|
+
limit = 5,
|
|
80
|
+
timeout = 5000,
|
|
81
|
+
toastManager,
|
|
82
|
+
}: ToastProviderProps) {
|
|
83
|
+
const localToastManagerRef = React.useRef<ToastManager | null>(null);
|
|
84
|
+
|
|
85
|
+
if (!localToastManagerRef.current) {
|
|
86
|
+
localToastManagerRef.current = ToastPrimitive.createToastManager();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const manager = toastManager ?? localToastManagerRef.current;
|
|
12
90
|
|
|
13
|
-
export function ToastProvider({ children }: { children: React.ReactNode }) {
|
|
14
91
|
return (
|
|
15
|
-
<ToastPrimitive.Provider toastManager={
|
|
92
|
+
<ToastPrimitive.Provider toastManager={manager} limit={limit} timeout={timeout}>
|
|
16
93
|
{children}
|
|
17
94
|
<ToastPrimitive.Portal>
|
|
18
|
-
<ToastPrimitive.Viewport className=
|
|
19
|
-
<
|
|
95
|
+
<ToastPrimitive.Viewport className={cn(toastViewportVariants({ position }))}>
|
|
96
|
+
<ToastStackConsumer position={position} />
|
|
97
|
+
</ToastPrimitive.Viewport>
|
|
98
|
+
<ToastPrimitive.Viewport className="pointer-events-none fixed inset-0 z-50 outline-none">
|
|
99
|
+
<ToastAnchorConsumer />
|
|
20
100
|
</ToastPrimitive.Viewport>
|
|
21
101
|
</ToastPrimitive.Portal>
|
|
22
102
|
</ToastPrimitive.Provider>
|
|
23
103
|
);
|
|
24
104
|
}
|
|
25
105
|
|
|
26
|
-
function
|
|
106
|
+
function ToastStackConsumer({ position }: { position: ToastPosition }) {
|
|
27
107
|
const { toasts } = ToastPrimitive.useToastManager();
|
|
108
|
+
const stackToasts = toasts.filter((currentToast) => !currentToast.positionerProps?.anchor);
|
|
109
|
+
|
|
28
110
|
return (
|
|
29
111
|
<>
|
|
30
|
-
{
|
|
31
|
-
<Toast key={
|
|
112
|
+
{stackToasts.map((currentToast) => (
|
|
113
|
+
<Toast key={currentToast.id} toast={currentToast} position={position} />
|
|
32
114
|
))}
|
|
33
115
|
</>
|
|
34
116
|
);
|
|
35
117
|
}
|
|
36
118
|
|
|
37
|
-
function
|
|
119
|
+
function ToastAnchorConsumer() {
|
|
120
|
+
const { toasts } = ToastPrimitive.useToastManager();
|
|
121
|
+
const anchorToasts = toasts.filter((currentToast) =>
|
|
122
|
+
Boolean(currentToast.positionerProps?.anchor),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<>
|
|
127
|
+
{anchorToasts.map((currentToast) => {
|
|
128
|
+
const { className, ...positionerProps } = currentToast.positionerProps ?? {};
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<ToastPrimitive.Positioner
|
|
132
|
+
key={currentToast.id}
|
|
133
|
+
toast={currentToast}
|
|
134
|
+
className={cn("pointer-events-none z-[calc(1000-var(--toast-index))]", className)}
|
|
135
|
+
{...positionerProps}
|
|
136
|
+
>
|
|
137
|
+
<AnchoredToast toast={currentToast} />
|
|
138
|
+
</ToastPrimitive.Positioner>
|
|
139
|
+
);
|
|
140
|
+
})}
|
|
141
|
+
</>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function Toast({
|
|
146
|
+
className,
|
|
147
|
+
toast,
|
|
148
|
+
position,
|
|
149
|
+
...props
|
|
150
|
+
}: ToastPrimitive.Root.Props & { position: ToastPosition }) {
|
|
151
|
+
const { vertical, horizontal } = getStackPlacement(position);
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<ToastPrimitive.Root
|
|
155
|
+
toast={toast}
|
|
156
|
+
className={cn(stackedToastVariants({ vertical, horizontal, className }))}
|
|
157
|
+
{...props}
|
|
158
|
+
>
|
|
159
|
+
<ToastPrimitive.Content className={cn(toastContentVariants())}>
|
|
160
|
+
<ToastBody toast={toast} />
|
|
161
|
+
</ToastPrimitive.Content>
|
|
162
|
+
</ToastPrimitive.Root>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function AnchoredToast({ className, toast, ...props }: ToastPrimitive.Root.Props) {
|
|
167
|
+
return (
|
|
168
|
+
<ToastPrimitive.Root
|
|
169
|
+
toast={toast}
|
|
170
|
+
className={cn(anchoredToastVariants({ className }))}
|
|
171
|
+
{...props}
|
|
172
|
+
>
|
|
173
|
+
<ToastPrimitive.Content className={cn(toastContentVariants())}>
|
|
174
|
+
<ToastBody toast={toast} />
|
|
175
|
+
</ToastPrimitive.Content>
|
|
176
|
+
</ToastPrimitive.Root>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function ToastBody({ toast }: { toast: ToastPrimitive.Root.Props["toast"] }) {
|
|
38
181
|
let icon;
|
|
39
182
|
|
|
40
183
|
switch (toast.type as ToastTypes) {
|
|
41
184
|
case "success":
|
|
42
|
-
icon = <CheckCircle2 className="h-4 w-4 text-
|
|
185
|
+
icon = <CheckCircle2 className="h-4 w-4 text-success" />;
|
|
43
186
|
break;
|
|
44
187
|
case "error":
|
|
45
|
-
icon = <AlertCircle className="h-4 w-4 text-
|
|
188
|
+
icon = <AlertCircle className="h-4 w-4 text-destructive" />;
|
|
46
189
|
break;
|
|
47
190
|
default:
|
|
48
191
|
icon = null;
|
|
@@ -50,27 +193,45 @@ function Toast({ className, toast, ...props }: ToastPrimitive.Root.Props) {
|
|
|
50
193
|
}
|
|
51
194
|
|
|
52
195
|
return (
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
className={cn(
|
|
56
|
-
"flex w-80 items-center gap-3 rounded-lg border bg-popup p-4 shadow-md",
|
|
57
|
-
className,
|
|
58
|
-
)}
|
|
59
|
-
{...props}
|
|
60
|
-
>
|
|
61
|
-
{icon && <div>{icon}</div>}
|
|
196
|
+
<div className={cn(toastBodyVariants())}>
|
|
197
|
+
{icon ? <div>{icon}</div> : null}
|
|
62
198
|
<div className="flex flex-1 flex-col">
|
|
63
|
-
{toast.title
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
)}
|
|
199
|
+
{toast.title ? <ToastPrimitive.Title className="text-sm font-medium" /> : null}
|
|
200
|
+
{toast.description ? (
|
|
201
|
+
<ToastPrimitive.Description className="text-sm text-muted-foreground" />
|
|
202
|
+
) : null}
|
|
203
|
+
{toast.actionProps ? (
|
|
204
|
+
<ToastPrimitive.Action className="mt-2 inline-flex h-7 items-center justify-center self-start rounded-md border px-2.5 text-xs font-medium hover:bg-muted" />
|
|
205
|
+
) : null}
|
|
71
206
|
</div>
|
|
72
|
-
</
|
|
207
|
+
</div>
|
|
73
208
|
);
|
|
74
209
|
}
|
|
75
210
|
|
|
211
|
+
function getStackPlacement(position: ToastPosition): {
|
|
212
|
+
vertical: StackVertical;
|
|
213
|
+
horizontal: StackHorizontal;
|
|
214
|
+
} {
|
|
215
|
+
const vertical: StackVertical = position.startsWith("top") ? "top" : "bottom";
|
|
216
|
+
|
|
217
|
+
let horizontal: StackHorizontal = "center";
|
|
218
|
+
if (position.endsWith("left")) {
|
|
219
|
+
horizontal = "left";
|
|
220
|
+
}
|
|
221
|
+
if (position.endsWith("right")) {
|
|
222
|
+
horizontal = "right";
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
vertical,
|
|
227
|
+
horizontal,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function useToast<Data extends object = any>() {
|
|
232
|
+
return ToastPrimitive.useToastManager<Data>();
|
|
233
|
+
}
|
|
234
|
+
|
|
76
235
|
export { ToastProvider as Toast };
|
|
236
|
+
export { useToast };
|
|
237
|
+
export type { ToastPosition, ToastManager };
|
|
@@ -7,7 +7,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
7
7
|
import { cn } from "@/lib/utils";
|
|
8
8
|
|
|
9
9
|
const toggleVariants = cva(
|
|
10
|
-
"group/toggle inline-flex items-center justify-center gap-1 rounded text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-pressed:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
10
|
+
"group/toggle inline-flex items-center justify-center gap-1 rounded text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-pressed:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_[data-slot=fill]_*]:fill-transparent data-[pressed]:[&_[data-slot=fill]_*]:fill-current",
|
|
11
11
|
{
|
|
12
12
|
variants: {
|
|
13
13
|
variant: {
|
|
@@ -4,10 +4,12 @@ import { Toolbar as ToolbarPrimitive } from "@base-ui/react";
|
|
|
4
4
|
|
|
5
5
|
import { cn } from "@/lib/utils";
|
|
6
6
|
|
|
7
|
+
import { Input } from "./input";
|
|
8
|
+
|
|
7
9
|
function Toolbar({ className, ...props }: ToolbarPrimitive.Root.Props) {
|
|
8
10
|
return (
|
|
9
11
|
<ToolbarPrimitive.Root
|
|
10
|
-
className={cn("flex h-9 items-center justify-evenly gap-1
|
|
12
|
+
className={cn("flex h-9 items-center justify-evenly gap-1 rounded-xl border p-1", className)}
|
|
11
13
|
{...props}
|
|
12
14
|
/>
|
|
13
15
|
);
|
|
@@ -22,18 +24,29 @@ function ToolbarLink({ className, ...props }: ToolbarPrimitive.Link.Props) {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
function ToolbarInput({ className, ...props }: ToolbarPrimitive.Input.Props) {
|
|
25
|
-
return
|
|
27
|
+
return (
|
|
28
|
+
<ToolbarPrimitive.Input
|
|
29
|
+
className={cn(
|
|
30
|
+
"rounded-none border-0 ring-0 outline-0 focus:ring-0 focus-visible:ring-0 focus-visible:outline-0",
|
|
31
|
+
className,
|
|
32
|
+
)}
|
|
33
|
+
render={<Input />}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
function ToolbarGroup({ className, ...props }: ToolbarPrimitive.Group.Props) {
|
|
29
|
-
return
|
|
40
|
+
return (
|
|
41
|
+
<ToolbarPrimitive.Group className={cn("flex items-center gap-0.5", className)} {...props} />
|
|
42
|
+
);
|
|
30
43
|
}
|
|
31
44
|
|
|
32
45
|
function ToolbarSeparator({ className, ...props }: ToolbarPrimitive.Separator.Props) {
|
|
33
46
|
return (
|
|
34
47
|
<ToolbarPrimitive.Separator
|
|
35
48
|
className={cn(
|
|
36
|
-
"shrink-0 bg-primary/
|
|
49
|
+
"shrink-0 bg-primary/30 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch",
|
|
37
50
|
className,
|
|
38
51
|
)}
|
|
39
52
|
{...props}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
function TooltipProvider({ delay = 0, ...props }: TooltipPrimitive.Provider.Props) {
|
|
8
|
+
return <TooltipPrimitive.Provider data-slot="tooltip-provider" delay={delay} {...props} />;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
|
|
12
|
+
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
|
|
16
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function TooltipPopup({
|
|
20
|
+
className,
|
|
21
|
+
side = "top",
|
|
22
|
+
sideOffset = 4,
|
|
23
|
+
align = "center",
|
|
24
|
+
alignOffset = 0,
|
|
25
|
+
children,
|
|
26
|
+
...props
|
|
27
|
+
}: TooltipPrimitive.Popup.Props &
|
|
28
|
+
Pick<TooltipPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">) {
|
|
29
|
+
return (
|
|
30
|
+
<TooltipPrimitive.Portal>
|
|
31
|
+
<TooltipPrimitive.Positioner
|
|
32
|
+
align={align}
|
|
33
|
+
alignOffset={alignOffset}
|
|
34
|
+
side={side}
|
|
35
|
+
sideOffset={sideOffset}
|
|
36
|
+
className="isolate z-50"
|
|
37
|
+
>
|
|
38
|
+
<TooltipPrimitive.Popup
|
|
39
|
+
data-slot="tooltip-popup"
|
|
40
|
+
className={cn(
|
|
41
|
+
"z-50 w-fit max-w-xs origin-(--transform-origin) rounded-md bg-foreground px-3 py-1.5 text-xs text-background data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95",
|
|
42
|
+
className,
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
{children}
|
|
47
|
+
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" />
|
|
48
|
+
</TooltipPrimitive.Popup>
|
|
49
|
+
</TooltipPrimitive.Positioner>
|
|
50
|
+
</TooltipPrimitive.Portal>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { Tooltip, TooltipTrigger, TooltipPopup, TooltipProvider };
|