@weichenlin/swell-ui 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -35
- package/dist/index.d.ts +106 -6
- package/dist/index.js +463 -138
- package/dist/theme.css +185 -77
- package/package.json +1 -2
- package/dist/themes/warm.css +0 -63
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Check, ChevronDown, CircleAlert, CircleCheck, CircleDashed, CircleX, Copy, Eye, EyeOff, Info, LoaderCircle, Menu, Moon, Search, Sun, TriangleAlert, X } from "lucide-react";
|
|
1
|
+
import { ArrowDown, ArrowUp, ArrowUpDown, Check, ChevronDown, ChevronLeft, ChevronRight, CircleAlert, CircleCheck, CircleDashed, CircleX, Copy, Eye, EyeOff, Info, LoaderCircle, Menu, Moon, Search, Sun, TriangleAlert, X } from "lucide-react";
|
|
2
2
|
import { clsx } from "clsx";
|
|
3
3
|
import { extendTailwindMerge } from "tailwind-merge";
|
|
4
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
4
|
import { cva } from "class-variance-authority";
|
|
6
5
|
import { Children, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useId, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
7
6
|
import { createPortal } from "react-dom";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/lib/cn.ts
|
|
9
9
|
const tone = (name) => [
|
|
10
10
|
name,
|
|
@@ -45,6 +45,8 @@ const twMerge = extendTailwindMerge({ extend: { theme: {
|
|
|
45
45
|
"input-halo-invalid-focus",
|
|
46
46
|
"control-checked",
|
|
47
47
|
"control-checked-fg",
|
|
48
|
+
"switch-handle",
|
|
49
|
+
"switch-handle-checked",
|
|
48
50
|
"popover-bg",
|
|
49
51
|
"popover-border",
|
|
50
52
|
"popover-highlight",
|
|
@@ -76,67 +78,6 @@ function cn(...inputs) {
|
|
|
76
78
|
return twMerge(clsx(inputs));
|
|
77
79
|
}
|
|
78
80
|
//#endregion
|
|
79
|
-
//#region src/components/badge/badge.tsx
|
|
80
|
-
const toneClasses$1 = {
|
|
81
|
-
neutral: {
|
|
82
|
-
subtle: ["border-neutral-border bg-neutral-subtle-bg text-neutral-subtle-fg", "text-neutral"],
|
|
83
|
-
outline: ["border-neutral-border bg-transparent text-neutral-subtle-fg", "text-neutral"],
|
|
84
|
-
solid: ["border-neutral bg-neutral text-neutral-fg", "text-neutral-fg"]
|
|
85
|
-
},
|
|
86
|
-
info: {
|
|
87
|
-
subtle: ["border-info-border bg-info-subtle-bg text-info-subtle-fg", "text-info"],
|
|
88
|
-
outline: ["border-info-border bg-transparent text-info-subtle-fg", "text-info"],
|
|
89
|
-
solid: ["border-info bg-info text-info-fg", "text-info-fg"]
|
|
90
|
-
},
|
|
91
|
-
success: {
|
|
92
|
-
subtle: ["border-success-border bg-success-subtle-bg text-success-subtle-fg", "text-success"],
|
|
93
|
-
outline: ["border-success-border bg-transparent text-success-subtle-fg", "text-success"],
|
|
94
|
-
solid: ["border-success bg-success text-success-fg", "text-success-fg"]
|
|
95
|
-
},
|
|
96
|
-
warning: {
|
|
97
|
-
subtle: ["border-warning-border bg-warning-subtle-bg text-warning-subtle-fg", "text-warning"],
|
|
98
|
-
outline: ["border-warning-border bg-transparent text-warning-subtle-fg", "text-warning"],
|
|
99
|
-
solid: ["border-warning bg-warning text-warning-fg", "text-warning-fg"]
|
|
100
|
-
},
|
|
101
|
-
danger: {
|
|
102
|
-
subtle: ["border-danger-border bg-danger-subtle-bg text-danger-subtle-fg", "text-danger"],
|
|
103
|
-
outline: ["border-danger-border bg-transparent text-danger-subtle-fg", "text-danger"],
|
|
104
|
-
solid: ["border-danger bg-danger text-danger-fg", "text-danger-fg"]
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
const sizeClasses$3 = {
|
|
108
|
-
sm: {
|
|
109
|
-
base: "h-5 px-1.5",
|
|
110
|
-
withIcon: "ps-1"
|
|
111
|
-
},
|
|
112
|
-
md: {
|
|
113
|
-
base: "h-6 px-2",
|
|
114
|
-
withIcon: "ps-1.5"
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
function Badge({ tone = "neutral", variant = "subtle", size = "md", icon, busy = false, context, className, children, ...props }) {
|
|
118
|
-
const [toneClass, iconClass] = toneClasses$1[tone][variant];
|
|
119
|
-
const hasIcon = busy || icon !== void 0 && icon !== null && icon !== false;
|
|
120
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
121
|
-
...props,
|
|
122
|
-
"data-slot": "badge",
|
|
123
|
-
className: cn("inline-flex items-center gap-1 rounded-md border text-xs leading-none font-medium whitespace-nowrap", "forced-colors:border-[CanvasText]", sizeClasses$3[size].base, hasIcon && sizeClasses$3[size].withIcon, toneClass, className),
|
|
124
|
-
children: [hasIcon && /* @__PURE__ */ jsx("span", {
|
|
125
|
-
"aria-hidden": "true",
|
|
126
|
-
"data-slot": "badge-icon",
|
|
127
|
-
className: cn("inline-flex shrink-0 items-center [&_svg]:size-3 [&_svg]:shrink-0", iconClass),
|
|
128
|
-
children: busy ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(LoaderCircle, { className: "animate-spin motion-reduce:hidden" }), /* @__PURE__ */ jsx(CircleDashed, { className: "hidden motion-reduce:block" })] }) : icon
|
|
129
|
-
}), /* @__PURE__ */ jsxs("span", {
|
|
130
|
-
"data-slot": "badge-label",
|
|
131
|
-
className: "min-w-0 truncate leading-4",
|
|
132
|
-
children: [context && /* @__PURE__ */ jsxs("span", {
|
|
133
|
-
className: "sr-only",
|
|
134
|
-
children: [context, ": "]
|
|
135
|
-
}), children]
|
|
136
|
-
})]
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
//#endregion
|
|
140
81
|
//#region src/hooks/use-press-feedback.ts
|
|
141
82
|
const GROW_MS = 450;
|
|
142
83
|
const FADE_MS = 300;
|
|
@@ -221,6 +162,61 @@ function usePressFeedback(ripple = true) {
|
|
|
221
162
|
return ref;
|
|
222
163
|
}
|
|
223
164
|
//#endregion
|
|
165
|
+
//#region src/lib/slot.tsx
|
|
166
|
+
function setRef(ref, node) {
|
|
167
|
+
if (typeof ref === "function") return ref(node);
|
|
168
|
+
if (ref) ref.current = node;
|
|
169
|
+
}
|
|
170
|
+
function composeRefs(...refs) {
|
|
171
|
+
return (node) => {
|
|
172
|
+
const cleanups = refs.map((ref) => setRef(ref, node));
|
|
173
|
+
return () => {
|
|
174
|
+
for (const [i, ref] of refs.entries()) {
|
|
175
|
+
const cleanup = cleanups[i];
|
|
176
|
+
if (typeof cleanup === "function") cleanup();
|
|
177
|
+
else setRef(ref, null);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function mergeProps(slot, child) {
|
|
183
|
+
const merged = {
|
|
184
|
+
...slot,
|
|
185
|
+
...child
|
|
186
|
+
};
|
|
187
|
+
for (const key of Object.keys(slot)) {
|
|
188
|
+
const own = slot[key];
|
|
189
|
+
const theirs = child[key];
|
|
190
|
+
if (/^on[A-Z]/.test(key) && typeof own === "function" && typeof theirs === "function") merged[key] = (...args) => {
|
|
191
|
+
theirs(...args);
|
|
192
|
+
own(...args);
|
|
193
|
+
};
|
|
194
|
+
else if (key === "className") merged.className = cn(own, theirs);
|
|
195
|
+
else if (key === "style") merged.style = {
|
|
196
|
+
...own,
|
|
197
|
+
...theirs
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return merged;
|
|
201
|
+
}
|
|
202
|
+
/** Applies `wrap` to an element's children, or to what a render-prop child returns. */
|
|
203
|
+
function wrapChildren(children, wrap) {
|
|
204
|
+
if (typeof children !== "function") return wrap(children);
|
|
205
|
+
return (...args) => wrap(children(...args));
|
|
206
|
+
}
|
|
207
|
+
/** Renders its only child with these props merged in (Radix Slot style). */
|
|
208
|
+
function Slot({ children, ref, ...props }) {
|
|
209
|
+
const child = Children.only(children);
|
|
210
|
+
const childProps = isValidElement(child) ? child.props : {};
|
|
211
|
+
const childRef = childProps.ref;
|
|
212
|
+
const composedRef = useMemo(() => composeRefs(ref, childRef), [ref, childRef]);
|
|
213
|
+
if (!isValidElement(child)) return null;
|
|
214
|
+
return cloneElement(child, {
|
|
215
|
+
...mergeProps(props, childProps),
|
|
216
|
+
ref: composedRef
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
//#endregion
|
|
224
220
|
//#region src/components/tooltip.tsx
|
|
225
221
|
const OPEN_DELAY_MS = 300;
|
|
226
222
|
const GAP_PX = 6;
|
|
@@ -514,22 +510,56 @@ function stateClass(disabled, loading) {
|
|
|
514
510
|
if (loading) return "cursor-progress opacity-70";
|
|
515
511
|
if (disabled) return "cursor-not-allowed opacity-50 forced-colors:opacity-100 forced-colors:text-[GrayText] forced-colors:after:border-[GrayText]";
|
|
516
512
|
}
|
|
517
|
-
function
|
|
513
|
+
function blockActivation(e) {
|
|
514
|
+
e.preventDefault();
|
|
515
|
+
e.stopPropagation();
|
|
516
|
+
}
|
|
517
|
+
function ButtonImpl({ asChild = false, className, intent, size, tone, fullWidth, square, loading = false, loadingText = "Loading", disabled = false, iconLeft, iconRight, ripple, tooltip, type = "button", onClick, onClickCapture, onAuxClickCapture, children, ...props }) {
|
|
518
518
|
const s = size ?? "md";
|
|
519
519
|
const inert = disabled || loading;
|
|
520
|
+
const classes = cn(buttonVariants({
|
|
521
|
+
intent,
|
|
522
|
+
size,
|
|
523
|
+
tone,
|
|
524
|
+
fullWidth,
|
|
525
|
+
square
|
|
526
|
+
}), iconPadding(s, iconLeft, iconRight), stateClass(disabled, loading), className);
|
|
527
|
+
const content = (inner) => /* @__PURE__ */ jsx(ButtonContent, {
|
|
528
|
+
size: s,
|
|
529
|
+
ripple: ripple ?? true,
|
|
530
|
+
loading,
|
|
531
|
+
iconLeft,
|
|
532
|
+
iconRight,
|
|
533
|
+
children: inner
|
|
534
|
+
});
|
|
535
|
+
if (asChild) {
|
|
536
|
+
const child = Children.only(children);
|
|
537
|
+
if (!isValidElement(child)) return null;
|
|
538
|
+
const link = /* @__PURE__ */ jsx(Slot, {
|
|
539
|
+
...props,
|
|
540
|
+
"data-slot": "button",
|
|
541
|
+
"aria-disabled": disabled || void 0,
|
|
542
|
+
className: classes,
|
|
543
|
+
onClick,
|
|
544
|
+
onClickCapture: disabled ? blockActivation : onClickCapture,
|
|
545
|
+
onAuxClickCapture: disabled ? blockActivation : onAuxClickCapture,
|
|
546
|
+
children: cloneElement(child, { children: wrapChildren(child.props.children, content) })
|
|
547
|
+
});
|
|
548
|
+
return tooltip ? /* @__PURE__ */ jsx(Tooltip, {
|
|
549
|
+
...tooltip,
|
|
550
|
+
className: fullWidth ? "flex w-full" : void 0,
|
|
551
|
+
children: link
|
|
552
|
+
}) : link;
|
|
553
|
+
}
|
|
520
554
|
const button = /* @__PURE__ */ jsx("button", {
|
|
521
555
|
...props,
|
|
522
556
|
type,
|
|
523
557
|
"data-slot": "button",
|
|
524
558
|
"aria-disabled": inert || void 0,
|
|
525
559
|
"aria-busy": loading || void 0,
|
|
526
|
-
className:
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
tone,
|
|
530
|
-
fullWidth,
|
|
531
|
-
square
|
|
532
|
-
}), iconPadding(s, iconLeft, iconRight), stateClass(disabled, loading), className),
|
|
560
|
+
className: classes,
|
|
561
|
+
onClickCapture,
|
|
562
|
+
onAuxClickCapture,
|
|
533
563
|
onClick: (e) => {
|
|
534
564
|
if (inert) {
|
|
535
565
|
e.preventDefault();
|
|
@@ -537,14 +567,7 @@ function ButtonImpl({ className, intent, size, tone, fullWidth, square, loading
|
|
|
537
567
|
}
|
|
538
568
|
onClick?.(e);
|
|
539
569
|
},
|
|
540
|
-
children:
|
|
541
|
-
size: s,
|
|
542
|
-
ripple: ripple ?? true,
|
|
543
|
-
loading,
|
|
544
|
-
iconLeft,
|
|
545
|
-
iconRight,
|
|
546
|
-
children
|
|
547
|
-
})
|
|
570
|
+
children: content(children)
|
|
548
571
|
});
|
|
549
572
|
return /* @__PURE__ */ jsxs(Fragment, { children: [tooltip ? /* @__PURE__ */ jsx(Tooltip, {
|
|
550
573
|
...tooltip,
|
|
@@ -557,7 +580,7 @@ function ButtonImpl({ className, intent, size, tone, fullWidth, square, loading
|
|
|
557
580
|
children: loading ? loadingText : ""
|
|
558
581
|
})] });
|
|
559
582
|
}
|
|
560
|
-
function IconOnlyButton({ icon, tooltip = true, tooltipSide, disabledReason, className, size, ...props }) {
|
|
583
|
+
function IconOnlyButton({ icon, tooltip = true, tooltipSide, disabledReason, className, size, children, ...props }) {
|
|
561
584
|
const reason = props.disabled ? disabledReason : void 0;
|
|
562
585
|
const tip = reason ? {
|
|
563
586
|
content: reason,
|
|
@@ -567,13 +590,14 @@ function IconOnlyButton({ icon, tooltip = true, tooltipSide, disabledReason, cla
|
|
|
567
590
|
side: tooltipSide,
|
|
568
591
|
describe: false
|
|
569
592
|
} : disabledReason !== void 0 ? { content: void 0 } : void 0;
|
|
593
|
+
const child = Children.toArray(children)[0];
|
|
570
594
|
return /* @__PURE__ */ jsx(ButtonImpl, {
|
|
571
595
|
...props,
|
|
572
596
|
size,
|
|
573
597
|
tooltip: tip,
|
|
574
598
|
square: true,
|
|
575
599
|
className,
|
|
576
|
-
children: icon
|
|
600
|
+
children: props.asChild && isValidElement(child) ? cloneElement(child, void 0, icon) : icon
|
|
577
601
|
});
|
|
578
602
|
}
|
|
579
603
|
function Button(props) {
|
|
@@ -586,6 +610,135 @@ function Button(props) {
|
|
|
586
610
|
});
|
|
587
611
|
}
|
|
588
612
|
//#endregion
|
|
613
|
+
//#region src/components/alert/alert.tsx
|
|
614
|
+
const tones = {
|
|
615
|
+
neutral: {
|
|
616
|
+
Icon: Info,
|
|
617
|
+
iconClass: "text-neutral"
|
|
618
|
+
},
|
|
619
|
+
info: {
|
|
620
|
+
Icon: Info,
|
|
621
|
+
iconClass: "text-info"
|
|
622
|
+
},
|
|
623
|
+
success: {
|
|
624
|
+
Icon: CircleCheck,
|
|
625
|
+
iconClass: "text-success"
|
|
626
|
+
},
|
|
627
|
+
warning: {
|
|
628
|
+
Icon: TriangleAlert,
|
|
629
|
+
iconClass: "text-warning"
|
|
630
|
+
},
|
|
631
|
+
danger: {
|
|
632
|
+
Icon: CircleAlert,
|
|
633
|
+
iconClass: "text-danger"
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
/** A persistent message shown next to the content it describes. Use a live region for updates that need announcing. */
|
|
637
|
+
function Alert({ tone = "neutral", title, action, onDismiss, dismissLabel = "Dismiss alert", className, children, ...props }) {
|
|
638
|
+
const { Icon, iconClass } = tones[tone];
|
|
639
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
640
|
+
...props,
|
|
641
|
+
"data-slot": "alert",
|
|
642
|
+
"data-tone": tone,
|
|
643
|
+
className: cn("@container/alert flex items-start gap-3 rounded-xl border border-ring-deep px-4 py-3", "text-sm text-fg forced-colors:border-[CanvasText]", className),
|
|
644
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
645
|
+
className: cn("grid min-w-0 flex-1 grid-cols-[1rem_minmax(0,1fr)] items-start gap-x-2.5 gap-y-3", action && "@md/alert:grid-cols-[1rem_minmax(0,1fr)_auto]"),
|
|
646
|
+
children: [
|
|
647
|
+
/* @__PURE__ */ jsx(Icon, {
|
|
648
|
+
"aria-hidden": "true",
|
|
649
|
+
"data-slot": "alert-icon",
|
|
650
|
+
className: cn("mt-0.5 size-4", iconClass)
|
|
651
|
+
}),
|
|
652
|
+
/* @__PURE__ */ jsxs("div", {
|
|
653
|
+
className: "min-w-0 space-y-0.5 wrap-anywhere",
|
|
654
|
+
children: [title != null && /* @__PURE__ */ jsx("div", {
|
|
655
|
+
"data-slot": "alert-title",
|
|
656
|
+
className: "font-medium",
|
|
657
|
+
children: title
|
|
658
|
+
}), children != null && /* @__PURE__ */ jsx("div", {
|
|
659
|
+
"data-slot": "alert-description",
|
|
660
|
+
className: title != null ? "text-fg-muted" : void 0,
|
|
661
|
+
children
|
|
662
|
+
})]
|
|
663
|
+
}),
|
|
664
|
+
action && /* @__PURE__ */ jsx("div", {
|
|
665
|
+
"data-slot": "alert-action",
|
|
666
|
+
className: "col-start-2 justify-self-start @md/alert:col-start-3 @md/alert:self-center",
|
|
667
|
+
children: action
|
|
668
|
+
})
|
|
669
|
+
]
|
|
670
|
+
}), onDismiss && /* @__PURE__ */ jsx(Button, {
|
|
671
|
+
"aria-label": dismissLabel,
|
|
672
|
+
className: "-my-1.5 -me-1.5 shrink-0 text-fg-muted @md/alert:self-center",
|
|
673
|
+
icon: /* @__PURE__ */ jsx(X, {}),
|
|
674
|
+
intent: "ghost",
|
|
675
|
+
size: "sm",
|
|
676
|
+
onClick: onDismiss
|
|
677
|
+
})]
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
//#endregion
|
|
681
|
+
//#region src/components/badge/badge.tsx
|
|
682
|
+
const toneClasses$1 = {
|
|
683
|
+
neutral: {
|
|
684
|
+
subtle: ["border-neutral-border bg-neutral-subtle-bg text-neutral-subtle-fg", "text-neutral"],
|
|
685
|
+
outline: ["border-neutral-border bg-transparent text-neutral-subtle-fg", "text-neutral"],
|
|
686
|
+
solid: ["border-neutral bg-neutral text-neutral-fg", "text-neutral-fg"]
|
|
687
|
+
},
|
|
688
|
+
info: {
|
|
689
|
+
subtle: ["border-info-border bg-info-subtle-bg text-info-subtle-fg", "text-info"],
|
|
690
|
+
outline: ["border-info-border bg-transparent text-info-subtle-fg", "text-info"],
|
|
691
|
+
solid: ["border-info bg-info text-info-fg", "text-info-fg"]
|
|
692
|
+
},
|
|
693
|
+
success: {
|
|
694
|
+
subtle: ["border-success-border bg-success-subtle-bg text-success-subtle-fg", "text-success"],
|
|
695
|
+
outline: ["border-success-border bg-transparent text-success-subtle-fg", "text-success"],
|
|
696
|
+
solid: ["border-success bg-success text-success-fg", "text-success-fg"]
|
|
697
|
+
},
|
|
698
|
+
warning: {
|
|
699
|
+
subtle: ["border-warning-border bg-warning-subtle-bg text-warning-subtle-fg", "text-warning"],
|
|
700
|
+
outline: ["border-warning-border bg-transparent text-warning-subtle-fg", "text-warning"],
|
|
701
|
+
solid: ["border-warning bg-warning text-warning-fg", "text-warning-fg"]
|
|
702
|
+
},
|
|
703
|
+
danger: {
|
|
704
|
+
subtle: ["border-danger-border bg-danger-subtle-bg text-danger-subtle-fg", "text-danger"],
|
|
705
|
+
outline: ["border-danger-border bg-transparent text-danger-subtle-fg", "text-danger"],
|
|
706
|
+
solid: ["border-danger bg-danger text-danger-fg", "text-danger-fg"]
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
const sizeClasses$3 = {
|
|
710
|
+
sm: {
|
|
711
|
+
base: "h-5 px-1.5",
|
|
712
|
+
withIcon: "ps-1"
|
|
713
|
+
},
|
|
714
|
+
md: {
|
|
715
|
+
base: "h-6 px-2",
|
|
716
|
+
withIcon: "ps-1.5"
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
function Badge({ tone = "neutral", variant = "subtle", size = "md", icon, busy = false, context, className, children, ...props }) {
|
|
720
|
+
const [toneClass, iconClass] = toneClasses$1[tone][variant];
|
|
721
|
+
const hasIcon = busy || icon !== void 0 && icon !== null && icon !== false;
|
|
722
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
723
|
+
...props,
|
|
724
|
+
"data-slot": "badge",
|
|
725
|
+
className: cn("inline-flex items-center gap-1 rounded-md border text-xs leading-none font-medium whitespace-nowrap", "forced-colors:border-[CanvasText]", sizeClasses$3[size].base, hasIcon && sizeClasses$3[size].withIcon, toneClass, className),
|
|
726
|
+
children: [hasIcon && /* @__PURE__ */ jsx("span", {
|
|
727
|
+
"aria-hidden": "true",
|
|
728
|
+
"data-slot": "badge-icon",
|
|
729
|
+
className: cn("inline-flex shrink-0 items-center [&_svg]:size-3 [&_svg]:shrink-0", iconClass),
|
|
730
|
+
children: busy ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(LoaderCircle, { className: "animate-spin motion-reduce:hidden" }), /* @__PURE__ */ jsx(CircleDashed, { className: "hidden motion-reduce:block" })] }) : icon
|
|
731
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
732
|
+
"data-slot": "badge-label",
|
|
733
|
+
className: "min-w-0 truncate leading-4",
|
|
734
|
+
children: [context && /* @__PURE__ */ jsxs("span", {
|
|
735
|
+
className: "sr-only",
|
|
736
|
+
children: [context, ": "]
|
|
737
|
+
}), children]
|
|
738
|
+
})]
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
//#endregion
|
|
589
742
|
//#region src/components/card/card.tsx
|
|
590
743
|
const CardContext = createContext({
|
|
591
744
|
titleId: "",
|
|
@@ -1802,61 +1955,6 @@ function Select({ options, placeholder, helperText, error, size = "md", start, m
|
|
|
1802
1955
|
});
|
|
1803
1956
|
}
|
|
1804
1957
|
//#endregion
|
|
1805
|
-
//#region src/lib/slot.tsx
|
|
1806
|
-
function setRef(ref, node) {
|
|
1807
|
-
if (typeof ref === "function") return ref(node);
|
|
1808
|
-
if (ref) ref.current = node;
|
|
1809
|
-
}
|
|
1810
|
-
function composeRefs(...refs) {
|
|
1811
|
-
return (node) => {
|
|
1812
|
-
const cleanups = refs.map((ref) => setRef(ref, node));
|
|
1813
|
-
return () => {
|
|
1814
|
-
for (const [i, ref] of refs.entries()) {
|
|
1815
|
-
const cleanup = cleanups[i];
|
|
1816
|
-
if (typeof cleanup === "function") cleanup();
|
|
1817
|
-
else setRef(ref, null);
|
|
1818
|
-
}
|
|
1819
|
-
};
|
|
1820
|
-
};
|
|
1821
|
-
}
|
|
1822
|
-
function mergeProps(slot, child) {
|
|
1823
|
-
const merged = {
|
|
1824
|
-
...slot,
|
|
1825
|
-
...child
|
|
1826
|
-
};
|
|
1827
|
-
for (const key of Object.keys(slot)) {
|
|
1828
|
-
const own = slot[key];
|
|
1829
|
-
const theirs = child[key];
|
|
1830
|
-
if (/^on[A-Z]/.test(key) && typeof own === "function" && typeof theirs === "function") merged[key] = (...args) => {
|
|
1831
|
-
theirs(...args);
|
|
1832
|
-
own(...args);
|
|
1833
|
-
};
|
|
1834
|
-
else if (key === "className") merged.className = cn(own, theirs);
|
|
1835
|
-
else if (key === "style") merged.style = {
|
|
1836
|
-
...own,
|
|
1837
|
-
...theirs
|
|
1838
|
-
};
|
|
1839
|
-
}
|
|
1840
|
-
return merged;
|
|
1841
|
-
}
|
|
1842
|
-
/** Applies `wrap` to an element's children, or to what a render-prop child returns. */
|
|
1843
|
-
function wrapChildren(children, wrap) {
|
|
1844
|
-
if (typeof children !== "function") return wrap(children);
|
|
1845
|
-
return (...args) => wrap(children(...args));
|
|
1846
|
-
}
|
|
1847
|
-
/** Renders its only child with these props merged in (Radix Slot style). */
|
|
1848
|
-
function Slot({ children, ref, ...props }) {
|
|
1849
|
-
const child = Children.only(children);
|
|
1850
|
-
const childProps = isValidElement(child) ? child.props : {};
|
|
1851
|
-
const childRef = childProps.ref;
|
|
1852
|
-
const composedRef = useMemo(() => composeRefs(ref, childRef), [ref, childRef]);
|
|
1853
|
-
if (!isValidElement(child)) return null;
|
|
1854
|
-
return cloneElement(child, {
|
|
1855
|
-
...mergeProps(props, childProps),
|
|
1856
|
-
ref: composedRef
|
|
1857
|
-
});
|
|
1858
|
-
}
|
|
1859
|
-
//#endregion
|
|
1860
1958
|
//#region src/components/tabs/shared.tsx
|
|
1861
1959
|
const listBase = [
|
|
1862
1960
|
"relative isolate max-w-full overflow-x-auto overscroll-x-contain scroll-px-6",
|
|
@@ -2432,13 +2530,240 @@ function Switch({ label, description, error, size = "md", loading = false, label
|
|
|
2432
2530
|
], "checked:focus-visible:[--switch-ring:transparent] checked:focus-visible:[--switch-halo:transparent]", "checked:focus-visible:outline-solid checked:focus-visible:outline-2 checked:focus-visible:outline-offset-2", row.invalid && "not-forced-colors:checked:focus-visible:outline-danger", "forced-colors:forced-color-adjust-none forced-colors:[box-shadow:none]", "forced-colors:border-[CanvasText] forced-colors:bg-[Canvas]", "forced-colors:checked:border-[Highlight] forced-colors:checked:bg-[Highlight]", "forced-colors:disabled:border-[GrayText] forced-colors:disabled:checked:bg-[GrayText]", "forced-colors:focus-visible:outline-[CanvasText]", inputClassName)
|
|
2433
2531
|
}), /* @__PURE__ */ jsx("span", {
|
|
2434
2532
|
"aria-hidden": true,
|
|
2435
|
-
className: cn("pointer-events-none absolute inset-s-0.5 top-0.5 grid place-items-center rounded-full", "h-(--switch-thumb) w-(--switch-thumb-w) bg-
|
|
2533
|
+
className: cn("pointer-events-none absolute inset-s-0.5 top-0.5 grid place-items-center rounded-full", "h-(--switch-thumb) w-(--switch-thumb-w) bg-switch-handle peer-checked:bg-switch-handle-checked text-control-checked shadow-switch-thumb", "[--switch-dir:1] rtl:[--switch-dir:-1] [translate:calc(var(--switch-x)*var(--switch-dir))_0]", "[--switch-x:0px] [--switch-thumb-w:var(--switch-thumb)] peer-checked:[--switch-x:var(--switch-travel)]", "transition-[translate,width] duration-150 ease-in-out", pressable && ["peer-active:[--switch-thumb-w:calc(var(--switch-thumb)+var(--switch-stretch))]", "peer-checked:peer-active:[--switch-x:calc(var(--switch-travel)-var(--switch-stretch))]"], "peer-disabled:shadow-none", "forced-colors:forced-color-adjust-none forced-colors:shadow-none", "forced-colors:bg-[CanvasText] forced-colors:text-[Canvas]", "forced-colors:peer-checked:bg-[HighlightText] forced-colors:peer-checked:text-[Highlight]", "forced-colors:peer-disabled:bg-[GrayText] forced-colors:peer-disabled:peer-checked:bg-[Canvas]", s.icon),
|
|
2436
2534
|
children: loading && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(LoaderCircle, { className: "animate-spin motion-reduce:hidden" }), /* @__PURE__ */ jsx(CircleDashed, { className: "hidden motion-reduce:block" })] })
|
|
2437
2535
|
})]
|
|
2438
2536
|
})
|
|
2439
2537
|
});
|
|
2440
2538
|
}
|
|
2441
2539
|
//#endregion
|
|
2540
|
+
//#region src/components/table/table.tsx
|
|
2541
|
+
const labels = {
|
|
2542
|
+
search: "Search rows",
|
|
2543
|
+
clearSelection: "Clear selection",
|
|
2544
|
+
selectPage: "Select all rows on this page",
|
|
2545
|
+
selectRow: (id) => `Select row ${id}`,
|
|
2546
|
+
selectionCount: (count) => `${count} selected`,
|
|
2547
|
+
scrollRegion: "Table",
|
|
2548
|
+
pagination: "Pagination",
|
|
2549
|
+
previousPage: "Previous page",
|
|
2550
|
+
nextPage: "Next page",
|
|
2551
|
+
page: (page, count) => `${page} / ${count}`,
|
|
2552
|
+
range: (first, last, total) => total === 0 ? "0 rows" : `${first}–${last} of ${total}`,
|
|
2553
|
+
emptyState: "No rows yet",
|
|
2554
|
+
noResults: "No matching rows"
|
|
2555
|
+
};
|
|
2556
|
+
const alignClasses = {
|
|
2557
|
+
start: "text-start",
|
|
2558
|
+
center: "text-center",
|
|
2559
|
+
end: "text-end"
|
|
2560
|
+
};
|
|
2561
|
+
const sortIcons = {
|
|
2562
|
+
asc: ArrowUp,
|
|
2563
|
+
desc: ArrowDown
|
|
2564
|
+
};
|
|
2565
|
+
function Table({ data, columns, getRowId, title, emptyState, noResults, filtered = false, search, sorting, pagination, selection, className, tableClassName, labels: labelOverrides, ...props }) {
|
|
2566
|
+
const titleId = useId();
|
|
2567
|
+
const scrollRef = useRef(null);
|
|
2568
|
+
const searchRef = useRef(null);
|
|
2569
|
+
const emptyRef = useRef(null);
|
|
2570
|
+
const text = {
|
|
2571
|
+
...labels,
|
|
2572
|
+
...labelOverrides
|
|
2573
|
+
};
|
|
2574
|
+
const tableName = props["aria-labelledby"] ?? (title != null && !props["aria-label"] ? titleId : void 0);
|
|
2575
|
+
const showEmpty = data.length === 0 && !filtered && !search?.value.trim() && (!pagination || pagination.rowCount === 0);
|
|
2576
|
+
const showSearch = !showEmpty && search != null;
|
|
2577
|
+
const hasControls = showSearch || !!selection?.ids.size;
|
|
2578
|
+
const hasToolbar = title != null || hasControls;
|
|
2579
|
+
const rows = data.map((row) => ({
|
|
2580
|
+
row,
|
|
2581
|
+
id: getRowId(row),
|
|
2582
|
+
canSelect: selection?.canSelectRow?.(row) ?? true
|
|
2583
|
+
}));
|
|
2584
|
+
const selectableIds = selection ? rows.filter((row) => row.canSelect).map((row) => row.id) : [];
|
|
2585
|
+
const selectedOnPage = selectableIds.filter((id) => selection?.ids.has(id)).length;
|
|
2586
|
+
const allOnPageSelected = selectableIds.length > 0 && selectedOnPage === selectableIds.length;
|
|
2587
|
+
const updateSelection = (ids, checked) => {
|
|
2588
|
+
if (!selection) return;
|
|
2589
|
+
const next = new Set(selection.ids);
|
|
2590
|
+
for (const id of ids) if (checked) next.add(id);
|
|
2591
|
+
else next.delete(id);
|
|
2592
|
+
selection.onChange(next);
|
|
2593
|
+
};
|
|
2594
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2595
|
+
"data-slot": "table-root",
|
|
2596
|
+
className: cn("w-full min-w-0 bg-surface text-fg", className),
|
|
2597
|
+
children: [hasToolbar && /* @__PURE__ */ jsxs("div", {
|
|
2598
|
+
"data-slot": "table-toolbar",
|
|
2599
|
+
className: "flex flex-wrap items-center justify-between gap-3 border-b border-border px-4 py-3",
|
|
2600
|
+
children: [title != null && /* @__PURE__ */ jsx("span", {
|
|
2601
|
+
id: titleId,
|
|
2602
|
+
className: "text-sm font-semibold",
|
|
2603
|
+
children: title
|
|
2604
|
+
}), hasControls && /* @__PURE__ */ jsxs("div", {
|
|
2605
|
+
className: "ms-auto flex min-w-0 flex-wrap items-center justify-end gap-x-3 gap-y-2",
|
|
2606
|
+
children: [
|
|
2607
|
+
selection && /* @__PURE__ */ jsx("output", {
|
|
2608
|
+
className: "text-xs text-fg-muted",
|
|
2609
|
+
children: selection.ids.size > 0 && text.selectionCount(selection.ids.size)
|
|
2610
|
+
}),
|
|
2611
|
+
!!selection?.ids.size && /* @__PURE__ */ jsx(Button, {
|
|
2612
|
+
intent: "ghost",
|
|
2613
|
+
size: "sm",
|
|
2614
|
+
ripple: false,
|
|
2615
|
+
onClick: () => {
|
|
2616
|
+
selection.onChange(/* @__PURE__ */ new Set());
|
|
2617
|
+
(searchRef.current ?? scrollRef.current ?? emptyRef.current)?.focus();
|
|
2618
|
+
},
|
|
2619
|
+
children: text.clearSelection
|
|
2620
|
+
}),
|
|
2621
|
+
showSearch && /* @__PURE__ */ jsx(SearchInput, {
|
|
2622
|
+
ref: searchRef,
|
|
2623
|
+
"aria-label": text.search,
|
|
2624
|
+
placeholder: `${text.search}…`,
|
|
2625
|
+
size: "sm",
|
|
2626
|
+
className: "w-48 max-w-full",
|
|
2627
|
+
value: search.value,
|
|
2628
|
+
onChange: (event) => search.onChange(event.currentTarget.value)
|
|
2629
|
+
})
|
|
2630
|
+
]
|
|
2631
|
+
})]
|
|
2632
|
+
}), showEmpty ? /* @__PURE__ */ jsx("div", {
|
|
2633
|
+
ref: emptyRef,
|
|
2634
|
+
"data-slot": "table-empty",
|
|
2635
|
+
tabIndex: -1,
|
|
2636
|
+
className: "grid min-h-48 place-items-center px-4 py-8 text-center text-sm text-fg-muted outline-hidden focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-solid focus-visible:outline-focus",
|
|
2637
|
+
children: emptyState === void 0 ? text.emptyState : emptyState
|
|
2638
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("section", {
|
|
2639
|
+
ref: scrollRef,
|
|
2640
|
+
"data-slot": "table-scroll",
|
|
2641
|
+
"aria-labelledby": tableName,
|
|
2642
|
+
"aria-label": tableName ? void 0 : props["aria-label"] ?? text.scrollRegion,
|
|
2643
|
+
tabIndex: 0,
|
|
2644
|
+
className: "relative w-full overflow-x-auto outline-hidden focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-solid focus-visible:outline-focus",
|
|
2645
|
+
children: /* @__PURE__ */ jsxs("table", {
|
|
2646
|
+
...props,
|
|
2647
|
+
"aria-labelledby": tableName,
|
|
2648
|
+
"data-slot": "table",
|
|
2649
|
+
className: cn("w-full border-separate border-spacing-0 text-sm", tableClassName),
|
|
2650
|
+
children: [/* @__PURE__ */ jsx("thead", {
|
|
2651
|
+
"data-slot": "table-header",
|
|
2652
|
+
children: /* @__PURE__ */ jsxs("tr", { children: [selection && /* @__PURE__ */ jsx("th", {
|
|
2653
|
+
scope: "col",
|
|
2654
|
+
className: "w-12 border-b border-border px-3",
|
|
2655
|
+
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
2656
|
+
"aria-label": text.selectPage,
|
|
2657
|
+
checked: allOnPageSelected,
|
|
2658
|
+
indeterminate: selectedOnPage > 0 && !allOnPageSelected,
|
|
2659
|
+
disabled: selectableIds.length === 0,
|
|
2660
|
+
onChange: (event) => updateSelection(selectableIds, event.currentTarget.checked),
|
|
2661
|
+
className: "mx-auto justify-center"
|
|
2662
|
+
})
|
|
2663
|
+
}), columns.map((column) => {
|
|
2664
|
+
const direction = sorting?.value?.id === column.id ? sorting.value.direction : void 0;
|
|
2665
|
+
const SortIcon = direction ? sortIcons[direction] : ArrowUpDown;
|
|
2666
|
+
const align = column.align ?? (column.numeric ? "end" : "start");
|
|
2667
|
+
return /* @__PURE__ */ jsx("th", {
|
|
2668
|
+
scope: "col",
|
|
2669
|
+
"aria-sort": direction ? direction === "asc" ? "ascending" : "descending" : void 0,
|
|
2670
|
+
className: cn("h-10 border-b border-border px-4 text-xs font-medium whitespace-nowrap text-fg-muted", alignClasses[align], column.headerClassName),
|
|
2671
|
+
children: sorting && column.sortable ? /* @__PURE__ */ jsxs("button", {
|
|
2672
|
+
type: "button",
|
|
2673
|
+
className: cn("inline-flex min-h-8 cursor-pointer items-center gap-1.5 rounded-sm hover:text-fg focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus pointer-coarse:min-h-11", direction && "text-fg"),
|
|
2674
|
+
onClick: () => sorting.onChange(direction === "desc" ? null : {
|
|
2675
|
+
id: column.id,
|
|
2676
|
+
direction: direction === "asc" ? "desc" : "asc"
|
|
2677
|
+
}),
|
|
2678
|
+
children: [column.header, /* @__PURE__ */ jsx(SortIcon, {
|
|
2679
|
+
"aria-hidden": true,
|
|
2680
|
+
className: "size-3.5 shrink-0"
|
|
2681
|
+
})]
|
|
2682
|
+
}) : column.header
|
|
2683
|
+
}, column.id);
|
|
2684
|
+
})] })
|
|
2685
|
+
}), /* @__PURE__ */ jsxs("tbody", {
|
|
2686
|
+
"data-slot": "table-body",
|
|
2687
|
+
className: "[&>tr:not(:last-child)>*]:border-b [&>tr>*]:border-border",
|
|
2688
|
+
children: [rows.map(({ row, id, canSelect }) => {
|
|
2689
|
+
const selected = selection?.ids.has(id) ?? false;
|
|
2690
|
+
return /* @__PURE__ */ jsxs("tr", {
|
|
2691
|
+
"data-slot": "table-row",
|
|
2692
|
+
"data-selected": selected || void 0,
|
|
2693
|
+
className: "hover:bg-surface-muted data-selected:bg-surface-muted",
|
|
2694
|
+
children: [selection && /* @__PURE__ */ jsx("td", {
|
|
2695
|
+
className: "w-12 px-3",
|
|
2696
|
+
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
2697
|
+
"aria-label": text.selectRow(id),
|
|
2698
|
+
checked: selected,
|
|
2699
|
+
disabled: !canSelect,
|
|
2700
|
+
onChange: (event) => updateSelection([id], event.currentTarget.checked),
|
|
2701
|
+
className: "mx-auto justify-center"
|
|
2702
|
+
})
|
|
2703
|
+
}), columns.map((column) => {
|
|
2704
|
+
const Cell = column.rowHeader ? "th" : "td";
|
|
2705
|
+
const align = column.align ?? (column.numeric ? "end" : "start");
|
|
2706
|
+
return /* @__PURE__ */ jsx(Cell, {
|
|
2707
|
+
scope: column.rowHeader ? "row" : void 0,
|
|
2708
|
+
className: cn("h-13 px-4 py-2 align-middle", alignClasses[align], column.numeric && "tabular-nums", column.rowHeader && "font-medium", column.className),
|
|
2709
|
+
children: column.cell(row)
|
|
2710
|
+
}, column.id);
|
|
2711
|
+
})]
|
|
2712
|
+
}, id);
|
|
2713
|
+
}), rows.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
|
|
2714
|
+
colSpan: Math.max(1, columns.length + Number(Boolean(selection))),
|
|
2715
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
2716
|
+
"data-slot": "table-no-results",
|
|
2717
|
+
className: "sticky inset-s-0 w-max max-w-[min(100%,18rem)] px-4 py-12 text-sm text-fg-muted",
|
|
2718
|
+
children: noResults === void 0 ? /* @__PURE__ */ jsx("output", { children: text.noResults }) : noResults
|
|
2719
|
+
})
|
|
2720
|
+
}) })]
|
|
2721
|
+
})]
|
|
2722
|
+
})
|
|
2723
|
+
}), pagination && /* @__PURE__ */ jsx(TablePagination, {
|
|
2724
|
+
...pagination,
|
|
2725
|
+
visibleCount: rows.length,
|
|
2726
|
+
text
|
|
2727
|
+
})] })]
|
|
2728
|
+
});
|
|
2729
|
+
}
|
|
2730
|
+
function TablePagination({ pageIndex, pageSize, rowCount, visibleCount, onPageChange, text }) {
|
|
2731
|
+
const count = Math.ceil(rowCount / pageSize);
|
|
2732
|
+
const first = visibleCount ? pageIndex * pageSize + 1 : 0;
|
|
2733
|
+
const last = first ? first + visibleCount - 1 : 0;
|
|
2734
|
+
const canGoBack = pageIndex > 0;
|
|
2735
|
+
const canGoForward = pageIndex + 1 < count;
|
|
2736
|
+
return /* @__PURE__ */ jsxs("nav", {
|
|
2737
|
+
"data-slot": "table-pagination",
|
|
2738
|
+
"aria-label": text.pagination,
|
|
2739
|
+
className: "flex min-h-12 flex-wrap items-center justify-between gap-x-3 gap-y-1 border-t border-border px-4 py-1 text-xs text-fg-muted tabular-nums",
|
|
2740
|
+
children: [/* @__PURE__ */ jsx("output", { children: text.range(first, last, rowCount) }), /* @__PURE__ */ jsxs("span", {
|
|
2741
|
+
className: "flex items-center gap-2",
|
|
2742
|
+
children: [
|
|
2743
|
+
/* @__PURE__ */ jsx(Button, {
|
|
2744
|
+
icon: /* @__PURE__ */ jsx(ChevronLeft, { className: "rtl:rotate-180" }),
|
|
2745
|
+
"aria-label": text.previousPage,
|
|
2746
|
+
intent: "ghost",
|
|
2747
|
+
size: "sm",
|
|
2748
|
+
ripple: false,
|
|
2749
|
+
disabled: !canGoBack,
|
|
2750
|
+
onClick: () => onPageChange(pageIndex - 1)
|
|
2751
|
+
}),
|
|
2752
|
+
/* @__PURE__ */ jsx("span", { children: count === 0 ? "—" : text.page(pageIndex + 1, count) }),
|
|
2753
|
+
/* @__PURE__ */ jsx(Button, {
|
|
2754
|
+
icon: /* @__PURE__ */ jsx(ChevronRight, { className: "rtl:rotate-180" }),
|
|
2755
|
+
"aria-label": text.nextPage,
|
|
2756
|
+
intent: "ghost",
|
|
2757
|
+
size: "sm",
|
|
2758
|
+
ripple: false,
|
|
2759
|
+
disabled: !canGoForward,
|
|
2760
|
+
onClick: () => onPageChange(pageIndex + 1)
|
|
2761
|
+
})
|
|
2762
|
+
]
|
|
2763
|
+
})]
|
|
2764
|
+
});
|
|
2765
|
+
}
|
|
2766
|
+
//#endregion
|
|
2442
2767
|
//#region src/components/tabs/tab-nav.tsx
|
|
2443
2768
|
const TabNavContext = createContext(null);
|
|
2444
2769
|
/**
|
|
@@ -3450,4 +3775,4 @@ function ToastCard({ record, layout, total, expanded, paused, frontHeight, ownHe
|
|
|
3450
3775
|
});
|
|
3451
3776
|
}
|
|
3452
3777
|
//#endregion
|
|
3453
|
-
export { Badge, Button, Card, CardContent, CardHeader, Checkbox, CheckboxGroup, CopyInput, Dialog, DialogBody, DialogFooter, DialogHeader, Drawer, DrawerBody, DrawerClose, DrawerFooter, DrawerHeader, Input, Meter, PasswordInput, SearchInput, Select, Sidebar, SidebarBadge, SidebarBody, SidebarFooter, SidebarGroup, SidebarHeader, SidebarIcon, SidebarItem, SidebarProvider, SidebarTrigger, Switch, Tab, TabList, TabNav, TabNavLink, TabPanel, Tabs, ThemeSwitcher, Toaster, Tooltip, cn, toast, useTheme };
|
|
3778
|
+
export { Alert, Badge, Button, Card, CardContent, CardHeader, Checkbox, CheckboxGroup, CopyInput, Dialog, DialogBody, DialogFooter, DialogHeader, Drawer, DrawerBody, DrawerClose, DrawerFooter, DrawerHeader, Input, Meter, PasswordInput, SearchInput, Select, Sidebar, SidebarBadge, SidebarBody, SidebarFooter, SidebarGroup, SidebarHeader, SidebarIcon, SidebarItem, SidebarProvider, SidebarTrigger, Switch, Tab, TabList, TabNav, TabNavLink, TabPanel, Table, Tabs, ThemeSwitcher, Toaster, Tooltip, cn, toast, useTheme };
|