@bmsuisse/ui 0.16.2 → 0.18.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/dist/index.d.ts +165 -8
- package/dist/index.js +1216 -311
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -167,7 +167,7 @@ var Badge = ({ className, variant, ...props }) => /* @__PURE__ */ jsx6("div", {
|
|
|
167
167
|
|
|
168
168
|
// src/primitives/dialog.tsx
|
|
169
169
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
170
|
-
import {
|
|
170
|
+
import { XMarkIcon } from "@heroicons/react/24/outline";
|
|
171
171
|
import { forwardRef as forwardRef5, useCallback, useLayoutEffect, useRef } from "react";
|
|
172
172
|
import { jsx as jsx7, jsxs } from "react/jsx-runtime";
|
|
173
173
|
var Dialog = DialogPrimitive.Root;
|
|
@@ -200,7 +200,7 @@ var DialogContent = forwardRef5(({ className, children, showCloseButton = true,
|
|
|
200
200
|
"data-testid": closeButtonTestId,
|
|
201
201
|
className: "absolute right-4 top-4 z-20 rounded-sm opacity-70 hover:opacity-100",
|
|
202
202
|
children: [
|
|
203
|
-
/* @__PURE__ */ jsx7(
|
|
203
|
+
/* @__PURE__ */ jsx7(XMarkIcon, { className: "h-4 w-4" }),
|
|
204
204
|
/* @__PURE__ */ jsx7("span", { className: "sr-only", children: "Close" })
|
|
205
205
|
]
|
|
206
206
|
}
|
|
@@ -334,7 +334,7 @@ PopoverContent.displayName = "PopoverContent";
|
|
|
334
334
|
|
|
335
335
|
// src/primitives/select.tsx
|
|
336
336
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
337
|
-
import {
|
|
337
|
+
import { CheckIcon, ChevronDownIcon } from "@heroicons/react/24/outline";
|
|
338
338
|
import { forwardRef as forwardRef7 } from "react";
|
|
339
339
|
import { jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
340
340
|
var Select = SelectPrimitive.Root;
|
|
@@ -353,7 +353,7 @@ var SelectTrigger = forwardRef7(
|
|
|
353
353
|
...props,
|
|
354
354
|
children: [
|
|
355
355
|
children,
|
|
356
|
-
/* @__PURE__ */ jsx9(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx9(
|
|
356
|
+
/* @__PURE__ */ jsx9(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx9(ChevronDownIcon, { className: "h-4 w-4 opacity-50" }) })
|
|
357
357
|
]
|
|
358
358
|
}
|
|
359
359
|
)
|
|
@@ -384,7 +384,7 @@ var SelectItem = forwardRef7(({ className, children, ...props }, ref) => /* @__P
|
|
|
384
384
|
),
|
|
385
385
|
...props,
|
|
386
386
|
children: [
|
|
387
|
-
/* @__PURE__ */ jsx9("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx9(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx9(
|
|
387
|
+
/* @__PURE__ */ jsx9("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx9(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx9(CheckIcon, { className: "h-4 w-4" }) }) }),
|
|
388
388
|
/* @__PURE__ */ jsx9(SelectPrimitive.ItemText, { children })
|
|
389
389
|
]
|
|
390
390
|
}
|
|
@@ -397,7 +397,7 @@ var Skeleton = ({ className, ...props }) => /* @__PURE__ */ jsx10("div", { class
|
|
|
397
397
|
|
|
398
398
|
// src/primitives/checkbox.tsx
|
|
399
399
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
400
|
-
import {
|
|
400
|
+
import { CheckIcon as CheckIcon2 } from "@heroicons/react/24/outline";
|
|
401
401
|
import { forwardRef as forwardRef8 } from "react";
|
|
402
402
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
403
403
|
var Checkbox = forwardRef8(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
|
|
@@ -409,7 +409,7 @@ var Checkbox = forwardRef8(({ className, ...props }, ref) => /* @__PURE__ */ jsx
|
|
|
409
409
|
className
|
|
410
410
|
),
|
|
411
411
|
...props,
|
|
412
|
-
children: /* @__PURE__ */ jsx11(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: /* @__PURE__ */ jsx11(
|
|
412
|
+
children: /* @__PURE__ */ jsx11(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: /* @__PURE__ */ jsx11(CheckIcon2, { className: "h-3.5 w-3.5" }) })
|
|
413
413
|
}
|
|
414
414
|
));
|
|
415
415
|
Checkbox.displayName = "Checkbox";
|
|
@@ -591,7 +591,7 @@ TableCaption.displayName = "TableCaption";
|
|
|
591
591
|
|
|
592
592
|
// src/primitives/dropdown-menu.tsx
|
|
593
593
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
594
|
-
import {
|
|
594
|
+
import { CheckIcon as CheckIcon3, ChevronRightIcon } from "@heroicons/react/24/outline";
|
|
595
595
|
import { forwardRef as forwardRef14 } from "react";
|
|
596
596
|
import { jsx as jsx17, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
597
597
|
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
@@ -637,7 +637,7 @@ var DropdownMenuCheckboxItem = forwardRef14(({ className, children, checked, ...
|
|
|
637
637
|
),
|
|
638
638
|
...props,
|
|
639
639
|
children: [
|
|
640
|
-
/* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(
|
|
640
|
+
/* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(CheckIcon3, { className: "h-4 w-4" }) }) }),
|
|
641
641
|
children
|
|
642
642
|
]
|
|
643
643
|
}
|
|
@@ -653,7 +653,7 @@ var DropdownMenuRadioItem = forwardRef14(({ className, children, ...props }, ref
|
|
|
653
653
|
),
|
|
654
654
|
...props,
|
|
655
655
|
children: [
|
|
656
|
-
/* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(
|
|
656
|
+
/* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17("span", { className: "h-2 w-2 rounded-full bg-current" }) }) }),
|
|
657
657
|
children
|
|
658
658
|
]
|
|
659
659
|
}
|
|
@@ -692,7 +692,7 @@ var DropdownMenuSubTrigger = forwardRef14(({ className, children, ...props }, re
|
|
|
692
692
|
...props,
|
|
693
693
|
children: [
|
|
694
694
|
children,
|
|
695
|
-
/* @__PURE__ */ jsx17(
|
|
695
|
+
/* @__PURE__ */ jsx17(ChevronRightIcon, { className: "ml-auto h-4 w-4" })
|
|
696
696
|
]
|
|
697
697
|
}
|
|
698
698
|
));
|
|
@@ -713,7 +713,7 @@ DropdownMenuSubContent.displayName = "DropdownMenuSubContent";
|
|
|
713
713
|
// src/primitives/sheet.tsx
|
|
714
714
|
import { cva as cva3 } from "class-variance-authority";
|
|
715
715
|
import * as DialogPrimitive2 from "@radix-ui/react-dialog";
|
|
716
|
-
import {
|
|
716
|
+
import { XMarkIcon as XMarkIcon2 } from "@heroicons/react/24/outline";
|
|
717
717
|
import { forwardRef as forwardRef15, useEffect, useRef as useRef2, useState } from "react";
|
|
718
718
|
import { jsx as jsx18, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
719
719
|
var Sheet = DialogPrimitive2.Root;
|
|
@@ -820,7 +820,7 @@ var SheetContent = forwardRef15(
|
|
|
820
820
|
),
|
|
821
821
|
children,
|
|
822
822
|
/* @__PURE__ */ jsxs5(DialogPrimitive2.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 hover:opacity-100", children: [
|
|
823
|
-
/* @__PURE__ */ jsx18(
|
|
823
|
+
/* @__PURE__ */ jsx18(XMarkIcon2, { className: "h-4 w-4" }),
|
|
824
824
|
/* @__PURE__ */ jsx18("span", { className: "sr-only", children: "Close" })
|
|
825
825
|
] })
|
|
826
826
|
]
|
|
@@ -1356,9 +1356,104 @@ function FormField({
|
|
|
1356
1356
|
}
|
|
1357
1357
|
|
|
1358
1358
|
// src/patterns/combobox/Combobox.tsx
|
|
1359
|
-
import {
|
|
1359
|
+
import { CheckIcon as CheckIcon4, ChevronUpDownIcon, XMarkIcon as XMarkIcon3 } from "@heroicons/react/24/outline";
|
|
1360
1360
|
import { useEffect as useEffect3, useMemo, useRef as useRef4, useState as useState8 } from "react";
|
|
1361
1361
|
|
|
1362
|
+
// src/lib/errorState.ts
|
|
1363
|
+
function toErrorInfo(error) {
|
|
1364
|
+
if (error == null || error === false || error === "") return void 0;
|
|
1365
|
+
if (typeof error === "string") return { message: error };
|
|
1366
|
+
if (error instanceof Error) {
|
|
1367
|
+
return { message: error.message || void 0, details: error.stack };
|
|
1368
|
+
}
|
|
1369
|
+
if (typeof error === "object") {
|
|
1370
|
+
const { title, message, details } = error;
|
|
1371
|
+
if (title !== void 0 || message !== void 0 || details !== void 0) return { title, message, details };
|
|
1372
|
+
}
|
|
1373
|
+
try {
|
|
1374
|
+
return { message: typeof error === "object" ? "Unknown error" : String(error) };
|
|
1375
|
+
} catch {
|
|
1376
|
+
return { message: "Unknown error" };
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
// src/patterns/error-state/ErrorState.tsx
|
|
1381
|
+
import { ArrowPathIcon, ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
|
1382
|
+
import { jsx as jsx27, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1383
|
+
var defaultErrorStateLabels = {
|
|
1384
|
+
title: "Couldn't load data",
|
|
1385
|
+
retry: "Retry",
|
|
1386
|
+
showDetails: "Show details"
|
|
1387
|
+
};
|
|
1388
|
+
var ErrorState = ({
|
|
1389
|
+
error,
|
|
1390
|
+
onRetry,
|
|
1391
|
+
variant = "block",
|
|
1392
|
+
labels,
|
|
1393
|
+
className,
|
|
1394
|
+
...props
|
|
1395
|
+
}) => {
|
|
1396
|
+
const info = toErrorInfo(error);
|
|
1397
|
+
if (!info) return null;
|
|
1398
|
+
const l = { ...defaultErrorStateLabels, ...labels };
|
|
1399
|
+
const compact = variant === "compact";
|
|
1400
|
+
return /* @__PURE__ */ jsxs11(
|
|
1401
|
+
"div",
|
|
1402
|
+
{
|
|
1403
|
+
role: "alert",
|
|
1404
|
+
"data-testid": "error-state",
|
|
1405
|
+
className: cn(
|
|
1406
|
+
"flex gap-3 text-sm",
|
|
1407
|
+
compact ? "items-start rounded-md border border-destructive bg-destructive/10 p-3 text-red-800 dark:text-red-300" : "min-h-32 w-full flex-col items-center justify-center p-6 text-center",
|
|
1408
|
+
className
|
|
1409
|
+
),
|
|
1410
|
+
...props,
|
|
1411
|
+
children: [
|
|
1412
|
+
/* @__PURE__ */ jsx27(
|
|
1413
|
+
ExclamationTriangleIcon,
|
|
1414
|
+
{
|
|
1415
|
+
className: cn("shrink-0", compact ? "mt-0.5 h-4 w-4" : "h-8 w-8 text-destructive"),
|
|
1416
|
+
"aria-hidden": "true"
|
|
1417
|
+
}
|
|
1418
|
+
),
|
|
1419
|
+
/* @__PURE__ */ jsxs11("div", { className: cn("flex min-w-0 flex-col gap-1", compact ? "items-start" : "items-center"), children: [
|
|
1420
|
+
/* @__PURE__ */ jsx27("p", { className: "font-semibold", children: info.title ?? l.title }),
|
|
1421
|
+
info.message ? /* @__PURE__ */ jsx27("p", { className: cn(!compact && "text-muted-foreground"), children: info.message }) : null,
|
|
1422
|
+
info.details ? /* @__PURE__ */ jsxs11("details", { className: "mt-1 w-full max-w-full text-left text-xs", children: [
|
|
1423
|
+
/* @__PURE__ */ jsx27("summary", { className: "cursor-pointer select-none underline underline-offset-2", children: l.showDetails }),
|
|
1424
|
+
/* @__PURE__ */ jsx27("pre", { className: "mt-1 max-h-40 overflow-auto whitespace-pre-wrap break-words rounded bg-muted p-2 text-muted-foreground", children: info.details })
|
|
1425
|
+
] }) : null,
|
|
1426
|
+
onRetry ? /* @__PURE__ */ jsxs11(Button, { type: "button", variant: "outline", size: "sm", className: "mt-2", onClick: onRetry, children: [
|
|
1427
|
+
/* @__PURE__ */ jsx27(ArrowPathIcon, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
1428
|
+
l.retry
|
|
1429
|
+
] }) : null
|
|
1430
|
+
] })
|
|
1431
|
+
]
|
|
1432
|
+
}
|
|
1433
|
+
);
|
|
1434
|
+
};
|
|
1435
|
+
var InlineError = ({ error, onRetry, labels, className, ...props }) => {
|
|
1436
|
+
const info = toErrorInfo(error);
|
|
1437
|
+
if (!info) return null;
|
|
1438
|
+
const l = { ...defaultErrorStateLabels, ...labels };
|
|
1439
|
+
const text = info.message ?? info.title ?? l.title;
|
|
1440
|
+
return /* @__PURE__ */ jsxs11(
|
|
1441
|
+
"span",
|
|
1442
|
+
{
|
|
1443
|
+
role: "alert",
|
|
1444
|
+
"data-testid": "inline-error",
|
|
1445
|
+
title: info.details,
|
|
1446
|
+
className: cn("inline-flex min-w-0 items-center gap-1.5 text-xs text-red-700 dark:text-red-300", className),
|
|
1447
|
+
...props,
|
|
1448
|
+
children: [
|
|
1449
|
+
/* @__PURE__ */ jsx27(ExclamationTriangleIcon, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": "true" }),
|
|
1450
|
+
/* @__PURE__ */ jsx27("span", { className: "truncate", children: text }),
|
|
1451
|
+
onRetry ? /* @__PURE__ */ jsx27("button", { type: "button", className: "shrink-0 underline underline-offset-2", onClick: onRetry, children: l.retry }) : null
|
|
1452
|
+
]
|
|
1453
|
+
}
|
|
1454
|
+
);
|
|
1455
|
+
};
|
|
1456
|
+
|
|
1362
1457
|
// src/lib/optionGrouping.ts
|
|
1363
1458
|
function groupMembers(options, group) {
|
|
1364
1459
|
return options.filter((o) => o.group === group && !o.disabled).map((o) => o.value);
|
|
@@ -1386,7 +1481,7 @@ function buildRenderChunks(visibleOptions) {
|
|
|
1386
1481
|
}
|
|
1387
1482
|
|
|
1388
1483
|
// src/lib/optionGrid.tsx
|
|
1389
|
-
import { jsx as
|
|
1484
|
+
import { jsx as jsx28, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1390
1485
|
function renderGridOptions({
|
|
1391
1486
|
columns,
|
|
1392
1487
|
options,
|
|
@@ -1397,10 +1492,10 @@ function renderGridOptions({
|
|
|
1397
1492
|
onHover,
|
|
1398
1493
|
testId
|
|
1399
1494
|
}) {
|
|
1400
|
-
return /* @__PURE__ */
|
|
1401
|
-
/* @__PURE__ */
|
|
1402
|
-
multiple && /* @__PURE__ */
|
|
1403
|
-
columns.map((column) => /* @__PURE__ */
|
|
1495
|
+
return /* @__PURE__ */ jsxs12(Table, { className: "text-sm", children: [
|
|
1496
|
+
/* @__PURE__ */ jsx28(TableHeader, { children: /* @__PURE__ */ jsxs12(TableRow, { className: "hover:bg-transparent", children: [
|
|
1497
|
+
multiple && /* @__PURE__ */ jsx28(TableHead, { className: "sticky top-0 z-10 w-6 bg-muted" }),
|
|
1498
|
+
columns.map((column) => /* @__PURE__ */ jsx28(
|
|
1404
1499
|
TableHead,
|
|
1405
1500
|
{
|
|
1406
1501
|
className: cn("sticky top-0 z-10 whitespace-nowrap bg-muted text-xs", column.className),
|
|
@@ -1409,10 +1504,10 @@ function renderGridOptions({
|
|
|
1409
1504
|
column.key
|
|
1410
1505
|
))
|
|
1411
1506
|
] }) }),
|
|
1412
|
-
/* @__PURE__ */
|
|
1507
|
+
/* @__PURE__ */ jsx28(TableBody, { children: options.map((option, index) => {
|
|
1413
1508
|
const selected = isSelected(option);
|
|
1414
1509
|
const active = index === activeIndex;
|
|
1415
|
-
return /* @__PURE__ */
|
|
1510
|
+
return /* @__PURE__ */ jsxs12(
|
|
1416
1511
|
TableRow,
|
|
1417
1512
|
{
|
|
1418
1513
|
role: "option",
|
|
@@ -1436,7 +1531,7 @@ function renderGridOptions({
|
|
|
1436
1531
|
option.disabled && "pointer-events-none opacity-50"
|
|
1437
1532
|
),
|
|
1438
1533
|
children: [
|
|
1439
|
-
multiple && /* @__PURE__ */
|
|
1534
|
+
multiple && /* @__PURE__ */ jsx28(TableCell, { className: "w-6", children: /* @__PURE__ */ jsx28(
|
|
1440
1535
|
"input",
|
|
1441
1536
|
{
|
|
1442
1537
|
type: "checkbox",
|
|
@@ -1446,7 +1541,7 @@ function renderGridOptions({
|
|
|
1446
1541
|
className: "pointer-events-none h-3.5 w-3.5 shrink-0 accent-primary"
|
|
1447
1542
|
}
|
|
1448
1543
|
) }),
|
|
1449
|
-
columns.map((column) => /* @__PURE__ */
|
|
1544
|
+
columns.map((column) => /* @__PURE__ */ jsx28(TableCell, { className: cn("truncate", column.className), children: column.key === "label" ? option.label : option.data?.[column.key] }, column.key))
|
|
1450
1545
|
]
|
|
1451
1546
|
},
|
|
1452
1547
|
option.value
|
|
@@ -1456,7 +1551,7 @@ function renderGridOptions({
|
|
|
1456
1551
|
}
|
|
1457
1552
|
|
|
1458
1553
|
// src/patterns/combobox/Combobox.tsx
|
|
1459
|
-
import { jsx as
|
|
1554
|
+
import { jsx as jsx29, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1460
1555
|
function resolveGroupTriggerLabel(options, selectedValues, groupLabel) {
|
|
1461
1556
|
const selectedSet = new Set(selectedValues);
|
|
1462
1557
|
const groupsPresent = Array.from(
|
|
@@ -1485,6 +1580,8 @@ function Combobox(props) {
|
|
|
1485
1580
|
disabled,
|
|
1486
1581
|
loading = false,
|
|
1487
1582
|
loadingMessage = "Loading\u2026",
|
|
1583
|
+
error,
|
|
1584
|
+
onRetry,
|
|
1488
1585
|
clearable = true,
|
|
1489
1586
|
className,
|
|
1490
1587
|
id,
|
|
@@ -1495,6 +1592,7 @@ function Combobox(props) {
|
|
|
1495
1592
|
columns
|
|
1496
1593
|
} = props;
|
|
1497
1594
|
const testId = props["data-testid"];
|
|
1595
|
+
const hasError = toErrorInfo(error) !== void 0;
|
|
1498
1596
|
const [open, setOpen] = useState8(false);
|
|
1499
1597
|
const [search, setSearch] = useState8("");
|
|
1500
1598
|
const [activeIndex, setActiveIndex] = useState8(0);
|
|
@@ -1536,6 +1634,7 @@ function Combobox(props) {
|
|
|
1536
1634
|
setOpen(false);
|
|
1537
1635
|
}
|
|
1538
1636
|
function handleKeyDown(event) {
|
|
1637
|
+
if (hasError) return;
|
|
1539
1638
|
if (event.key === "ArrowDown") {
|
|
1540
1639
|
event.preventDefault();
|
|
1541
1640
|
setActiveIndex((i) => Math.min(i + 1, visibleOptions.length - 1));
|
|
@@ -1560,7 +1659,7 @@ function Combobox(props) {
|
|
|
1560
1659
|
function renderOption({ option, index }) {
|
|
1561
1660
|
const isSelected = selectedValues.includes(option.value);
|
|
1562
1661
|
const isActive = index === activeIndex;
|
|
1563
|
-
return /* @__PURE__ */
|
|
1662
|
+
return /* @__PURE__ */ jsxs13(
|
|
1564
1663
|
"button",
|
|
1565
1664
|
{
|
|
1566
1665
|
type: "button",
|
|
@@ -1576,7 +1675,7 @@ function Combobox(props) {
|
|
|
1576
1675
|
isActive && "bg-accent text-accent-foreground"
|
|
1577
1676
|
),
|
|
1578
1677
|
children: [
|
|
1579
|
-
props.multiple ? /* @__PURE__ */
|
|
1678
|
+
props.multiple ? /* @__PURE__ */ jsx29(
|
|
1580
1679
|
"input",
|
|
1581
1680
|
{
|
|
1582
1681
|
type: "checkbox",
|
|
@@ -1585,15 +1684,15 @@ function Combobox(props) {
|
|
|
1585
1684
|
tabIndex: -1,
|
|
1586
1685
|
className: "pointer-events-none h-3.5 w-3.5 shrink-0 accent-primary"
|
|
1587
1686
|
}
|
|
1588
|
-
) : /* @__PURE__ */
|
|
1589
|
-
/* @__PURE__ */
|
|
1687
|
+
) : /* @__PURE__ */ jsx29(CheckIcon4, { className: cn("h-4 w-4 shrink-0", isSelected ? "opacity-100" : "opacity-0") }),
|
|
1688
|
+
/* @__PURE__ */ jsx29("span", { className: "truncate", children: option.label })
|
|
1590
1689
|
]
|
|
1591
1690
|
},
|
|
1592
1691
|
option.value
|
|
1593
1692
|
);
|
|
1594
1693
|
}
|
|
1595
|
-
return /* @__PURE__ */
|
|
1596
|
-
/* @__PURE__ */
|
|
1694
|
+
return /* @__PURE__ */ jsxs13(Popover, { open, onOpenChange: setOpen, children: [
|
|
1695
|
+
/* @__PURE__ */ jsx29(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs13(
|
|
1597
1696
|
Button,
|
|
1598
1697
|
{
|
|
1599
1698
|
id,
|
|
@@ -1602,16 +1701,18 @@ function Combobox(props) {
|
|
|
1602
1701
|
variant: "outline",
|
|
1603
1702
|
role: "combobox",
|
|
1604
1703
|
"aria-expanded": open,
|
|
1704
|
+
"aria-invalid": hasError || void 0,
|
|
1605
1705
|
disabled: disabled || loading,
|
|
1606
1706
|
className: cn(
|
|
1607
1707
|
"w-full justify-between font-normal",
|
|
1708
|
+
hasError && "border-destructive",
|
|
1608
1709
|
(selectedOptions.length === 0 || loading) && "text-muted-foreground",
|
|
1609
1710
|
className
|
|
1610
1711
|
),
|
|
1611
1712
|
children: [
|
|
1612
|
-
/* @__PURE__ */
|
|
1613
|
-
/* @__PURE__ */
|
|
1614
|
-
clearable && !loading && selectedValues.length > 0 ? /* @__PURE__ */
|
|
1713
|
+
/* @__PURE__ */ jsx29("span", { className: "truncate", children: triggerLabel }),
|
|
1714
|
+
/* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-1", children: [
|
|
1715
|
+
clearable && !loading && selectedValues.length > 0 ? /* @__PURE__ */ jsx29(
|
|
1615
1716
|
"span",
|
|
1616
1717
|
{
|
|
1617
1718
|
role: "button",
|
|
@@ -1626,15 +1727,15 @@ function Combobox(props) {
|
|
|
1626
1727
|
props.onChange(null);
|
|
1627
1728
|
}
|
|
1628
1729
|
},
|
|
1629
|
-
children: /* @__PURE__ */
|
|
1730
|
+
children: /* @__PURE__ */ jsx29(XMarkIcon3, { className: "h-3.5 w-3.5" })
|
|
1630
1731
|
}
|
|
1631
1732
|
) : null,
|
|
1632
|
-
/* @__PURE__ */
|
|
1733
|
+
/* @__PURE__ */ jsx29(ChevronUpDownIcon, { className: "h-4 w-4 shrink-0 opacity-50", "aria-hidden": "true" })
|
|
1633
1734
|
] })
|
|
1634
1735
|
]
|
|
1635
1736
|
}
|
|
1636
1737
|
) }),
|
|
1637
|
-
/* @__PURE__ */
|
|
1738
|
+
/* @__PURE__ */ jsx29(
|
|
1638
1739
|
PopoverContent,
|
|
1639
1740
|
{
|
|
1640
1741
|
align: "start",
|
|
@@ -1644,8 +1745,8 @@ function Combobox(props) {
|
|
|
1644
1745
|
columns && "w-max min-w-[var(--radix-popover-trigger-width)] max-w-[min(40rem,90vw)]"
|
|
1645
1746
|
),
|
|
1646
1747
|
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
1647
|
-
children: /* @__PURE__ */
|
|
1648
|
-
/* @__PURE__ */
|
|
1748
|
+
children: /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
|
|
1749
|
+
/* @__PURE__ */ jsx29(
|
|
1649
1750
|
Input,
|
|
1650
1751
|
{
|
|
1651
1752
|
ref: inputRef,
|
|
@@ -1659,7 +1760,7 @@ function Combobox(props) {
|
|
|
1659
1760
|
"aria-label": searchPlaceholder
|
|
1660
1761
|
}
|
|
1661
1762
|
),
|
|
1662
|
-
/* @__PURE__ */
|
|
1763
|
+
/* @__PURE__ */ jsx29("div", { role: hasError ? void 0 : "listbox", className: cn("max-h-60 overflow-y-auto", !columns && "flex flex-col gap-0.5"), children: hasError ? /* @__PURE__ */ jsx29("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsx29(InlineError, { error, onRetry }) }) : visibleOptions.length === 0 ? /* @__PURE__ */ jsx29("p", { className: "py-2 text-center text-sm text-muted-foreground", children: emptyMessage }) : columns ? renderGridOptions({
|
|
1663
1764
|
columns,
|
|
1664
1765
|
options: visibleOptions,
|
|
1665
1766
|
activeIndex,
|
|
@@ -1679,14 +1780,14 @@ function Combobox(props) {
|
|
|
1679
1780
|
// lives on this wrapper's `pt-1`, not on the header itself -- a margin on
|
|
1680
1781
|
// the sticky element would travel with it once stuck, leaving a gap at the
|
|
1681
1782
|
// scrollport's top that the row behind it shows through.
|
|
1682
|
-
/* @__PURE__ */
|
|
1683
|
-
/* @__PURE__ */
|
|
1783
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-0.5 pt-1 first:pt-0", children: [
|
|
1784
|
+
/* @__PURE__ */ jsxs13(
|
|
1684
1785
|
"div",
|
|
1685
1786
|
{
|
|
1686
1787
|
"data-group-header": true,
|
|
1687
1788
|
className: "sticky top-0 z-10 flex items-center gap-2 rounded-sm bg-muted px-2 py-1.5 text-sm font-semibold text-foreground",
|
|
1688
1789
|
children: [
|
|
1689
|
-
props.multiple ? /* @__PURE__ */
|
|
1790
|
+
props.multiple ? /* @__PURE__ */ jsx29(
|
|
1690
1791
|
"input",
|
|
1691
1792
|
{
|
|
1692
1793
|
type: "checkbox",
|
|
@@ -1700,7 +1801,7 @@ function Combobox(props) {
|
|
|
1700
1801
|
"aria-label": `Select all of ${groupLabel(chunk.group)}`
|
|
1701
1802
|
}
|
|
1702
1803
|
) : null,
|
|
1703
|
-
/* @__PURE__ */
|
|
1804
|
+
/* @__PURE__ */ jsx29("span", { className: "truncate", children: groupLabel(chunk.group) })
|
|
1704
1805
|
]
|
|
1705
1806
|
}
|
|
1706
1807
|
),
|
|
@@ -1715,9 +1816,9 @@ function Combobox(props) {
|
|
|
1715
1816
|
}
|
|
1716
1817
|
|
|
1717
1818
|
// src/patterns/tag-combobox/TagCombobox.tsx
|
|
1718
|
-
import {
|
|
1819
|
+
import { XMarkIcon as XMarkIcon4 } from "@heroicons/react/24/outline";
|
|
1719
1820
|
import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState9 } from "react";
|
|
1720
|
-
import { jsx as
|
|
1821
|
+
import { jsx as jsx30, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1721
1822
|
function TagCombobox({
|
|
1722
1823
|
options,
|
|
1723
1824
|
value,
|
|
@@ -1727,6 +1828,8 @@ function TagCombobox({
|
|
|
1727
1828
|
disabled,
|
|
1728
1829
|
loading = false,
|
|
1729
1830
|
loadingMessage = "Loading\u2026",
|
|
1831
|
+
error,
|
|
1832
|
+
onRetry,
|
|
1730
1833
|
className,
|
|
1731
1834
|
id,
|
|
1732
1835
|
onSearchChange,
|
|
@@ -1786,6 +1889,7 @@ function TagCombobox({
|
|
|
1786
1889
|
onChange(next);
|
|
1787
1890
|
inputRef.current?.focus();
|
|
1788
1891
|
}
|
|
1892
|
+
const hasError = toErrorInfo(error) !== void 0;
|
|
1789
1893
|
function handleKeyDown(event) {
|
|
1790
1894
|
if (event.key === "ArrowDown") {
|
|
1791
1895
|
event.preventDefault();
|
|
@@ -1797,7 +1901,7 @@ function TagCombobox({
|
|
|
1797
1901
|
} else if (event.key === "Enter") {
|
|
1798
1902
|
event.preventDefault();
|
|
1799
1903
|
const option = visibleOptions[activeIndex];
|
|
1800
|
-
if (option) toggleOption(option);
|
|
1904
|
+
if (option && !hasError) toggleOption(option);
|
|
1801
1905
|
} else if (event.key === "Escape") {
|
|
1802
1906
|
setOpen(false);
|
|
1803
1907
|
} else if (event.key === "Backspace" && search === "") {
|
|
@@ -1808,7 +1912,7 @@ function TagCombobox({
|
|
|
1808
1912
|
function renderOption({ option, index }) {
|
|
1809
1913
|
const isSelected = value.includes(option.value);
|
|
1810
1914
|
const isActive = index === activeIndex;
|
|
1811
|
-
return /* @__PURE__ */
|
|
1915
|
+
return /* @__PURE__ */ jsxs14(
|
|
1812
1916
|
"button",
|
|
1813
1917
|
{
|
|
1814
1918
|
type: "button",
|
|
@@ -1824,7 +1928,7 @@ function TagCombobox({
|
|
|
1824
1928
|
isActive && "bg-accent text-accent-foreground"
|
|
1825
1929
|
),
|
|
1826
1930
|
children: [
|
|
1827
|
-
/* @__PURE__ */
|
|
1931
|
+
/* @__PURE__ */ jsx30(
|
|
1828
1932
|
"input",
|
|
1829
1933
|
{
|
|
1830
1934
|
type: "checkbox",
|
|
@@ -1834,14 +1938,14 @@ function TagCombobox({
|
|
|
1834
1938
|
className: "pointer-events-none h-3.5 w-3.5 shrink-0 accent-primary"
|
|
1835
1939
|
}
|
|
1836
1940
|
),
|
|
1837
|
-
/* @__PURE__ */
|
|
1941
|
+
/* @__PURE__ */ jsx30("span", { className: "truncate", children: option.label })
|
|
1838
1942
|
]
|
|
1839
1943
|
},
|
|
1840
1944
|
option.value
|
|
1841
1945
|
);
|
|
1842
1946
|
}
|
|
1843
|
-
return /* @__PURE__ */
|
|
1844
|
-
/* @__PURE__ */
|
|
1947
|
+
return /* @__PURE__ */ jsxs14(Popover, { open, onOpenChange: setOpen, children: [
|
|
1948
|
+
/* @__PURE__ */ jsx30(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs14(
|
|
1845
1949
|
"div",
|
|
1846
1950
|
{
|
|
1847
1951
|
ref: fieldRef,
|
|
@@ -1859,13 +1963,13 @@ function TagCombobox({
|
|
|
1859
1963
|
if (!disabled) inputRef.current?.focus();
|
|
1860
1964
|
},
|
|
1861
1965
|
children: [
|
|
1862
|
-
selectedOptions.map((option) => /* @__PURE__ */
|
|
1966
|
+
selectedOptions.map((option) => /* @__PURE__ */ jsxs14(
|
|
1863
1967
|
"span",
|
|
1864
1968
|
{
|
|
1865
1969
|
className: "inline-flex items-center gap-1 rounded-full bg-muted py-0.5 pr-1 pl-2.5 text-xs font-medium text-muted-foreground",
|
|
1866
1970
|
children: [
|
|
1867
|
-
/* @__PURE__ */
|
|
1868
|
-
!disabled && /* @__PURE__ */
|
|
1971
|
+
/* @__PURE__ */ jsx30("span", { className: "max-w-48 truncate", children: option.label }),
|
|
1972
|
+
!disabled && /* @__PURE__ */ jsx30(
|
|
1869
1973
|
"button",
|
|
1870
1974
|
{
|
|
1871
1975
|
type: "button",
|
|
@@ -1875,14 +1979,14 @@ function TagCombobox({
|
|
|
1875
1979
|
event.stopPropagation();
|
|
1876
1980
|
removeValue(option.value);
|
|
1877
1981
|
},
|
|
1878
|
-
children: /* @__PURE__ */
|
|
1982
|
+
children: /* @__PURE__ */ jsx30(XMarkIcon4, { className: "h-3 w-3" })
|
|
1879
1983
|
}
|
|
1880
1984
|
)
|
|
1881
1985
|
]
|
|
1882
1986
|
},
|
|
1883
1987
|
option.value
|
|
1884
1988
|
)),
|
|
1885
|
-
/* @__PURE__ */
|
|
1989
|
+
/* @__PURE__ */ jsx30(
|
|
1886
1990
|
"input",
|
|
1887
1991
|
{
|
|
1888
1992
|
ref: inputRef,
|
|
@@ -1900,7 +2004,7 @@ function TagCombobox({
|
|
|
1900
2004
|
]
|
|
1901
2005
|
}
|
|
1902
2006
|
) }),
|
|
1903
|
-
/* @__PURE__ */
|
|
2007
|
+
/* @__PURE__ */ jsx30(
|
|
1904
2008
|
PopoverContent,
|
|
1905
2009
|
{
|
|
1906
2010
|
align: "start",
|
|
@@ -1914,7 +2018,7 @@ function TagCombobox({
|
|
|
1914
2018
|
onInteractOutside: (event) => {
|
|
1915
2019
|
if (fieldRef.current?.contains(event.target)) event.preventDefault();
|
|
1916
2020
|
},
|
|
1917
|
-
children: /* @__PURE__ */
|
|
2021
|
+
children: /* @__PURE__ */ jsx30("div", { role: hasError ? void 0 : "listbox", className: cn("max-h-60 overflow-y-auto", !columns && "flex flex-col gap-0.5"), children: loading ? /* @__PURE__ */ jsx30("p", { className: "py-2 text-center text-sm text-muted-foreground", children: loadingMessage }) : hasError ? /* @__PURE__ */ jsx30("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsx30(InlineError, { error, onRetry }) }) : visibleOptions.length === 0 ? /* @__PURE__ */ jsx30("p", { className: "py-2 text-center text-sm text-muted-foreground", children: emptyMessage }) : columns ? renderGridOptions({
|
|
1918
2022
|
columns,
|
|
1919
2023
|
options: visibleOptions,
|
|
1920
2024
|
activeIndex,
|
|
@@ -1933,14 +2037,14 @@ function TagCombobox({
|
|
|
1933
2037
|
// past its first row. Spacing above a group lives on this wrapper's
|
|
1934
2038
|
// `pt-1`/`first:pt-0`, not on the header itself -- see `Combobox`'s own
|
|
1935
2039
|
// identical structure for why both of these matter.
|
|
1936
|
-
/* @__PURE__ */
|
|
1937
|
-
/* @__PURE__ */
|
|
2040
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-0.5 pt-1 first:pt-0", children: [
|
|
2041
|
+
/* @__PURE__ */ jsxs14(
|
|
1938
2042
|
"div",
|
|
1939
2043
|
{
|
|
1940
2044
|
"data-group-header": true,
|
|
1941
2045
|
className: "sticky top-0 z-10 flex items-center gap-2 rounded-sm bg-muted px-2 py-1.5 text-sm font-semibold text-foreground",
|
|
1942
2046
|
children: [
|
|
1943
|
-
/* @__PURE__ */
|
|
2047
|
+
/* @__PURE__ */ jsx30(
|
|
1944
2048
|
"input",
|
|
1945
2049
|
{
|
|
1946
2050
|
type: "checkbox",
|
|
@@ -1954,7 +2058,7 @@ function TagCombobox({
|
|
|
1954
2058
|
"aria-label": `Select all of ${groupLabel(chunk.group)}`
|
|
1955
2059
|
}
|
|
1956
2060
|
),
|
|
1957
|
-
/* @__PURE__ */
|
|
2061
|
+
/* @__PURE__ */ jsx30("span", { className: "truncate", children: groupLabel(chunk.group) })
|
|
1958
2062
|
]
|
|
1959
2063
|
}
|
|
1960
2064
|
),
|
|
@@ -1968,8 +2072,13 @@ function TagCombobox({
|
|
|
1968
2072
|
}
|
|
1969
2073
|
|
|
1970
2074
|
// src/patterns/alert-box/AlertBox.tsx
|
|
1971
|
-
import {
|
|
1972
|
-
|
|
2075
|
+
import {
|
|
2076
|
+
CheckCircleIcon,
|
|
2077
|
+
ExclamationCircleIcon,
|
|
2078
|
+
ExclamationTriangleIcon as ExclamationTriangleIcon2,
|
|
2079
|
+
InformationCircleIcon
|
|
2080
|
+
} from "@heroicons/react/24/outline";
|
|
2081
|
+
import { jsx as jsx31, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1973
2082
|
var variantStyles = {
|
|
1974
2083
|
error: "border-destructive bg-destructive/10 text-red-800 dark:text-red-300",
|
|
1975
2084
|
warning: "border-amber-500 bg-amber-500/10 text-amber-900 dark:text-amber-200",
|
|
@@ -1977,24 +2086,24 @@ var variantStyles = {
|
|
|
1977
2086
|
success: "border-emerald-500 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"
|
|
1978
2087
|
};
|
|
1979
2088
|
var defaultIcons = {
|
|
1980
|
-
error: /* @__PURE__ */
|
|
1981
|
-
warning: /* @__PURE__ */
|
|
1982
|
-
info: /* @__PURE__ */
|
|
1983
|
-
success: /* @__PURE__ */
|
|
2089
|
+
error: /* @__PURE__ */ jsx31(ExclamationCircleIcon, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
|
|
2090
|
+
warning: /* @__PURE__ */ jsx31(ExclamationTriangleIcon2, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
|
|
2091
|
+
info: /* @__PURE__ */ jsx31(InformationCircleIcon, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
|
|
2092
|
+
success: /* @__PURE__ */ jsx31(CheckCircleIcon, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" })
|
|
1984
2093
|
};
|
|
1985
2094
|
var AlertBox = ({ variant, title, children, className, icon }) => {
|
|
1986
2095
|
const resolvedIcon = icon === void 0 ? defaultIcons[variant] : icon;
|
|
1987
|
-
return /* @__PURE__ */
|
|
1988
|
-
resolvedIcon != null && /* @__PURE__ */
|
|
1989
|
-
/* @__PURE__ */
|
|
1990
|
-
title && /* @__PURE__ */
|
|
1991
|
-
/* @__PURE__ */
|
|
2096
|
+
return /* @__PURE__ */ jsx31("div", { className: cn("rounded-md border p-3 text-sm", variantStyles[variant], className), children: /* @__PURE__ */ jsxs15("div", { className: "flex flex-row items-start gap-2", children: [
|
|
2097
|
+
resolvedIcon != null && /* @__PURE__ */ jsx31("span", { className: "mt-0.5 shrink-0", children: resolvedIcon }),
|
|
2098
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
|
|
2099
|
+
title && /* @__PURE__ */ jsx31("p", { className: "font-bold", children: title }),
|
|
2100
|
+
/* @__PURE__ */ jsx31("div", { children })
|
|
1992
2101
|
] })
|
|
1993
2102
|
] }) });
|
|
1994
2103
|
};
|
|
1995
2104
|
|
|
1996
2105
|
// src/patterns/status-badge/StatusBadge.tsx
|
|
1997
|
-
import { jsx as
|
|
2106
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
1998
2107
|
var TONE_CLASSES = {
|
|
1999
2108
|
success: "border-transparent bg-emerald-500/15 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-300",
|
|
2000
2109
|
warning: "border-transparent bg-amber-500/15 text-amber-800 dark:bg-amber-500/20 dark:text-amber-300",
|
|
@@ -2041,11 +2150,11 @@ function resolveTone(status, tone, toneMap) {
|
|
|
2041
2150
|
var StatusBadge = ({ status, label, tone, toneMap, className, ...props }) => {
|
|
2042
2151
|
const resolvedTone = resolveTone(status, tone, toneMap);
|
|
2043
2152
|
const displayLabel = label ?? deriveLabel(status);
|
|
2044
|
-
return /* @__PURE__ */
|
|
2153
|
+
return /* @__PURE__ */ jsx32(Badge, { variant: "outline", className: cn(TONE_CLASSES[resolvedTone], className), ...props, children: displayLabel });
|
|
2045
2154
|
};
|
|
2046
2155
|
|
|
2047
2156
|
// src/patterns/button-group/ButtonGroup.tsx
|
|
2048
|
-
import { jsx as
|
|
2157
|
+
import { jsx as jsx33, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2049
2158
|
function ButtonGroup({
|
|
2050
2159
|
options,
|
|
2051
2160
|
value,
|
|
@@ -2055,10 +2164,10 @@ function ButtonGroup({
|
|
|
2055
2164
|
className,
|
|
2056
2165
|
...props
|
|
2057
2166
|
}) {
|
|
2058
|
-
return /* @__PURE__ */
|
|
2167
|
+
return /* @__PURE__ */ jsx33("div", { role: "group", "aria-label": props["aria-label"], className: cn("inline-flex", className), "data-testid": props["data-testid"], children: options.map((option, index) => {
|
|
2059
2168
|
const selected = option.value === value;
|
|
2060
2169
|
const Icon2 = option.icon;
|
|
2061
|
-
return /* @__PURE__ */
|
|
2170
|
+
return /* @__PURE__ */ jsxs16(
|
|
2062
2171
|
Button,
|
|
2063
2172
|
{
|
|
2064
2173
|
type: "button",
|
|
@@ -2076,7 +2185,7 @@ function ButtonGroup({
|
|
|
2076
2185
|
index > 0 && "-ml-px"
|
|
2077
2186
|
),
|
|
2078
2187
|
children: [
|
|
2079
|
-
Icon2 && /* @__PURE__ */
|
|
2188
|
+
Icon2 && /* @__PURE__ */ jsx33(Icon2, { className: "h-4 w-4" }),
|
|
2080
2189
|
option.label
|
|
2081
2190
|
]
|
|
2082
2191
|
},
|
|
@@ -2087,8 +2196,8 @@ function ButtonGroup({
|
|
|
2087
2196
|
|
|
2088
2197
|
// src/patterns/loading-spinner/LoadingSpinner.tsx
|
|
2089
2198
|
import { cva as cva4 } from "class-variance-authority";
|
|
2090
|
-
import {
|
|
2091
|
-
import { jsx as
|
|
2199
|
+
import { ArrowPathIcon as ArrowPathIcon2 } from "@heroicons/react/24/outline";
|
|
2200
|
+
import { jsx as jsx34, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2092
2201
|
var loadingSpinnerIconVariants = cva4("animate-spin text-muted-foreground", {
|
|
2093
2202
|
variants: {
|
|
2094
2203
|
size: {
|
|
@@ -2106,75 +2215,167 @@ var LoadingSpinner = ({
|
|
|
2106
2215
|
label,
|
|
2107
2216
|
className,
|
|
2108
2217
|
...props
|
|
2109
|
-
}) => /* @__PURE__ */
|
|
2110
|
-
/* @__PURE__ */
|
|
2111
|
-
label ? /* @__PURE__ */
|
|
2218
|
+
}) => /* @__PURE__ */ jsxs17("span", { role: "status", className: cn("inline-flex items-center gap-2", className), ...props, children: [
|
|
2219
|
+
/* @__PURE__ */ jsx34(ArrowPathIcon2, { className: cn(loadingSpinnerIconVariants({ size })), "aria-hidden": "true" }),
|
|
2220
|
+
label ? /* @__PURE__ */ jsx34("span", { children: label }) : null
|
|
2112
2221
|
] });
|
|
2113
2222
|
var LoadingOverlay = ({
|
|
2114
2223
|
size = "lg",
|
|
2115
2224
|
label,
|
|
2116
2225
|
className,
|
|
2117
2226
|
...props
|
|
2118
|
-
}) => /* @__PURE__ */
|
|
2227
|
+
}) => /* @__PURE__ */ jsx34(
|
|
2119
2228
|
"div",
|
|
2120
2229
|
{
|
|
2121
2230
|
className: cn("flex h-full min-h-32 w-full items-center justify-center", className),
|
|
2122
2231
|
...props,
|
|
2123
|
-
children: /* @__PURE__ */
|
|
2232
|
+
children: /* @__PURE__ */ jsx34(LoadingSpinner, { size, label })
|
|
2124
2233
|
}
|
|
2125
2234
|
);
|
|
2126
2235
|
|
|
2236
|
+
// src/patterns/loading-spinner/LoadingState.tsx
|
|
2237
|
+
import { useEffect as useEffect5, useState as useState10 } from "react";
|
|
2238
|
+
import { jsx as jsx35, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2239
|
+
function useDelayedFlag(active, delayMs = 150) {
|
|
2240
|
+
const [shown, setShown] = useState10(false);
|
|
2241
|
+
useEffect5(() => {
|
|
2242
|
+
if (!active) {
|
|
2243
|
+
setShown(false);
|
|
2244
|
+
return;
|
|
2245
|
+
}
|
|
2246
|
+
if (delayMs <= 0) {
|
|
2247
|
+
setShown(true);
|
|
2248
|
+
return;
|
|
2249
|
+
}
|
|
2250
|
+
const timer = setTimeout(() => setShown(true), delayMs);
|
|
2251
|
+
return () => clearTimeout(timer);
|
|
2252
|
+
}, [active, delayMs]);
|
|
2253
|
+
return active && (delayMs <= 0 || shown);
|
|
2254
|
+
}
|
|
2255
|
+
var LoadingState = ({
|
|
2256
|
+
variant = "skeleton",
|
|
2257
|
+
lines = 3,
|
|
2258
|
+
label = "Loading\u2026",
|
|
2259
|
+
delayMs = 150,
|
|
2260
|
+
className,
|
|
2261
|
+
...props
|
|
2262
|
+
}) => {
|
|
2263
|
+
const visible = useDelayedFlag(true, delayMs);
|
|
2264
|
+
if (variant === "spinner") {
|
|
2265
|
+
return /* @__PURE__ */ jsx35("div", { "data-testid": "loading-state", "aria-busy": "true", className: cn(!visible && "invisible", className), ...props, children: /* @__PURE__ */ jsx35(LoadingOverlay, { label }) });
|
|
2266
|
+
}
|
|
2267
|
+
return /* @__PURE__ */ jsxs18(
|
|
2268
|
+
"div",
|
|
2269
|
+
{
|
|
2270
|
+
role: "status",
|
|
2271
|
+
"aria-busy": "true",
|
|
2272
|
+
"data-testid": "loading-state",
|
|
2273
|
+
className: cn("flex w-full flex-col gap-2 p-1", !visible && "invisible", className),
|
|
2274
|
+
...props,
|
|
2275
|
+
children: [
|
|
2276
|
+
/* @__PURE__ */ jsx35("span", { className: "sr-only", children: label }),
|
|
2277
|
+
Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx35(Skeleton, { "aria-hidden": "true", className: cn("h-4", i === lines - 1 && lines > 1 ? "w-2/3" : "w-full") }, i))
|
|
2278
|
+
]
|
|
2279
|
+
}
|
|
2280
|
+
);
|
|
2281
|
+
};
|
|
2282
|
+
var RefreshBar = ({ active, className }) => active ? /* @__PURE__ */ jsx35(
|
|
2283
|
+
"div",
|
|
2284
|
+
{
|
|
2285
|
+
role: "progressbar",
|
|
2286
|
+
"aria-label": "Refreshing",
|
|
2287
|
+
"data-testid": "refresh-bar",
|
|
2288
|
+
className: cn("absolute inset-x-0 top-0 z-30 h-0.5 overflow-hidden bg-muted", className),
|
|
2289
|
+
children: /* @__PURE__ */ jsx35("div", { className: "h-full w-1/3 animate-pulse bg-primary motion-reduce:animate-none" })
|
|
2290
|
+
}
|
|
2291
|
+
) : null;
|
|
2292
|
+
|
|
2293
|
+
// src/patterns/async-boundary/AsyncBoundary.tsx
|
|
2294
|
+
import { Fragment as Fragment3, jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2295
|
+
var AsyncBoundary = ({
|
|
2296
|
+
loading = false,
|
|
2297
|
+
error,
|
|
2298
|
+
onRetry,
|
|
2299
|
+
empty = false,
|
|
2300
|
+
emptyContent,
|
|
2301
|
+
loadingContent,
|
|
2302
|
+
hasData,
|
|
2303
|
+
children
|
|
2304
|
+
}) => {
|
|
2305
|
+
const failed = toErrorInfo(error) !== void 0;
|
|
2306
|
+
const showData = hasData ?? false;
|
|
2307
|
+
if (loading && !showData) return /* @__PURE__ */ jsx36(Fragment3, { children: loadingContent ?? /* @__PURE__ */ jsx36(LoadingState, {}) });
|
|
2308
|
+
if (failed && !showData) return /* @__PURE__ */ jsx36(ErrorState, { error, onRetry });
|
|
2309
|
+
if (empty && !showData) return /* @__PURE__ */ jsx36(Fragment3, { children: emptyContent ?? null });
|
|
2310
|
+
return /* @__PURE__ */ jsxs19("div", { className: "relative", children: [
|
|
2311
|
+
/* @__PURE__ */ jsx36(RefreshBar, { active: loading }),
|
|
2312
|
+
failed ? /* @__PURE__ */ jsx36(InlineError, { error, onRetry, className: "mb-2" }) : null,
|
|
2313
|
+
children
|
|
2314
|
+
] });
|
|
2315
|
+
};
|
|
2316
|
+
|
|
2127
2317
|
// src/patterns/search-bar/SearchBar.tsx
|
|
2128
|
-
import {
|
|
2129
|
-
import { jsx as
|
|
2318
|
+
import { ExclamationTriangleIcon as ExclamationTriangleIcon3, MagnifyingGlassIcon, XMarkIcon as XMarkIcon5 } from "@heroicons/react/24/outline";
|
|
2319
|
+
import { jsx as jsx37, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2130
2320
|
function SearchBar({
|
|
2131
2321
|
value,
|
|
2132
2322
|
onChange,
|
|
2323
|
+
loading,
|
|
2133
2324
|
isLoading,
|
|
2325
|
+
error,
|
|
2326
|
+
onRetry,
|
|
2134
2327
|
onClear,
|
|
2135
2328
|
clearLabel = "Clear search",
|
|
2136
2329
|
inputRef,
|
|
2137
2330
|
className,
|
|
2138
2331
|
...props
|
|
2139
2332
|
}) {
|
|
2333
|
+
const busy = loading ?? isLoading;
|
|
2334
|
+
const hasError = toErrorInfo(error) !== void 0;
|
|
2140
2335
|
const showClear = onClear !== false && value.length > 0;
|
|
2141
|
-
return /* @__PURE__ */
|
|
2142
|
-
/* @__PURE__ */
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2336
|
+
return /* @__PURE__ */ jsxs20("div", { className, children: [
|
|
2337
|
+
/* @__PURE__ */ jsxs20("div", { className: "relative", children: [
|
|
2338
|
+
/* @__PURE__ */ jsx37("span", { className: "pointer-events-none absolute top-1/2 left-4 -translate-y-1/2 text-muted-foreground", children: busy ? /* @__PURE__ */ jsx37(LoadingSpinner, { size: "sm" }) : hasError ? /* @__PURE__ */ jsx37(ExclamationTriangleIcon3, { className: "h-4 w-4 text-destructive", "aria-hidden": "true" }) : /* @__PURE__ */ jsx37(MagnifyingGlassIcon, { className: "h-4 w-4", "aria-hidden": "true" }) }),
|
|
2339
|
+
/* @__PURE__ */ jsx37(
|
|
2340
|
+
"input",
|
|
2341
|
+
{
|
|
2342
|
+
ref: inputRef,
|
|
2343
|
+
type: "search",
|
|
2344
|
+
"aria-invalid": hasError || void 0,
|
|
2345
|
+
value,
|
|
2346
|
+
onChange: (event) => onChange(event.target.value),
|
|
2347
|
+
className: cn(
|
|
2348
|
+
"h-11 w-full rounded-full border bg-background text-[15px] text-foreground placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
2349
|
+
// Chromium/Safari render their own native clear (×) control on
|
|
2350
|
+
// type="search" inputs -- left alone, it stacks on top of our own
|
|
2351
|
+
// custom clear button below instead of replacing it.
|
|
2352
|
+
"[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none",
|
|
2353
|
+
hasError ? "border-destructive" : "border-input",
|
|
2354
|
+
showClear ? "pr-11" : "pr-4",
|
|
2355
|
+
"pl-11"
|
|
2356
|
+
),
|
|
2357
|
+
...props
|
|
2358
|
+
}
|
|
2359
|
+
),
|
|
2360
|
+
showClear && /* @__PURE__ */ jsx37(
|
|
2361
|
+
"button",
|
|
2362
|
+
{
|
|
2363
|
+
type: "button",
|
|
2364
|
+
onClick: () => onClear ? onClear() : onChange(""),
|
|
2365
|
+
"aria-label": clearLabel,
|
|
2366
|
+
className: "absolute top-1/2 right-2 flex h-7 w-7 -translate-y-1/2 items-center justify-center rounded-full text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
2367
|
+
children: /* @__PURE__ */ jsx37(XMarkIcon5, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
2368
|
+
}
|
|
2369
|
+
)
|
|
2370
|
+
] }),
|
|
2371
|
+
hasError && /* @__PURE__ */ jsx37(InlineError, { error, onRetry, className: "mt-1 ml-4" })
|
|
2172
2372
|
] });
|
|
2173
2373
|
}
|
|
2174
2374
|
|
|
2175
2375
|
// src/patterns/kpi-card/KpiCard.tsx
|
|
2176
2376
|
import { memo } from "react";
|
|
2177
|
-
import {
|
|
2377
|
+
import { ExclamationTriangleIcon as ExclamationTriangleIcon4 } from "@heroicons/react/24/outline";
|
|
2378
|
+
import { Fragment as Fragment4, jsx as jsx38, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2178
2379
|
var DONUT_COLORS = [
|
|
2179
2380
|
"var(--chart-1, #3b82f6)",
|
|
2180
2381
|
"var(--chart-2, #22c55e)",
|
|
@@ -2195,13 +2396,13 @@ function DonutChart({
|
|
|
2195
2396
|
const radius = (size - thickness) / 2;
|
|
2196
2397
|
const circumference = 2 * Math.PI * radius;
|
|
2197
2398
|
let offset = 0;
|
|
2198
|
-
return /* @__PURE__ */
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
/* @__PURE__ */
|
|
2399
|
+
return /* @__PURE__ */ jsxs21("div", { className: "relative inline-flex shrink-0 items-center justify-center", style: { width: size, height: size }, children: [
|
|
2400
|
+
/* @__PURE__ */ jsxs21("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", children: [
|
|
2401
|
+
/* @__PURE__ */ jsx38("circle", { cx: size / 2, cy: size / 2, r: radius, fill: "none", stroke: "currentColor", className: "text-muted/40", strokeWidth: thickness }),
|
|
2201
2402
|
data.map((segment, i) => {
|
|
2202
2403
|
const fraction = segment.value / total;
|
|
2203
2404
|
const dash = fraction * circumference;
|
|
2204
|
-
const el = /* @__PURE__ */
|
|
2405
|
+
const el = /* @__PURE__ */ jsx38(
|
|
2205
2406
|
"circle",
|
|
2206
2407
|
{
|
|
2207
2408
|
cx: size / 2,
|
|
@@ -2220,9 +2421,9 @@ function DonutChart({
|
|
|
2220
2421
|
return el;
|
|
2221
2422
|
})
|
|
2222
2423
|
] }),
|
|
2223
|
-
(centerValue || centerLabel) && /* @__PURE__ */
|
|
2224
|
-
centerValue && /* @__PURE__ */
|
|
2225
|
-
centerLabel && /* @__PURE__ */
|
|
2424
|
+
(centerValue || centerLabel) && /* @__PURE__ */ jsxs21("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [
|
|
2425
|
+
centerValue && /* @__PURE__ */ jsx38("span", { className: "text-base font-black tracking-tight text-foreground tabular-nums", children: centerValue }),
|
|
2426
|
+
centerLabel && /* @__PURE__ */ jsx38("span", { className: "text-[9px] font-medium text-muted-foreground uppercase", children: centerLabel })
|
|
2226
2427
|
] })
|
|
2227
2428
|
] });
|
|
2228
2429
|
}
|
|
@@ -2234,7 +2435,7 @@ function Sparkline({ data, color }) {
|
|
|
2234
2435
|
const W = 72;
|
|
2235
2436
|
const H = 28;
|
|
2236
2437
|
const pts = data.map((v, i) => `${i / (data.length - 1) * W},${H - (v - min) / range * (H - 2) - 1}`).join(" ");
|
|
2237
|
-
return /* @__PURE__ */
|
|
2438
|
+
return /* @__PURE__ */ jsx38("svg", { width: W, height: H, viewBox: `0 0 ${W} ${H}`, className: "overflow-visible opacity-70", children: /* @__PURE__ */ jsx38("polyline", { points: pts, fill: "none", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
2238
2439
|
}
|
|
2239
2440
|
function AreaSparkline({ data, color }) {
|
|
2240
2441
|
if (data.length < 2) return null;
|
|
@@ -2248,14 +2449,14 @@ function AreaSparkline({ data, color }) {
|
|
|
2248
2449
|
const ys = data.map((v) => H - (v - min) / range * (H - 2 * P) - P);
|
|
2249
2450
|
const linePts = xs.map((x, i) => `${x},${ys[i]}`).join(" ");
|
|
2250
2451
|
const areaPath = `M${xs[0]},${H} ` + xs.map((x, i) => `L${x},${ys[i]}`).join(" ") + ` L${xs[xs.length - 1]},${H} Z`;
|
|
2251
|
-
return /* @__PURE__ */
|
|
2252
|
-
/* @__PURE__ */
|
|
2253
|
-
/* @__PURE__ */
|
|
2254
|
-
/* @__PURE__ */
|
|
2452
|
+
return /* @__PURE__ */ jsxs21("svg", { width: W, height: H, viewBox: `0 0 ${W} ${H}`, className: "overflow-visible", preserveAspectRatio: "none", children: [
|
|
2453
|
+
/* @__PURE__ */ jsx38("defs", { children: /* @__PURE__ */ jsxs21("linearGradient", { id: "kpi-card-spark-fill", x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
2454
|
+
/* @__PURE__ */ jsx38("stop", { offset: "0%", stopColor: color, stopOpacity: "0.22" }),
|
|
2455
|
+
/* @__PURE__ */ jsx38("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
|
|
2255
2456
|
] }) }),
|
|
2256
|
-
/* @__PURE__ */
|
|
2257
|
-
/* @__PURE__ */
|
|
2258
|
-
/* @__PURE__ */
|
|
2457
|
+
/* @__PURE__ */ jsx38("path", { d: areaPath, fill: "url(#kpi-card-spark-fill)" }),
|
|
2458
|
+
/* @__PURE__ */ jsx38("polyline", { points: linePts, fill: "none", stroke: color, strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
2459
|
+
/* @__PURE__ */ jsx38("circle", { cx: xs[xs.length - 1], cy: ys[ys.length - 1], r: "2.5", fill: color })
|
|
2259
2460
|
] });
|
|
2260
2461
|
}
|
|
2261
2462
|
var rowBetween = "flex items-center justify-between";
|
|
@@ -2267,6 +2468,8 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2267
2468
|
badgeLabel,
|
|
2268
2469
|
variant = "default",
|
|
2269
2470
|
loading = false,
|
|
2471
|
+
error,
|
|
2472
|
+
onRetry,
|
|
2270
2473
|
sub,
|
|
2271
2474
|
subTone = "default",
|
|
2272
2475
|
href,
|
|
@@ -2279,9 +2482,33 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2279
2482
|
background,
|
|
2280
2483
|
testId
|
|
2281
2484
|
}) {
|
|
2485
|
+
const errorInfo = loading ? void 0 : toErrorInfo(error);
|
|
2486
|
+
if (errorInfo) {
|
|
2487
|
+
const hero = variant === "hero";
|
|
2488
|
+
return /* @__PURE__ */ jsxs21(
|
|
2489
|
+
"div",
|
|
2490
|
+
{
|
|
2491
|
+
"data-testid": testId,
|
|
2492
|
+
role: "status",
|
|
2493
|
+
className: cn(
|
|
2494
|
+
"flex min-w-0 flex-col gap-1 rounded-2xl border border-destructive/40 bg-card p-3",
|
|
2495
|
+
hero && "col-span-2 flex-1 lg:col-span-1 lg:max-w-[340px] lg:min-w-[260px]"
|
|
2496
|
+
),
|
|
2497
|
+
children: [
|
|
2498
|
+
/* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.14em] text-muted-foreground uppercase", children: label }),
|
|
2499
|
+
/* @__PURE__ */ jsxs21("p", { className: "flex items-center gap-1.5 text-xl font-bold text-muted-foreground", children: [
|
|
2500
|
+
"\u2014",
|
|
2501
|
+
/* @__PURE__ */ jsx38(ExclamationTriangleIcon4, { className: "h-4 w-4 text-destructive", "aria-hidden": "true" })
|
|
2502
|
+
] }),
|
|
2503
|
+
/* @__PURE__ */ jsx38("p", { className: "truncate text-xs text-red-700 dark:text-red-300", children: errorInfo.message ?? errorInfo.title ?? "Failed to load" }),
|
|
2504
|
+
onRetry ? /* @__PURE__ */ jsx38("button", { type: "button", onClick: onRetry, className: "self-start text-xs text-red-700 underline underline-offset-2 dark:text-red-300", children: "Retry" }) : null
|
|
2505
|
+
]
|
|
2506
|
+
}
|
|
2507
|
+
);
|
|
2508
|
+
}
|
|
2282
2509
|
const bgStyle = background ? { background } : void 0;
|
|
2283
2510
|
if (variant === "hero") {
|
|
2284
|
-
return /* @__PURE__ */
|
|
2511
|
+
return /* @__PURE__ */ jsxs21(
|
|
2285
2512
|
"div",
|
|
2286
2513
|
{
|
|
2287
2514
|
"data-testid": testId,
|
|
@@ -2291,13 +2518,13 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2291
2518
|
boxShadow: `0 2px 10px color-mix(in oklch, ${background ?? "var(--color-primary)"} 18%, transparent)`
|
|
2292
2519
|
},
|
|
2293
2520
|
children: [
|
|
2294
|
-
/* @__PURE__ */
|
|
2295
|
-
/* @__PURE__ */
|
|
2296
|
-
Icon2 && /* @__PURE__ */
|
|
2521
|
+
/* @__PURE__ */ jsxs21("div", { className: "relative flex items-start justify-between", children: [
|
|
2522
|
+
/* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.14em] text-white/70 uppercase", children: label }),
|
|
2523
|
+
Icon2 && /* @__PURE__ */ jsx38("div", { className: "flex h-6 w-6 items-center justify-center rounded-lg bg-white/15 ring-1 ring-white/20", children: /* @__PURE__ */ jsx38(Icon2, { className: "h-3 w-3 text-white/90", "aria-hidden": "true" }) })
|
|
2297
2524
|
] }),
|
|
2298
|
-
/* @__PURE__ */
|
|
2299
|
-
(badge || badgeLabel) && !loading && /* @__PURE__ */
|
|
2300
|
-
badge && /* @__PURE__ */
|
|
2525
|
+
/* @__PURE__ */ jsx38("div", { className: "relative", children: loading ? /* @__PURE__ */ jsx38("div", { className: "h-6 w-28 animate-pulse rounded-lg bg-white/15" }) : /* @__PURE__ */ jsx38("p", { className: "text-2xl leading-none font-black tracking-tight text-white tabular-nums md:text-[22px]", children: value ?? "\u2014" }) }),
|
|
2526
|
+
(badge || badgeLabel) && !loading && /* @__PURE__ */ jsxs21("div", { className: "relative flex items-center gap-2", children: [
|
|
2527
|
+
badge && /* @__PURE__ */ jsx38(
|
|
2301
2528
|
"span",
|
|
2302
2529
|
{
|
|
2303
2530
|
className: cn(
|
|
@@ -2307,28 +2534,28 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2307
2534
|
children: badge.text
|
|
2308
2535
|
}
|
|
2309
2536
|
),
|
|
2310
|
-
badgeLabel && /* @__PURE__ */
|
|
2537
|
+
badgeLabel && /* @__PURE__ */ jsx38("span", { className: "text-[11px] text-white/70", children: badgeLabel })
|
|
2311
2538
|
] }),
|
|
2312
|
-
sub && !loading && /* @__PURE__ */
|
|
2313
|
-
progress != null && !loading && /* @__PURE__ */
|
|
2314
|
-
/* @__PURE__ */
|
|
2315
|
-
progressLabel && /* @__PURE__ */
|
|
2539
|
+
sub && !loading && /* @__PURE__ */ jsx38("p", { className: "relative -mt-1 text-[11px] font-medium text-white/75 tabular-nums", children: sub }),
|
|
2540
|
+
progress != null && !loading && /* @__PURE__ */ jsxs21("div", { className: "relative flex items-center gap-1.5", children: [
|
|
2541
|
+
/* @__PURE__ */ jsx38("div", { className: "h-1 flex-1 overflow-hidden rounded-full bg-white/20", children: /* @__PURE__ */ jsx38("div", { className: "h-1 rounded-full bg-white/85", style: { width: `${Math.min(100, Math.max(0, progress))}%` } }) }),
|
|
2542
|
+
progressLabel && /* @__PURE__ */ jsx38("span", { className: "shrink-0 text-[11px] font-semibold text-white/80 tabular-nums", children: progressLabel })
|
|
2316
2543
|
] }),
|
|
2317
|
-
sparkline && sparkline.length > 1 && !loading && /* @__PURE__ */
|
|
2544
|
+
sparkline && sparkline.length > 1 && !loading && /* @__PURE__ */ jsx38("div", { className: "relative -mx-4 mt-auto -mb-4 md:-mx-3 md:-mb-3", children: /* @__PURE__ */ jsx38(AreaSparkline, { data: sparkline, color: "#ffffff" }) })
|
|
2318
2545
|
]
|
|
2319
2546
|
}
|
|
2320
2547
|
);
|
|
2321
2548
|
}
|
|
2322
2549
|
if (variant === "mini") {
|
|
2323
|
-
const iconSlot = Icon2 ? href ? /* @__PURE__ */
|
|
2550
|
+
const iconSlot = Icon2 ? href ? /* @__PURE__ */ jsx38(
|
|
2324
2551
|
"a",
|
|
2325
2552
|
{
|
|
2326
2553
|
href,
|
|
2327
2554
|
className: "tap-target flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary transition-[background-color,scale] hover:bg-primary/20 active:scale-90 motion-reduce:transition-none md:h-6 md:w-6",
|
|
2328
|
-
children: /* @__PURE__ */
|
|
2555
|
+
children: /* @__PURE__ */ jsx38(Icon2, { className: "h-4 w-4 md:h-3.5 md:w-3.5", "aria-hidden": "true" })
|
|
2329
2556
|
}
|
|
2330
|
-
) : /* @__PURE__ */
|
|
2331
|
-
return /* @__PURE__ */
|
|
2557
|
+
) : /* @__PURE__ */ jsx38("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary md:h-6 md:w-6", children: /* @__PURE__ */ jsx38(Icon2, { className: "h-4 w-4 md:h-3.5 md:w-3.5", "aria-hidden": "true" }) }) : null;
|
|
2558
|
+
return /* @__PURE__ */ jsxs21(
|
|
2332
2559
|
"div",
|
|
2333
2560
|
{
|
|
2334
2561
|
"data-testid": testId,
|
|
@@ -2338,13 +2565,13 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2338
2565
|
href && "hover:border-primary/20 hover:shadow-md"
|
|
2339
2566
|
),
|
|
2340
2567
|
children: [
|
|
2341
|
-
/* @__PURE__ */
|
|
2342
|
-
/* @__PURE__ */
|
|
2568
|
+
/* @__PURE__ */ jsxs21("div", { className: rowBetween, children: [
|
|
2569
|
+
/* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
|
|
2343
2570
|
iconSlot
|
|
2344
2571
|
] }),
|
|
2345
|
-
/* @__PURE__ */
|
|
2346
|
-
/* @__PURE__ */
|
|
2347
|
-
badge && /* @__PURE__ */
|
|
2572
|
+
/* @__PURE__ */ jsx38("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: loading ? /* @__PURE__ */ jsx38(Skeleton, { className: "h-6 w-16" }) : /* @__PURE__ */ jsxs21(Fragment4, { children: [
|
|
2573
|
+
/* @__PURE__ */ jsx38("p", { className: "min-w-0 animate-in truncate text-[20px] leading-none font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none md:text-[16px]", children: value ?? "\u2014" }),
|
|
2574
|
+
badge && /* @__PURE__ */ jsx38(
|
|
2348
2575
|
"span",
|
|
2349
2576
|
{
|
|
2350
2577
|
className: cn(
|
|
@@ -2355,8 +2582,8 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2355
2582
|
}
|
|
2356
2583
|
)
|
|
2357
2584
|
] }) }),
|
|
2358
|
-
(sub || sparkline) && !loading && /* @__PURE__ */
|
|
2359
|
-
sub && /* @__PURE__ */
|
|
2585
|
+
(sub || sparkline) && !loading && /* @__PURE__ */ jsxs21("div", { className: "flex items-end justify-between gap-2", children: [
|
|
2586
|
+
sub && /* @__PURE__ */ jsx38(
|
|
2360
2587
|
"p",
|
|
2361
2588
|
{
|
|
2362
2589
|
className: cn(
|
|
@@ -2366,7 +2593,7 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2366
2593
|
children: sub
|
|
2367
2594
|
}
|
|
2368
2595
|
),
|
|
2369
|
-
sparkline && /* @__PURE__ */
|
|
2596
|
+
sparkline && /* @__PURE__ */ jsx38(Sparkline, { data: sparkline, color: sparklineColor })
|
|
2370
2597
|
] })
|
|
2371
2598
|
]
|
|
2372
2599
|
}
|
|
@@ -2374,22 +2601,22 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2374
2601
|
}
|
|
2375
2602
|
if (variant === "donut") {
|
|
2376
2603
|
const total = segments?.reduce((sum, s) => sum + s.value, 0) ?? 0;
|
|
2377
|
-
return /* @__PURE__ */
|
|
2378
|
-
/* @__PURE__ */
|
|
2379
|
-
/* @__PURE__ */
|
|
2380
|
-
Icon2 && /* @__PURE__ */
|
|
2604
|
+
return /* @__PURE__ */ jsxs21("div", { "data-testid": testId, style: bgStyle, className: "rounded-xl border border-border bg-card p-5", children: [
|
|
2605
|
+
/* @__PURE__ */ jsxs21("div", { className: rowBetween, children: [
|
|
2606
|
+
/* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
|
|
2607
|
+
Icon2 && /* @__PURE__ */ jsx38("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/8 text-primary", children: /* @__PURE__ */ jsx38(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) })
|
|
2381
2608
|
] }),
|
|
2382
|
-
loading ? /* @__PURE__ */
|
|
2383
|
-
/* @__PURE__ */
|
|
2384
|
-
/* @__PURE__ */
|
|
2385
|
-
/* @__PURE__ */
|
|
2386
|
-
/* @__PURE__ */
|
|
2387
|
-
/* @__PURE__ */
|
|
2609
|
+
loading ? /* @__PURE__ */ jsxs21("div", { className: "mt-3 flex items-center gap-4", children: [
|
|
2610
|
+
/* @__PURE__ */ jsx38(Skeleton, { className: "h-24 w-24 shrink-0 rounded-full" }),
|
|
2611
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex flex-1 flex-col gap-2", children: [
|
|
2612
|
+
/* @__PURE__ */ jsx38(Skeleton, { className: "h-3 w-full" }),
|
|
2613
|
+
/* @__PURE__ */ jsx38(Skeleton, { className: "h-3 w-3/4" }),
|
|
2614
|
+
/* @__PURE__ */ jsx38(Skeleton, { className: "h-3 w-1/2" })
|
|
2388
2615
|
] })
|
|
2389
|
-
] }) : segments && segments.length > 0 ? /* @__PURE__ */
|
|
2390
|
-
/* @__PURE__ */
|
|
2391
|
-
/* @__PURE__ */
|
|
2392
|
-
/* @__PURE__ */
|
|
2616
|
+
] }) : segments && segments.length > 0 ? /* @__PURE__ */ jsxs21("div", { className: "mt-3 flex items-center gap-4", children: [
|
|
2617
|
+
/* @__PURE__ */ jsx38(DonutChart, { data: segments, centerValue: centerValue ?? String(total) }),
|
|
2618
|
+
/* @__PURE__ */ jsx38("ul", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: segments.map((segment, i) => /* @__PURE__ */ jsxs21("li", { className: "flex items-center gap-2 text-[12px]", children: [
|
|
2619
|
+
/* @__PURE__ */ jsx38(
|
|
2393
2620
|
"span",
|
|
2394
2621
|
{
|
|
2395
2622
|
className: "h-2 w-2 shrink-0 rounded-full",
|
|
@@ -2397,11 +2624,11 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2397
2624
|
"aria-hidden": "true"
|
|
2398
2625
|
}
|
|
2399
2626
|
),
|
|
2400
|
-
/* @__PURE__ */
|
|
2401
|
-
/* @__PURE__ */
|
|
2627
|
+
/* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate text-muted-foreground", children: segment.label }),
|
|
2628
|
+
/* @__PURE__ */ jsx38("span", { className: "shrink-0 font-semibold text-foreground tabular-nums", children: total > 0 ? `${Math.round(segment.value / total * 100)}%` : segment.value })
|
|
2402
2629
|
] }, segment.label)) })
|
|
2403
|
-
] }) : /* @__PURE__ */
|
|
2404
|
-
sub && !loading && /* @__PURE__ */
|
|
2630
|
+
] }) : /* @__PURE__ */ jsx38("span", { className: "mt-3 block text-2xl font-black text-muted-foreground/40", children: "\u2014" }),
|
|
2631
|
+
sub && !loading && /* @__PURE__ */ jsx38("p", { className: "mt-2.5 text-[11px] text-muted-foreground tabular-nums", children: sub })
|
|
2405
2632
|
] });
|
|
2406
2633
|
}
|
|
2407
2634
|
const strValue = value != null ? String(value) : null;
|
|
@@ -2411,28 +2638,28 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2411
2638
|
const prefix = isSuffix ? null : parts?.[0];
|
|
2412
2639
|
const number = isSuffix ? parts[0] : parts?.[1] ?? parts?.[0];
|
|
2413
2640
|
const suffix = isSuffix ? parts[1] : null;
|
|
2414
|
-
return /* @__PURE__ */
|
|
2415
|
-
/* @__PURE__ */
|
|
2416
|
-
/* @__PURE__ */
|
|
2417
|
-
Icon2 && /* @__PURE__ */
|
|
2641
|
+
return /* @__PURE__ */ jsxs21("div", { "data-testid": testId, style: bgStyle, className: "rounded-xl border border-border bg-card p-5", children: [
|
|
2642
|
+
/* @__PURE__ */ jsxs21("div", { className: rowBetween, children: [
|
|
2643
|
+
/* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
|
|
2644
|
+
Icon2 && /* @__PURE__ */ jsx38("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/8 text-primary", children: /* @__PURE__ */ jsx38(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) })
|
|
2418
2645
|
] }),
|
|
2419
|
-
/* @__PURE__ */
|
|
2420
|
-
loading ? /* @__PURE__ */
|
|
2421
|
-
prefix && /* @__PURE__ */
|
|
2646
|
+
/* @__PURE__ */ jsxs21("div", { className: "mt-3", children: [
|
|
2647
|
+
loading ? /* @__PURE__ */ jsx38(Skeleton, { className: "h-7 w-20" }) : value == null ? /* @__PURE__ */ jsx38("span", { className: "text-2xl font-black text-muted-foreground/40", children: "\u2014" }) : plain ? /* @__PURE__ */ jsx38("span", { className: "animate-in text-2xl font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none", children: strValue }) : /* @__PURE__ */ jsxs21("span", { className: "animate-in font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none", children: [
|
|
2648
|
+
prefix && /* @__PURE__ */ jsxs21("span", { className: "text-sm text-muted-foreground", children: [
|
|
2422
2649
|
prefix,
|
|
2423
2650
|
" "
|
|
2424
2651
|
] }),
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
suffix && /* @__PURE__ */
|
|
2652
|
+
/* @__PURE__ */ jsx38("span", { className: "text-2xl", children: number }),
|
|
2653
|
+
suffix && /* @__PURE__ */ jsxs21("span", { className: "text-sm text-muted-foreground", children: [
|
|
2427
2654
|
" ",
|
|
2428
2655
|
suffix
|
|
2429
2656
|
] })
|
|
2430
2657
|
] }),
|
|
2431
|
-
sub && !loading && /* @__PURE__ */
|
|
2658
|
+
sub && !loading && /* @__PURE__ */ jsx38("p", { className: "mt-0.5 text-[11px] text-muted-foreground tabular-nums", children: sub })
|
|
2432
2659
|
] }),
|
|
2433
|
-
(badge || badgeLabel || sparkline) && !loading && /* @__PURE__ */
|
|
2434
|
-
/* @__PURE__ */
|
|
2435
|
-
badge && /* @__PURE__ */
|
|
2660
|
+
(badge || badgeLabel || sparkline) && !loading && /* @__PURE__ */ jsxs21("div", { className: "mt-2.5 flex items-end justify-between gap-2", children: [
|
|
2661
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2662
|
+
badge && /* @__PURE__ */ jsx38(
|
|
2436
2663
|
"span",
|
|
2437
2664
|
{
|
|
2438
2665
|
className: cn(
|
|
@@ -2442,20 +2669,23 @@ var KpiCard = memo(function KpiCard2({
|
|
|
2442
2669
|
children: badge.text
|
|
2443
2670
|
}
|
|
2444
2671
|
),
|
|
2445
|
-
badgeLabel && /* @__PURE__ */
|
|
2672
|
+
badgeLabel && /* @__PURE__ */ jsx38("span", { className: "text-[11px] text-muted-foreground", children: badgeLabel })
|
|
2446
2673
|
] }),
|
|
2447
|
-
sparkline && /* @__PURE__ */
|
|
2674
|
+
sparkline && /* @__PURE__ */ jsx38(Sparkline, { data: sparkline, color: sparklineColor })
|
|
2448
2675
|
] })
|
|
2449
2676
|
] });
|
|
2450
2677
|
});
|
|
2451
2678
|
|
|
2452
2679
|
// src/patterns/search-panel/SearchPanel.tsx
|
|
2453
|
-
import {
|
|
2454
|
-
import { jsx as
|
|
2680
|
+
import { ExclamationTriangleIcon as ExclamationTriangleIcon5, MagnifyingGlassIcon as MagnifyingGlassIcon2 } from "@heroicons/react/24/outline";
|
|
2681
|
+
import { jsx as jsx39, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2455
2682
|
function SearchPanel({
|
|
2456
2683
|
value,
|
|
2457
2684
|
onChange,
|
|
2685
|
+
loading,
|
|
2458
2686
|
isLoading,
|
|
2687
|
+
error,
|
|
2688
|
+
onRetry,
|
|
2459
2689
|
trailingSlot,
|
|
2460
2690
|
shortcutHint,
|
|
2461
2691
|
modes,
|
|
@@ -2466,7 +2696,9 @@ function SearchPanel({
|
|
|
2466
2696
|
className,
|
|
2467
2697
|
...props
|
|
2468
2698
|
}) {
|
|
2469
|
-
|
|
2699
|
+
const busy = loading ?? isLoading;
|
|
2700
|
+
const hasError = toErrorInfo(error) !== void 0;
|
|
2701
|
+
return /* @__PURE__ */ jsxs22(
|
|
2470
2702
|
"div",
|
|
2471
2703
|
{
|
|
2472
2704
|
className: cn(
|
|
@@ -2475,9 +2707,9 @@ function SearchPanel({
|
|
|
2475
2707
|
className
|
|
2476
2708
|
),
|
|
2477
2709
|
children: [
|
|
2478
|
-
/* @__PURE__ */
|
|
2479
|
-
|
|
2480
|
-
/* @__PURE__ */
|
|
2710
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex h-14 items-center gap-3 px-4", children: [
|
|
2711
|
+
busy ? /* @__PURE__ */ jsx39(LoadingSpinner, { size: "sm" }) : hasError ? /* @__PURE__ */ jsx39(ExclamationTriangleIcon5, { className: "h-5 w-5 shrink-0 text-destructive", "aria-hidden": "true" }) : /* @__PURE__ */ jsx39(MagnifyingGlassIcon2, { className: "h-5 w-5 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
|
|
2712
|
+
/* @__PURE__ */ jsx39(
|
|
2481
2713
|
"input",
|
|
2482
2714
|
{
|
|
2483
2715
|
ref: inputRef,
|
|
@@ -2489,7 +2721,7 @@ function SearchPanel({
|
|
|
2489
2721
|
}
|
|
2490
2722
|
),
|
|
2491
2723
|
trailingSlot,
|
|
2492
|
-
shortcutHint && /* @__PURE__ */
|
|
2724
|
+
shortcutHint && /* @__PURE__ */ jsx39(
|
|
2493
2725
|
"kbd",
|
|
2494
2726
|
{
|
|
2495
2727
|
"aria-hidden": "true",
|
|
@@ -2498,7 +2730,8 @@ function SearchPanel({
|
|
|
2498
2730
|
}
|
|
2499
2731
|
)
|
|
2500
2732
|
] }),
|
|
2501
|
-
|
|
2733
|
+
hasError && /* @__PURE__ */ jsx39("div", { className: "px-4 pb-3", children: /* @__PURE__ */ jsx39(InlineError, { error, onRetry }) }),
|
|
2734
|
+
modes && modes.length > 0 && /* @__PURE__ */ jsx39("div", { className: "flex items-center gap-2 px-4 pb-3", children: modes.map(({ key, label, icon: Icon2 }) => /* @__PURE__ */ jsxs22(
|
|
2502
2735
|
"button",
|
|
2503
2736
|
{
|
|
2504
2737
|
type: "button",
|
|
@@ -2508,7 +2741,7 @@ function SearchPanel({
|
|
|
2508
2741
|
activeMode === key ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"
|
|
2509
2742
|
),
|
|
2510
2743
|
children: [
|
|
2511
|
-
Icon2 && /* @__PURE__ */
|
|
2744
|
+
Icon2 && /* @__PURE__ */ jsx39(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
2512
2745
|
label
|
|
2513
2746
|
]
|
|
2514
2747
|
},
|
|
@@ -2520,10 +2753,10 @@ function SearchPanel({
|
|
|
2520
2753
|
}
|
|
2521
2754
|
|
|
2522
2755
|
// src/patterns/search-panel/SearchTrigger.tsx
|
|
2523
|
-
import {
|
|
2524
|
-
import { jsx as
|
|
2756
|
+
import { MagnifyingGlassIcon as MagnifyingGlassIcon3 } from "@heroicons/react/24/outline";
|
|
2757
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
2525
2758
|
function SearchTrigger({ label = "Search", ...props }) {
|
|
2526
|
-
return /* @__PURE__ */
|
|
2759
|
+
return /* @__PURE__ */ jsx40(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": label, ...props, children: /* @__PURE__ */ jsx40(MagnifyingGlassIcon3, { className: "h-[18px] w-[18px]", "aria-hidden": "true" }) });
|
|
2527
2760
|
}
|
|
2528
2761
|
|
|
2529
2762
|
// src/patterns/sidebar/context.ts
|
|
@@ -2535,7 +2768,7 @@ function useSidebarCollapsed() {
|
|
|
2535
2768
|
}
|
|
2536
2769
|
|
|
2537
2770
|
// src/patterns/sidebar/NavItem.tsx
|
|
2538
|
-
import { jsx as
|
|
2771
|
+
import { jsx as jsx41, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2539
2772
|
function NavItem({
|
|
2540
2773
|
as,
|
|
2541
2774
|
icon: Icon2,
|
|
@@ -2547,7 +2780,7 @@ function NavItem({
|
|
|
2547
2780
|
}) {
|
|
2548
2781
|
const collapsed = useSidebarCollapsed();
|
|
2549
2782
|
const Comp = as ?? "a";
|
|
2550
|
-
const row = /* @__PURE__ */
|
|
2783
|
+
const row = /* @__PURE__ */ jsxs23(
|
|
2551
2784
|
Comp,
|
|
2552
2785
|
{
|
|
2553
2786
|
className: cn(
|
|
@@ -2559,7 +2792,7 @@ function NavItem({
|
|
|
2559
2792
|
),
|
|
2560
2793
|
...rest,
|
|
2561
2794
|
children: [
|
|
2562
|
-
Icon2 && /* @__PURE__ */
|
|
2795
|
+
Icon2 && /* @__PURE__ */ jsx41(
|
|
2563
2796
|
Icon2,
|
|
2564
2797
|
{
|
|
2565
2798
|
className: cn("h-[18px] w-[18px] shrink-0", active ? "text-nav-primary" : "text-muted-foreground"),
|
|
@@ -2567,7 +2800,7 @@ function NavItem({
|
|
|
2567
2800
|
"aria-hidden": true
|
|
2568
2801
|
}
|
|
2569
2802
|
),
|
|
2570
|
-
/* @__PURE__ */
|
|
2803
|
+
/* @__PURE__ */ jsx41(
|
|
2571
2804
|
"span",
|
|
2572
2805
|
{
|
|
2573
2806
|
className: cn(
|
|
@@ -2582,9 +2815,9 @@ function NavItem({
|
|
|
2582
2815
|
}
|
|
2583
2816
|
);
|
|
2584
2817
|
if (!collapsed) return row;
|
|
2585
|
-
return /* @__PURE__ */
|
|
2586
|
-
/* @__PURE__ */
|
|
2587
|
-
/* @__PURE__ */
|
|
2818
|
+
return /* @__PURE__ */ jsxs23(Tooltip, { children: [
|
|
2819
|
+
/* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: row }),
|
|
2820
|
+
/* @__PURE__ */ jsxs23(TooltipContent, { side: "right", className: "flex items-center gap-1.5", children: [
|
|
2588
2821
|
label,
|
|
2589
2822
|
badge
|
|
2590
2823
|
] })
|
|
@@ -2592,9 +2825,9 @@ function NavItem({
|
|
|
2592
2825
|
}
|
|
2593
2826
|
|
|
2594
2827
|
// src/patterns/sidebar/NavGroup.tsx
|
|
2595
|
-
import {
|
|
2596
|
-
import { useState as
|
|
2597
|
-
import { jsx as
|
|
2828
|
+
import { ChevronDownIcon as ChevronDownIcon2 } from "@heroicons/react/24/outline";
|
|
2829
|
+
import { useState as useState11 } from "react";
|
|
2830
|
+
import { jsx as jsx42, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2598
2831
|
function NavGroup({
|
|
2599
2832
|
label,
|
|
2600
2833
|
defaultCollapsed = false,
|
|
@@ -2603,15 +2836,15 @@ function NavGroup({
|
|
|
2603
2836
|
children,
|
|
2604
2837
|
className
|
|
2605
2838
|
}) {
|
|
2606
|
-
const [internalCollapsed, setInternalCollapsed] =
|
|
2839
|
+
const [internalCollapsed, setInternalCollapsed] = useState11(defaultCollapsed);
|
|
2607
2840
|
const groupCollapsed = collapsed ?? internalCollapsed;
|
|
2608
2841
|
const railCollapsed = useSidebarCollapsed();
|
|
2609
2842
|
const setGroupCollapsed = (next) => {
|
|
2610
2843
|
onCollapsedChange?.(next);
|
|
2611
2844
|
if (collapsed === void 0) setInternalCollapsed(next);
|
|
2612
2845
|
};
|
|
2613
|
-
return /* @__PURE__ */
|
|
2614
|
-
label && (railCollapsed ? /* @__PURE__ */
|
|
2846
|
+
return /* @__PURE__ */ jsxs24("div", { className: cn("flex flex-col gap-0.5", className), children: [
|
|
2847
|
+
label && (railCollapsed ? /* @__PURE__ */ jsx42("div", { className: "mx-2 my-1 h-px bg-border/50", "aria-hidden": true }) : /* @__PURE__ */ jsxs24(
|
|
2615
2848
|
"button",
|
|
2616
2849
|
{
|
|
2617
2850
|
type: "button",
|
|
@@ -2619,9 +2852,9 @@ function NavGroup({
|
|
|
2619
2852
|
"aria-expanded": !groupCollapsed,
|
|
2620
2853
|
className: "group flex w-full items-center justify-between px-2.5 py-0.5 text-[11px] font-medium text-muted-foreground/80 hover:text-foreground",
|
|
2621
2854
|
children: [
|
|
2622
|
-
/* @__PURE__ */
|
|
2623
|
-
/* @__PURE__ */
|
|
2624
|
-
|
|
2855
|
+
/* @__PURE__ */ jsx42("span", { children: label }),
|
|
2856
|
+
/* @__PURE__ */ jsx42(
|
|
2857
|
+
ChevronDownIcon2,
|
|
2625
2858
|
{
|
|
2626
2859
|
className: cn(
|
|
2627
2860
|
"h-4 w-4 opacity-40 transition-transform group-hover:opacity-100",
|
|
@@ -2633,19 +2866,19 @@ function NavGroup({
|
|
|
2633
2866
|
]
|
|
2634
2867
|
}
|
|
2635
2868
|
)),
|
|
2636
|
-
!groupCollapsed && /* @__PURE__ */
|
|
2869
|
+
!groupCollapsed && /* @__PURE__ */ jsx42("div", { className: "flex flex-col gap-0.5", children })
|
|
2637
2870
|
] });
|
|
2638
2871
|
}
|
|
2639
2872
|
|
|
2640
2873
|
// src/patterns/sidebar/Sidebar.tsx
|
|
2641
|
-
import {
|
|
2874
|
+
import { ChevronDoubleLeftIcon, ChevronDoubleRightIcon } from "@heroicons/react/24/outline";
|
|
2642
2875
|
import {
|
|
2643
2876
|
useCallback as useCallback2,
|
|
2644
|
-
useEffect as
|
|
2877
|
+
useEffect as useEffect6,
|
|
2645
2878
|
useRef as useRef6,
|
|
2646
|
-
useState as
|
|
2879
|
+
useState as useState12
|
|
2647
2880
|
} from "react";
|
|
2648
|
-
import { Fragment as
|
|
2881
|
+
import { Fragment as Fragment5, jsx as jsx43, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2649
2882
|
function resolve(value, collapsed) {
|
|
2650
2883
|
return typeof value === "function" ? value(collapsed) : value;
|
|
2651
2884
|
}
|
|
@@ -2664,9 +2897,9 @@ function Sidebar({
|
|
|
2664
2897
|
children,
|
|
2665
2898
|
className
|
|
2666
2899
|
}) {
|
|
2667
|
-
const [internalWidth, setInternalWidth] =
|
|
2900
|
+
const [internalWidth, setInternalWidth] = useState12(defaultWidth);
|
|
2668
2901
|
const currentWidth = width ?? internalWidth;
|
|
2669
|
-
const [isDragging, setIsDragging] =
|
|
2902
|
+
const [isDragging, setIsDragging] = useState12(false);
|
|
2670
2903
|
const setWidth = useCallback2(
|
|
2671
2904
|
(next) => {
|
|
2672
2905
|
const clamped = Math.min(maxWidth, Math.max(minWidth, next));
|
|
@@ -2692,7 +2925,7 @@ function Sidebar({
|
|
|
2692
2925
|
dragStartRef.current = null;
|
|
2693
2926
|
setIsDragging(false);
|
|
2694
2927
|
};
|
|
2695
|
-
return /* @__PURE__ */
|
|
2928
|
+
return /* @__PURE__ */ jsx43(SidebarContextProvider, { value: { collapsed }, children: /* @__PURE__ */ jsx43(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs25(
|
|
2696
2929
|
"aside",
|
|
2697
2930
|
{
|
|
2698
2931
|
style: { width: collapsed ? railWidth : currentWidth },
|
|
@@ -2702,13 +2935,13 @@ function Sidebar({
|
|
|
2702
2935
|
className
|
|
2703
2936
|
),
|
|
2704
2937
|
children: [
|
|
2705
|
-
(header || onCollapsedChange) && /* @__PURE__ */
|
|
2938
|
+
(header || onCollapsedChange) && /* @__PURE__ */ jsx43("div", { className: "flex h-16 items-center gap-2 border-b border-border px-3", children: collapsed && onCollapsedChange ? (
|
|
2706
2939
|
// Collapsed rail: the header slot (e.g. a compact logo mark) and the
|
|
2707
2940
|
// expand toggle would otherwise compete for the narrow rail's width
|
|
2708
2941
|
// and clip each other, so they're stacked instead — the header shows
|
|
2709
2942
|
// by default and cross-fades to the toggle icon on hover, matching
|
|
2710
2943
|
// the same affordance OneSales' own sidebar rail uses.
|
|
2711
|
-
/* @__PURE__ */
|
|
2944
|
+
/* @__PURE__ */ jsxs25(
|
|
2712
2945
|
"button",
|
|
2713
2946
|
{
|
|
2714
2947
|
type: "button",
|
|
@@ -2716,9 +2949,9 @@ function Sidebar({
|
|
|
2716
2949
|
"aria-label": "Expand sidebar",
|
|
2717
2950
|
className: "group relative flex h-9 w-9 shrink-0 items-center justify-center",
|
|
2718
2951
|
children: [
|
|
2719
|
-
header && /* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
2721
|
-
|
|
2952
|
+
header && /* @__PURE__ */ jsx43("span", { className: "transition-opacity group-hover:opacity-0", children: resolve(header, collapsed) }),
|
|
2953
|
+
/* @__PURE__ */ jsx43(
|
|
2954
|
+
ChevronDoubleRightIcon,
|
|
2722
2955
|
{
|
|
2723
2956
|
className: "absolute h-4 w-4 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100",
|
|
2724
2957
|
"aria-hidden": true
|
|
@@ -2727,22 +2960,22 @@ function Sidebar({
|
|
|
2727
2960
|
]
|
|
2728
2961
|
}
|
|
2729
2962
|
)
|
|
2730
|
-
) : /* @__PURE__ */
|
|
2731
|
-
header && /* @__PURE__ */
|
|
2732
|
-
onCollapsedChange && /* @__PURE__ */
|
|
2963
|
+
) : /* @__PURE__ */ jsxs25(Fragment5, { children: [
|
|
2964
|
+
header && /* @__PURE__ */ jsx43("div", { className: "min-w-0 flex-1", children: resolve(header, collapsed) }),
|
|
2965
|
+
onCollapsedChange && /* @__PURE__ */ jsx43(
|
|
2733
2966
|
"button",
|
|
2734
2967
|
{
|
|
2735
2968
|
type: "button",
|
|
2736
2969
|
onClick: () => onCollapsedChange(!collapsed),
|
|
2737
2970
|
"aria-label": "Collapse sidebar",
|
|
2738
2971
|
className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2739
|
-
children: /* @__PURE__ */
|
|
2972
|
+
children: /* @__PURE__ */ jsx43(ChevronDoubleLeftIcon, { className: "h-4 w-4", "aria-hidden": true })
|
|
2740
2973
|
}
|
|
2741
2974
|
)
|
|
2742
2975
|
] }) }),
|
|
2743
|
-
/* @__PURE__ */
|
|
2744
|
-
footer && /* @__PURE__ */
|
|
2745
|
-
resizable && !collapsed && /* @__PURE__ */
|
|
2976
|
+
/* @__PURE__ */ jsx43(SidebarNav, { children }),
|
|
2977
|
+
footer && /* @__PURE__ */ jsx43("div", { className: "border-t border-border/50 px-2 py-2", children: resolve(footer, collapsed) }),
|
|
2978
|
+
resizable && !collapsed && /* @__PURE__ */ jsx43(
|
|
2746
2979
|
"div",
|
|
2747
2980
|
{
|
|
2748
2981
|
onPointerDown: handlePointerDown,
|
|
@@ -2758,8 +2991,8 @@ function Sidebar({
|
|
|
2758
2991
|
}
|
|
2759
2992
|
function SidebarNav({ children, className, ...rest }) {
|
|
2760
2993
|
const ref = useRef6(null);
|
|
2761
|
-
const [showFade, setShowFade] =
|
|
2762
|
-
|
|
2994
|
+
const [showFade, setShowFade] = useState12(false);
|
|
2995
|
+
useEffect6(() => {
|
|
2763
2996
|
const el = ref.current;
|
|
2764
2997
|
if (!el) return;
|
|
2765
2998
|
const update = () => setShowFade(el.scrollHeight - el.scrollTop - el.clientHeight > 1);
|
|
@@ -2772,8 +3005,8 @@ function SidebarNav({ children, className, ...rest }) {
|
|
|
2772
3005
|
observer.disconnect();
|
|
2773
3006
|
};
|
|
2774
3007
|
}, []);
|
|
2775
|
-
return /* @__PURE__ */
|
|
2776
|
-
/* @__PURE__ */
|
|
3008
|
+
return /* @__PURE__ */ jsxs25("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [
|
|
3009
|
+
/* @__PURE__ */ jsx43(
|
|
2777
3010
|
"div",
|
|
2778
3011
|
{
|
|
2779
3012
|
ref,
|
|
@@ -2782,7 +3015,7 @@ function SidebarNav({ children, className, ...rest }) {
|
|
|
2782
3015
|
children
|
|
2783
3016
|
}
|
|
2784
3017
|
),
|
|
2785
|
-
showFade && /* @__PURE__ */
|
|
3018
|
+
showFade && /* @__PURE__ */ jsx43(
|
|
2786
3019
|
"div",
|
|
2787
3020
|
{
|
|
2788
3021
|
className: "pointer-events-none absolute right-0 bottom-0 left-0 h-6 bg-gradient-to-t from-sidebar to-transparent",
|
|
@@ -2793,11 +3026,11 @@ function SidebarNav({ children, className, ...rest }) {
|
|
|
2793
3026
|
}
|
|
2794
3027
|
|
|
2795
3028
|
// src/patterns/ai/AiButton.tsx
|
|
2796
|
-
import {
|
|
3029
|
+
import { SparklesIcon } from "@heroicons/react/24/outline";
|
|
2797
3030
|
import { forwardRef as forwardRef17 } from "react";
|
|
2798
|
-
import { jsx as
|
|
3031
|
+
import { jsx as jsx44, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2799
3032
|
var AiButton = forwardRef17(
|
|
2800
|
-
({ variant = "ai-subtle", loading = false, icon: Icon2 =
|
|
3033
|
+
({ variant = "ai-subtle", loading = false, icon: Icon2 = SparklesIcon, disabled, children, ...props }, ref) => /* @__PURE__ */ jsxs26(
|
|
2801
3034
|
Button,
|
|
2802
3035
|
{
|
|
2803
3036
|
ref,
|
|
@@ -2806,7 +3039,7 @@ var AiButton = forwardRef17(
|
|
|
2806
3039
|
"aria-busy": loading || void 0,
|
|
2807
3040
|
...props,
|
|
2808
3041
|
children: [
|
|
2809
|
-
loading ? /* @__PURE__ */
|
|
3042
|
+
loading ? /* @__PURE__ */ jsx44(LoadingSpinner, { size: "sm", className: "[&_svg]:text-current" }) : /* @__PURE__ */ jsx44(Icon2, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
2810
3043
|
children
|
|
2811
3044
|
]
|
|
2812
3045
|
}
|
|
@@ -2815,9 +3048,9 @@ var AiButton = forwardRef17(
|
|
|
2815
3048
|
AiButton.displayName = "AiButton";
|
|
2816
3049
|
|
|
2817
3050
|
// src/patterns/ai/AiExplainButton.tsx
|
|
2818
|
-
import {
|
|
2819
|
-
import { useState as
|
|
2820
|
-
import { jsx as
|
|
3051
|
+
import { SparklesIcon as SparklesIcon2 } from "@heroicons/react/24/outline";
|
|
3052
|
+
import { useState as useState13 } from "react";
|
|
3053
|
+
import { jsx as jsx45, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2821
3054
|
function AiExplainButton({
|
|
2822
3055
|
onExplain,
|
|
2823
3056
|
label = "Explain",
|
|
@@ -2827,10 +3060,10 @@ function AiExplainButton({
|
|
|
2827
3060
|
size = "sm",
|
|
2828
3061
|
...props
|
|
2829
3062
|
}) {
|
|
2830
|
-
const [open, setOpen] =
|
|
2831
|
-
const [loading, setLoading] =
|
|
2832
|
-
const [content, setContent] =
|
|
2833
|
-
const [error, setError] =
|
|
3063
|
+
const [open, setOpen] = useState13(false);
|
|
3064
|
+
const [loading, setLoading] = useState13(false);
|
|
3065
|
+
const [content, setContent] = useState13(null);
|
|
3066
|
+
const [error, setError] = useState13(null);
|
|
2834
3067
|
const load = async () => {
|
|
2835
3068
|
setLoading(true);
|
|
2836
3069
|
setError(null);
|
|
@@ -2846,30 +3079,32 @@ function AiExplainButton({
|
|
|
2846
3079
|
setOpen(next);
|
|
2847
3080
|
if (next && content === null && error === null && !loading) void load();
|
|
2848
3081
|
};
|
|
2849
|
-
return /* @__PURE__ */
|
|
2850
|
-
/* @__PURE__ */
|
|
2851
|
-
/* @__PURE__ */
|
|
2852
|
-
/* @__PURE__ */
|
|
2853
|
-
/* @__PURE__ */
|
|
3082
|
+
return /* @__PURE__ */ jsxs27(Popover, { open, onOpenChange: handleOpenChange, children: [
|
|
3083
|
+
/* @__PURE__ */ jsx45(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx45(AiButton, { size, ...props, children: label }) }),
|
|
3084
|
+
/* @__PURE__ */ jsxs27(PopoverContent, { align, className: contentClassName, children: [
|
|
3085
|
+
/* @__PURE__ */ jsxs27("p", { className: "mb-2 flex items-center gap-1.5 text-sm font-semibold", children: [
|
|
3086
|
+
/* @__PURE__ */ jsx45(SparklesIcon2, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
|
|
2854
3087
|
title ?? label
|
|
2855
3088
|
] }),
|
|
2856
|
-
loading ? /* @__PURE__ */
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
3089
|
+
loading ? /* @__PURE__ */ jsx45(LoadingSpinner, { size: "sm", label: "Thinking\u2026", className: "text-sm text-muted-foreground" }) : error ? /* @__PURE__ */ jsx45(
|
|
3090
|
+
ErrorState,
|
|
3091
|
+
{
|
|
3092
|
+
variant: "compact",
|
|
3093
|
+
error,
|
|
3094
|
+
onRetry: () => void load(),
|
|
3095
|
+
labels: { title: "Something went wrong", retry: "Try again" }
|
|
3096
|
+
}
|
|
3097
|
+
) : /* @__PURE__ */ jsx45("div", { className: "max-h-80 overflow-y-auto text-sm leading-relaxed", children: content })
|
|
2863
3098
|
] })
|
|
2864
3099
|
] });
|
|
2865
3100
|
}
|
|
2866
3101
|
|
|
2867
3102
|
// src/patterns/ai/VoiceInputButton.tsx
|
|
2868
|
-
import {
|
|
3103
|
+
import { MicrophoneIcon, SlashIcon } from "@heroicons/react/24/outline";
|
|
2869
3104
|
import { forwardRef as forwardRef18 } from "react";
|
|
2870
3105
|
|
|
2871
3106
|
// src/patterns/ai/useSpeechRecognition.ts
|
|
2872
|
-
import { useCallback as useCallback3, useEffect as
|
|
3107
|
+
import { useCallback as useCallback3, useEffect as useEffect7, useRef as useRef7, useState as useState14 } from "react";
|
|
2873
3108
|
function getCtor() {
|
|
2874
3109
|
if (typeof window === "undefined") return void 0;
|
|
2875
3110
|
const w = window;
|
|
@@ -2902,9 +3137,9 @@ function useSpeechRecognition({
|
|
|
2902
3137
|
onError,
|
|
2903
3138
|
engine
|
|
2904
3139
|
} = {}) {
|
|
2905
|
-
const [listening, setListening] =
|
|
2906
|
-
const [interim, setInterim] =
|
|
2907
|
-
const [error, setError] =
|
|
3140
|
+
const [listening, setListening] = useState14(false);
|
|
3141
|
+
const [interim, setInterim] = useState14("");
|
|
3142
|
+
const [error, setError] = useState14(null);
|
|
2908
3143
|
const recognitionRef = useRef7(null);
|
|
2909
3144
|
const onResultRef = useRef7(onResult);
|
|
2910
3145
|
const onErrorRef = useRef7(onError);
|
|
@@ -2953,12 +3188,12 @@ function useSpeechRecognition({
|
|
|
2953
3188
|
if (recognitionRef.current) stop();
|
|
2954
3189
|
else start();
|
|
2955
3190
|
}, [start, stop]);
|
|
2956
|
-
|
|
3191
|
+
useEffect7(() => () => recognitionRef.current?.abort(), []);
|
|
2957
3192
|
return { supported, listening, interim, error, start, stop, toggle };
|
|
2958
3193
|
}
|
|
2959
3194
|
|
|
2960
3195
|
// src/patterns/ai/VoiceInputButton.tsx
|
|
2961
|
-
import { jsx as
|
|
3196
|
+
import { jsx as jsx46, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2962
3197
|
var VoiceInputButton = forwardRef18(
|
|
2963
3198
|
({
|
|
2964
3199
|
onTranscript,
|
|
@@ -2984,8 +3219,8 @@ var VoiceInputButton = forwardRef18(
|
|
|
2984
3219
|
return (
|
|
2985
3220
|
// `title` lives on the wrapper, not the button: buttonVariants sets
|
|
2986
3221
|
// `disabled:pointer-events-none`, so a disabled button never shows its own.
|
|
2987
|
-
/* @__PURE__ */
|
|
2988
|
-
/* @__PURE__ */
|
|
3222
|
+
/* @__PURE__ */ jsxs28("span", { className: "inline-flex min-w-0 items-center gap-2", title: supported ? void 0 : unsupportedTitle, children: [
|
|
3223
|
+
/* @__PURE__ */ jsxs28(
|
|
2989
3224
|
Button,
|
|
2990
3225
|
{
|
|
2991
3226
|
ref,
|
|
@@ -3002,12 +3237,25 @@ var VoiceInputButton = forwardRef18(
|
|
|
3002
3237
|
),
|
|
3003
3238
|
...props,
|
|
3004
3239
|
children: [
|
|
3005
|
-
supported ? /* @__PURE__ */
|
|
3240
|
+
supported ? /* @__PURE__ */ jsx46(
|
|
3241
|
+
MicrophoneIcon,
|
|
3242
|
+
{
|
|
3243
|
+
className: cn("h-4 w-4", listening && "animate-pulse motion-reduce:animate-none"),
|
|
3244
|
+
"aria-hidden": "true"
|
|
3245
|
+
}
|
|
3246
|
+
) : (
|
|
3247
|
+
// heroicons has no muted-mic glyph -- MicrophoneIcon plus SlashIcon
|
|
3248
|
+
// (same 24x24 viewBox/stroke) layered on top approximates one.
|
|
3249
|
+
/* @__PURE__ */ jsxs28("span", { className: "relative inline-flex h-4 w-4", "aria-hidden": "true", children: [
|
|
3250
|
+
/* @__PURE__ */ jsx46(MicrophoneIcon, { className: "h-4 w-4" }),
|
|
3251
|
+
/* @__PURE__ */ jsx46(SlashIcon, { className: "absolute inset-0 h-4 w-4" })
|
|
3252
|
+
] })
|
|
3253
|
+
),
|
|
3006
3254
|
label
|
|
3007
3255
|
]
|
|
3008
3256
|
}
|
|
3009
3257
|
),
|
|
3010
|
-
showInterim && interim ? /* @__PURE__ */
|
|
3258
|
+
showInterim && interim ? /* @__PURE__ */ jsx46("span", { "aria-live": "polite", className: "truncate text-sm text-muted-foreground italic", children: interim }) : null
|
|
3011
3259
|
] })
|
|
3012
3260
|
);
|
|
3013
3261
|
}
|
|
@@ -3015,9 +3263,9 @@ var VoiceInputButton = forwardRef18(
|
|
|
3015
3263
|
VoiceInputButton.displayName = "VoiceInputButton";
|
|
3016
3264
|
|
|
3017
3265
|
// src/patterns/ai/VoiceTranscript.tsx
|
|
3018
|
-
import {
|
|
3019
|
-
import { useState as
|
|
3020
|
-
import { jsx as
|
|
3266
|
+
import { ArrowUturnLeftIcon, SparklesIcon as SparklesIcon3 } from "@heroicons/react/24/outline";
|
|
3267
|
+
import { useState as useState15 } from "react";
|
|
3268
|
+
import { jsx as jsx47, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
3021
3269
|
function VoiceTranscript({
|
|
3022
3270
|
value,
|
|
3023
3271
|
onChange,
|
|
@@ -3031,9 +3279,9 @@ function VoiceTranscript({
|
|
|
3031
3279
|
className,
|
|
3032
3280
|
...props
|
|
3033
3281
|
}) {
|
|
3034
|
-
const [loading, setLoading] =
|
|
3035
|
-
const [error, setError] =
|
|
3036
|
-
const [previous, setPrevious] =
|
|
3282
|
+
const [loading, setLoading] = useState15(false);
|
|
3283
|
+
const [error, setError] = useState15(null);
|
|
3284
|
+
const [previous, setPrevious] = useState15(null);
|
|
3037
3285
|
const append = (chunk) => {
|
|
3038
3286
|
onChange(value ? `${value.trimEnd()} ${chunk}` : chunk);
|
|
3039
3287
|
};
|
|
@@ -3057,8 +3305,8 @@ function VoiceTranscript({
|
|
|
3057
3305
|
onChange(previous);
|
|
3058
3306
|
setPrevious(null);
|
|
3059
3307
|
};
|
|
3060
|
-
return /* @__PURE__ */
|
|
3061
|
-
/* @__PURE__ */
|
|
3308
|
+
return /* @__PURE__ */ jsxs29("div", { className: cn("flex flex-col gap-2", className), ...props, children: [
|
|
3309
|
+
/* @__PURE__ */ jsx47(
|
|
3062
3310
|
Textarea,
|
|
3063
3311
|
{
|
|
3064
3312
|
value,
|
|
@@ -3069,8 +3317,8 @@ function VoiceTranscript({
|
|
|
3069
3317
|
"aria-busy": loading || void 0
|
|
3070
3318
|
}
|
|
3071
3319
|
),
|
|
3072
|
-
/* @__PURE__ */
|
|
3073
|
-
/* @__PURE__ */
|
|
3320
|
+
/* @__PURE__ */ jsxs29("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
3321
|
+
/* @__PURE__ */ jsx47(
|
|
3074
3322
|
VoiceInputButton,
|
|
3075
3323
|
{
|
|
3076
3324
|
onTranscript: append,
|
|
@@ -3083,35 +3331,35 @@ function VoiceTranscript({
|
|
|
3083
3331
|
disabled: disabled || loading
|
|
3084
3332
|
}
|
|
3085
3333
|
),
|
|
3086
|
-
onTransform ? /* @__PURE__ */
|
|
3334
|
+
onTransform ? /* @__PURE__ */ jsx47(
|
|
3087
3335
|
AiButton,
|
|
3088
3336
|
{
|
|
3089
3337
|
variant: "ai",
|
|
3090
3338
|
size: "sm",
|
|
3091
|
-
icon:
|
|
3339
|
+
icon: SparklesIcon3,
|
|
3092
3340
|
loading,
|
|
3093
3341
|
disabled: disabled || value.trim().length === 0,
|
|
3094
3342
|
onClick: () => void transform(),
|
|
3095
3343
|
children: transformLabel
|
|
3096
3344
|
}
|
|
3097
3345
|
) : null,
|
|
3098
|
-
previous !== null && !loading ? /* @__PURE__ */
|
|
3099
|
-
/* @__PURE__ */
|
|
3346
|
+
previous !== null && !loading ? /* @__PURE__ */ jsxs29(Button, { type: "button", variant: "ghost", size: "sm", onClick: undo, children: [
|
|
3347
|
+
/* @__PURE__ */ jsx47(ArrowUturnLeftIcon, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
3100
3348
|
"Undo"
|
|
3101
3349
|
] }) : null
|
|
3102
3350
|
] }),
|
|
3103
3351
|
error ? (
|
|
3104
3352
|
// AlertBox has no `role` prop, so the live region wraps it; same shape
|
|
3105
3353
|
// a consuming app's own form errors take.
|
|
3106
|
-
/* @__PURE__ */
|
|
3354
|
+
/* @__PURE__ */ jsx47("div", { role: "alert", children: /* @__PURE__ */ jsx47(AlertBox, { variant: "error", children: error }) })
|
|
3107
3355
|
) : null
|
|
3108
3356
|
] });
|
|
3109
3357
|
}
|
|
3110
3358
|
|
|
3111
3359
|
// src/patterns/stepper/Stepper.tsx
|
|
3112
|
-
import { useEffect as
|
|
3113
|
-
import {
|
|
3114
|
-
import { jsx as
|
|
3360
|
+
import { useEffect as useEffect8, useRef as useRef8 } from "react";
|
|
3361
|
+
import { CheckIcon as CheckIcon5, PlusIcon } from "@heroicons/react/24/outline";
|
|
3362
|
+
import { jsx as jsx48, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
3115
3363
|
function Stepper({
|
|
3116
3364
|
step,
|
|
3117
3365
|
maxStep,
|
|
@@ -3124,7 +3372,7 @@ function Stepper({
|
|
|
3124
3372
|
newTestId
|
|
3125
3373
|
}) {
|
|
3126
3374
|
const stepRefs = useRef8(/* @__PURE__ */ new Map());
|
|
3127
|
-
|
|
3375
|
+
useEffect8(() => {
|
|
3128
3376
|
const activeStep = stepRefs.current.get(step);
|
|
3129
3377
|
activeStep?.scrollIntoView({ block: "nearest", inline: "center" });
|
|
3130
3378
|
}, [step]);
|
|
@@ -3132,19 +3380,19 @@ function Stepper({
|
|
|
3132
3380
|
// onNew is pinned outside the horizontally-scrolling region below (a sibling of
|
|
3133
3381
|
// it, not a child) so its own edge never scrolls off-screen along with the
|
|
3134
3382
|
// later steps once the scroller's min-width doesn't fit the viewport.
|
|
3135
|
-
/* @__PURE__ */
|
|
3136
|
-
/* @__PURE__ */
|
|
3383
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex w-full shrink-0 items-center gap-2", children: [
|
|
3384
|
+
/* @__PURE__ */ jsx48("nav", { "aria-label": navLabel, className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx48(
|
|
3137
3385
|
"div",
|
|
3138
3386
|
{
|
|
3139
3387
|
"data-testid": scrollTestId,
|
|
3140
3388
|
className: "flex w-full items-center gap-0 overflow-x-auto px-2 py-1",
|
|
3141
|
-
children: /* @__PURE__ */
|
|
3389
|
+
children: /* @__PURE__ */ jsx48("ol", { className: "flex min-w-[700px] flex-1 items-start", children: steps.map(({ n, label, phase }, i) => {
|
|
3142
3390
|
const done = step > n;
|
|
3143
3391
|
const active = step === n;
|
|
3144
3392
|
const navigable = n <= maxStep && n !== step;
|
|
3145
3393
|
const last = i === steps.length - 1;
|
|
3146
|
-
return /* @__PURE__ */
|
|
3147
|
-
/* @__PURE__ */
|
|
3394
|
+
return /* @__PURE__ */ jsxs30("li", { className: cn("flex items-start", !last && "flex-1"), children: [
|
|
3395
|
+
/* @__PURE__ */ jsxs30(
|
|
3148
3396
|
"button",
|
|
3149
3397
|
{
|
|
3150
3398
|
ref: (element) => {
|
|
@@ -3160,17 +3408,17 @@ function Stepper({
|
|
|
3160
3408
|
navigable ? "cursor-pointer hover:opacity-80" : "cursor-default"
|
|
3161
3409
|
),
|
|
3162
3410
|
children: [
|
|
3163
|
-
/* @__PURE__ */
|
|
3411
|
+
/* @__PURE__ */ jsx48(
|
|
3164
3412
|
"div",
|
|
3165
3413
|
{
|
|
3166
3414
|
className: cn(
|
|
3167
3415
|
"flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-[11px] font-bold transition-colors",
|
|
3168
3416
|
done ? "bg-primary/15 text-primary" : active ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"
|
|
3169
3417
|
),
|
|
3170
|
-
children: done ? /* @__PURE__ */
|
|
3418
|
+
children: done ? /* @__PURE__ */ jsx48(CheckIcon5, { className: "h-3 w-3" }) : n
|
|
3171
3419
|
}
|
|
3172
3420
|
),
|
|
3173
|
-
/* @__PURE__ */
|
|
3421
|
+
/* @__PURE__ */ jsx48(
|
|
3174
3422
|
"span",
|
|
3175
3423
|
{
|
|
3176
3424
|
className: cn(
|
|
@@ -3180,11 +3428,11 @@ function Stepper({
|
|
|
3180
3428
|
children: label
|
|
3181
3429
|
}
|
|
3182
3430
|
),
|
|
3183
|
-
/* @__PURE__ */
|
|
3431
|
+
/* @__PURE__ */ jsx48("span", { className: "text-[9px] tracking-[0.5px] text-muted-foreground/50 uppercase", children: phase })
|
|
3184
3432
|
]
|
|
3185
3433
|
}
|
|
3186
3434
|
),
|
|
3187
|
-
!last && /* @__PURE__ */
|
|
3435
|
+
!last && /* @__PURE__ */ jsx48(
|
|
3188
3436
|
"div",
|
|
3189
3437
|
{
|
|
3190
3438
|
className: cn(
|
|
@@ -3197,7 +3445,7 @@ function Stepper({
|
|
|
3197
3445
|
}) })
|
|
3198
3446
|
}
|
|
3199
3447
|
) }),
|
|
3200
|
-
onNew && /* @__PURE__ */
|
|
3448
|
+
onNew && /* @__PURE__ */ jsxs30(
|
|
3201
3449
|
"button",
|
|
3202
3450
|
{
|
|
3203
3451
|
"data-testid": newTestId,
|
|
@@ -3205,7 +3453,7 @@ function Stepper({
|
|
|
3205
3453
|
title: newLabel,
|
|
3206
3454
|
className: "flex shrink-0 items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-[12px] font-semibold text-foreground transition-colors hover:bg-muted/50",
|
|
3207
3455
|
children: [
|
|
3208
|
-
/* @__PURE__ */
|
|
3456
|
+
/* @__PURE__ */ jsx48(PlusIcon, { className: "h-3.5 w-3.5" }),
|
|
3209
3457
|
newLabel
|
|
3210
3458
|
]
|
|
3211
3459
|
}
|
|
@@ -3213,10 +3461,660 @@ function Stepper({
|
|
|
3213
3461
|
] })
|
|
3214
3462
|
);
|
|
3215
3463
|
}
|
|
3464
|
+
|
|
3465
|
+
// src/patterns/animated-brand/AnimatedBrand.tsx
|
|
3466
|
+
import {
|
|
3467
|
+
useEffect as useEffect9,
|
|
3468
|
+
useRef as useRef9,
|
|
3469
|
+
useState as useState16
|
|
3470
|
+
} from "react";
|
|
3471
|
+
|
|
3472
|
+
// src/patterns/animated-brand/brandMotion.ts
|
|
3473
|
+
var BRAND_ANIMATIONS = [
|
|
3474
|
+
{ id: "bounce", label: "Bounce home" },
|
|
3475
|
+
{ id: "orbit", label: "Orbit and settle" },
|
|
3476
|
+
{ id: "impact", label: "Shot in, boom" },
|
|
3477
|
+
{ id: "liquid", label: "Liquid split" },
|
|
3478
|
+
{ id: "signature", label: "Solid to signature" },
|
|
3479
|
+
{ id: "burst", label: "Big bang, small dot" },
|
|
3480
|
+
{ id: "gravity", label: "Gravity press" }
|
|
3481
|
+
];
|
|
3482
|
+
function playBrandMotion(p, name, onComplete) {
|
|
3483
|
+
const list = [];
|
|
3484
|
+
if (!p.animate || window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
3485
|
+
onComplete?.();
|
|
3486
|
+
return () => {
|
|
3487
|
+
};
|
|
3488
|
+
}
|
|
3489
|
+
const accent2 = "var(--bms-brand-dot)";
|
|
3490
|
+
const q = (s) => {
|
|
3491
|
+
const element = p.querySelector(s);
|
|
3492
|
+
if (!element) throw new Error(`Missing logo part: ${s}`);
|
|
3493
|
+
return element;
|
|
3494
|
+
}, logo = q('[data-logo-part="logo"]'), ring = q('[data-logo-part="ring"]'), bead = q('[data-logo-part="bead"]'), tail = q('[data-logo-part="tail"]'), core = q('[data-logo-part="core"]');
|
|
3495
|
+
const unit = parseFloat(getComputedStyle(logo).fontSize) || 48;
|
|
3496
|
+
const a = (el, k, d = 2e3, delay = 0) => {
|
|
3497
|
+
const v = el.animate(k, {
|
|
3498
|
+
duration: d,
|
|
3499
|
+
delay,
|
|
3500
|
+
iterations: 1,
|
|
3501
|
+
fill: "both",
|
|
3502
|
+
easing: "linear"
|
|
3503
|
+
});
|
|
3504
|
+
list.push(v);
|
|
3505
|
+
return v;
|
|
3506
|
+
};
|
|
3507
|
+
const t = (x, y, sx = 1, sy = sx) => `translate(${x}em,${y}em) scale(${sx},${sy})`;
|
|
3508
|
+
const points = (items) => items.map(([offset, x, y, sx = 1, sy = sx, color = accent2]) => ({
|
|
3509
|
+
offset,
|
|
3510
|
+
transform: t(x, y, sx, sy),
|
|
3511
|
+
background: color
|
|
3512
|
+
}));
|
|
3513
|
+
const shock = (delay, strength = 1) => p.querySelectorAll('[data-logo-part="echo"]').forEach((e, j) => {
|
|
3514
|
+
a(
|
|
3515
|
+
e,
|
|
3516
|
+
[
|
|
3517
|
+
{ opacity: 0, transform: "scale(1)" },
|
|
3518
|
+
{ opacity: 0.48 * strength, transform: "scale(1.6)", offset: 0.08 },
|
|
3519
|
+
{ opacity: 0, transform: `scale(${j ? 8 : 6})`, offset: 1 }
|
|
3520
|
+
],
|
|
3521
|
+
650,
|
|
3522
|
+
delay + j * 110
|
|
3523
|
+
);
|
|
3524
|
+
});
|
|
3525
|
+
const sparks = (delay, out = 1) => p.querySelectorAll('[data-logo-part="particle"]').forEach((e, j) => {
|
|
3526
|
+
const angle = j * Math.PI / 4, x = Math.cos(angle) * out, y = Math.sin(angle) * out;
|
|
3527
|
+
a(
|
|
3528
|
+
e,
|
|
3529
|
+
[
|
|
3530
|
+
{ opacity: 0, transform: t(0, 0, 0.2) },
|
|
3531
|
+
{ opacity: 0.85, transform: t(x * 0.3, y * 0.3), offset: 0.12 },
|
|
3532
|
+
{ opacity: 0, transform: t(x, y, 0.25), offset: 1 }
|
|
3533
|
+
],
|
|
3534
|
+
650,
|
|
3535
|
+
delay
|
|
3536
|
+
);
|
|
3537
|
+
});
|
|
3538
|
+
const impact = (start, duration) => {
|
|
3539
|
+
a(
|
|
3540
|
+
ring,
|
|
3541
|
+
[
|
|
3542
|
+
{ offset: 0, transform: "scale(1)" },
|
|
3543
|
+
{ offset: start - 0.015, transform: "scale(1)" },
|
|
3544
|
+
{ offset: start + 0.045, transform: "scale(.82,1.12)" },
|
|
3545
|
+
{ offset: start + 0.12, transform: "scale(1.06,.97)" },
|
|
3546
|
+
{ offset: start + 0.24, transform: "scale(1)" },
|
|
3547
|
+
{ offset: 1, transform: "scale(1)" }
|
|
3548
|
+
],
|
|
3549
|
+
duration
|
|
3550
|
+
);
|
|
3551
|
+
a(
|
|
3552
|
+
tail,
|
|
3553
|
+
[
|
|
3554
|
+
{ offset: 0, transform: "translateX(0)" },
|
|
3555
|
+
{ offset: start, transform: "translateX(0)" },
|
|
3556
|
+
{ offset: start + 0.04, transform: "translateX(-.065em)" },
|
|
3557
|
+
{ offset: start + 0.14, transform: "translateX(.018em)" },
|
|
3558
|
+
{ offset: start + 0.24, transform: "translateX(0)" },
|
|
3559
|
+
{ offset: 1, transform: "translateX(0)" }
|
|
3560
|
+
],
|
|
3561
|
+
duration
|
|
3562
|
+
);
|
|
3563
|
+
};
|
|
3564
|
+
if (name === "bounce") {
|
|
3565
|
+
const beadRect = bead.getBoundingClientRect();
|
|
3566
|
+
const viewportUnitX = beadRect.width > 0 ? beadRect.width / 0.2 : unit;
|
|
3567
|
+
const viewportUnitY = beadRect.height > 0 ? beadRect.height / 0.2 : unit;
|
|
3568
|
+
const originX = beadRect.x + beadRect.width / 2;
|
|
3569
|
+
const originY = beadRect.y + beadRect.height / 2;
|
|
3570
|
+
const letters = Array.from(
|
|
3571
|
+
p.querySelectorAll("[data-brand-letter]")
|
|
3572
|
+
).reverse();
|
|
3573
|
+
const baseline = p.querySelector("[data-brand-baseline]")?.getBoundingClientRect().top ?? originY;
|
|
3574
|
+
const pen = typeof CanvasRenderingContext2D !== "undefined" ? document.createElement("canvas").getContext("2d") : null;
|
|
3575
|
+
if (pen) pen.font = getComputedStyle(logo).font;
|
|
3576
|
+
const stops = letters.length ? letters.map((letter) => {
|
|
3577
|
+
const rect = letter.getBoundingClientRect();
|
|
3578
|
+
const ascent = pen?.measureText(letter.textContent ?? "").actualBoundingBoxAscent ?? unit * 0.7;
|
|
3579
|
+
return {
|
|
3580
|
+
x: (rect.x + rect.width / 2 - originX) / viewportUnitX,
|
|
3581
|
+
y: (baseline - originY) / viewportUnitY - ascent / unit - 0.1
|
|
3582
|
+
};
|
|
3583
|
+
}) : [
|
|
3584
|
+
{ x: -1.1, y: -0.7 },
|
|
3585
|
+
{ x: -0.3, y: -0.4 },
|
|
3586
|
+
{ x: 0.3, y: -0.4 }
|
|
3587
|
+
];
|
|
3588
|
+
const duration = 1e3 + stops.length * 340;
|
|
3589
|
+
let from = { x: stops[0].x + 0.5, y: stops[0].y - 0.65 };
|
|
3590
|
+
const frames = [{ offset: 0, transform: t(from.x, from.y) }];
|
|
3591
|
+
const destinations = [...stops, { x: 0, y: 0 }];
|
|
3592
|
+
const jumpEnd = 0.94;
|
|
3593
|
+
destinations.forEach((to, index) => {
|
|
3594
|
+
const start = index / destinations.length * jumpEnd;
|
|
3595
|
+
const length = jumpEnd / destinations.length;
|
|
3596
|
+
for (let k = 1; k <= 10; k++) {
|
|
3597
|
+
const u = k / 10;
|
|
3598
|
+
frames.push({
|
|
3599
|
+
offset: start + length * u * 0.87,
|
|
3600
|
+
transform: t(
|
|
3601
|
+
from.x + (to.x - from.x) * u,
|
|
3602
|
+
from.y + (to.y - from.y) * u - 1.6 * u * (1 - u)
|
|
3603
|
+
)
|
|
3604
|
+
});
|
|
3605
|
+
}
|
|
3606
|
+
frames.push({
|
|
3607
|
+
offset: start + length * 0.94,
|
|
3608
|
+
transform: t(to.x, to.y + 0.018, 1.15, 0.82)
|
|
3609
|
+
});
|
|
3610
|
+
frames.push({ offset: start + length, transform: t(to.x, to.y) });
|
|
3611
|
+
from = to;
|
|
3612
|
+
});
|
|
3613
|
+
frames.push({ offset: 1, transform: t(0, 0) });
|
|
3614
|
+
a(bead, frames, duration);
|
|
3615
|
+
shock(duration * 0.94, 0.5);
|
|
3616
|
+
} else if (name === "orbit") {
|
|
3617
|
+
const frames = [];
|
|
3618
|
+
for (let step = 0; step <= 72; step++) {
|
|
3619
|
+
const u = step / 72;
|
|
3620
|
+
const angle = -Math.PI / 2 + u * Math.PI * 3.7;
|
|
3621
|
+
const radius = 0.683 * (1 - u ** 2.4);
|
|
3622
|
+
frames.push({
|
|
3623
|
+
offset: u,
|
|
3624
|
+
transform: t(Math.cos(angle) * radius, Math.sin(angle) * radius)
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
a(bead, frames, 2500);
|
|
3628
|
+
a(
|
|
3629
|
+
ring,
|
|
3630
|
+
[
|
|
3631
|
+
{ transform: "scale(1)" },
|
|
3632
|
+
{ offset: 0.8, transform: "scale(1.06)" },
|
|
3633
|
+
{ offset: 1, transform: "scale(1)" }
|
|
3634
|
+
],
|
|
3635
|
+
2500
|
|
3636
|
+
);
|
|
3637
|
+
shock(2400, 0.5);
|
|
3638
|
+
} else if (name === "impact") {
|
|
3639
|
+
const d = 1650;
|
|
3640
|
+
a(
|
|
3641
|
+
bead,
|
|
3642
|
+
points([
|
|
3643
|
+
[0, 6.5, 0, 4, 0.38],
|
|
3644
|
+
[0.2, 6.5, 0, 4, 0.38],
|
|
3645
|
+
[0.3, 1.5, 0, 4, 0.38],
|
|
3646
|
+
[0.33, 0, 0, 0.55, 1.55],
|
|
3647
|
+
[0.39, -0.09, 0, 1.35, 0.72],
|
|
3648
|
+
[0.48, 0.035, 0, 0.93, 1.06],
|
|
3649
|
+
[0.65, 0, 0, 1, 1],
|
|
3650
|
+
[1, 0, 0, 1, 1]
|
|
3651
|
+
]),
|
|
3652
|
+
d
|
|
3653
|
+
);
|
|
3654
|
+
a(
|
|
3655
|
+
q('[data-logo-part="trail"]'),
|
|
3656
|
+
[
|
|
3657
|
+
{ opacity: 0, transform: t(6.5, 0, 2, 1) },
|
|
3658
|
+
{ opacity: 0, transform: t(6.5, 0, 2, 1), offset: 0.2 },
|
|
3659
|
+
{ opacity: 0.6, transform: t(0.5, 0, 1.8, 1), offset: 0.32 },
|
|
3660
|
+
{ opacity: 0, transform: t(0, 0, 0.1, 1), offset: 0.39 },
|
|
3661
|
+
{ opacity: 0, offset: 1 }
|
|
3662
|
+
],
|
|
3663
|
+
d
|
|
3664
|
+
);
|
|
3665
|
+
impact(0.33, d);
|
|
3666
|
+
shock(545);
|
|
3667
|
+
sparks(545, 0.94);
|
|
3668
|
+
} else if (name === "liquid") {
|
|
3669
|
+
const d = 2400;
|
|
3670
|
+
a(
|
|
3671
|
+
bead,
|
|
3672
|
+
points([
|
|
3673
|
+
[0, 0, 0, 4],
|
|
3674
|
+
[0.15, 0, 0, 4],
|
|
3675
|
+
[0.3, 0, 0, 5.2, 2.7],
|
|
3676
|
+
[0.43, 0, 0, 2.8, 4.4],
|
|
3677
|
+
[0.58, 0, 0, 1.6, 2],
|
|
3678
|
+
[0.74, 0, 0, 0.85, 1.15],
|
|
3679
|
+
[0.88, 0, 0, 1.06, 0.94],
|
|
3680
|
+
[1, 0, 0, 1]
|
|
3681
|
+
]),
|
|
3682
|
+
d
|
|
3683
|
+
);
|
|
3684
|
+
a(
|
|
3685
|
+
ring,
|
|
3686
|
+
[
|
|
3687
|
+
{ offset: 0, opacity: 0, transform: "scale(.2) rotate(-35deg)" },
|
|
3688
|
+
{ offset: 0.36, opacity: 0, transform: "scale(.2) rotate(-35deg)" },
|
|
3689
|
+
{ offset: 0.63, opacity: 1, transform: "scale(1.1,.9) rotate(8deg)" },
|
|
3690
|
+
{ offset: 0.8, opacity: 1, transform: "scale(.97,1.03) rotate(-2deg)" },
|
|
3691
|
+
{ offset: 1, opacity: 1, transform: "scale(1) rotate(0deg)" }
|
|
3692
|
+
],
|
|
3693
|
+
d
|
|
3694
|
+
);
|
|
3695
|
+
a(
|
|
3696
|
+
tail,
|
|
3697
|
+
[
|
|
3698
|
+
{ offset: 0, opacity: 0, transform: "translateX(-.25em)" },
|
|
3699
|
+
{ offset: 0.35, opacity: 0, transform: "translateX(-.25em)" },
|
|
3700
|
+
{ offset: 0.72, opacity: 1, transform: "translateX(.025em)" },
|
|
3701
|
+
{ offset: 1, opacity: 1, transform: "translateX(0)" }
|
|
3702
|
+
],
|
|
3703
|
+
d
|
|
3704
|
+
);
|
|
3705
|
+
} else if (name === "gravity") {
|
|
3706
|
+
const d = 2600;
|
|
3707
|
+
a(
|
|
3708
|
+
bead,
|
|
3709
|
+
points([
|
|
3710
|
+
[0, 0, -1.15, 4],
|
|
3711
|
+
[0.12, 0, -1.15, 4],
|
|
3712
|
+
[0.24, 0, -0.88, 4],
|
|
3713
|
+
[0.34, 0, -0.35, 3.7, 4.3],
|
|
3714
|
+
[0.4, 0, 0.15, 5.1, 2.5],
|
|
3715
|
+
[0.49, 0, -0.32, 3.4, 4.2],
|
|
3716
|
+
[0.58, 0, 0.07, 4.4, 3.5],
|
|
3717
|
+
[0.67, 0, 0, 3.8, 4],
|
|
3718
|
+
[0.81, 0, 0, 0.78, 1.22],
|
|
3719
|
+
[0.91, 0, 0, 1.1, 0.9],
|
|
3720
|
+
[1, 0, 0, 1]
|
|
3721
|
+
]),
|
|
3722
|
+
d
|
|
3723
|
+
);
|
|
3724
|
+
a(
|
|
3725
|
+
ring,
|
|
3726
|
+
[
|
|
3727
|
+
{ offset: 0, opacity: 0, transform: "scale(.25)" },
|
|
3728
|
+
{ offset: 0.64, opacity: 0, transform: "scale(.25)" },
|
|
3729
|
+
{ offset: 0.81, opacity: 1, transform: "scale(1.12,.88)" },
|
|
3730
|
+
{ offset: 0.92, opacity: 1, transform: "scale(.97,1.03)" },
|
|
3731
|
+
{ offset: 1, opacity: 1, transform: "scale(1)" }
|
|
3732
|
+
],
|
|
3733
|
+
d
|
|
3734
|
+
);
|
|
3735
|
+
a(
|
|
3736
|
+
tail,
|
|
3737
|
+
[
|
|
3738
|
+
{ offset: 0, opacity: 0, transform: "translateY(.12em)" },
|
|
3739
|
+
{ offset: 0.43, opacity: 0, transform: "translateY(.12em)" },
|
|
3740
|
+
{ offset: 0.72, opacity: 1, transform: "translateY(0)" },
|
|
3741
|
+
{ offset: 1, opacity: 1, transform: "translateY(0)" }
|
|
3742
|
+
],
|
|
3743
|
+
d
|
|
3744
|
+
);
|
|
3745
|
+
shock(1040, 0.5);
|
|
3746
|
+
} else if (name === "signature") {
|
|
3747
|
+
const d = 2200;
|
|
3748
|
+
a(
|
|
3749
|
+
core,
|
|
3750
|
+
[
|
|
3751
|
+
{ opacity: 1, background: accent2, transform: "scale(1)" },
|
|
3752
|
+
{ opacity: 1, background: accent2, transform: "scale(1.08)", offset: 0.22 },
|
|
3753
|
+
{ opacity: 1, background: accent2, transform: "scale(.22)", offset: 0.65 },
|
|
3754
|
+
{ opacity: 1, background: accent2, transform: "scale(.25)", offset: 0.84 },
|
|
3755
|
+
{ opacity: 0, background: accent2, transform: "scale(.25)", offset: 1 }
|
|
3756
|
+
],
|
|
3757
|
+
d
|
|
3758
|
+
);
|
|
3759
|
+
a(
|
|
3760
|
+
bead,
|
|
3761
|
+
[{ opacity: 0 }, { opacity: 0, offset: 0.85 }, { opacity: 1, offset: 1 }],
|
|
3762
|
+
d
|
|
3763
|
+
);
|
|
3764
|
+
a(
|
|
3765
|
+
ring,
|
|
3766
|
+
[
|
|
3767
|
+
{ opacity: 0, transform: "scale(.3)" },
|
|
3768
|
+
{ opacity: 0, transform: "scale(.3)", offset: 0.25 },
|
|
3769
|
+
{ opacity: 1, transform: "scale(1.04)", offset: 0.65 },
|
|
3770
|
+
{ opacity: 1, transform: "scale(1)", offset: 0.83 },
|
|
3771
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
3772
|
+
],
|
|
3773
|
+
d
|
|
3774
|
+
);
|
|
3775
|
+
a(
|
|
3776
|
+
tail,
|
|
3777
|
+
[
|
|
3778
|
+
{ opacity: 0, transform: "translateX(-.18em)" },
|
|
3779
|
+
{ opacity: 0, transform: "translateX(-.18em)", offset: 0.22 },
|
|
3780
|
+
{ opacity: 1, transform: "translateX(0)", offset: 0.64 },
|
|
3781
|
+
{ opacity: 1, transform: "translateX(0)", offset: 1 }
|
|
3782
|
+
],
|
|
3783
|
+
d
|
|
3784
|
+
);
|
|
3785
|
+
} else {
|
|
3786
|
+
const d = 2500;
|
|
3787
|
+
a(
|
|
3788
|
+
core,
|
|
3789
|
+
[
|
|
3790
|
+
{ opacity: 1, background: accent2, transform: "scale(.92)" },
|
|
3791
|
+
{ opacity: 1, background: accent2, transform: "scale(1.14)", offset: 0.24 },
|
|
3792
|
+
{ opacity: 0, background: accent2, transform: "scale(.1)", offset: 0.36 },
|
|
3793
|
+
{ opacity: 0, offset: 1 }
|
|
3794
|
+
],
|
|
3795
|
+
d
|
|
3796
|
+
);
|
|
3797
|
+
a(
|
|
3798
|
+
bead,
|
|
3799
|
+
[
|
|
3800
|
+
{ opacity: 0, transform: "scale(.2)" },
|
|
3801
|
+
{ opacity: 0, transform: "scale(.2)", offset: 0.69 },
|
|
3802
|
+
{ opacity: 1, transform: "scale(1.2)", offset: 0.84 },
|
|
3803
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
3804
|
+
],
|
|
3805
|
+
d
|
|
3806
|
+
);
|
|
3807
|
+
a(
|
|
3808
|
+
ring,
|
|
3809
|
+
[
|
|
3810
|
+
{ opacity: 0, transform: "scale(.82)" },
|
|
3811
|
+
{ opacity: 0, transform: "scale(.82)", offset: 0.34 },
|
|
3812
|
+
{ opacity: 0.7, transform: "scale(1.04)", offset: 0.57 },
|
|
3813
|
+
{ opacity: 1, transform: "scale(1)", offset: 0.82 },
|
|
3814
|
+
{ opacity: 1, transform: "scale(1)", offset: 1 }
|
|
3815
|
+
],
|
|
3816
|
+
d
|
|
3817
|
+
);
|
|
3818
|
+
a(
|
|
3819
|
+
tail,
|
|
3820
|
+
[
|
|
3821
|
+
{ opacity: 0.15, transform: "translateX(-.06em)" },
|
|
3822
|
+
{ opacity: 0.15, transform: "translateX(-.06em)", offset: 0.3 },
|
|
3823
|
+
{ opacity: 1, transform: "translateX(0)", offset: 0.68 },
|
|
3824
|
+
{ opacity: 1, transform: "translateX(0)", offset: 1 }
|
|
3825
|
+
],
|
|
3826
|
+
d
|
|
3827
|
+
);
|
|
3828
|
+
p.querySelectorAll('[data-logo-part="particle"]').forEach((el, j) => {
|
|
3829
|
+
const angle = j * Math.PI / 4, x = Math.cos(angle) * 0.86, y = Math.sin(angle) * 0.86;
|
|
3830
|
+
a(
|
|
3831
|
+
el,
|
|
3832
|
+
[
|
|
3833
|
+
{ opacity: 0, transform: t(0, 0, 0.2) },
|
|
3834
|
+
{ opacity: 0, transform: t(0, 0, 0.2), offset: 0.27 },
|
|
3835
|
+
{ opacity: 1, transform: t(x, y, 1.2), offset: 0.43 },
|
|
3836
|
+
{ opacity: 1, transform: t(x * 0.85, y * 0.85), offset: 0.59 },
|
|
3837
|
+
{ opacity: 0, transform: t(0, 0, 0.5), offset: 0.82 },
|
|
3838
|
+
{ opacity: 0, transform: t(0, 0, 0.5), offset: 1 }
|
|
3839
|
+
],
|
|
3840
|
+
d
|
|
3841
|
+
);
|
|
3842
|
+
});
|
|
3843
|
+
shock(1800, 0.6);
|
|
3844
|
+
}
|
|
3845
|
+
let cancelled = false;
|
|
3846
|
+
void Promise.all(list.map((animation) => animation.finished)).then(
|
|
3847
|
+
() => {
|
|
3848
|
+
if (!cancelled) {
|
|
3849
|
+
for (const animation of list) animation.cancel();
|
|
3850
|
+
onComplete?.();
|
|
3851
|
+
}
|
|
3852
|
+
},
|
|
3853
|
+
() => {
|
|
3854
|
+
}
|
|
3855
|
+
);
|
|
3856
|
+
return () => {
|
|
3857
|
+
cancelled = true;
|
|
3858
|
+
for (const animation of list) animation.cancel();
|
|
3859
|
+
};
|
|
3860
|
+
}
|
|
3861
|
+
|
|
3862
|
+
// src/patterns/animated-brand/AnimatedBrand.tsx
|
|
3863
|
+
import { jsx as jsx49, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3864
|
+
var absolute = {
|
|
3865
|
+
position: "absolute",
|
|
3866
|
+
borderRadius: "50%",
|
|
3867
|
+
pointerEvents: "none"
|
|
3868
|
+
};
|
|
3869
|
+
var centered = {
|
|
3870
|
+
...absolute,
|
|
3871
|
+
width: ".2em",
|
|
3872
|
+
height: ".2em",
|
|
3873
|
+
left: "50%",
|
|
3874
|
+
top: "50%",
|
|
3875
|
+
margin: "-.1em"
|
|
3876
|
+
};
|
|
3877
|
+
var accent = "var(--bms-brand-dot)";
|
|
3878
|
+
function AnimatedBrand({
|
|
3879
|
+
product = "Brain",
|
|
3880
|
+
dotColor = "#e60028",
|
|
3881
|
+
textColor = "#929292",
|
|
3882
|
+
oneColor,
|
|
3883
|
+
productColor,
|
|
3884
|
+
ringColor,
|
|
3885
|
+
mode = "full",
|
|
3886
|
+
animation = "random",
|
|
3887
|
+
size = 48,
|
|
3888
|
+
autoPlay = true,
|
|
3889
|
+
replayKey,
|
|
3890
|
+
onComplete,
|
|
3891
|
+
className,
|
|
3892
|
+
style
|
|
3893
|
+
}) {
|
|
3894
|
+
const ref = useRef9(null);
|
|
3895
|
+
const completion = useRef9(onComplete);
|
|
3896
|
+
const [segmented, setSegmented] = useState16(null);
|
|
3897
|
+
useEffect9(() => {
|
|
3898
|
+
const letters2 = typeof Intl.Segmenter === "function" ? Array.from(new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(product), ({ segment }) => segment) : product ? [product] : [];
|
|
3899
|
+
setSegmented({ product, letters: letters2 });
|
|
3900
|
+
}, [product]);
|
|
3901
|
+
useEffect9(() => {
|
|
3902
|
+
completion.current = onComplete;
|
|
3903
|
+
}, [onComplete]);
|
|
3904
|
+
useEffect9(() => {
|
|
3905
|
+
const element = ref.current;
|
|
3906
|
+
if (!element || !autoPlay || segmented?.product !== product) return;
|
|
3907
|
+
let disposed = false;
|
|
3908
|
+
let stop;
|
|
3909
|
+
let completed = false;
|
|
3910
|
+
const finish = () => {
|
|
3911
|
+
if (!disposed && !completed) {
|
|
3912
|
+
completed = true;
|
|
3913
|
+
completion.current?.();
|
|
3914
|
+
}
|
|
3915
|
+
};
|
|
3916
|
+
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
3917
|
+
const changed = () => {
|
|
3918
|
+
if (reduced.matches) {
|
|
3919
|
+
stop?.();
|
|
3920
|
+
finish();
|
|
3921
|
+
}
|
|
3922
|
+
};
|
|
3923
|
+
reduced.addEventListener("change", changed);
|
|
3924
|
+
const start = () => {
|
|
3925
|
+
if (disposed || completed) return;
|
|
3926
|
+
if (reduced.matches) {
|
|
3927
|
+
finish();
|
|
3928
|
+
return;
|
|
3929
|
+
}
|
|
3930
|
+
const choice = animation === "random" ? BRAND_ANIMATIONS[Math.floor(Math.random() * BRAND_ANIMATIONS.length)].id : animation;
|
|
3931
|
+
stop = playBrandMotion(element, choice, finish);
|
|
3932
|
+
};
|
|
3933
|
+
void (document.fonts?.ready ?? Promise.resolve()).then(start, start);
|
|
3934
|
+
return () => {
|
|
3935
|
+
disposed = true;
|
|
3936
|
+
stop?.();
|
|
3937
|
+
reduced.removeEventListener("change", changed);
|
|
3938
|
+
};
|
|
3939
|
+
}, [product, mode, animation, size, autoPlay, replayKey, segmented]);
|
|
3940
|
+
const tail = mode === "full" ? `ne${product}` : mode === "one" ? "ne" : "";
|
|
3941
|
+
const suffix = mode === "full" && product ? segmented?.product === product ? segmented.letters : [product] : [];
|
|
3942
|
+
const letters = tail ? ["n", "e", ...suffix] : [];
|
|
3943
|
+
const label = mode === "full" ? `One${product}` : mode === "one" ? "One" : "O";
|
|
3944
|
+
const wrapperStyle = {
|
|
3945
|
+
"--bms-brand-dot": dotColor,
|
|
3946
|
+
display: "inline-flex",
|
|
3947
|
+
fontSize: size,
|
|
3948
|
+
color: textColor,
|
|
3949
|
+
...style
|
|
3950
|
+
};
|
|
3951
|
+
return /* @__PURE__ */ jsx49(
|
|
3952
|
+
"span",
|
|
3953
|
+
{
|
|
3954
|
+
ref,
|
|
3955
|
+
className,
|
|
3956
|
+
style: wrapperStyle,
|
|
3957
|
+
children: /* @__PURE__ */ jsxs31(
|
|
3958
|
+
"span",
|
|
3959
|
+
{
|
|
3960
|
+
"data-logo-part": "logo",
|
|
3961
|
+
role: "img",
|
|
3962
|
+
"aria-label": label,
|
|
3963
|
+
style: {
|
|
3964
|
+
display: "inline-flex",
|
|
3965
|
+
position: "relative",
|
|
3966
|
+
alignItems: "center",
|
|
3967
|
+
fontSize: "inherit",
|
|
3968
|
+
fontWeight: 700,
|
|
3969
|
+
lineHeight: 1,
|
|
3970
|
+
letterSpacing: "-.055em",
|
|
3971
|
+
whiteSpace: "nowrap",
|
|
3972
|
+
userSelect: "none"
|
|
3973
|
+
},
|
|
3974
|
+
children: [
|
|
3975
|
+
/* @__PURE__ */ jsxs31(
|
|
3976
|
+
"span",
|
|
3977
|
+
{
|
|
3978
|
+
"data-logo-part": "mark",
|
|
3979
|
+
"aria-hidden": "true",
|
|
3980
|
+
style: {
|
|
3981
|
+
position: "relative",
|
|
3982
|
+
flex: "none",
|
|
3983
|
+
color: ringColor ?? oneColor,
|
|
3984
|
+
width: ".8em",
|
|
3985
|
+
height: ".8em",
|
|
3986
|
+
marginRight: tail ? ".04em" : 0
|
|
3987
|
+
},
|
|
3988
|
+
children: [
|
|
3989
|
+
/* @__PURE__ */ jsx49(
|
|
3990
|
+
"span",
|
|
3991
|
+
{
|
|
3992
|
+
"data-logo-part": "ring",
|
|
3993
|
+
style: {
|
|
3994
|
+
...absolute,
|
|
3995
|
+
inset: 0,
|
|
3996
|
+
border: ".157em solid currentColor",
|
|
3997
|
+
boxSizing: "border-box"
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
4000
|
+
),
|
|
4001
|
+
/* @__PURE__ */ jsx49(
|
|
4002
|
+
"span",
|
|
4003
|
+
{
|
|
4004
|
+
"data-logo-part": "core",
|
|
4005
|
+
style: {
|
|
4006
|
+
...absolute,
|
|
4007
|
+
inset: 0,
|
|
4008
|
+
background: accent,
|
|
4009
|
+
opacity: 0,
|
|
4010
|
+
zIndex: 2
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
),
|
|
4014
|
+
/* @__PURE__ */ jsx49(
|
|
4015
|
+
"span",
|
|
4016
|
+
{
|
|
4017
|
+
"data-logo-part": "trail",
|
|
4018
|
+
style: {
|
|
4019
|
+
position: "absolute",
|
|
4020
|
+
width: "1.8em",
|
|
4021
|
+
height: ".045em",
|
|
4022
|
+
left: "50%",
|
|
4023
|
+
top: "50%",
|
|
4024
|
+
marginTop: "-.0225em",
|
|
4025
|
+
background: `linear-gradient(90deg, ${accent}, transparent)`,
|
|
4026
|
+
transformOrigin: "left center",
|
|
4027
|
+
opacity: 0,
|
|
4028
|
+
pointerEvents: "none"
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
),
|
|
4032
|
+
[0, 1].map((id) => /* @__PURE__ */ jsx49(
|
|
4033
|
+
"span",
|
|
4034
|
+
{
|
|
4035
|
+
"data-logo-part": "echo",
|
|
4036
|
+
style: {
|
|
4037
|
+
...centered,
|
|
4038
|
+
border: `.025em solid ${accent}`,
|
|
4039
|
+
boxSizing: "border-box",
|
|
4040
|
+
opacity: 0
|
|
4041
|
+
}
|
|
4042
|
+
},
|
|
4043
|
+
id
|
|
4044
|
+
)),
|
|
4045
|
+
Array.from({ length: 8 }, (_, id) => /* @__PURE__ */ jsx49(
|
|
4046
|
+
"span",
|
|
4047
|
+
{
|
|
4048
|
+
"data-logo-part": "particle",
|
|
4049
|
+
style: {
|
|
4050
|
+
...centered,
|
|
4051
|
+
width: ".055em",
|
|
4052
|
+
height: ".055em",
|
|
4053
|
+
margin: "-.0275em",
|
|
4054
|
+
background: accent,
|
|
4055
|
+
opacity: 0
|
|
4056
|
+
}
|
|
4057
|
+
},
|
|
4058
|
+
id
|
|
4059
|
+
)),
|
|
4060
|
+
/* @__PURE__ */ jsx49(
|
|
4061
|
+
"span",
|
|
4062
|
+
{
|
|
4063
|
+
"data-logo-part": "bead",
|
|
4064
|
+
style: { ...centered, background: accent, zIndex: 3 }
|
|
4065
|
+
}
|
|
4066
|
+
)
|
|
4067
|
+
]
|
|
4068
|
+
}
|
|
4069
|
+
),
|
|
4070
|
+
/* @__PURE__ */ jsxs31(
|
|
4071
|
+
"span",
|
|
4072
|
+
{
|
|
4073
|
+
"data-logo-part": "tail",
|
|
4074
|
+
"aria-hidden": "true",
|
|
4075
|
+
style: {
|
|
4076
|
+
display: "inline-flex",
|
|
4077
|
+
alignItems: "baseline",
|
|
4078
|
+
whiteSpace: "pre"
|
|
4079
|
+
},
|
|
4080
|
+
children: [
|
|
4081
|
+
letters.map((letter, index) => /* @__PURE__ */ jsx49(
|
|
4082
|
+
"span",
|
|
4083
|
+
{
|
|
4084
|
+
"data-brand-letter": "",
|
|
4085
|
+
style: { display: "inline-block", color: index < 2 ? oneColor : productColor },
|
|
4086
|
+
children: letter
|
|
4087
|
+
},
|
|
4088
|
+
`${index}-${letter}`
|
|
4089
|
+
)),
|
|
4090
|
+
/* @__PURE__ */ jsx49(
|
|
4091
|
+
"span",
|
|
4092
|
+
{
|
|
4093
|
+
"data-brand-baseline": "",
|
|
4094
|
+
style: {
|
|
4095
|
+
display: "inline-block",
|
|
4096
|
+
width: 0,
|
|
4097
|
+
height: 0,
|
|
4098
|
+
alignSelf: "baseline"
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
)
|
|
4102
|
+
]
|
|
4103
|
+
}
|
|
4104
|
+
)
|
|
4105
|
+
]
|
|
4106
|
+
}
|
|
4107
|
+
)
|
|
4108
|
+
}
|
|
4109
|
+
);
|
|
4110
|
+
}
|
|
3216
4111
|
export {
|
|
3217
4112
|
AiButton,
|
|
3218
4113
|
AiExplainButton,
|
|
3219
4114
|
AlertBox,
|
|
4115
|
+
AnimatedBrand,
|
|
4116
|
+
AsyncBoundary,
|
|
4117
|
+
BRAND_ANIMATIONS,
|
|
3220
4118
|
Badge,
|
|
3221
4119
|
Button,
|
|
3222
4120
|
ButtonGroup,
|
|
@@ -3254,13 +4152,16 @@ export {
|
|
|
3254
4152
|
DropdownMenuSubContent,
|
|
3255
4153
|
DropdownMenuSubTrigger,
|
|
3256
4154
|
DropdownMenuTrigger,
|
|
4155
|
+
ErrorState,
|
|
3257
4156
|
FormField,
|
|
3258
4157
|
FormModal,
|
|
4158
|
+
InlineError,
|
|
3259
4159
|
Input,
|
|
3260
4160
|
KpiCard,
|
|
3261
4161
|
Label,
|
|
3262
4162
|
LoadingOverlay,
|
|
3263
4163
|
LoadingSpinner,
|
|
4164
|
+
LoadingState,
|
|
3264
4165
|
Modal,
|
|
3265
4166
|
NavGroup,
|
|
3266
4167
|
NavItem,
|
|
@@ -3269,6 +4170,7 @@ export {
|
|
|
3269
4170
|
PopoverContent,
|
|
3270
4171
|
PopoverTrigger,
|
|
3271
4172
|
QuestionDialog,
|
|
4173
|
+
RefreshBar,
|
|
3272
4174
|
ResponsivePanel,
|
|
3273
4175
|
ScrollArea,
|
|
3274
4176
|
ScrollBar,
|
|
@@ -3322,11 +4224,14 @@ export {
|
|
|
3322
4224
|
badgeVariants,
|
|
3323
4225
|
buttonVariants,
|
|
3324
4226
|
cn,
|
|
4227
|
+
defaultErrorStateLabels,
|
|
3325
4228
|
describeSpeechError,
|
|
3326
4229
|
getConfirmButtonPlacement,
|
|
3327
4230
|
isWindowsPlatform,
|
|
3328
4231
|
loadingSpinnerIconVariants,
|
|
3329
4232
|
sheetVariants,
|
|
4233
|
+
toErrorInfo,
|
|
4234
|
+
useDelayedFlag,
|
|
3330
4235
|
useMediaQuery,
|
|
3331
4236
|
useSidebarCollapsed,
|
|
3332
4237
|
useSpeechRecognition
|