@waveso/ui 0.15.1 → 0.17.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 +13 -12
- package/dist/accordion.js +2 -2
- package/dist/action-bar.js +4 -4
- package/dist/alert-dialog.js +5 -5
- package/dist/alert.d.ts +8 -1
- package/dist/alert.js +13 -4
- package/dist/animate.d.ts +1 -1
- package/dist/animate.js +2 -9
- package/dist/autocomplete.js +3 -3
- package/dist/avatar.d.ts +1 -1
- package/dist/avatar.js +4 -4
- package/dist/badge.d.ts +1 -1
- package/dist/badge.js +6 -6
- package/dist/button-group.d.ts +4 -2
- package/dist/button-group.js +5 -4
- package/dist/button.d.ts +1 -1
- package/dist/button.js +6 -6
- package/dist/card.d.ts +11 -4
- package/dist/card.js +27 -14
- package/dist/checkbox.js +2 -2
- package/dist/combobox.js +4 -4
- package/dist/context-menu.d.ts +2 -1
- package/dist/context-menu.js +14 -14
- package/dist/dialog.js +5 -5
- package/dist/drawer.js +1 -1
- package/dist/encrypted-text.d.ts +15 -1
- package/dist/encrypted-text.js +205 -67
- package/dist/field.d.ts +21 -3
- package/dist/field.js +36 -8
- package/dist/fieldset.d.ts +14 -0
- package/dist/fieldset.js +26 -0
- package/dist/form.d.ts +14 -14
- package/dist/form.js +7 -4
- package/dist/glyph-matrix.d.ts +25 -0
- package/dist/glyph-matrix.js +266 -0
- package/dist/gradient-reveal-text.d.ts +3 -3
- package/dist/gradient-reveal-text.js +8 -8
- package/dist/input-group.js +1 -1
- package/dist/input-otp.d.ts +3 -3
- package/dist/input-otp.js +2 -2
- package/dist/input.js +1 -1
- package/dist/item.d.ts +1 -1
- package/dist/item.js +17 -11
- package/dist/kbd.d.ts +1 -1
- package/dist/kbd.js +2 -2
- package/dist/label.js +1 -1
- package/dist/lib/merge-refs.d.ts +9 -0
- package/dist/lib/merge-refs.js +16 -0
- package/dist/lib/utils.js +7 -0
- package/dist/masonry.d.ts +1 -1
- package/dist/masonry.js +4 -2
- package/dist/menu.d.ts +2 -1
- package/dist/menu.js +7 -7
- package/dist/menubar.js +1 -1
- package/dist/pagination.js +1 -1
- package/dist/popover.js +1 -1
- package/dist/preview-card.js +1 -1
- package/dist/progress.js +2 -2
- package/dist/radio-group.js +1 -1
- package/dist/radio.js +2 -2
- package/dist/resizable.d.ts +43 -0
- package/dist/resizable.js +53 -0
- package/dist/scroll-area.d.ts +13 -2
- package/dist/scroll-area.js +26 -7
- package/dist/select.js +4 -4
- package/dist/separator.js +1 -1
- package/dist/sidebar.js +12 -12
- package/dist/slider.js +3 -3
- package/dist/spinner.d.ts +7 -0
- package/dist/spinner.js +24 -6
- package/dist/styles.css +581 -194
- package/dist/swipe-deck.d.ts +98 -0
- package/dist/swipe-deck.js +931 -0
- package/dist/switch.js +6 -6
- package/dist/table.d.ts +7 -1
- package/dist/table.js +40 -9
- package/dist/tabs.js +3 -3
- package/dist/textarea.js +1 -1
- package/dist/toast.js +4 -4
- package/dist/toggle-group.js +3 -3
- package/dist/toggle.d.ts +1 -1
- package/dist/toggle.js +11 -6
- package/dist/tooltip.d.ts +3 -1
- package/dist/tooltip.js +10 -6
- package/dist/video-text.d.ts +25 -0
- package/dist/video-text.js +147 -0
- package/package.json +6 -1
package/dist/item.js
CHANGED
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
import { cn } from "./lib/utils.js";
|
|
3
3
|
import { Separator } from "./separator.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import * as React from "react";
|
|
5
6
|
import { cva } from "class-variance-authority";
|
|
6
7
|
import { mergeProps } from "@base-ui/react/merge-props";
|
|
7
8
|
import { useRender } from "@base-ui/react/use-render";
|
|
8
9
|
//#region src/item.tsx
|
|
9
|
-
const itemVariants = cva("[a]:hover:bg-
|
|
10
|
+
const itemVariants = cva("[a,button]:hover:bg-highlight [a,button]:cursor-clickable rounded-md border text-sm w-full group/item focus-visible:border-focus focus-visible:ring-focus/50 flex items-center flex-wrap outline-hidden motion-color focus-visible:ring-3 disabled:pointer-events-none disabled:opacity-30 aria-disabled:pointer-events-none aria-disabled:opacity-30", {
|
|
10
11
|
variants: {
|
|
11
12
|
variant: {
|
|
12
13
|
default: "border-transparent",
|
|
13
|
-
outline: "border-
|
|
14
|
-
muted: "bg-secondary/50 border-transparent"
|
|
14
|
+
outline: "border-contour",
|
|
15
|
+
muted: "bg-secondary/50 border-transparent [a,button]:hover:bg-secondary"
|
|
15
16
|
},
|
|
16
17
|
size: {
|
|
17
|
-
default: "gap-
|
|
18
|
-
sm: "gap-
|
|
19
|
-
xs: "gap-2 px-
|
|
18
|
+
default: "gap-3.5 px-4 py-3.5",
|
|
19
|
+
sm: "gap-3.5 px-3.5 py-3",
|
|
20
|
+
xs: "gap-2.5 px-3 py-2.5 in-data-[slot=menu-content]:p-0"
|
|
20
21
|
}
|
|
21
22
|
},
|
|
22
23
|
defaultVariants: {
|
|
@@ -77,21 +78,26 @@ function ItemMedia({ className, variant = "default", ...props }) {
|
|
|
77
78
|
function ItemContent({ className, ...props }) {
|
|
78
79
|
return /* @__PURE__ */ jsx("div", {
|
|
79
80
|
"data-slot": "item-content",
|
|
80
|
-
className: cn("flex flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0 [&+[data-slot=item-content]]:flex-none", className),
|
|
81
|
+
className: cn("flex min-w-0 flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0.5 [&+[data-slot=item-content]]:flex-none", className),
|
|
81
82
|
...props
|
|
82
83
|
});
|
|
83
84
|
}
|
|
84
|
-
function ItemTitle({ className, ...props }) {
|
|
85
|
+
function ItemTitle({ className, children, ...props }) {
|
|
85
86
|
return /* @__PURE__ */ jsx("div", {
|
|
86
87
|
"data-slot": "item-title",
|
|
87
|
-
className: cn("line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4", className),
|
|
88
|
-
...props
|
|
88
|
+
className: cn("line-clamp-1 flex w-fit max-w-full min-w-0 items-center gap-2 text-sm leading-snug font-medium underline-offset-4 [&>:not([data-slot=item-title-text])]:shrink-0", className),
|
|
89
|
+
...props,
|
|
90
|
+
children: React.Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsx("span", {
|
|
91
|
+
"data-slot": "item-title-text",
|
|
92
|
+
className: "truncate",
|
|
93
|
+
children: child
|
|
94
|
+
}) : child)
|
|
89
95
|
});
|
|
90
96
|
}
|
|
91
97
|
function ItemDescription({ className, ...props }) {
|
|
92
98
|
return /* @__PURE__ */ jsx("p", {
|
|
93
99
|
"data-slot": "item-description",
|
|
94
|
-
className: cn("text-muted [&>a:hover]:text-primary line-clamp-2 text-
|
|
100
|
+
className: cn("text-muted [&>a:hover]:text-primary line-clamp-2 text-start text-sm leading-normal font-normal group-data-[size=xs]/item:text-xs [&>a]:underline [&>a]:underline-offset-4", className),
|
|
95
101
|
...props
|
|
96
102
|
});
|
|
97
103
|
}
|
package/dist/kbd.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
//#region src/kbd.d.ts
|
|
3
3
|
type KbdProps = React.ComponentProps<"kbd">;
|
|
4
|
-
type KbdGroupProps = React.ComponentProps<"
|
|
4
|
+
type KbdGroupProps = React.ComponentProps<"kbd">;
|
|
5
5
|
declare function Kbd({ className, ...props }: KbdProps): React.JSX.Element;
|
|
6
6
|
declare function KbdGroup({ className, ...props }: KbdGroupProps): React.JSX.Element;
|
|
7
7
|
//#endregion
|
package/dist/kbd.js
CHANGED
|
@@ -4,12 +4,12 @@ import { jsx } from "react/jsx-runtime";
|
|
|
4
4
|
function Kbd({ className, ...props }) {
|
|
5
5
|
return /* @__PURE__ */ jsx("kbd", {
|
|
6
6
|
"data-slot": "kbd",
|
|
7
|
-
className: cn("bg-secondary text-
|
|
7
|
+
className: cn("bg-secondary text-contrast in-data-[slot=tooltip-content]:bg-contrast-inverse/10 in-data-[slot=tooltip-content]:text-contrast-inverse pointer-events-none inline-flex h-5.5 w-fit min-w-5.5 items-center justify-center gap-1 rounded-sm px-1.5 font-sans text-xs font-medium select-none [&_svg:not([class*='size-'])]:size-3 in-data-[slot=input-group]:bg-contrast-inverse/50", className),
|
|
8
8
|
...props
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
function KbdGroup({ className, ...props }) {
|
|
12
|
-
return /* @__PURE__ */ jsx("
|
|
12
|
+
return /* @__PURE__ */ jsx("kbd", {
|
|
13
13
|
"data-slot": "kbd-group",
|
|
14
14
|
className: cn("inline-flex items-center gap-1", className),
|
|
15
15
|
...props
|
package/dist/label.js
CHANGED
|
@@ -4,7 +4,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
4
4
|
function Label({ className, ...props }) {
|
|
5
5
|
return /* @__PURE__ */ jsx("label", {
|
|
6
6
|
"data-slot": "label",
|
|
7
|
-
className: cn("flex items-center gap-2 text-sm leading-
|
|
7
|
+
className: cn("flex items-center gap-2 text-sm leading-snug font-medium select-none [&[for]]:cursor-clickable", "in-data-disabled:pointer-events-none in-data-disabled:opacity-30", "peer-data-disabled:pointer-events-none peer-data-disabled:opacity-30", "has-[+:is(:disabled,[data-disabled])]:pointer-events-none has-[+:is(:disabled,[data-disabled])]:opacity-30", className),
|
|
8
8
|
...props
|
|
9
9
|
});
|
|
10
10
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/lib/merge-refs.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Combines refs so one element can feed several of them: a component's own
|
|
5
|
+
* ref and the one a consumer passes. Takes object refs, callback refs and
|
|
6
|
+
* `undefined`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]): (el: T | null) => void;
|
|
9
|
+
//#endregion
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/lib/merge-refs.ts
|
|
2
|
+
/**
|
|
3
|
+
* Combines refs so one element can feed several of them: a component's own
|
|
4
|
+
* ref and the one a consumer passes. Takes object refs, callback refs and
|
|
5
|
+
* `undefined`.
|
|
6
|
+
*/
|
|
7
|
+
function mergeRefs(...refs) {
|
|
8
|
+
return (el) => {
|
|
9
|
+
refs.forEach((ref) => {
|
|
10
|
+
if (typeof ref === "function") ref(el);
|
|
11
|
+
else if (ref && typeof ref === "object") ref.current = el;
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { mergeRefs };
|
package/dist/lib/utils.js
CHANGED
|
@@ -8,6 +8,8 @@ import { extendTailwindMerge } from "tailwind-merge";
|
|
|
8
8
|
* exclusive — the last one applied wins (e.g. a consumer overriding a
|
|
9
9
|
* component's default animation). `motion-color` / `motion-scrim` are left out
|
|
10
10
|
* on purpose: they compose with an enter recipe on the same element.
|
|
11
|
+
* - the spin speeds (`motion-spin-*`) are mutually exclusive too, so a
|
|
12
|
+
* consumer's `motion-spin-lg` replaces a component's `motion-spin-sm`.
|
|
11
13
|
* - `cursor-clickable` joins the built-in `cursor` group.
|
|
12
14
|
*/
|
|
13
15
|
const twMerge = extendTailwindMerge({ extend: { classGroups: {
|
|
@@ -23,6 +25,11 @@ const twMerge = extendTailwindMerge({ extend: { classGroups: {
|
|
|
23
25
|
"motion-fade-lg",
|
|
24
26
|
"motion-pop-md"
|
|
25
27
|
],
|
|
28
|
+
"motion-spin": [
|
|
29
|
+
"motion-spin-sm",
|
|
30
|
+
"motion-spin-md",
|
|
31
|
+
"motion-spin-lg"
|
|
32
|
+
],
|
|
26
33
|
cursor: ["cursor-clickable"]
|
|
27
34
|
} } });
|
|
28
35
|
function cn(...inputs) {
|
package/dist/masonry.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ type MasonryItemProps = Omit<HTMLMotionProps<"div">, "children"> & {
|
|
|
10
10
|
span?: number;
|
|
11
11
|
children?: React.ReactNode;
|
|
12
12
|
};
|
|
13
|
-
declare function Masonry({ columns, columnWidth, gap, className, children, ...props }: MasonryProps): React.JSX.Element;
|
|
13
|
+
declare function Masonry({ columns, columnWidth, gap, className, children, ref, ...props }: MasonryProps): React.JSX.Element;
|
|
14
14
|
declare function MasonryItem({ className, span, children, ...props }: MasonryItemProps): React.JSX.Element;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { Masonry, MasonryItem, type MasonryItemProps, type MasonryProps };
|
package/dist/masonry.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "./lib/utils.js";
|
|
3
3
|
import { StarIcon } from "./lib/internal-icons.js";
|
|
4
|
+
import { mergeRefs } from "./lib/merge-refs.js";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
import * as React from "react";
|
|
6
7
|
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
|
|
7
8
|
//#region src/masonry.tsx
|
|
8
9
|
const STAGGER_STEP = .05;
|
|
9
10
|
const MasonryStaggerContext = React.createContext(null);
|
|
10
|
-
function Masonry({ columns, columnWidth, gap = 4, className, children, ...props }) {
|
|
11
|
+
function Masonry({ columns, columnWidth, gap = 4, className, children, ref, ...props }) {
|
|
11
12
|
const containerRef = React.useRef(null);
|
|
13
|
+
const mergedRef = React.useMemo(() => mergeRefs(containerRef, ref), [ref]);
|
|
12
14
|
const rafRef = React.useRef(0);
|
|
13
15
|
const staggerCounterRef = React.useRef(0);
|
|
14
16
|
staggerCounterRef.current = 0;
|
|
@@ -134,7 +136,7 @@ function Masonry({ columns, columnWidth, gap = 4, className, children, ...props
|
|
|
134
136
|
return /* @__PURE__ */ jsx(MasonryStaggerContext.Provider, {
|
|
135
137
|
value: getStaggerIndex,
|
|
136
138
|
children: /* @__PURE__ */ jsx("div", {
|
|
137
|
-
ref:
|
|
139
|
+
ref: mergedRef,
|
|
138
140
|
"data-slot": "masonry",
|
|
139
141
|
className: cn("relative", className),
|
|
140
142
|
...props,
|
package/dist/menu.d.ts
CHANGED
|
@@ -20,7 +20,8 @@ type MenuLabelProps = React.ComponentProps<typeof Menu$1.GroupLabel> & {
|
|
|
20
20
|
};
|
|
21
21
|
type MenuItemProps = React.ComponentProps<typeof Menu$1.Item> & {
|
|
22
22
|
inset?: boolean;
|
|
23
|
-
|
|
23
|
+
/** `danger` turns the item's text and leading icon red. */
|
|
24
|
+
variant?: "default" | "danger";
|
|
24
25
|
};
|
|
25
26
|
type MenuSubProps = React.ComponentProps<typeof Menu$1.SubmenuRoot>;
|
|
26
27
|
type MenuSubTriggerProps = React.ComponentProps<typeof Menu$1.SubmenuTrigger> & {
|
package/dist/menu.js
CHANGED
|
@@ -33,7 +33,7 @@ function MenuContent({ align = "start", alignOffset = 0, side = "bottom", sideOf
|
|
|
33
33
|
sideOffset,
|
|
34
34
|
children: /* @__PURE__ */ jsx(Menu$1.Popup, {
|
|
35
35
|
"data-slot": "menu-content",
|
|
36
|
-
className: cn("motion-pop-md ring-contrast/10 bg-elevated text-contrast z-50 max-h-(--available-height) max-w-(--available-width) w-auto min-w-32
|
|
36
|
+
className: cn("motion-pop-md ring-contrast/10 bg-elevated text-contrast z-50 max-h-(--available-height) max-w-(--available-width) w-auto min-w-32 overflow-x-hidden overflow-y-auto rounded-md p-1 shadow-md ring-1 outline-hidden data-closed:overflow-hidden", className),
|
|
37
37
|
finalFocus: resolveFinalFocus(restoreFocusOnClose, finalFocus),
|
|
38
38
|
...props
|
|
39
39
|
})
|
|
@@ -58,7 +58,7 @@ function MenuItem({ className, inset, variant = "default", ...props }) {
|
|
|
58
58
|
"data-slot": "menu-item",
|
|
59
59
|
"data-inset": inset,
|
|
60
60
|
"data-variant": variant,
|
|
61
|
-
className: cn("focus:bg-
|
|
61
|
+
className: cn("focus:bg-highlight data-[variant=danger]:text-danger data-[variant=danger]:*:[svg]:text-danger data-[variant=danger]:focus:bg-danger data-[variant=danger]:focus:text-white data-[variant=danger]:focus:**:text-white group/menu-item relative flex cursor-clickable items-center gap-1.5 rounded-sm px-1.5 py-1 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-30 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
|
|
62
62
|
...props
|
|
63
63
|
});
|
|
64
64
|
}
|
|
@@ -72,7 +72,7 @@ function MenuSubTrigger({ className, inset, children, ...props }) {
|
|
|
72
72
|
return /* @__PURE__ */ jsxs(Menu$1.SubmenuTrigger, {
|
|
73
73
|
"data-slot": "menu-sub-trigger",
|
|
74
74
|
"data-inset": inset,
|
|
75
|
-
className: cn("focus:bg-
|
|
75
|
+
className: cn("focus:bg-highlight data-popup-open:bg-highlight flex cursor-clickable items-center gap-1.5 rounded-sm px-1.5 py-1 text-sm outline-hidden select-none data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
|
|
76
76
|
...props,
|
|
77
77
|
children: [children, /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto" })]
|
|
78
78
|
});
|
|
@@ -92,7 +92,7 @@ function MenuCheckboxItem({ className, children, checked, inset, ...props }) {
|
|
|
92
92
|
return /* @__PURE__ */ jsxs(Menu$1.CheckboxItem, {
|
|
93
93
|
"data-slot": "menu-checkbox-item",
|
|
94
94
|
"data-inset": inset,
|
|
95
|
-
className: cn("focus:bg-
|
|
95
|
+
className: cn("focus:bg-highlight relative flex cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-30 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
|
|
96
96
|
checked,
|
|
97
97
|
...props,
|
|
98
98
|
children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -112,7 +112,7 @@ function MenuRadioItem({ className, children, inset, ...props }) {
|
|
|
112
112
|
return /* @__PURE__ */ jsxs(Menu$1.RadioItem, {
|
|
113
113
|
"data-slot": "menu-radio-item",
|
|
114
114
|
"data-inset": inset,
|
|
115
|
-
className: cn("focus:bg-
|
|
115
|
+
className: cn("focus:bg-highlight relative flex cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-30 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
|
|
116
116
|
...props,
|
|
117
117
|
children: [/* @__PURE__ */ jsx("span", {
|
|
118
118
|
"data-slot": "menu-radio-item-indicator",
|
|
@@ -124,14 +124,14 @@ function MenuRadioItem({ className, children, inset, ...props }) {
|
|
|
124
124
|
function MenuSeparator({ className, ...props }) {
|
|
125
125
|
return /* @__PURE__ */ jsx(Menu$1.Separator, {
|
|
126
126
|
"data-slot": "menu-separator",
|
|
127
|
-
className: cn("bg-
|
|
127
|
+
className: cn("bg-contour -mx-1 my-1 h-px", className),
|
|
128
128
|
...props
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
function MenuShortcut({ className, ...props }) {
|
|
132
132
|
return /* @__PURE__ */ jsx("span", {
|
|
133
133
|
"data-slot": "menu-shortcut",
|
|
134
|
-
className: cn("text-muted
|
|
134
|
+
className: cn("text-muted ml-auto text-xs tracking-widest", className),
|
|
135
135
|
...props
|
|
136
136
|
});
|
|
137
137
|
}
|
package/dist/menubar.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Menubar as Menubar$1 } from "@base-ui/react/menubar";
|
|
|
7
7
|
function Menubar({ className, ...props }) {
|
|
8
8
|
return /* @__PURE__ */ jsx(Menubar$1, {
|
|
9
9
|
"data-slot": "menubar",
|
|
10
|
-
className: cn("bg-foundation flex h-9 items-center gap-0.5 rounded-md border border-
|
|
10
|
+
className: cn("bg-foundation flex h-9 items-center gap-0.5 rounded-md border border-shade p-1", className),
|
|
11
11
|
...props
|
|
12
12
|
});
|
|
13
13
|
}
|
package/dist/pagination.js
CHANGED
|
@@ -26,7 +26,7 @@ function PaginationItem(props) {
|
|
|
26
26
|
}
|
|
27
27
|
function PaginationLink({ className, isActive, disabled, size = "icon", ...props }) {
|
|
28
28
|
return /* @__PURE__ */ jsx(Button, {
|
|
29
|
-
variant: isActive ? "
|
|
29
|
+
variant: isActive ? "default" : "ghost",
|
|
30
30
|
size,
|
|
31
31
|
className: cn(disabled && "pointer-events-none opacity-50", className),
|
|
32
32
|
render: /* @__PURE__ */ jsx("a", {
|
package/dist/popover.js
CHANGED
|
@@ -46,7 +46,7 @@ function PopoverContent({ className, positionerClassName, align = "center", alig
|
|
|
46
46
|
className: cn("isolate z-50", positionerClassName),
|
|
47
47
|
children: /* @__PURE__ */ jsx(Popover$1.Popup, {
|
|
48
48
|
"data-slot": "popover-content",
|
|
49
|
-
className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 z-50 flex w-72
|
|
49
|
+
className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 z-50 flex w-72 flex-col gap-2.5 rounded-md p-2.5 text-sm shadow-md ring-1 outline-hidden", className),
|
|
50
50
|
finalFocus: resolveFinalFocus(restoreFocusOnClose, finalFocus),
|
|
51
51
|
...props
|
|
52
52
|
})
|
package/dist/preview-card.js
CHANGED
|
@@ -38,7 +38,7 @@ function PreviewCardContent({ className, positionerClassName, side = "bottom", s
|
|
|
38
38
|
className: cn("isolate z-50", positionerClassName),
|
|
39
39
|
children: /* @__PURE__ */ jsx(PreviewCard$1.Popup, {
|
|
40
40
|
"data-slot": "preview-card-content",
|
|
41
|
-
className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 z-50 w-64
|
|
41
|
+
className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 z-50 w-64 rounded-md p-2.5 text-sm shadow-md ring-1 outline-hidden", className),
|
|
42
42
|
...props
|
|
43
43
|
})
|
|
44
44
|
}) });
|
package/dist/progress.js
CHANGED
|
@@ -14,7 +14,7 @@ function Progress({ className, children, value = null, ...props }) {
|
|
|
14
14
|
}
|
|
15
15
|
function ProgressTrack({ className, ...props }) {
|
|
16
16
|
return /* @__PURE__ */ jsx(Progress$1.Track, {
|
|
17
|
-
className: cn("bg-secondary relative flex h-
|
|
17
|
+
className: cn("bg-secondary relative flex h-3 w-full items-center overflow-x-hidden rounded-full", className),
|
|
18
18
|
"data-slot": "progress-track",
|
|
19
19
|
...props
|
|
20
20
|
});
|
|
@@ -35,7 +35,7 @@ function ProgressLabel({ className, ...props }) {
|
|
|
35
35
|
}
|
|
36
36
|
function ProgressValue({ className, ...props }) {
|
|
37
37
|
return /* @__PURE__ */ jsx(Progress$1.Value, {
|
|
38
|
-
className: cn("text-muted
|
|
38
|
+
className: cn("text-muted ms-auto text-sm tabular-nums", className),
|
|
39
39
|
"data-slot": "progress-value",
|
|
40
40
|
...props
|
|
41
41
|
});
|
package/dist/radio-group.js
CHANGED
|
@@ -7,7 +7,7 @@ import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
|
|
|
7
7
|
function RadioGroup({ className, ...props }) {
|
|
8
8
|
return /* @__PURE__ */ jsx(RadioGroup$1, {
|
|
9
9
|
"data-slot": "radio-group",
|
|
10
|
-
className: cn("grid w-full gap-
|
|
10
|
+
className: cn("grid w-full gap-3", className),
|
|
11
11
|
...props
|
|
12
12
|
});
|
|
13
13
|
}
|
package/dist/radio.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Radio as Radio$1 } from "@base-ui/react/radio";
|
|
|
6
6
|
function Radio({ className, ...props }) {
|
|
7
7
|
return /* @__PURE__ */ jsx(Radio$1.Root, {
|
|
8
8
|
"data-slot": "radio",
|
|
9
|
-
className: cn("cursor-clickable border-
|
|
9
|
+
className: cn("cursor-clickable bg-shade border-transparent not-data-disabled:data-unchecked:hover:border-focus not-data-disabled:data-unchecked:group-hover/field:border-focus data-checked:bg-primary data-checked:text-white data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-danger focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 group/radio peer relative flex aspect-square size-6 shrink-0 rounded-full border motion-color outline-hidden group-has-disabled/field:opacity-30 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 aria-invalid:ring-3", className),
|
|
10
10
|
...props,
|
|
11
11
|
children: /* @__PURE__ */ jsx(RadioIndicator, {})
|
|
12
12
|
});
|
|
@@ -14,7 +14,7 @@ function Radio({ className, ...props }) {
|
|
|
14
14
|
function RadioIndicator({ className, ...props }) {
|
|
15
15
|
return /* @__PURE__ */ jsx(Radio$1.Indicator, {
|
|
16
16
|
"data-slot": "radio-indicator",
|
|
17
|
-
className: cn("
|
|
17
|
+
className: cn("text-white absolute inset-0 flex items-center justify-center data-unchecked:opacity-0", "after:block after:size-3 after:rounded-full after:bg-current", className),
|
|
18
18
|
...props
|
|
19
19
|
});
|
|
20
20
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Group, Panel, Separator } from "react-resizable-panels";
|
|
3
|
+
//#region src/resizable.d.ts
|
|
4
|
+
type ResizablePanelGroupProps = Omit<React.ComponentProps<typeof Group>, "elementRef"> & {
|
|
5
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
6
|
+
};
|
|
7
|
+
type ResizablePanelProps = Omit<React.ComponentProps<typeof Panel>, "elementRef"> & {
|
|
8
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
9
|
+
};
|
|
10
|
+
type ResizableHandleProps = Omit<React.ComponentProps<typeof Separator>, "elementRef"> & {
|
|
11
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
12
|
+
/**
|
|
13
|
+
* Show a grip on the line, a visible hint that it can be dragged.
|
|
14
|
+
*
|
|
15
|
+
* @default false
|
|
16
|
+
*/
|
|
17
|
+
grip?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* A row of panels the user resizes by dragging the handles between them, or
|
|
21
|
+
* from the keyboard once a handle has focus. Pass `orientation="vertical"` to
|
|
22
|
+
* stack them instead.
|
|
23
|
+
*
|
|
24
|
+
* The group fills its parent: it sets its own `width` and `height` to 100%
|
|
25
|
+
* inline, so a height class on the group has no effect. Size the parent, or
|
|
26
|
+
* pass `style`.
|
|
27
|
+
*/
|
|
28
|
+
declare function ResizablePanelGroup({ ref, ...props }: ResizablePanelGroupProps): React.JSX.Element;
|
|
29
|
+
/**
|
|
30
|
+
* One resizable region. Numeric sizes are pixels; use strings for
|
|
31
|
+
* percentages (`defaultSize="25%"`). `className` lands on the panel's inner
|
|
32
|
+
* element, which scrolls when the content overflows.
|
|
33
|
+
*/
|
|
34
|
+
declare function ResizablePanel({ ref, ...props }: ResizablePanelProps): React.JSX.Element;
|
|
35
|
+
/**
|
|
36
|
+
* The line between two panels. It lights up while the pointer is close
|
|
37
|
+
* enough to drag it: the library hit-tests a zone wider than the line itself
|
|
38
|
+
* and reports it in `data-separator` (`hover`, `active`, `focus`, `disabled`),
|
|
39
|
+
* which CSS `:hover` on a 1px line would miss.
|
|
40
|
+
*/
|
|
41
|
+
declare function ResizableHandle({ className, grip, ref, ...props }: ResizableHandleProps): React.JSX.Element;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { ResizableHandle, type ResizableHandleProps, ResizablePanel, ResizablePanelGroup, type ResizablePanelGroupProps, type ResizablePanelProps };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "./lib/utils.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { Group, Panel, Separator } from "react-resizable-panels";
|
|
5
|
+
//#region src/resizable.tsx
|
|
6
|
+
/**
|
|
7
|
+
* A row of panels the user resizes by dragging the handles between them, or
|
|
8
|
+
* from the keyboard once a handle has focus. Pass `orientation="vertical"` to
|
|
9
|
+
* stack them instead.
|
|
10
|
+
*
|
|
11
|
+
* The group fills its parent: it sets its own `width` and `height` to 100%
|
|
12
|
+
* inline, so a height class on the group has no effect. Size the parent, or
|
|
13
|
+
* pass `style`.
|
|
14
|
+
*/
|
|
15
|
+
function ResizablePanelGroup({ ref, ...props }) {
|
|
16
|
+
return /* @__PURE__ */ jsx(Group, {
|
|
17
|
+
"data-slot": "resizable-panel-group",
|
|
18
|
+
elementRef: ref,
|
|
19
|
+
...props
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* One resizable region. Numeric sizes are pixels; use strings for
|
|
24
|
+
* percentages (`defaultSize="25%"`). `className` lands on the panel's inner
|
|
25
|
+
* element, which scrolls when the content overflows.
|
|
26
|
+
*/
|
|
27
|
+
function ResizablePanel({ ref, ...props }) {
|
|
28
|
+
return /* @__PURE__ */ jsx(Panel, {
|
|
29
|
+
"data-slot": "resizable-panel",
|
|
30
|
+
elementRef: ref,
|
|
31
|
+
...props
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The line between two panels. It lights up while the pointer is close
|
|
36
|
+
* enough to drag it: the library hit-tests a zone wider than the line itself
|
|
37
|
+
* and reports it in `data-separator` (`hover`, `active`, `focus`, `disabled`),
|
|
38
|
+
* which CSS `:hover` on a 1px line would miss.
|
|
39
|
+
*/
|
|
40
|
+
function ResizableHandle({ className, grip = false, ref, ...props }) {
|
|
41
|
+
return /* @__PURE__ */ jsx(Separator, {
|
|
42
|
+
"data-slot": "resizable-handle",
|
|
43
|
+
elementRef: ref,
|
|
44
|
+
className: cn("group/resizable-handle bg-contour z-10 flex items-center justify-center motion-color outline-hidden focus-visible:ring-3 focus-visible:ring-focus/50 data-[separator=active]:bg-focus data-[separator=hover]:bg-focus data-[separator=disabled]:pointer-events-none aria-[orientation=horizontal]:h-px aria-[orientation=vertical]:w-px", className),
|
|
45
|
+
...props,
|
|
46
|
+
children: grip && /* @__PURE__ */ jsx("div", {
|
|
47
|
+
"data-slot": "resizable-handle-grip",
|
|
48
|
+
className: "bg-shade h-6 w-1 shrink-0 rounded-full motion-color group-data-[separator=active]/resizable-handle:bg-focus group-data-[separator=hover]/resizable-handle:bg-focus group-data-[separator=disabled]/resizable-handle:opacity-30 group-aria-[orientation=horizontal]/resizable-handle:h-1 group-aria-[orientation=horizontal]/resizable-handle:w-6"
|
|
49
|
+
})
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
|
package/dist/scroll-area.d.ts
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { ScrollArea as ScrollArea$1 } from "@base-ui/react/scroll-area";
|
|
3
3
|
//#region src/scroll-area.d.ts
|
|
4
|
-
type ScrollAreaProps = React.ComponentProps<typeof ScrollArea$1.Root
|
|
5
|
-
|
|
4
|
+
type ScrollAreaProps = React.ComponentProps<typeof ScrollArea$1.Root> & {
|
|
5
|
+
/**
|
|
6
|
+
* Fade the content out toward any edge that has more to scroll to. On by
|
|
7
|
+
* default; the fade size follows `--scroll-area-fade` (default `2.5rem`).
|
|
8
|
+
*/
|
|
9
|
+
fade?: boolean;
|
|
10
|
+
};
|
|
6
11
|
type ScrollBarProps = React.ComponentProps<typeof ScrollArea$1.Scrollbar>;
|
|
12
|
+
/**
|
|
13
|
+
* A scrollable region with styled scrollbars. Both scrollbars are built in:
|
|
14
|
+
* Base UI only mounts one when its axis overflows, so pass content and the
|
|
15
|
+
* right bars appear. They fade in while the area is hovered or scrolling.
|
|
16
|
+
*/
|
|
17
|
+
declare function ScrollArea({ className, children, fade, ...props }: ScrollAreaProps): React.JSX.Element;
|
|
7
18
|
declare function ScrollBar({ className, orientation, ...props }: ScrollBarProps): React.JSX.Element;
|
|
8
19
|
//#endregion
|
|
9
20
|
export { ScrollArea, type ScrollAreaProps, ScrollBar, type ScrollBarProps };
|
package/dist/scroll-area.js
CHANGED
|
@@ -3,18 +3,37 @@ import { cn } from "./lib/utils.js";
|
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { ScrollArea as ScrollArea$1 } from "@base-ui/react/scroll-area";
|
|
5
5
|
//#region src/scroll-area.tsx
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The edge fade is a mask, so the content itself turns transparent and
|
|
8
|
+
* whatever is behind it shows through: no shadow color to match, in any
|
|
9
|
+
* theme. Each edge has a fixed fade (`--scroll-area-fade`) that switches on
|
|
10
|
+
* when Base UI marks that edge as having more content (`data-overflow-*`):
|
|
11
|
+
* its edge opacity goes from 1 (none) to 0 (fully faded).
|
|
12
|
+
* The two axes are intersected; the horizontal one flips in right-to-left
|
|
13
|
+
* layouts, where Base UI's "start" is the right edge.
|
|
14
|
+
*/
|
|
15
|
+
const FADE_MASK = "[--scroll-area-fade-x:to_right] rtl:[--scroll-area-fade-x:to_left] data-overflow-y-start:[--scroll-area-fade-top:0] data-overflow-y-end:[--scroll-area-fade-bottom:0] data-overflow-x-start:[--scroll-area-fade-start:0] data-overflow-x-end:[--scroll-area-fade-end:0] [mask-composite:intersect] [mask-image:linear-gradient(to_bottom,rgb(0_0_0/var(--scroll-area-fade-top,1)),#000_var(--scroll-area-fade,2.5rem),#000_calc(100%_-_var(--scroll-area-fade,2.5rem)),rgb(0_0_0/var(--scroll-area-fade-bottom,1))),linear-gradient(var(--scroll-area-fade-x),rgb(0_0_0/var(--scroll-area-fade-start,1)),#000_var(--scroll-area-fade,2.5rem),#000_calc(100%_-_var(--scroll-area-fade,2.5rem)),rgb(0_0_0/var(--scroll-area-fade-end,1)))]";
|
|
16
|
+
/**
|
|
17
|
+
* A scrollable region with styled scrollbars. Both scrollbars are built in:
|
|
18
|
+
* Base UI only mounts one when its axis overflows, so pass content and the
|
|
19
|
+
* right bars appear. They fade in while the area is hovered or scrolling.
|
|
20
|
+
*/
|
|
21
|
+
function ScrollArea({ className, children, fade = true, ...props }) {
|
|
7
22
|
return /* @__PURE__ */ jsxs(ScrollArea$1.Root, {
|
|
8
23
|
"data-slot": "scroll-area",
|
|
9
|
-
className: cn("relative", className),
|
|
24
|
+
className: cn("relative motion-color has-[>[data-slot=scroll-area-viewport]:focus-visible]:ring-3 has-[>[data-slot=scroll-area-viewport]:focus-visible]:ring-focus/50 has-[>[data-slot=scroll-area-viewport]:focus-visible]:outline-hidden", className),
|
|
10
25
|
...props,
|
|
11
26
|
children: [
|
|
12
27
|
/* @__PURE__ */ jsx(ScrollArea$1.Viewport, {
|
|
13
28
|
"data-slot": "scroll-area-viewport",
|
|
14
|
-
className: "
|
|
15
|
-
children
|
|
29
|
+
className: cn("size-full rounded-[inherit] outline-hidden", fade && FADE_MASK),
|
|
30
|
+
children: /* @__PURE__ */ jsx(ScrollArea$1.Content, {
|
|
31
|
+
"data-slot": "scroll-area-content",
|
|
32
|
+
children
|
|
33
|
+
})
|
|
16
34
|
}),
|
|
17
|
-
/* @__PURE__ */ jsx(ScrollBar, {}),
|
|
35
|
+
/* @__PURE__ */ jsx(ScrollBar, { orientation: "vertical" }),
|
|
36
|
+
/* @__PURE__ */ jsx(ScrollBar, { orientation: "horizontal" }),
|
|
18
37
|
/* @__PURE__ */ jsx(ScrollArea$1.Corner, { "data-slot": "scroll-area-corner" })
|
|
19
38
|
]
|
|
20
39
|
});
|
|
@@ -23,11 +42,11 @@ function ScrollBar({ className, orientation = "vertical", ...props }) {
|
|
|
23
42
|
return /* @__PURE__ */ jsx(ScrollArea$1.Scrollbar, {
|
|
24
43
|
"data-slot": "scroll-area-scrollbar",
|
|
25
44
|
orientation,
|
|
26
|
-
className: cn("flex touch-none p-px transition-
|
|
45
|
+
className: cn("pointer-events-none flex touch-none p-px opacity-0 transition-opacity duration-(--duration-md) ease-(--ease) select-none data-hovering:pointer-events-auto data-hovering:opacity-100 data-scrolling:pointer-events-auto data-scrolling:opacity-100 data-scrolling:duration-0 data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:border-t data-[orientation=horizontal]:border-t-transparent data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2.5 data-[orientation=vertical]:border-s data-[orientation=vertical]:border-s-transparent", className),
|
|
27
46
|
...props,
|
|
28
47
|
children: /* @__PURE__ */ jsx(ScrollArea$1.Thumb, {
|
|
29
48
|
"data-slot": "scroll-area-thumb",
|
|
30
|
-
className: "bg-
|
|
49
|
+
className: "bg-shade relative flex-1 rounded-full"
|
|
31
50
|
})
|
|
32
51
|
});
|
|
33
52
|
}
|
package/dist/select.js
CHANGED
|
@@ -5,7 +5,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
import { cva } from "class-variance-authority";
|
|
6
6
|
import { Select as Select$1 } from "@base-ui/react/select";
|
|
7
7
|
//#region src/select.tsx
|
|
8
|
-
const selectTriggerVariants = cva("data-placeholder:text-soft bg-
|
|
8
|
+
const selectTriggerVariants = cva("data-placeholder:text-soft bg-shade hover:border-focus focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger flex w-fit items-center justify-between gap-1.5 rounded-md border border-transparent whitespace-nowrap motion-color outline-hidden select-none focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 aria-invalid:ring-3 *: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 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
9
9
|
variants: { size: {
|
|
10
10
|
xs: "h-6 rounded-sm px-2 text-xs",
|
|
11
11
|
sm: "h-8 px-3 text-sm",
|
|
@@ -76,7 +76,7 @@ function SelectContent({ className, children, side = "bottom", sideOffset = 4, a
|
|
|
76
76
|
className: "isolate z-50",
|
|
77
77
|
children: /* @__PURE__ */ jsxs(Select$1.Popup, {
|
|
78
78
|
"data-slot": "select-content",
|
|
79
|
-
className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 relative isolate z-50 max-h-(--available-height) min-w-(--anchor-width) max-w-(--available-width)
|
|
79
|
+
className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 relative isolate z-50 max-h-(--available-height) min-w-(--anchor-width) max-w-(--available-width) overflow-x-hidden overflow-y-auto rounded-md shadow-md ring-1", className),
|
|
80
80
|
...props,
|
|
81
81
|
children: [
|
|
82
82
|
/* @__PURE__ */ jsx(SelectScrollUpButton, {}),
|
|
@@ -96,7 +96,7 @@ function SelectLabel({ className, ...props }) {
|
|
|
96
96
|
function SelectItem({ className, children, ...props }) {
|
|
97
97
|
return /* @__PURE__ */ jsxs(Select$1.Item, {
|
|
98
98
|
"data-slot": "select-item",
|
|
99
|
-
className: cn("data-highlighted:bg-
|
|
99
|
+
className: cn("data-highlighted:bg-highlight relative flex w-full cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-30 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
|
|
100
100
|
...props,
|
|
101
101
|
children: [/* @__PURE__ */ jsx(Select$1.ItemText, {
|
|
102
102
|
"data-slot": "select-item-text",
|
|
@@ -114,7 +114,7 @@ function SelectItem({ className, children, ...props }) {
|
|
|
114
114
|
function SelectSeparator({ className, ...props }) {
|
|
115
115
|
return /* @__PURE__ */ jsx(Select$1.Separator, {
|
|
116
116
|
"data-slot": "select-separator",
|
|
117
|
-
className: cn("bg-
|
|
117
|
+
className: cn("bg-contour pointer-events-none -mx-1 my-1 h-px", className),
|
|
118
118
|
...props
|
|
119
119
|
});
|
|
120
120
|
}
|
package/dist/separator.js
CHANGED
|
@@ -7,7 +7,7 @@ function Separator({ className, orientation = "horizontal", ...props }) {
|
|
|
7
7
|
return /* @__PURE__ */ jsx(Separator$1, {
|
|
8
8
|
"data-slot": "separator",
|
|
9
9
|
orientation,
|
|
10
|
-
className: cn("bg-
|
|
10
|
+
className: cn("bg-contour shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch", className),
|
|
11
11
|
...props
|
|
12
12
|
});
|
|
13
13
|
}
|