@mirror-physics/fractal-ui 0.2.0-next.27 → 0.2.0-next.29

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.cjs CHANGED
@@ -32,44 +32,70 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  Alert: () => Alert,
34
34
  AlertDescription: () => AlertDescription,
35
+ AlertGhost: () => AlertGhost,
35
36
  AlertTitle: () => AlertTitle,
36
37
  Button: () => Button,
38
+ ButtonGhost: () => ButtonGhost,
37
39
  Card: () => Card,
38
40
  CardContent: () => CardContent,
39
41
  CardDescription: () => CardDescription,
40
42
  CardFooter: () => CardFooter,
43
+ CardGhost: () => CardGhost,
41
44
  CardHeader: () => CardHeader,
42
45
  CardTitle: () => CardTitle,
43
46
  Checkbox: () => Checkbox,
47
+ CheckboxGhost: () => CheckboxGhost,
44
48
  Chip: () => Chip,
49
+ ChipGhost: () => ChipGhost,
45
50
  ContentSwitcher: () => ContentSwitcher,
51
+ ContentSwitcherGhost: () => ContentSwitcherGhost,
46
52
  DataTable: () => DataTable,
53
+ DataTableGhost: () => DataTableGhost,
47
54
  Disclosure: () => Disclosure,
55
+ DisclosureGhost: () => DisclosureGhost,
48
56
  Dropdown: () => Dropdown,
57
+ DropdownGhost: () => DropdownGhost,
49
58
  FeatureCard: () => FeatureCard,
50
59
  FileDropzone: () => FileDropzone,
60
+ FileDropzoneGhost: () => FileDropzoneGhost,
51
61
  FolderCard: () => FolderCard,
62
+ Ghost: () => Ghost,
63
+ GhostLine: () => GhostLine,
52
64
  Input: () => Input,
65
+ InputGhost: () => InputGhost,
53
66
  Label: () => Label,
67
+ LabelGhost: () => LabelGhost,
54
68
  LatticeLoader: () => LatticeLoader,
55
69
  Link: () => Link,
70
+ LinkGhost: () => LinkGhost,
56
71
  Modal: () => Modal,
72
+ ModalGhost: () => ModalGhost,
57
73
  Pagination: () => Pagination,
74
+ PaginationGhost: () => PaginationGhost,
58
75
  PromptCard: () => PromptCard,
76
+ PromptCardGhost: () => PromptCardGhost,
59
77
  PromptGrid: () => PromptGrid,
60
78
  SidePanel: () => SidePanel,
79
+ SidePanelGhost: () => SidePanelGhost,
61
80
  Sidebar: () => Sidebar,
62
81
  SidebarBrand: () => SidebarBrand,
63
82
  SidebarFooter: () => SidebarFooter,
83
+ SidebarGhost: () => SidebarGhost,
64
84
  SidebarHeader: () => SidebarHeader,
65
85
  SidebarNav: () => SidebarNav,
66
86
  SidebarNavItem: () => SidebarNavItem,
67
87
  SidebarSection: () => SidebarSection,
68
88
  SortableTable: () => SortableTable,
89
+ SortableTableGhost: () => SortableTableGhost,
69
90
  Tabs: () => Tabs,
91
+ TabsGhost: () => TabsGhost,
70
92
  TextButton: () => TextButton,
93
+ TextButtonGhost: () => TextButtonGhost,
71
94
  Textarea: () => Textarea,
95
+ TextareaGhost: () => TextareaGhost,
72
96
  Toggle: () => Toggle,
97
+ ToggleGhost: () => ToggleGhost,
98
+ UILoader: () => UILoader,
73
99
  cn: () => cn,
74
100
  useEscapeDismiss: () => useEscapeDismiss
75
101
  });
@@ -406,28 +432,32 @@ Label.displayName = "Label";
406
432
 
407
433
  // src/components/Alert/Alert.tsx
408
434
  var React6 = __toESM(require("react"), 1);
435
+ var import_fractal_icons2 = require("@mirror-physics/fractal-icons");
409
436
  var import_jsx_runtime6 = require("react/jsx-runtime");
410
437
  var defaultIcons = {
411
- default: "\u2139",
412
- info: "\u2139",
413
- success: "\u2713",
414
- warning: "\u26A0",
415
- error: "\u2715"
438
+ default: import_fractal_icons2.CircleInfo,
439
+ info: import_fractal_icons2.CircleInfo,
440
+ success: import_fractal_icons2.CircleCheck,
441
+ warning: import_fractal_icons2.Warning,
442
+ error: import_fractal_icons2.CircleClose
416
443
  };
417
444
  var Alert = React6.forwardRef(
418
- ({ className, variant = "default", icon, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
419
- "div",
420
- {
421
- ref,
422
- role: "alert",
423
- className: cn("fractal-alert", `fractal-alert--${variant}`, className),
424
- ...props,
425
- children: [
426
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "fractal-alert-icon", "aria-hidden": true, children: icon ?? defaultIcons[variant] }),
427
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "fractal-alert-content", children })
428
- ]
429
- }
430
- )
445
+ ({ className, variant = "default", icon, children, ...props }, ref) => {
446
+ const DefaultIcon = defaultIcons[variant];
447
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
448
+ "div",
449
+ {
450
+ ref,
451
+ role: "alert",
452
+ className: cn("fractal-alert", `fractal-alert--${variant}`, className),
453
+ ...props,
454
+ children: [
455
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "fractal-alert-icon", "aria-hidden": true, children: icon ?? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DefaultIcon, { size: 18 }) }),
456
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "fractal-alert-content", children })
457
+ ]
458
+ }
459
+ );
460
+ }
431
461
  );
432
462
  Alert.displayName = "Alert";
433
463
  var AlertTitle = React6.forwardRef(
@@ -511,27 +541,72 @@ function useEscapeDismiss(priority, handler, enabled = true) {
511
541
  }, [priority, enabled]);
512
542
  }
513
543
 
514
- // src/components/Modal/Modal.tsx
544
+ // src/components/UILoader/UILoader.tsx
545
+ var import_react2 = require("react");
515
546
  var import_jsx_runtime8 = require("react/jsx-runtime");
516
- var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
517
- function Modal({ open, onClose, title, children, danger, warn, footer, noClose, size = "sm", className }) {
518
- useEscapeDismiss(80, onClose, open && !noClose);
547
+ var LEFT = "M0 53C0 51 1.6 49.5 3.6 49.5h16.5c1 0 1.9.4 2.5 1L42.1 69.6c.7.7 1.1 1.6 1.1 2.5v16.2c0 2-1.6 3.5-3.6 3.5H23.1c-1 0-1.9-.4-2.5-1L1.1 71.7C.4 71 0 70.1 0 69.2V53Z";
548
+ var CENTER = "M0 3.5C0 1.6 1.6 0 3.6 0h16.5c1 0 1.9.4 2.5 1L92.5 69.6c.7.7 1 1.6 1 2.5v16.2c0 2-1.6 3.5-3.6 3.5H73.4c-1 0-1.9-.4-2.5-1L1.1 22.2C.4 21.6 0 20.7 0 19.7V3.5Z";
549
+ var RIGHT = "M50.4 3.5C50.4 1.6 52 0 54 0h16.5c1 0 1.9.4 2.5 1l69.8 68.6c.7.7 1.1 1.6 1.1 2.5v16.2c0 2-1.6 3.5-3.6 3.5h-16.5c-1 0-1.9-.4-2.5-1L51.4 22.2c-.7-.6-1-1.5-1-2.5V3.5Z";
550
+ function UILoader({ size = 48, tone = "neutral", className, style, label = "Loading", ariaHidden = false }) {
551
+ const rawId = (0, import_react2.useId)().replace(/[^a-zA-Z0-9_-]/g, "");
552
+ const clipId = `fractal-ui-loader-clip-${rawId}`;
553
+ const gradientId = `fractal-ui-loader-gradient-${rawId}`;
554
+ const height = typeof size === "number" ? `${size}px` : size;
555
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
556
+ "span",
557
+ {
558
+ "aria-hidden": ariaHidden || void 0,
559
+ "aria-label": ariaHidden ? void 0 : label,
560
+ className: cn("fractal-ui-loader", `fractal-ui-loader--${tone}`, className),
561
+ role: ariaHidden ? void 0 : "status",
562
+ style,
563
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 144 92", style: { height, width: "auto" }, children: [
564
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("defs", { children: [
565
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("linearGradient", { id: gradientId, x1: "59", x2: "94.3", y1: "0", y2: "89.1", gradientUnits: "userSpaceOnUse", children: [
566
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("stop", { className: "fractal-ui-loader__stop-start", offset: "0" }),
567
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("stop", { className: "fractal-ui-loader__stop-end", offset: "1" })
568
+ ] }),
569
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("linearGradient", { id: `${gradientId}-shine`, x1: "0", x2: "1", y1: "0", y2: "0", children: [
570
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("stop", { offset: "0.4", stopColor: "white", stopOpacity: "0" }),
571
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("stop", { offset: "0.5", stopColor: "white", stopOpacity: "0.62" }),
572
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("stop", { offset: "0.6", stopColor: "white", stopOpacity: "0" })
573
+ ] }),
574
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("clipPath", { id: clipId, children: [
575
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: LEFT }),
576
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: CENTER }),
577
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: RIGHT })
578
+ ] })
579
+ ] }),
580
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: CENTER, fill: `url(#${gradientId})` }),
581
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: RIGHT, fill: `url(#${gradientId})` }),
582
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: LEFT, fill: `url(#${gradientId})` }),
583
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("g", { clipPath: `url(#${clipId})`, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("g", { className: "fractal-ui-loader__shine-axis", transform: "translate(72 46) rotate(68.4)", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("rect", { className: "fractal-ui-loader__shine", x: "-160", y: "-100", width: "320", height: "200", fill: `url(#${gradientId}-shine)` }) }) })
584
+ ] })
585
+ }
586
+ );
587
+ }
588
+
589
+ // src/components/Modal/Modal.tsx
590
+ var import_jsx_runtime9 = require("react/jsx-runtime");
591
+ var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
592
+ function Modal({ open, onClose, title, children, danger, warn, footer, noClose, closeDisabled = false, size = "sm", loading = false, loadingLabel = "Loading", className }) {
593
+ useEscapeDismiss(80, onClose, open && !noClose && !closeDisabled);
519
594
  if (!open) return null;
520
595
  const sizeClass = `fractal-modal-panel--${size}`;
521
596
  const accentClass = danger ? "fractal-modal-panel--danger" : warn ? "fractal-modal-panel--warn" : "";
522
597
  return (0, import_react_dom.createPortal)(
523
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "fractal-modal-overlay", onClick: noClose ? void 0 : onClose, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
598
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fractal-modal-overlay", onClick: noClose || closeDisabled ? void 0 : onClose, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
524
599
  "div",
525
600
  {
526
601
  className: cn("fractal-modal-panel", sizeClass, accentClass, className),
527
602
  onClick: (e) => e.stopPropagation(),
528
603
  children: [
529
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "fractal-modal-title-row", children: [
530
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
531
- !noClose && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", onClick: onClose, title: "Close", className: "fractal-modal-close", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseIcon, {}) })
604
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "fractal-modal-title-row", children: [
605
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
606
+ !noClose && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CloseIcon, {}) })
532
607
  ] }),
533
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cn("fractal-modal-body", size === "lg" && "fractal-modal-body--lg"), children }),
534
- footer && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "fractal-modal-footer", children: footer })
608
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "aria-busy": loading || void 0, className: cn("fractal-modal-body", size === "lg" && "fractal-modal-body--lg", loading && "fractal-modal-body--loading"), children: loading ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UILoader, { label: loadingLabel }) : children }),
609
+ footer && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fractal-modal-footer", children: footer })
535
610
  ]
536
611
  }
537
612
  ) }),
@@ -540,17 +615,17 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
540
615
  }
541
616
 
542
617
  // src/components/DataTable/DataTable.tsx
543
- var import_jsx_runtime9 = require("react/jsx-runtime");
618
+ var import_jsx_runtime10 = require("react/jsx-runtime");
544
619
  function DataTable({ columns, data, emptyMessage, header, size = "md", className }) {
545
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cn("fractal-datatable", `fractal-datatable--${size}`, className), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "fractal-datatable-surface", children: [
546
- header && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fractal-datatable-header", children: header }),
547
- data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fractal-datatable-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("table", { className: "fractal-datatable-table", children: [
548
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { className: "fractal-datatable-thead-row", children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("th", { className: "fractal-datatable-th", style: { width: col.width }, children: col.header }, col.key)) }) }),
549
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
620
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn("fractal-datatable", `fractal-datatable--${size}`, className), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "fractal-datatable-surface", children: [
621
+ header && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fractal-datatable-header", children: header }),
622
+ data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fractal-datatable-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("table", { className: "fractal-datatable-table", children: [
623
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { className: "fractal-datatable-thead-row", children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("th", { className: "fractal-datatable-th", style: { width: col.width }, children: col.header }, col.key)) }) }),
624
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
550
625
  "tr",
551
626
  {
552
627
  className: "fractal-datatable-row",
553
- children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { className: "fractal-datatable-td", style: { width: col.width }, children: col.render(row, rowIndex) }, col.key))
628
+ children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { className: "fractal-datatable-td", style: { width: col.width }, children: col.render(row, rowIndex) }, col.key))
554
629
  },
555
630
  rowIndex
556
631
  )) })
@@ -560,8 +635,8 @@ function DataTable({ columns, data, emptyMessage, header, size = "md", className
560
635
 
561
636
  // src/components/Dropdown/Dropdown.tsx
562
637
  var React7 = __toESM(require("react"), 1);
563
- var import_fractal_icons2 = require("@mirror-physics/fractal-icons");
564
- var import_jsx_runtime10 = require("react/jsx-runtime");
638
+ var import_fractal_icons3 = require("@mirror-physics/fractal-icons");
639
+ var import_jsx_runtime11 = require("react/jsx-runtime");
565
640
  var MARGIN = 4;
566
641
  function Dropdown({
567
642
  items,
@@ -592,7 +667,7 @@ function Dropdown({
592
667
  const selectableItems = visibleItems.filter((i) => i.kind !== "header");
593
668
  const selected = items.find((i) => i.value === selectedValue && i.kind !== "header") ?? selectableItems[0] ?? visibleItems[0];
594
669
  const isUp = direction === "up";
595
- const ChevronIcon = isUp ? import_fractal_icons2.ChevronUp : import_fractal_icons2.ChevronDown;
670
+ const ChevronIcon = isUp ? import_fractal_icons3.ChevronUp : import_fractal_icons3.ChevronDown;
596
671
  React7.useLayoutEffect(() => {
597
672
  if (!open || !triggerRef.current || !panelRef.current) return;
598
673
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -637,8 +712,8 @@ function Dropdown({
637
712
  document.addEventListener("mousedown", handleClickOutside);
638
713
  return () => document.removeEventListener("mousedown", handleClickOutside);
639
714
  }, [open]);
640
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: cn("fractal-dropdown", className), children: [
641
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
715
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: cn("fractal-dropdown", className), children: [
716
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
642
717
  "button",
643
718
  {
644
719
  ref: triggerRef,
@@ -655,15 +730,15 @@ function Dropdown({
655
730
  triggerClassName
656
731
  ),
657
732
  children: [
658
- triggerContent != null ? triggerContent : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
659
- selected.icon != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-icon fractal-dropdown-icon--trigger", children: selected.icon }),
660
- selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-selected-text", children: selected.description })
733
+ triggerContent != null ? triggerContent : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
734
+ selected.icon != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "fractal-dropdown-icon fractal-dropdown-icon--trigger", children: selected.icon }),
735
+ selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "fractal-dropdown-selected-text", children: selected.description })
661
736
  ] }),
662
- !noChevron && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-chevron", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChevronIcon, { size: size === "sm" ? 14 : 16 }) })
737
+ !noChevron && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "fractal-dropdown-chevron", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChevronIcon, { size: size === "sm" ? 14 : 16 }) })
663
738
  ]
664
739
  }
665
740
  ),
666
- open && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
741
+ open && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
667
742
  "div",
668
743
  {
669
744
  ref: panelRef,
@@ -672,21 +747,21 @@ function Dropdown({
672
747
  className: cn("fractal-dropdown-panel", `fractal-dropdown-panel--${size}`, panelClassName),
673
748
  style: panelStyle,
674
749
  children: [
675
- label != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fractal-dropdown-label", children: label }),
750
+ label != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fractal-dropdown-label", children: label }),
676
751
  visibleItems.map((item, index) => {
677
- const topDivider = item.border === "top" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
678
- const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
752
+ const topDivider = item.border === "top" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
753
+ const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
679
754
  if (item.kind === "header") {
680
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(React7.Fragment, { children: [
755
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React7.Fragment, { children: [
681
756
  topDivider,
682
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
757
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
683
758
  bottomDivider
684
759
  ] }, `header-${index}`);
685
760
  }
686
761
  const isSelected = item.value === selectedValue;
687
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(React7.Fragment, { children: [
762
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React7.Fragment, { children: [
688
763
  topDivider,
689
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
764
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
690
765
  "button",
691
766
  {
692
767
  type: "button",
@@ -698,9 +773,9 @@ function Dropdown({
698
773
  },
699
774
  className: "fractal-dropdown-option",
700
775
  children: [
701
- item.icon != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-icon", children: item.icon }),
702
- item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-option-text", children: item.description }),
703
- item.trailing != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-trailing", children: item.trailing })
776
+ item.icon != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "fractal-dropdown-icon", children: item.icon }),
777
+ item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "fractal-dropdown-option-text", children: item.description }),
778
+ item.trailing != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "fractal-dropdown-trailing", children: item.trailing })
704
779
  ]
705
780
  }
706
781
  ),
@@ -715,9 +790,9 @@ function Dropdown({
715
790
 
716
791
  // src/components/Link/Link.tsx
717
792
  var React8 = __toESM(require("react"), 1);
718
- var import_jsx_runtime11 = require("react/jsx-runtime");
793
+ var import_jsx_runtime12 = require("react/jsx-runtime");
719
794
  var Link = React8.forwardRef(
720
- ({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
795
+ ({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
721
796
  "a",
722
797
  {
723
798
  ref,
@@ -730,9 +805,9 @@ Link.displayName = "Link";
730
805
 
731
806
  // src/components/Chip/Chip.tsx
732
807
  var React9 = __toESM(require("react"), 1);
733
- var import_jsx_runtime12 = require("react/jsx-runtime");
808
+ var import_jsx_runtime13 = require("react/jsx-runtime");
734
809
  var Chip = React9.forwardRef(
735
- ({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
810
+ ({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
736
811
  "span",
737
812
  {
738
813
  ref,
@@ -744,10 +819,10 @@ var Chip = React9.forwardRef(
744
819
  Chip.displayName = "Chip";
745
820
 
746
821
  // src/components/Checkbox/Checkbox.tsx
747
- var import_fractal_icons3 = require("@mirror-physics/fractal-icons");
748
- var import_jsx_runtime13 = require("react/jsx-runtime");
822
+ var import_fractal_icons4 = require("@mirror-physics/fractal-icons");
823
+ var import_jsx_runtime14 = require("react/jsx-runtime");
749
824
  function Checkbox({ checked, onCheckedChange, className, disabled, onClick, onKeyDown, ...props }) {
750
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
825
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
751
826
  "button",
752
827
  {
753
828
  ...props,
@@ -764,15 +839,15 @@ function Checkbox({ checked, onCheckedChange, className, disabled, onClick, onKe
764
839
  onKeyDown?.(event);
765
840
  if (event.key === " " || event.key === "Enter") event.stopPropagation();
766
841
  },
767
- children: checked ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_fractal_icons3.CheckboxChecked, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_fractal_icons3.Checkbox, { "aria-hidden": "true", size: 18 })
842
+ children: checked ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_fractal_icons4.CheckboxChecked, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_fractal_icons4.Checkbox, { "aria-hidden": "true", size: 18 })
768
843
  }
769
844
  );
770
845
  }
771
846
 
772
847
  // src/components/SortableTable/SortableTable.tsx
773
- var import_react2 = require("react");
774
- var import_fractal_icons4 = require("@mirror-physics/fractal-icons");
775
- var import_jsx_runtime14 = require("react/jsx-runtime");
848
+ var import_react3 = require("react");
849
+ var import_fractal_icons5 = require("@mirror-physics/fractal-icons");
850
+ var import_jsx_runtime15 = require("react/jsx-runtime");
776
851
  function SortableTable({
777
852
  columns,
778
853
  data,
@@ -791,8 +866,8 @@ function SortableTable({
791
866
  onRowClick,
792
867
  rowAction
793
868
  }) {
794
- const [internalKey, setInternalKey] = (0, import_react2.useState)(defaultSortKey ?? null);
795
- const [internalDirection, setInternalDirection] = (0, import_react2.useState)(defaultSortDirection);
869
+ const [internalKey, setInternalKey] = (0, import_react3.useState)(defaultSortKey ?? null);
870
+ const [internalDirection, setInternalDirection] = (0, import_react3.useState)(defaultSortDirection);
796
871
  const isControlled = controlledKey !== void 0 && controlledDirection !== void 0;
797
872
  const activeKey = isControlled ? controlledKey : internalKey;
798
873
  const activeDirection = isControlled ? controlledDirection : internalDirection;
@@ -800,7 +875,7 @@ function SortableTable({
800
875
  const baselineDirection = defaultSort?.direction ?? null;
801
876
  const effectiveKey = activeKey && activeDirection ? activeKey : baselineKey;
802
877
  const effectiveDirection = activeKey && activeDirection ? activeDirection : baselineDirection;
803
- const sorted = (0, import_react2.useMemo)(() => {
878
+ const sorted = (0, import_react3.useMemo)(() => {
804
879
  if (!effectiveKey || !effectiveDirection) return data;
805
880
  const col = columns.find((c) => c.key === effectiveKey);
806
881
  if (!col) return data;
@@ -832,12 +907,12 @@ function SortableTable({
832
907
  nextDirection = baselineKey === key && baselineDirection ? baselineDirection : "asc";
833
908
  } else if (activeKey !== key) {
834
909
  nextDirection = "asc";
910
+ } else if (baselineKey === key && baselineDirection) {
911
+ nextDirection = activeDirection === baselineDirection ? baselineDirection === "asc" ? "desc" : "asc" : null;
835
912
  } else if (activeDirection === "asc") {
836
913
  nextDirection = "desc";
837
- } else if (activeDirection === "desc") {
838
- nextDirection = null;
839
914
  } else {
840
- nextDirection = "asc";
915
+ nextDirection = null;
841
916
  }
842
917
  const nextKey = nextDirection === null ? null : key;
843
918
  if (isControlled) {
@@ -848,13 +923,13 @@ function SortableTable({
848
923
  onSortChange?.(nextKey, nextDirection);
849
924
  }
850
925
  };
851
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "fractal-sortable-table-surface", children: [
852
- header && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "fractal-sortable-table-header", children: header }),
853
- sorted.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("table", { className: "fractal-sortable-table-table", children: [
854
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tr", { className: "fractal-sortable-table-thead-row", children: columns.map((col) => {
926
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "fractal-sortable-table-surface", children: [
927
+ header && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "fractal-sortable-table-header", children: header }),
928
+ sorted.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("table", { className: "fractal-sortable-table-table", children: [
929
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("tr", { className: "fractal-sortable-table-thead-row", children: columns.map((col) => {
855
930
  const isActive = activeKey === col.key && activeDirection !== null;
856
931
  if (!col.sortable) {
857
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
932
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
858
933
  "th",
859
934
  {
860
935
  className: "fractal-sortable-table-th",
@@ -864,12 +939,12 @@ function SortableTable({
864
939
  col.key
865
940
  );
866
941
  }
867
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
942
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
868
943
  "th",
869
944
  {
870
945
  className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
871
946
  style: { width: col.width },
872
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
947
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
873
948
  "button",
874
949
  {
875
950
  type: "button",
@@ -880,8 +955,8 @@ function SortableTable({
880
955
  onClick: () => handleSortClick(col.key),
881
956
  "aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
882
957
  children: [
883
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: col.header }),
884
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_fractal_icons4.ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_fractal_icons4.ArrowDown, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_fractal_icons4.ArrowsUpDown, { size: 14 }) })
958
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: col.header }),
959
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_fractal_icons5.ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_fractal_icons5.ArrowDown, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_fractal_icons5.ArrowsUpDown, { size: 14 }) })
885
960
  ]
886
961
  }
887
962
  )
@@ -889,13 +964,13 @@ function SortableTable({
889
964
  col.key
890
965
  );
891
966
  }) }) }),
892
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tbody", { children: sorted.map((row, rowIndex) => {
967
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("tbody", { children: sorted.map((row, rowIndex) => {
893
968
  const highlighted = highlightRow?.(row, rowIndex) ?? false;
894
969
  const action = rowAction ? {
895
970
  label: rowAction.label(row, rowIndex),
896
971
  icon: rowAction.icon(row, rowIndex)
897
972
  } : null;
898
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
973
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
899
974
  "tr",
900
975
  {
901
976
  className: cn(
@@ -913,7 +988,7 @@ function SortableTable({
913
988
  "aria-label": action?.label,
914
989
  role: onRowClick ? "button" : void 0,
915
990
  tabIndex: onRowClick ? 0 : void 0,
916
- children: columns.map((col, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
991
+ children: columns.map((col, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
917
992
  "td",
918
993
  {
919
994
  className: cn(
@@ -923,7 +998,7 @@ function SortableTable({
923
998
  style: { width: col.width, textAlign: col.align ?? "left" },
924
999
  children: [
925
1000
  col.render(row, rowIndex),
926
- action && columnIndex === columns.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "fractal-sortable-table-row-action", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "fractal-sortable-table-row-action__icon", children: action.icon }) })
1001
+ action && columnIndex === columns.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-sortable-table-row-action", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-sortable-table-row-action__icon", children: action.icon }) })
927
1002
  ]
928
1003
  },
929
1004
  col.key
@@ -937,8 +1012,8 @@ function SortableTable({
937
1012
  }
938
1013
 
939
1014
  // src/components/Tabs/Tabs.tsx
940
- var import_react3 = require("react");
941
- var import_jsx_runtime15 = require("react/jsx-runtime");
1015
+ var import_react4 = require("react");
1016
+ var import_jsx_runtime16 = require("react/jsx-runtime");
942
1017
  function Tabs({
943
1018
  items,
944
1019
  defaultValue,
@@ -948,16 +1023,16 @@ function Tabs({
948
1023
  ariaLabel,
949
1024
  divider = false
950
1025
  }) {
951
- const reactId = (0, import_react3.useId)();
952
- const [internalValue, setInternalValue] = (0, import_react3.useState)(
1026
+ const reactId = (0, import_react4.useId)();
1027
+ const [internalValue, setInternalValue] = (0, import_react4.useState)(
953
1028
  defaultValue ?? items.find((i) => !i.disabled)?.id ?? items[0]?.id ?? ""
954
1029
  );
955
1030
  const isControlled = controlledValue !== void 0;
956
1031
  const activeId = isControlled ? controlledValue : internalValue;
957
- const tabListRef = (0, import_react3.useRef)(null);
958
- const tabRefs = (0, import_react3.useRef)({});
959
- const [indicator, setIndicator] = (0, import_react3.useState)(null);
960
- (0, import_react3.useLayoutEffect)(() => {
1032
+ const tabListRef = (0, import_react4.useRef)(null);
1033
+ const tabRefs = (0, import_react4.useRef)({});
1034
+ const [indicator, setIndicator] = (0, import_react4.useState)(null);
1035
+ (0, import_react4.useLayoutEffect)(() => {
961
1036
  const updateIndicator = () => {
962
1037
  const activeTab = tabRefs.current[activeId];
963
1038
  if (!activeTab) return;
@@ -1008,8 +1083,8 @@ function Tabs({
1008
1083
  selectTab(nextId2);
1009
1084
  requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
1010
1085
  };
1011
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn("fractal-tabs", divider && "fractal-tabs--divider", className), children: [
1012
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1086
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cn("fractal-tabs", divider && "fractal-tabs--divider", className), children: [
1087
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1013
1088
  "div",
1014
1089
  {
1015
1090
  ref: tabListRef,
@@ -1022,7 +1097,7 @@ function Tabs({
1022
1097
  const isActive = item.id === activeId;
1023
1098
  const tabId = `${reactId}-tab-${item.id}`;
1024
1099
  const panelId = `${reactId}-panel-${item.id}`;
1025
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1100
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1026
1101
  "button",
1027
1102
  {
1028
1103
  ref: (el) => {
@@ -1053,7 +1128,7 @@ function Tabs({
1053
1128
  const tabId = `${reactId}-tab-${item.id}`;
1054
1129
  const panelId = `${reactId}-panel-${item.id}`;
1055
1130
  const isActive = item.id === activeId;
1056
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1131
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1057
1132
  "div",
1058
1133
  {
1059
1134
  id: panelId,
@@ -1071,9 +1146,36 @@ function Tabs({
1071
1146
 
1072
1147
  // src/components/ContentSwitcher/ContentSwitcher.tsx
1073
1148
  var React10 = __toESM(require("react"), 1);
1074
- var import_jsx_runtime16 = require("react/jsx-runtime");
1149
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1075
1150
  function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
1151
+ const switcherRef = React10.useRef(null);
1076
1152
  const buttonRefs = React10.useRef([]);
1153
+ const activeIndex = items.findIndex((item) => item.value === value);
1154
+ React10.useLayoutEffect(() => {
1155
+ const switcher = switcherRef.current;
1156
+ const activeButton = buttonRefs.current[activeIndex];
1157
+ if (!switcher || !activeButton) {
1158
+ switcher?.removeAttribute("data-indicator-ready");
1159
+ return;
1160
+ }
1161
+ const updateIndicator = () => {
1162
+ const switcherRect = switcher.getBoundingClientRect();
1163
+ const activeButtonRect = activeButton.getBoundingClientRect();
1164
+ switcher.style.setProperty("--fractal-content-switcher-indicator-x", `${activeButtonRect.left - switcherRect.left - switcher.clientLeft}px`);
1165
+ switcher.style.setProperty("--fractal-content-switcher-indicator-y", `${activeButtonRect.top - switcherRect.top - switcher.clientTop}px`);
1166
+ switcher.style.setProperty("--fractal-content-switcher-indicator-width", `${activeButtonRect.width}px`);
1167
+ switcher.style.setProperty("--fractal-content-switcher-indicator-height", `${activeButtonRect.height}px`);
1168
+ switcher.setAttribute("data-indicator-ready", "true");
1169
+ };
1170
+ updateIndicator();
1171
+ if (typeof ResizeObserver === "undefined") return;
1172
+ const resizeObserver = new ResizeObserver(updateIndicator);
1173
+ resizeObserver.observe(switcher);
1174
+ buttonRefs.current.forEach((button) => {
1175
+ if (button) resizeObserver.observe(button);
1176
+ });
1177
+ return () => resizeObserver.disconnect();
1178
+ }, [activeIndex, items.length]);
1077
1179
  const moveFocus = (index, direction) => {
1078
1180
  let nextIndex = index;
1079
1181
  do {
@@ -1084,40 +1186,52 @@ function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = f
1084
1186
  onValueChange(items[nextIndex].value);
1085
1187
  }
1086
1188
  };
1087
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cn("fractal-content-switcher", fullWidth && "fractal-content-switcher--full-width", className), role: "group", "aria-label": ariaLabel, children: items.map((item, index) => {
1088
- const active = item.value === value;
1089
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1090
- "button",
1091
- {
1092
- className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
1093
- type: "button",
1094
- "aria-pressed": active,
1095
- disabled: item.disabled,
1096
- onClick: () => onValueChange(item.value),
1097
- onKeyDown: (event) => {
1098
- if (event.key === "ArrowRight") {
1099
- event.preventDefault();
1100
- moveFocus(index, 1);
1101
- }
1102
- if (event.key === "ArrowLeft") {
1103
- event.preventDefault();
1104
- moveFocus(index, -1);
1105
- }
1106
- },
1107
- ref: (element) => {
1108
- buttonRefs.current[index] = element;
1109
- },
1110
- children: item.label
1111
- },
1112
- item.value
1113
- );
1114
- }) });
1189
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1190
+ "div",
1191
+ {
1192
+ className: cn("fractal-content-switcher", fullWidth && "fractal-content-switcher--full-width", className),
1193
+ role: "group",
1194
+ "aria-label": ariaLabel,
1195
+ ref: switcherRef,
1196
+ children: [
1197
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "fractal-content-switcher__indicator", "aria-hidden": true }),
1198
+ items.map((item, index) => {
1199
+ const active = item.value === value;
1200
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1201
+ "button",
1202
+ {
1203
+ className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
1204
+ type: "button",
1205
+ "aria-pressed": active,
1206
+ disabled: item.disabled,
1207
+ onClick: () => onValueChange(item.value),
1208
+ onKeyDown: (event) => {
1209
+ if (event.key === "ArrowRight") {
1210
+ event.preventDefault();
1211
+ moveFocus(index, 1);
1212
+ }
1213
+ if (event.key === "ArrowLeft") {
1214
+ event.preventDefault();
1215
+ moveFocus(index, -1);
1216
+ }
1217
+ },
1218
+ ref: (element) => {
1219
+ buttonRefs.current[index] = element;
1220
+ },
1221
+ children: item.label
1222
+ },
1223
+ item.value
1224
+ );
1225
+ })
1226
+ ]
1227
+ }
1228
+ );
1115
1229
  }
1116
1230
 
1117
1231
  // src/components/Disclosure/Disclosure.tsx
1118
- var import_react4 = require("react");
1119
- var import_fractal_icons5 = require("@mirror-physics/fractal-icons");
1120
- var import_jsx_runtime17 = require("react/jsx-runtime");
1232
+ var import_react5 = require("react");
1233
+ var import_fractal_icons6 = require("@mirror-physics/fractal-icons");
1234
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1121
1235
  function Disclosure({
1122
1236
  title,
1123
1237
  meta,
@@ -1129,10 +1243,10 @@ function Disclosure({
1129
1243
  className,
1130
1244
  variant = "card"
1131
1245
  }) {
1132
- const reactId = (0, import_react4.useId)();
1246
+ const reactId = (0, import_react5.useId)();
1133
1247
  const headerId = `${reactId}-header`;
1134
1248
  const panelId = `${reactId}-panel`;
1135
- const [internalOpen, setInternalOpen] = (0, import_react4.useState)(defaultOpen);
1249
+ const [internalOpen, setInternalOpen] = (0, import_react5.useState)(defaultOpen);
1136
1250
  const isControlled = controlledOpen !== void 0;
1137
1251
  const isOpen = isControlled ? controlledOpen : internalOpen;
1138
1252
  const toggle = () => {
@@ -1145,7 +1259,7 @@ function Disclosure({
1145
1259
  onOpenChange?.(next);
1146
1260
  }
1147
1261
  };
1148
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1262
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1149
1263
  "div",
1150
1264
  {
1151
1265
  className: cn(
@@ -1156,7 +1270,7 @@ function Disclosure({
1156
1270
  className
1157
1271
  ),
1158
1272
  children: [
1159
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1273
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1160
1274
  "button",
1161
1275
  {
1162
1276
  type: "button",
@@ -1167,13 +1281,13 @@ function Disclosure({
1167
1281
  disabled,
1168
1282
  onClick: toggle,
1169
1283
  children: [
1170
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_fractal_icons5.ChevronDown, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_fractal_icons5.ChevronRight, { size: 16 }) }),
1171
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "fractal-disclosure-title", children: title }),
1172
- meta && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "fractal-disclosure-meta", children: meta })
1284
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_fractal_icons6.ChevronDown, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_fractal_icons6.ChevronRight, { size: 16 }) }),
1285
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "fractal-disclosure-title", children: title }),
1286
+ meta && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "fractal-disclosure-meta", children: meta })
1173
1287
  ]
1174
1288
  }
1175
1289
  ),
1176
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1290
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1177
1291
  "div",
1178
1292
  {
1179
1293
  id: panelId,
@@ -1181,7 +1295,7 @@ function Disclosure({
1181
1295
  "aria-labelledby": headerId,
1182
1296
  className: "fractal-disclosure-panel",
1183
1297
  hidden: !isOpen,
1184
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "fractal-disclosure-panel-inner", children })
1298
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fractal-disclosure-panel-inner", children })
1185
1299
  }
1186
1300
  )
1187
1301
  ]
@@ -1190,18 +1304,18 @@ function Disclosure({
1190
1304
  }
1191
1305
 
1192
1306
  // src/components/LatticeLoader/LatticeLoader.tsx
1193
- var import_jsx_runtime18 = require("react/jsx-runtime");
1307
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1194
1308
  var LATTICE_COUNT = 160;
1195
1309
  var WAVE_PERIOD = 80;
1196
1310
  function LatticeLoader({ className, label = "Loading", ...props }) {
1197
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1311
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1198
1312
  "span",
1199
1313
  {
1200
1314
  "aria-label": label,
1201
1315
  className: cn("fractal-lattice-loader", className),
1202
1316
  role: "progressbar",
1203
1317
  ...props,
1204
- children: Array.from({ length: LATTICE_COUNT }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1318
+ children: Array.from({ length: LATTICE_COUNT }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1205
1319
  "span",
1206
1320
  {
1207
1321
  "aria-hidden": "true",
@@ -1214,11 +1328,151 @@ function LatticeLoader({ className, label = "Loading", ...props }) {
1214
1328
  );
1215
1329
  }
1216
1330
 
1331
+ // src/components/Ghost/Ghost.tsx
1332
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1333
+ var toCssLength = (value) => typeof value === "number" ? `${value}px` : value;
1334
+ function Ghost({ className, width, height, radius, style, ...props }) {
1335
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1336
+ "div",
1337
+ {
1338
+ "aria-hidden": "true",
1339
+ className: cn("fractal-ghost", className),
1340
+ style: {
1341
+ width: toCssLength(width),
1342
+ height: toCssLength(height),
1343
+ borderRadius: toCssLength(radius),
1344
+ ...style
1345
+ },
1346
+ ...props
1347
+ }
1348
+ );
1349
+ }
1350
+ function GhostLine({ className, size = "md", width = "100%", ...props }) {
1351
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: cn("fractal-ghost-line", `fractal-ghost-line--${size}`, className), width, ...props });
1352
+ }
1353
+ function ButtonGhost({ className, size = "md", iconOnly = false, width, ...props }) {
1354
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: cn("fractal-ghost-button", `fractal-ghost-button--${size}`, iconOnly && "fractal-ghost-button--icon-only", className), width, ...props });
1355
+ }
1356
+ function CardGhost({ className, lines = 3, showHeader = true, ...props }) {
1357
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-card", className), ...props, children: [
1358
+ showHeader && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: "38%" }),
1359
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: index === lines - 1 ? "62%" : "100%" }, index)) })
1360
+ ] });
1361
+ }
1362
+ function DataTableGhost({
1363
+ className,
1364
+ showHeader = true,
1365
+ headers,
1366
+ columns = 4,
1367
+ rows = 5,
1368
+ columnWidths,
1369
+ size = "md",
1370
+ ...props
1371
+ }) {
1372
+ const cells = Array.from({ length: columns }, (_, index) => index);
1373
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { "aria-busy": "true", "aria-label": "Loading table", className: cn("fractal-ghost-table", `fractal-ghost-table--${size}`, className), role: "status", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("table", { className: "fractal-ghost-table__table", children: [
1374
+ (showHeader || headers) && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tr", { className: "fractal-ghost-table__head-row", children: cells.map((index) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("th", { style: { width: columnWidths?.[index] }, children: headers?.[index] ?? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { size: "sm", width: index === columns - 1 ? "62%" : "76%" }) }, index)) }) }),
1375
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tbody", { children: Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tr", { className: "fractal-ghost-table__row", children: cells.map((columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("td", { style: { width: columnWidths?.[columnIndex] }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: `${[72, 54, 82, 63, 46][(rowIndex + columnIndex) % 5]}%` }) }, columnIndex)) }, rowIndex)) })
1376
+ ] }) });
1377
+ }
1378
+ function InputGhost({ className, labelWidth = "26%", ...props }) {
1379
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FormFieldGhost, { className, labelWidth, ...props });
1380
+ }
1381
+ function TextareaGhost({ className, labelWidth = "26%", ...props }) {
1382
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FormFieldGhost, { className, labelWidth, multiline: true, ...props });
1383
+ }
1384
+ function LabelGhost({ className, width = "26%", ...props }) {
1385
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { className: cn("fractal-ghost-label", className), size: "sm", width, ...props });
1386
+ }
1387
+ function FormFieldGhost({ className, labelWidth = "26%", multiline = false, ...props }) {
1388
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-field", className), ...props, children: [
1389
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LabelGhost, { width: labelWidth }),
1390
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: cn("fractal-ghost-field__control", multiline && "fractal-ghost-field__control--multiline") })
1391
+ ] });
1392
+ }
1393
+ function AlertGhost({ className, ...props }) {
1394
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-alert", className), ...props, children: [
1395
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: "30%" }),
1396
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { size: "sm", width: "78%" })
1397
+ ] });
1398
+ }
1399
+ function CheckboxGhost({ className, ...props }) {
1400
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-choice", className), ...props, children: [
1401
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: "fractal-ghost-choice__control" }),
1402
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: "42%" })
1403
+ ] });
1404
+ }
1405
+ var ToggleGhost = CheckboxGhost;
1406
+ function ChipGhost({ className, width = 74, ...props }) {
1407
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: cn("fractal-ghost-chip", className), height: 24, width, ...props });
1408
+ }
1409
+ function LinkGhost({ className, width = 96, ...props }) {
1410
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { className: cn("fractal-ghost-link", className), size: "sm", width, ...props });
1411
+ }
1412
+ var TextButtonGhost = LinkGhost;
1413
+ function DropdownGhost({ className, ...props }) {
1414
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropdown", className), ...props, children: [
1415
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: "38%" }),
1416
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: "fractal-ghost-dropdown__chevron" })
1417
+ ] });
1418
+ }
1419
+ function ContentSwitcherGhost({ className, options = 3, ...props }) {
1420
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { "aria-hidden": "true", className: cn("fractal-ghost-switcher", className), ...props, children: Array.from({ length: options }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, {}, index)) });
1421
+ }
1422
+ var TabsGhost = ContentSwitcherGhost;
1423
+ function DisclosureGhost({ className, ...props }) {
1424
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-disclosure", className), ...props, children: [
1425
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: "fractal-ghost-disclosure__icon" }),
1426
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: "42%" })
1427
+ ] });
1428
+ }
1429
+ function PaginationGhost({ className, pages = 5, ...props }) {
1430
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { "aria-hidden": "true", className: cn("fractal-ghost-pagination", className), ...props, children: Array.from({ length: pages }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, {}, index)) });
1431
+ }
1432
+ function FileDropzoneGhost({ className, ...props }) {
1433
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropzone", className), ...props, children: [
1434
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: "fractal-ghost-dropzone__icon" }),
1435
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: "26%" }),
1436
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { size: "sm", width: "46%" })
1437
+ ] });
1438
+ }
1439
+ function PromptCardGhost({ className, ...props }) {
1440
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardGhost, { className: cn("fractal-ghost-prompt-card", className), lines: 4, ...props });
1441
+ }
1442
+ function SortableTableGhost(props) {
1443
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DataTableGhost, { ...props });
1444
+ }
1445
+ function SidebarGhost({ className, items = 6, ...props }) {
1446
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("aside", { "aria-hidden": "true", className: cn("fractal-ghost-sidebar", className), ...props, children: [
1447
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: "fractal-ghost-sidebar__brand" }),
1448
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-ghost-sidebar__items", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "fractal-ghost-sidebar__item", children: [
1449
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, {}),
1450
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: `${[54, 68, 44, 61][index % 4]}%` })
1451
+ ] }, index)) })
1452
+ ] });
1453
+ }
1454
+ function ModalGhost({ className, title, lines = 3, ...props }) {
1455
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SurfaceGhost, { className: cn("fractal-ghost-modal", className), title, lines, ...props });
1456
+ }
1457
+ function SidePanelGhost({ className, title, lines = 5, ...props }) {
1458
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SurfaceGhost, { className: cn("fractal-ghost-side-panel", className), title, lines, ...props });
1459
+ }
1460
+ function SurfaceGhost({ className, title, lines = 3, ...props }) {
1461
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-surface", className), ...props, children: [
1462
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "fractal-ghost-surface__header", children: [
1463
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: "42%" }),
1464
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Ghost, { className: "fractal-ghost-surface__close" })
1465
+ ] }),
1466
+ title && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-ghost-surface__title", children: title }),
1467
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GhostLine, { width: index === lines - 1 ? "64%" : "100%" }, index)) })
1468
+ ] });
1469
+ }
1470
+
1217
1471
  // src/components/Sidebar/Sidebar.tsx
1218
1472
  var React11 = __toESM(require("react"), 1);
1219
- var import_jsx_runtime19 = require("react/jsx-runtime");
1473
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1220
1474
  var Sidebar = React11.forwardRef(
1221
- ({ className, width, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1475
+ ({ className, width, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1222
1476
  "aside",
1223
1477
  {
1224
1478
  ref,
@@ -1230,23 +1484,23 @@ var Sidebar = React11.forwardRef(
1230
1484
  );
1231
1485
  Sidebar.displayName = "Sidebar";
1232
1486
  var SidebarHeader = React11.forwardRef(
1233
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
1487
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
1234
1488
  );
1235
1489
  SidebarHeader.displayName = "SidebarHeader";
1236
1490
  var SidebarBrand = React11.forwardRef(
1237
- ({ className, type = "button", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
1491
+ ({ className, type = "button", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
1238
1492
  );
1239
1493
  SidebarBrand.displayName = "SidebarBrand";
1240
1494
  var SidebarNav = React11.forwardRef(
1241
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
1495
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
1242
1496
  );
1243
1497
  SidebarNav.displayName = "SidebarNav";
1244
1498
  var SidebarSection = React11.forwardRef(
1245
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
1499
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
1246
1500
  );
1247
1501
  SidebarSection.displayName = "SidebarSection";
1248
1502
  var SidebarNavItem = React11.forwardRef(
1249
- ({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1503
+ ({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1250
1504
  "button",
1251
1505
  {
1252
1506
  ref,
@@ -1256,28 +1510,28 @@ var SidebarNavItem = React11.forwardRef(
1256
1510
  "aria-current": active ? "page" : void 0,
1257
1511
  ...props,
1258
1512
  children: [
1259
- icon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
1260
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fractal-sidebar__nav-item-label", children }),
1261
- endAdornment && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
1513
+ icon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
1514
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fractal-sidebar__nav-item-label", children }),
1515
+ endAdornment && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
1262
1516
  ]
1263
1517
  }
1264
1518
  )
1265
1519
  );
1266
1520
  SidebarNavItem.displayName = "SidebarNavItem";
1267
1521
  var SidebarFooter = React11.forwardRef(
1268
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
1522
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
1269
1523
  );
1270
1524
  SidebarFooter.displayName = "SidebarFooter";
1271
1525
 
1272
1526
  // src/components/SidePanel/SidePanel.tsx
1273
1527
  var import_react_dom2 = require("react-dom");
1274
- var import_fractal_icons6 = require("@mirror-physics/fractal-icons");
1275
- var import_jsx_runtime20 = require("react/jsx-runtime");
1276
- function SidePanel({ open, onClose, title, description, children, footer, size = "md", className }) {
1528
+ var import_fractal_icons7 = require("@mirror-physics/fractal-icons");
1529
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1530
+ function SidePanel({ open, onClose, title, description, children, footer, size = "md", loading = false, loadingLabel = "Loading", className }) {
1277
1531
  useEscapeDismiss(80, onClose, open);
1278
1532
  if (!open) return null;
1279
1533
  return (0, import_react_dom2.createPortal)(
1280
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1534
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1281
1535
  "aside",
1282
1536
  {
1283
1537
  className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
@@ -1286,15 +1540,15 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
1286
1540
  role: "dialog",
1287
1541
  onMouseDown: (event) => event.stopPropagation(),
1288
1542
  children: [
1289
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("header", { className: "fractal-side-panel__header", children: [
1290
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "fractal-side-panel__heading", children: [
1291
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h2", { className: "fractal-side-panel__title", children: title }),
1292
- description && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "fractal-side-panel__description", children: description })
1543
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("header", { className: "fractal-side-panel__header", children: [
1544
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fractal-side-panel__heading", children: [
1545
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { className: "fractal-side-panel__title", children: title }),
1546
+ description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "fractal-side-panel__description", children: description })
1293
1547
  ] }),
1294
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_fractal_icons6.Close, { size: 18 }) })
1548
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_fractal_icons7.Close, { size: 18 }) })
1295
1549
  ] }),
1296
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-side-panel__body", children }),
1297
- footer && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("footer", { className: "fractal-side-panel__footer", children: footer })
1550
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { "aria-busy": loading || void 0, className: cn("fractal-side-panel__body", loading && "fractal-side-panel__body--loading"), children: loading ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(UILoader, { label: loadingLabel }) : children }),
1551
+ footer && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("footer", { className: "fractal-side-panel__footer", children: footer })
1298
1552
  ]
1299
1553
  }
1300
1554
  ) }),
@@ -1304,17 +1558,17 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
1304
1558
 
1305
1559
  // src/components/Textarea/Textarea.tsx
1306
1560
  var React12 = __toESM(require("react"), 1);
1307
- var import_jsx_runtime21 = require("react/jsx-runtime");
1561
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1308
1562
  var Textarea = React12.forwardRef(
1309
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("textarea", { ref, className: cn("fractal-textarea", className), ...props })
1563
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("textarea", { ref, className: cn("fractal-textarea", className), ...props })
1310
1564
  );
1311
1565
  Textarea.displayName = "Textarea";
1312
1566
 
1313
1567
  // src/components/TextButton/TextButton.tsx
1314
1568
  var React13 = __toESM(require("react"), 1);
1315
- var import_jsx_runtime22 = require("react/jsx-runtime");
1569
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1316
1570
  var TextButton = React13.forwardRef(
1317
- ({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1571
+ ({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
1318
1572
  "button",
1319
1573
  {
1320
1574
  ref,
@@ -1322,9 +1576,9 @@ var TextButton = React13.forwardRef(
1322
1576
  type: "button",
1323
1577
  ...props,
1324
1578
  children: [
1325
- icon && iconPosition === "start" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
1326
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children }),
1327
- icon && iconPosition === "end" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
1579
+ icon && iconPosition === "start" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
1580
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children }),
1581
+ icon && iconPosition === "end" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
1328
1582
  ]
1329
1583
  }
1330
1584
  )
@@ -1333,8 +1587,8 @@ TextButton.displayName = "TextButton";
1333
1587
 
1334
1588
  // src/components/FileDropzone/FileDropzone.tsx
1335
1589
  var React14 = __toESM(require("react"), 1);
1336
- var import_fractal_icons7 = require("@mirror-physics/fractal-icons");
1337
- var import_jsx_runtime23 = require("react/jsx-runtime");
1590
+ var import_fractal_icons8 = require("@mirror-physics/fractal-icons");
1591
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1338
1592
  function FileDropzone({
1339
1593
  files,
1340
1594
  onFilesChange,
@@ -1354,8 +1608,8 @@ function FileDropzone({
1354
1608
  if (additions.length === 0) return;
1355
1609
  onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
1356
1610
  };
1357
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cn("fractal-file-dropzone", className), children: [
1358
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1611
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("fractal-file-dropzone", className), children: [
1612
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1359
1613
  "input",
1360
1614
  {
1361
1615
  ref: inputRef,
@@ -1371,7 +1625,7 @@ function FileDropzone({
1371
1625
  }
1372
1626
  }
1373
1627
  ),
1374
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1628
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1375
1629
  "button",
1376
1630
  {
1377
1631
  className: "fractal-file-dropzone__target",
@@ -1394,18 +1648,18 @@ function FileDropzone({
1394
1648
  addFiles(event.dataTransfer.files);
1395
1649
  },
1396
1650
  children: [
1397
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_fractal_icons7.FileArrowUp, { "aria-hidden": "true", size: 20 }),
1398
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "fractal-file-dropzone__copy", children: [
1399
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-file-dropzone__title", children: title }),
1400
- description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-file-dropzone__description", children: description })
1651
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_fractal_icons8.FileArrowUp, { "aria-hidden": "true", size: 20 }),
1652
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "fractal-file-dropzone__copy", children: [
1653
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-file-dropzone__title", children: title }),
1654
+ description && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-file-dropzone__description", children: description })
1401
1655
  ] })
1402
1656
  ]
1403
1657
  }
1404
1658
  ),
1405
- files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "fractal-file-dropzone__file", children: [
1406
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
1407
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
1408
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1659
+ files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("li", { className: "fractal-file-dropzone__file", children: [
1660
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
1661
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
1662
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1409
1663
  "button",
1410
1664
  {
1411
1665
  className: "fractal-file-dropzone__remove",
@@ -1413,7 +1667,7 @@ function FileDropzone({
1413
1667
  "aria-label": `Remove ${file.name}`,
1414
1668
  disabled,
1415
1669
  onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
1416
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_fractal_icons7.Close, { "aria-hidden": "true", size: 14 })
1670
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_fractal_icons8.Close, { "aria-hidden": "true", size: 14 })
1417
1671
  }
1418
1672
  )
1419
1673
  ] }, `${file.name}-${file.size}-${index}`)) })
@@ -1426,8 +1680,8 @@ function formatFileSize(bytes) {
1426
1680
  }
1427
1681
 
1428
1682
  // src/components/Pagination/Pagination.tsx
1429
- var import_fractal_icons8 = require("@mirror-physics/fractal-icons");
1430
- var import_jsx_runtime24 = require("react/jsx-runtime");
1683
+ var import_fractal_icons9 = require("@mirror-physics/fractal-icons");
1684
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1431
1685
  function Pagination({
1432
1686
  page,
1433
1687
  pageSize,
@@ -1443,10 +1697,10 @@ function Pagination({
1443
1697
  const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
1444
1698
  const end = Math.min(currentPage * pageSize, totalItems);
1445
1699
  const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
1446
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
1447
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
1448
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "fractal-pagination__controls", children: [
1449
- canChangePageSize && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1700
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
1701
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
1702
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "fractal-pagination__controls", children: [
1703
+ canChangePageSize && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1450
1704
  Dropdown,
1451
1705
  {
1452
1706
  align: "right",
@@ -1463,7 +1717,7 @@ function Pagination({
1463
1717
  triggerVariant: "tertiary"
1464
1718
  }
1465
1719
  ),
1466
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1720
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1467
1721
  "button",
1468
1722
  {
1469
1723
  className: "fractal-pagination__button",
@@ -1472,15 +1726,15 @@ function Pagination({
1472
1726
  title: "Previous page",
1473
1727
  disabled: currentPage === 1 || totalItems === 0,
1474
1728
  onClick: () => onPageChange(currentPage - 1),
1475
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_fractal_icons8.ArrowLeft, { "aria-hidden": "true", size: 16 })
1729
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_fractal_icons9.ArrowLeft, { "aria-hidden": "true", size: 16 })
1476
1730
  }
1477
1731
  ),
1478
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
1732
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
1479
1733
  currentPage,
1480
1734
  " of ",
1481
1735
  totalPages
1482
1736
  ] }),
1483
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1737
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1484
1738
  "button",
1485
1739
  {
1486
1740
  className: "fractal-pagination__button",
@@ -1489,7 +1743,7 @@ function Pagination({
1489
1743
  title: "Next page",
1490
1744
  disabled: currentPage === totalPages || totalItems === 0,
1491
1745
  onClick: () => onPageChange(currentPage + 1),
1492
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_fractal_icons8.ArrowRight, { "aria-hidden": "true", size: 16 })
1746
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_fractal_icons9.ArrowRight, { "aria-hidden": "true", size: 16 })
1493
1747
  }
1494
1748
  )
1495
1749
  ] })
@@ -1499,44 +1753,70 @@ function Pagination({
1499
1753
  0 && (module.exports = {
1500
1754
  Alert,
1501
1755
  AlertDescription,
1756
+ AlertGhost,
1502
1757
  AlertTitle,
1503
1758
  Button,
1759
+ ButtonGhost,
1504
1760
  Card,
1505
1761
  CardContent,
1506
1762
  CardDescription,
1507
1763
  CardFooter,
1764
+ CardGhost,
1508
1765
  CardHeader,
1509
1766
  CardTitle,
1510
1767
  Checkbox,
1768
+ CheckboxGhost,
1511
1769
  Chip,
1770
+ ChipGhost,
1512
1771
  ContentSwitcher,
1772
+ ContentSwitcherGhost,
1513
1773
  DataTable,
1774
+ DataTableGhost,
1514
1775
  Disclosure,
1776
+ DisclosureGhost,
1515
1777
  Dropdown,
1778
+ DropdownGhost,
1516
1779
  FeatureCard,
1517
1780
  FileDropzone,
1781
+ FileDropzoneGhost,
1518
1782
  FolderCard,
1783
+ Ghost,
1784
+ GhostLine,
1519
1785
  Input,
1786
+ InputGhost,
1520
1787
  Label,
1788
+ LabelGhost,
1521
1789
  LatticeLoader,
1522
1790
  Link,
1791
+ LinkGhost,
1523
1792
  Modal,
1793
+ ModalGhost,
1524
1794
  Pagination,
1795
+ PaginationGhost,
1525
1796
  PromptCard,
1797
+ PromptCardGhost,
1526
1798
  PromptGrid,
1527
1799
  SidePanel,
1800
+ SidePanelGhost,
1528
1801
  Sidebar,
1529
1802
  SidebarBrand,
1530
1803
  SidebarFooter,
1804
+ SidebarGhost,
1531
1805
  SidebarHeader,
1532
1806
  SidebarNav,
1533
1807
  SidebarNavItem,
1534
1808
  SidebarSection,
1535
1809
  SortableTable,
1810
+ SortableTableGhost,
1536
1811
  Tabs,
1812
+ TabsGhost,
1537
1813
  TextButton,
1814
+ TextButtonGhost,
1538
1815
  Textarea,
1816
+ TextareaGhost,
1539
1817
  Toggle,
1818
+ ToggleGhost,
1819
+ UILoader,
1540
1820
  cn,
1541
1821
  useEscapeDismiss
1542
1822
  });