@mirror-physics/fractal-ui 0.2.0-next.26 → 0.2.0-next.28

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 }) {
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, size = "sm", loading = false, loadingLabel = "Loading", className }) {
518
593
  useEscapeDismiss(80, onClose, open && !noClose);
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 ? 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", 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,
@@ -578,7 +653,8 @@ function Dropdown({
578
653
  className,
579
654
  triggerClassName,
580
655
  panelClassName,
581
- closeOnSelect = true
656
+ closeOnSelect = true,
657
+ disabled = false
582
658
  }) {
583
659
  const [open, setOpen] = React7.useState(false);
584
660
  const triggerRef = React7.useRef(null);
@@ -591,7 +667,7 @@ function Dropdown({
591
667
  const selectableItems = visibleItems.filter((i) => i.kind !== "header");
592
668
  const selected = items.find((i) => i.value === selectedValue && i.kind !== "header") ?? selectableItems[0] ?? visibleItems[0];
593
669
  const isUp = direction === "up";
594
- const ChevronIcon = isUp ? import_fractal_icons2.ChevronUp : import_fractal_icons2.ChevronDown;
670
+ const ChevronIcon = isUp ? import_fractal_icons3.ChevronUp : import_fractal_icons3.ChevronDown;
595
671
  React7.useLayoutEffect(() => {
596
672
  if (!open || !triggerRef.current || !panelRef.current) return;
597
673
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -636,12 +712,13 @@ function Dropdown({
636
712
  document.addEventListener("mousedown", handleClickOutside);
637
713
  return () => document.removeEventListener("mousedown", handleClickOutside);
638
714
  }, [open]);
639
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: cn("fractal-dropdown", className), children: [
640
- /* @__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)(
641
717
  "button",
642
718
  {
643
719
  ref: triggerRef,
644
720
  type: "button",
721
+ disabled,
645
722
  "aria-haspopup": "listbox",
646
723
  "aria-expanded": open,
647
724
  "aria-label": triggerLabel,
@@ -653,15 +730,15 @@ function Dropdown({
653
730
  triggerClassName
654
731
  ),
655
732
  children: [
656
- triggerContent != null ? triggerContent : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
657
- selected.icon != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-icon fractal-dropdown-icon--trigger", children: selected.icon }),
658
- 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 })
659
736
  ] }),
660
- !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 }) })
661
738
  ]
662
739
  }
663
740
  ),
664
- open && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
741
+ open && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
665
742
  "div",
666
743
  {
667
744
  ref: panelRef,
@@ -670,21 +747,21 @@ function Dropdown({
670
747
  className: cn("fractal-dropdown-panel", `fractal-dropdown-panel--${size}`, panelClassName),
671
748
  style: panelStyle,
672
749
  children: [
673
- 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 }),
674
751
  visibleItems.map((item, index) => {
675
- const topDivider = item.border === "top" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
676
- 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;
677
754
  if (item.kind === "header") {
678
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(React7.Fragment, { children: [
755
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React7.Fragment, { children: [
679
756
  topDivider,
680
- /* @__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 }),
681
758
  bottomDivider
682
759
  ] }, `header-${index}`);
683
760
  }
684
761
  const isSelected = item.value === selectedValue;
685
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(React7.Fragment, { children: [
762
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(React7.Fragment, { children: [
686
763
  topDivider,
687
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
764
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
688
765
  "button",
689
766
  {
690
767
  type: "button",
@@ -696,9 +773,9 @@ function Dropdown({
696
773
  },
697
774
  className: "fractal-dropdown-option",
698
775
  children: [
699
- item.icon != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-icon", children: item.icon }),
700
- item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-dropdown-option-text", children: item.description }),
701
- 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 })
702
779
  ]
703
780
  }
704
781
  ),
@@ -713,9 +790,9 @@ function Dropdown({
713
790
 
714
791
  // src/components/Link/Link.tsx
715
792
  var React8 = __toESM(require("react"), 1);
716
- var import_jsx_runtime11 = require("react/jsx-runtime");
793
+ var import_jsx_runtime12 = require("react/jsx-runtime");
717
794
  var Link = React8.forwardRef(
718
- ({ 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)(
719
796
  "a",
720
797
  {
721
798
  ref,
@@ -728,9 +805,9 @@ Link.displayName = "Link";
728
805
 
729
806
  // src/components/Chip/Chip.tsx
730
807
  var React9 = __toESM(require("react"), 1);
731
- var import_jsx_runtime12 = require("react/jsx-runtime");
808
+ var import_jsx_runtime13 = require("react/jsx-runtime");
732
809
  var Chip = React9.forwardRef(
733
- ({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
810
+ ({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
734
811
  "span",
735
812
  {
736
813
  ref,
@@ -742,10 +819,10 @@ var Chip = React9.forwardRef(
742
819
  Chip.displayName = "Chip";
743
820
 
744
821
  // src/components/Checkbox/Checkbox.tsx
745
- var import_fractal_icons3 = require("@mirror-physics/fractal-icons");
746
- 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");
747
824
  function Checkbox({ checked, onCheckedChange, className, disabled, onClick, onKeyDown, ...props }) {
748
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
825
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
749
826
  "button",
750
827
  {
751
828
  ...props,
@@ -762,15 +839,15 @@ function Checkbox({ checked, onCheckedChange, className, disabled, onClick, onKe
762
839
  onKeyDown?.(event);
763
840
  if (event.key === " " || event.key === "Enter") event.stopPropagation();
764
841
  },
765
- 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 })
766
843
  }
767
844
  );
768
845
  }
769
846
 
770
847
  // src/components/SortableTable/SortableTable.tsx
771
- var import_react2 = require("react");
772
- var import_fractal_icons4 = require("@mirror-physics/fractal-icons");
773
- 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");
774
851
  function SortableTable({
775
852
  columns,
776
853
  data,
@@ -789,8 +866,8 @@ function SortableTable({
789
866
  onRowClick,
790
867
  rowAction
791
868
  }) {
792
- const [internalKey, setInternalKey] = (0, import_react2.useState)(defaultSortKey ?? null);
793
- 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);
794
871
  const isControlled = controlledKey !== void 0 && controlledDirection !== void 0;
795
872
  const activeKey = isControlled ? controlledKey : internalKey;
796
873
  const activeDirection = isControlled ? controlledDirection : internalDirection;
@@ -798,7 +875,7 @@ function SortableTable({
798
875
  const baselineDirection = defaultSort?.direction ?? null;
799
876
  const effectiveKey = activeKey && activeDirection ? activeKey : baselineKey;
800
877
  const effectiveDirection = activeKey && activeDirection ? activeDirection : baselineDirection;
801
- const sorted = (0, import_react2.useMemo)(() => {
878
+ const sorted = (0, import_react3.useMemo)(() => {
802
879
  if (!effectiveKey || !effectiveDirection) return data;
803
880
  const col = columns.find((c) => c.key === effectiveKey);
804
881
  if (!col) return data;
@@ -830,12 +907,12 @@ function SortableTable({
830
907
  nextDirection = baselineKey === key && baselineDirection ? baselineDirection : "asc";
831
908
  } else if (activeKey !== key) {
832
909
  nextDirection = "asc";
910
+ } else if (baselineKey === key && baselineDirection) {
911
+ nextDirection = activeDirection === baselineDirection ? baselineDirection === "asc" ? "desc" : "asc" : null;
833
912
  } else if (activeDirection === "asc") {
834
913
  nextDirection = "desc";
835
- } else if (activeDirection === "desc") {
836
- nextDirection = null;
837
914
  } else {
838
- nextDirection = "asc";
915
+ nextDirection = null;
839
916
  }
840
917
  const nextKey = nextDirection === null ? null : key;
841
918
  if (isControlled) {
@@ -846,13 +923,13 @@ function SortableTable({
846
923
  onSortChange?.(nextKey, nextDirection);
847
924
  }
848
925
  };
849
- 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: [
850
- header && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "fractal-sortable-table-header", children: header }),
851
- 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: [
852
- /* @__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) => {
853
930
  const isActive = activeKey === col.key && activeDirection !== null;
854
931
  if (!col.sortable) {
855
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
932
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
856
933
  "th",
857
934
  {
858
935
  className: "fractal-sortable-table-th",
@@ -862,12 +939,12 @@ function SortableTable({
862
939
  col.key
863
940
  );
864
941
  }
865
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
942
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
866
943
  "th",
867
944
  {
868
945
  className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
869
946
  style: { width: col.width },
870
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
947
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
871
948
  "button",
872
949
  {
873
950
  type: "button",
@@ -878,8 +955,8 @@ function SortableTable({
878
955
  onClick: () => handleSortClick(col.key),
879
956
  "aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
880
957
  children: [
881
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: col.header }),
882
- /* @__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 }) })
883
960
  ]
884
961
  }
885
962
  )
@@ -887,13 +964,13 @@ function SortableTable({
887
964
  col.key
888
965
  );
889
966
  }) }) }),
890
- /* @__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) => {
891
968
  const highlighted = highlightRow?.(row, rowIndex) ?? false;
892
969
  const action = rowAction ? {
893
970
  label: rowAction.label(row, rowIndex),
894
971
  icon: rowAction.icon(row, rowIndex)
895
972
  } : null;
896
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
973
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
897
974
  "tr",
898
975
  {
899
976
  className: cn(
@@ -911,7 +988,7 @@ function SortableTable({
911
988
  "aria-label": action?.label,
912
989
  role: onRowClick ? "button" : void 0,
913
990
  tabIndex: onRowClick ? 0 : void 0,
914
- children: columns.map((col, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
991
+ children: columns.map((col, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
915
992
  "td",
916
993
  {
917
994
  className: cn(
@@ -921,7 +998,7 @@ function SortableTable({
921
998
  style: { width: col.width, textAlign: col.align ?? "left" },
922
999
  children: [
923
1000
  col.render(row, rowIndex),
924
- 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 }) })
925
1002
  ]
926
1003
  },
927
1004
  col.key
@@ -935,8 +1012,8 @@ function SortableTable({
935
1012
  }
936
1013
 
937
1014
  // src/components/Tabs/Tabs.tsx
938
- var import_react3 = require("react");
939
- var import_jsx_runtime15 = require("react/jsx-runtime");
1015
+ var import_react4 = require("react");
1016
+ var import_jsx_runtime16 = require("react/jsx-runtime");
940
1017
  function Tabs({
941
1018
  items,
942
1019
  defaultValue,
@@ -946,16 +1023,16 @@ function Tabs({
946
1023
  ariaLabel,
947
1024
  divider = false
948
1025
  }) {
949
- const reactId = (0, import_react3.useId)();
950
- const [internalValue, setInternalValue] = (0, import_react3.useState)(
1026
+ const reactId = (0, import_react4.useId)();
1027
+ const [internalValue, setInternalValue] = (0, import_react4.useState)(
951
1028
  defaultValue ?? items.find((i) => !i.disabled)?.id ?? items[0]?.id ?? ""
952
1029
  );
953
1030
  const isControlled = controlledValue !== void 0;
954
1031
  const activeId = isControlled ? controlledValue : internalValue;
955
- const tabListRef = (0, import_react3.useRef)(null);
956
- const tabRefs = (0, import_react3.useRef)({});
957
- const [indicator, setIndicator] = (0, import_react3.useState)(null);
958
- (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)(() => {
959
1036
  const updateIndicator = () => {
960
1037
  const activeTab = tabRefs.current[activeId];
961
1038
  if (!activeTab) return;
@@ -1006,8 +1083,8 @@ function Tabs({
1006
1083
  selectTab(nextId2);
1007
1084
  requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
1008
1085
  };
1009
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn("fractal-tabs", divider && "fractal-tabs--divider", className), children: [
1010
- /* @__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)(
1011
1088
  "div",
1012
1089
  {
1013
1090
  ref: tabListRef,
@@ -1020,7 +1097,7 @@ function Tabs({
1020
1097
  const isActive = item.id === activeId;
1021
1098
  const tabId = `${reactId}-tab-${item.id}`;
1022
1099
  const panelId = `${reactId}-panel-${item.id}`;
1023
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1100
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1024
1101
  "button",
1025
1102
  {
1026
1103
  ref: (el) => {
@@ -1051,7 +1128,7 @@ function Tabs({
1051
1128
  const tabId = `${reactId}-tab-${item.id}`;
1052
1129
  const panelId = `${reactId}-panel-${item.id}`;
1053
1130
  const isActive = item.id === activeId;
1054
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1131
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1055
1132
  "div",
1056
1133
  {
1057
1134
  id: panelId,
@@ -1069,9 +1146,36 @@ function Tabs({
1069
1146
 
1070
1147
  // src/components/ContentSwitcher/ContentSwitcher.tsx
1071
1148
  var React10 = __toESM(require("react"), 1);
1072
- var import_jsx_runtime16 = require("react/jsx-runtime");
1149
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1073
1150
  function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
1151
+ const switcherRef = React10.useRef(null);
1074
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]);
1075
1179
  const moveFocus = (index, direction) => {
1076
1180
  let nextIndex = index;
1077
1181
  do {
@@ -1082,40 +1186,52 @@ function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = f
1082
1186
  onValueChange(items[nextIndex].value);
1083
1187
  }
1084
1188
  };
1085
- 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) => {
1086
- const active = item.value === value;
1087
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1088
- "button",
1089
- {
1090
- className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
1091
- type: "button",
1092
- "aria-pressed": active,
1093
- disabled: item.disabled,
1094
- onClick: () => onValueChange(item.value),
1095
- onKeyDown: (event) => {
1096
- if (event.key === "ArrowRight") {
1097
- event.preventDefault();
1098
- moveFocus(index, 1);
1099
- }
1100
- if (event.key === "ArrowLeft") {
1101
- event.preventDefault();
1102
- moveFocus(index, -1);
1103
- }
1104
- },
1105
- ref: (element) => {
1106
- buttonRefs.current[index] = element;
1107
- },
1108
- children: item.label
1109
- },
1110
- item.value
1111
- );
1112
- }) });
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
+ );
1113
1229
  }
1114
1230
 
1115
1231
  // src/components/Disclosure/Disclosure.tsx
1116
- var import_react4 = require("react");
1117
- var import_fractal_icons5 = require("@mirror-physics/fractal-icons");
1118
- 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");
1119
1235
  function Disclosure({
1120
1236
  title,
1121
1237
  meta,
@@ -1127,10 +1243,10 @@ function Disclosure({
1127
1243
  className,
1128
1244
  variant = "card"
1129
1245
  }) {
1130
- const reactId = (0, import_react4.useId)();
1246
+ const reactId = (0, import_react5.useId)();
1131
1247
  const headerId = `${reactId}-header`;
1132
1248
  const panelId = `${reactId}-panel`;
1133
- const [internalOpen, setInternalOpen] = (0, import_react4.useState)(defaultOpen);
1249
+ const [internalOpen, setInternalOpen] = (0, import_react5.useState)(defaultOpen);
1134
1250
  const isControlled = controlledOpen !== void 0;
1135
1251
  const isOpen = isControlled ? controlledOpen : internalOpen;
1136
1252
  const toggle = () => {
@@ -1143,7 +1259,7 @@ function Disclosure({
1143
1259
  onOpenChange?.(next);
1144
1260
  }
1145
1261
  };
1146
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1262
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1147
1263
  "div",
1148
1264
  {
1149
1265
  className: cn(
@@ -1154,7 +1270,7 @@ function Disclosure({
1154
1270
  className
1155
1271
  ),
1156
1272
  children: [
1157
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1273
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1158
1274
  "button",
1159
1275
  {
1160
1276
  type: "button",
@@ -1165,13 +1281,13 @@ function Disclosure({
1165
1281
  disabled,
1166
1282
  onClick: toggle,
1167
1283
  children: [
1168
- /* @__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 }) }),
1169
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "fractal-disclosure-title", children: title }),
1170
- 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 })
1171
1287
  ]
1172
1288
  }
1173
1289
  ),
1174
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1290
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1175
1291
  "div",
1176
1292
  {
1177
1293
  id: panelId,
@@ -1179,7 +1295,7 @@ function Disclosure({
1179
1295
  "aria-labelledby": headerId,
1180
1296
  className: "fractal-disclosure-panel",
1181
1297
  hidden: !isOpen,
1182
- 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 })
1183
1299
  }
1184
1300
  )
1185
1301
  ]
@@ -1188,18 +1304,18 @@ function Disclosure({
1188
1304
  }
1189
1305
 
1190
1306
  // src/components/LatticeLoader/LatticeLoader.tsx
1191
- var import_jsx_runtime18 = require("react/jsx-runtime");
1307
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1192
1308
  var LATTICE_COUNT = 160;
1193
1309
  var WAVE_PERIOD = 80;
1194
1310
  function LatticeLoader({ className, label = "Loading", ...props }) {
1195
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1311
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1196
1312
  "span",
1197
1313
  {
1198
1314
  "aria-label": label,
1199
1315
  className: cn("fractal-lattice-loader", className),
1200
1316
  role: "progressbar",
1201
1317
  ...props,
1202
- 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)(
1203
1319
  "span",
1204
1320
  {
1205
1321
  "aria-hidden": "true",
@@ -1212,11 +1328,151 @@ function LatticeLoader({ className, label = "Loading", ...props }) {
1212
1328
  );
1213
1329
  }
1214
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
+
1215
1471
  // src/components/Sidebar/Sidebar.tsx
1216
1472
  var React11 = __toESM(require("react"), 1);
1217
- var import_jsx_runtime19 = require("react/jsx-runtime");
1473
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1218
1474
  var Sidebar = React11.forwardRef(
1219
- ({ className, width, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1475
+ ({ className, width, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1220
1476
  "aside",
1221
1477
  {
1222
1478
  ref,
@@ -1228,23 +1484,23 @@ var Sidebar = React11.forwardRef(
1228
1484
  );
1229
1485
  Sidebar.displayName = "Sidebar";
1230
1486
  var SidebarHeader = React11.forwardRef(
1231
- ({ 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 })
1232
1488
  );
1233
1489
  SidebarHeader.displayName = "SidebarHeader";
1234
1490
  var SidebarBrand = React11.forwardRef(
1235
- ({ 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 })
1236
1492
  );
1237
1493
  SidebarBrand.displayName = "SidebarBrand";
1238
1494
  var SidebarNav = React11.forwardRef(
1239
- ({ 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 })
1240
1496
  );
1241
1497
  SidebarNav.displayName = "SidebarNav";
1242
1498
  var SidebarSection = React11.forwardRef(
1243
- ({ 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 })
1244
1500
  );
1245
1501
  SidebarSection.displayName = "SidebarSection";
1246
1502
  var SidebarNavItem = React11.forwardRef(
1247
- ({ 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)(
1248
1504
  "button",
1249
1505
  {
1250
1506
  ref,
@@ -1254,28 +1510,28 @@ var SidebarNavItem = React11.forwardRef(
1254
1510
  "aria-current": active ? "page" : void 0,
1255
1511
  ...props,
1256
1512
  children: [
1257
- icon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
1258
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fractal-sidebar__nav-item-label", children }),
1259
- 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 })
1260
1516
  ]
1261
1517
  }
1262
1518
  )
1263
1519
  );
1264
1520
  SidebarNavItem.displayName = "SidebarNavItem";
1265
1521
  var SidebarFooter = React11.forwardRef(
1266
- ({ 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 })
1267
1523
  );
1268
1524
  SidebarFooter.displayName = "SidebarFooter";
1269
1525
 
1270
1526
  // src/components/SidePanel/SidePanel.tsx
1271
1527
  var import_react_dom2 = require("react-dom");
1272
- var import_fractal_icons6 = require("@mirror-physics/fractal-icons");
1273
- var import_jsx_runtime20 = require("react/jsx-runtime");
1274
- 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 }) {
1275
1531
  useEscapeDismiss(80, onClose, open);
1276
1532
  if (!open) return null;
1277
1533
  return (0, import_react_dom2.createPortal)(
1278
- /* @__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)(
1279
1535
  "aside",
1280
1536
  {
1281
1537
  className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
@@ -1284,15 +1540,15 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
1284
1540
  role: "dialog",
1285
1541
  onMouseDown: (event) => event.stopPropagation(),
1286
1542
  children: [
1287
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("header", { className: "fractal-side-panel__header", children: [
1288
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "fractal-side-panel__heading", children: [
1289
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h2", { className: "fractal-side-panel__title", children: title }),
1290
- 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 })
1291
1547
  ] }),
1292
- /* @__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 }) })
1293
1549
  ] }),
1294
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-side-panel__body", children }),
1295
- 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 })
1296
1552
  ]
1297
1553
  }
1298
1554
  ) }),
@@ -1302,17 +1558,17 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
1302
1558
 
1303
1559
  // src/components/Textarea/Textarea.tsx
1304
1560
  var React12 = __toESM(require("react"), 1);
1305
- var import_jsx_runtime21 = require("react/jsx-runtime");
1561
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1306
1562
  var Textarea = React12.forwardRef(
1307
- ({ 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 })
1308
1564
  );
1309
1565
  Textarea.displayName = "Textarea";
1310
1566
 
1311
1567
  // src/components/TextButton/TextButton.tsx
1312
1568
  var React13 = __toESM(require("react"), 1);
1313
- var import_jsx_runtime22 = require("react/jsx-runtime");
1569
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1314
1570
  var TextButton = React13.forwardRef(
1315
- ({ 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)(
1316
1572
  "button",
1317
1573
  {
1318
1574
  ref,
@@ -1320,9 +1576,9 @@ var TextButton = React13.forwardRef(
1320
1576
  type: "button",
1321
1577
  ...props,
1322
1578
  children: [
1323
- icon && iconPosition === "start" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
1324
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children }),
1325
- 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 })
1326
1582
  ]
1327
1583
  }
1328
1584
  )
@@ -1331,8 +1587,8 @@ TextButton.displayName = "TextButton";
1331
1587
 
1332
1588
  // src/components/FileDropzone/FileDropzone.tsx
1333
1589
  var React14 = __toESM(require("react"), 1);
1334
- var import_fractal_icons7 = require("@mirror-physics/fractal-icons");
1335
- 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");
1336
1592
  function FileDropzone({
1337
1593
  files,
1338
1594
  onFilesChange,
@@ -1352,8 +1608,8 @@ function FileDropzone({
1352
1608
  if (additions.length === 0) return;
1353
1609
  onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
1354
1610
  };
1355
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cn("fractal-file-dropzone", className), children: [
1356
- /* @__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)(
1357
1613
  "input",
1358
1614
  {
1359
1615
  ref: inputRef,
@@ -1369,7 +1625,7 @@ function FileDropzone({
1369
1625
  }
1370
1626
  }
1371
1627
  ),
1372
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1628
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1373
1629
  "button",
1374
1630
  {
1375
1631
  className: "fractal-file-dropzone__target",
@@ -1392,18 +1648,18 @@ function FileDropzone({
1392
1648
  addFiles(event.dataTransfer.files);
1393
1649
  },
1394
1650
  children: [
1395
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_fractal_icons7.FileArrowUp, { "aria-hidden": "true", size: 20 }),
1396
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "fractal-file-dropzone__copy", children: [
1397
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-file-dropzone__title", children: title }),
1398
- 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 })
1399
1655
  ] })
1400
1656
  ]
1401
1657
  }
1402
1658
  ),
1403
- 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: [
1404
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
1405
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
1406
- /* @__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)(
1407
1663
  "button",
1408
1664
  {
1409
1665
  className: "fractal-file-dropzone__remove",
@@ -1411,7 +1667,7 @@ function FileDropzone({
1411
1667
  "aria-label": `Remove ${file.name}`,
1412
1668
  disabled,
1413
1669
  onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
1414
- 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 })
1415
1671
  }
1416
1672
  )
1417
1673
  ] }, `${file.name}-${file.size}-${index}`)) })
@@ -1424,8 +1680,8 @@ function formatFileSize(bytes) {
1424
1680
  }
1425
1681
 
1426
1682
  // src/components/Pagination/Pagination.tsx
1427
- var import_fractal_icons8 = require("@mirror-physics/fractal-icons");
1428
- 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");
1429
1685
  function Pagination({
1430
1686
  page,
1431
1687
  pageSize,
@@ -1441,10 +1697,10 @@ function Pagination({
1441
1697
  const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
1442
1698
  const end = Math.min(currentPage * pageSize, totalItems);
1443
1699
  const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
1444
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
1445
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
1446
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "fractal-pagination__controls", children: [
1447
- 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)(
1448
1704
  Dropdown,
1449
1705
  {
1450
1706
  align: "right",
@@ -1461,7 +1717,7 @@ function Pagination({
1461
1717
  triggerVariant: "tertiary"
1462
1718
  }
1463
1719
  ),
1464
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1720
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1465
1721
  "button",
1466
1722
  {
1467
1723
  className: "fractal-pagination__button",
@@ -1470,15 +1726,15 @@ function Pagination({
1470
1726
  title: "Previous page",
1471
1727
  disabled: currentPage === 1 || totalItems === 0,
1472
1728
  onClick: () => onPageChange(currentPage - 1),
1473
- 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 })
1474
1730
  }
1475
1731
  ),
1476
- /* @__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: [
1477
1733
  currentPage,
1478
1734
  " of ",
1479
1735
  totalPages
1480
1736
  ] }),
1481
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1737
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1482
1738
  "button",
1483
1739
  {
1484
1740
  className: "fractal-pagination__button",
@@ -1487,7 +1743,7 @@ function Pagination({
1487
1743
  title: "Next page",
1488
1744
  disabled: currentPage === totalPages || totalItems === 0,
1489
1745
  onClick: () => onPageChange(currentPage + 1),
1490
- 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 })
1491
1747
  }
1492
1748
  )
1493
1749
  ] })
@@ -1497,44 +1753,70 @@ function Pagination({
1497
1753
  0 && (module.exports = {
1498
1754
  Alert,
1499
1755
  AlertDescription,
1756
+ AlertGhost,
1500
1757
  AlertTitle,
1501
1758
  Button,
1759
+ ButtonGhost,
1502
1760
  Card,
1503
1761
  CardContent,
1504
1762
  CardDescription,
1505
1763
  CardFooter,
1764
+ CardGhost,
1506
1765
  CardHeader,
1507
1766
  CardTitle,
1508
1767
  Checkbox,
1768
+ CheckboxGhost,
1509
1769
  Chip,
1770
+ ChipGhost,
1510
1771
  ContentSwitcher,
1772
+ ContentSwitcherGhost,
1511
1773
  DataTable,
1774
+ DataTableGhost,
1512
1775
  Disclosure,
1776
+ DisclosureGhost,
1513
1777
  Dropdown,
1778
+ DropdownGhost,
1514
1779
  FeatureCard,
1515
1780
  FileDropzone,
1781
+ FileDropzoneGhost,
1516
1782
  FolderCard,
1783
+ Ghost,
1784
+ GhostLine,
1517
1785
  Input,
1786
+ InputGhost,
1518
1787
  Label,
1788
+ LabelGhost,
1519
1789
  LatticeLoader,
1520
1790
  Link,
1791
+ LinkGhost,
1521
1792
  Modal,
1793
+ ModalGhost,
1522
1794
  Pagination,
1795
+ PaginationGhost,
1523
1796
  PromptCard,
1797
+ PromptCardGhost,
1524
1798
  PromptGrid,
1525
1799
  SidePanel,
1800
+ SidePanelGhost,
1526
1801
  Sidebar,
1527
1802
  SidebarBrand,
1528
1803
  SidebarFooter,
1804
+ SidebarGhost,
1529
1805
  SidebarHeader,
1530
1806
  SidebarNav,
1531
1807
  SidebarNavItem,
1532
1808
  SidebarSection,
1533
1809
  SortableTable,
1810
+ SortableTableGhost,
1534
1811
  Tabs,
1812
+ TabsGhost,
1535
1813
  TextButton,
1814
+ TextButtonGhost,
1536
1815
  Textarea,
1816
+ TextareaGhost,
1537
1817
  Toggle,
1818
+ ToggleGhost,
1819
+ UILoader,
1538
1820
  cn,
1539
1821
  useEscapeDismiss
1540
1822
  });