@mirror-physics/fractal-ui 0.2.0-next.3 → 0.2.0-next.30
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 +876 -162
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1122 -94
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +224 -7
- package/dist/index.d.ts +224 -7
- package/dist/index.js +830 -151
- package/dist/index.js.map +1 -1
- package/dist/lattice-FAYE5KWW.svg +3 -0
- package/dist/tokens.css +5 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -50,7 +50,7 @@ var colorPalette = {
|
|
|
50
50
|
var sizeConfig = {
|
|
51
51
|
xs: { height: "28px", padding: "4px 8px", iconOnly: "28px", fontSize: "0.75rem" },
|
|
52
52
|
sm: { height: "32px", padding: "6px 12px", iconOnly: "32px", fontSize: "0.75rem" },
|
|
53
|
-
md: { height: "
|
|
53
|
+
md: { height: "40px", padding: "8px 16px", iconOnly: "40px", fontSize: "0.875rem" },
|
|
54
54
|
lg: { height: "44px", padding: "10px 20px", iconOnly: "44px", fontSize: "1rem" },
|
|
55
55
|
xl: { height: "56px", padding: "14px 28px", iconOnly: "56px", fontSize: "1rem" }
|
|
56
56
|
};
|
|
@@ -329,28 +329,32 @@ Label.displayName = "Label";
|
|
|
329
329
|
|
|
330
330
|
// src/components/Alert/Alert.tsx
|
|
331
331
|
import * as React6 from "react";
|
|
332
|
+
import { CircleCheck, CircleClose, CircleInfo, Warning } from "@mirror-physics/fractal-icons";
|
|
332
333
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
333
334
|
var defaultIcons = {
|
|
334
|
-
default:
|
|
335
|
-
info:
|
|
336
|
-
success:
|
|
337
|
-
warning:
|
|
338
|
-
error:
|
|
335
|
+
default: CircleInfo,
|
|
336
|
+
info: CircleInfo,
|
|
337
|
+
success: CircleCheck,
|
|
338
|
+
warning: Warning,
|
|
339
|
+
error: CircleClose
|
|
339
340
|
};
|
|
340
341
|
var Alert = React6.forwardRef(
|
|
341
|
-
({ className, variant = "default", icon, children, ...props }, ref) =>
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
342
|
+
({ className, variant = "default", icon, children, ...props }, ref) => {
|
|
343
|
+
const DefaultIcon = defaultIcons[variant];
|
|
344
|
+
return /* @__PURE__ */ jsxs4(
|
|
345
|
+
"div",
|
|
346
|
+
{
|
|
347
|
+
ref,
|
|
348
|
+
role: "alert",
|
|
349
|
+
className: cn("fractal-alert", `fractal-alert--${variant}`, className),
|
|
350
|
+
...props,
|
|
351
|
+
children: [
|
|
352
|
+
/* @__PURE__ */ jsx5("span", { className: "fractal-alert-icon", "aria-hidden": true, children: icon ?? /* @__PURE__ */ jsx5(DefaultIcon, { size: 18 }) }),
|
|
353
|
+
/* @__PURE__ */ jsx5("div", { className: "fractal-alert-content", children })
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
);
|
|
357
|
+
}
|
|
354
358
|
);
|
|
355
359
|
Alert.displayName = "Alert";
|
|
356
360
|
var AlertTitle = React6.forwardRef(
|
|
@@ -434,27 +438,72 @@ function useEscapeDismiss(priority, handler, enabled = true) {
|
|
|
434
438
|
}, [priority, enabled]);
|
|
435
439
|
}
|
|
436
440
|
|
|
437
|
-
// src/components/
|
|
441
|
+
// src/components/UILoader/UILoader.tsx
|
|
442
|
+
import { useId } from "react";
|
|
438
443
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
439
|
-
var
|
|
440
|
-
|
|
441
|
-
|
|
444
|
+
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";
|
|
445
|
+
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";
|
|
446
|
+
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";
|
|
447
|
+
function UILoader({ size = 48, tone = "neutral", className, style, label = "Loading", ariaHidden = false }) {
|
|
448
|
+
const rawId = useId().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
449
|
+
const clipId = `fractal-ui-loader-clip-${rawId}`;
|
|
450
|
+
const gradientId = `fractal-ui-loader-gradient-${rawId}`;
|
|
451
|
+
const height = typeof size === "number" ? `${size}px` : size;
|
|
452
|
+
return /* @__PURE__ */ jsx7(
|
|
453
|
+
"span",
|
|
454
|
+
{
|
|
455
|
+
"aria-hidden": ariaHidden || void 0,
|
|
456
|
+
"aria-label": ariaHidden ? void 0 : label,
|
|
457
|
+
className: cn("fractal-ui-loader", `fractal-ui-loader--${tone}`, className),
|
|
458
|
+
role: ariaHidden ? void 0 : "status",
|
|
459
|
+
style,
|
|
460
|
+
children: /* @__PURE__ */ jsxs6("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 144 92", style: { height, width: "auto" }, children: [
|
|
461
|
+
/* @__PURE__ */ jsxs6("defs", { children: [
|
|
462
|
+
/* @__PURE__ */ jsxs6("linearGradient", { id: gradientId, x1: "59", x2: "94.3", y1: "0", y2: "89.1", gradientUnits: "userSpaceOnUse", children: [
|
|
463
|
+
/* @__PURE__ */ jsx7("stop", { className: "fractal-ui-loader__stop-start", offset: "0" }),
|
|
464
|
+
/* @__PURE__ */ jsx7("stop", { className: "fractal-ui-loader__stop-end", offset: "1" })
|
|
465
|
+
] }),
|
|
466
|
+
/* @__PURE__ */ jsxs6("linearGradient", { id: `${gradientId}-shine`, x1: "0", x2: "1", y1: "0", y2: "0", children: [
|
|
467
|
+
/* @__PURE__ */ jsx7("stop", { offset: "0.4", stopColor: "white", stopOpacity: "0" }),
|
|
468
|
+
/* @__PURE__ */ jsx7("stop", { offset: "0.5", stopColor: "white", stopOpacity: "0.62" }),
|
|
469
|
+
/* @__PURE__ */ jsx7("stop", { offset: "0.6", stopColor: "white", stopOpacity: "0" })
|
|
470
|
+
] }),
|
|
471
|
+
/* @__PURE__ */ jsxs6("clipPath", { id: clipId, children: [
|
|
472
|
+
/* @__PURE__ */ jsx7("path", { d: LEFT }),
|
|
473
|
+
/* @__PURE__ */ jsx7("path", { d: CENTER }),
|
|
474
|
+
/* @__PURE__ */ jsx7("path", { d: RIGHT })
|
|
475
|
+
] })
|
|
476
|
+
] }),
|
|
477
|
+
/* @__PURE__ */ jsx7("path", { d: CENTER, fill: `url(#${gradientId})` }),
|
|
478
|
+
/* @__PURE__ */ jsx7("path", { d: RIGHT, fill: `url(#${gradientId})` }),
|
|
479
|
+
/* @__PURE__ */ jsx7("path", { d: LEFT, fill: `url(#${gradientId})` }),
|
|
480
|
+
/* @__PURE__ */ jsx7("g", { clipPath: `url(#${clipId})`, children: /* @__PURE__ */ jsx7("g", { className: "fractal-ui-loader__shine-axis", transform: "translate(72 46) rotate(68.4)", children: /* @__PURE__ */ jsx7("rect", { className: "fractal-ui-loader__shine", x: "-160", y: "-100", width: "320", height: "200", fill: `url(#${gradientId}-shine)` }) }) })
|
|
481
|
+
] })
|
|
482
|
+
}
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// src/components/Modal/Modal.tsx
|
|
487
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
488
|
+
var CloseIcon = () => /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx8("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
489
|
+
function Modal({ open, onClose, title, children, danger, warn, footer, noClose, closeDisabled = false, size = "sm", loading = false, loadingLabel = "Loading", className }) {
|
|
490
|
+
useEscapeDismiss(80, onClose, open && !noClose && !closeDisabled);
|
|
442
491
|
if (!open) return null;
|
|
443
492
|
const sizeClass = `fractal-modal-panel--${size}`;
|
|
444
493
|
const accentClass = danger ? "fractal-modal-panel--danger" : warn ? "fractal-modal-panel--warn" : "";
|
|
445
494
|
return createPortal(
|
|
446
|
-
/* @__PURE__ */
|
|
495
|
+
/* @__PURE__ */ jsx8("div", { className: "fractal-modal-overlay", onClick: noClose || closeDisabled ? void 0 : onClose, children: /* @__PURE__ */ jsxs7(
|
|
447
496
|
"div",
|
|
448
497
|
{
|
|
449
498
|
className: cn("fractal-modal-panel", sizeClass, accentClass, className),
|
|
450
499
|
onClick: (e) => e.stopPropagation(),
|
|
451
500
|
children: [
|
|
452
|
-
/* @__PURE__ */
|
|
453
|
-
/* @__PURE__ */
|
|
454
|
-
!noClose && /* @__PURE__ */
|
|
501
|
+
/* @__PURE__ */ jsxs7("div", { className: "fractal-modal-title-row", children: [
|
|
502
|
+
/* @__PURE__ */ jsx8("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
|
|
503
|
+
!noClose && /* @__PURE__ */ jsx8("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ jsx8(CloseIcon, {}) })
|
|
455
504
|
] }),
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
footer && /* @__PURE__ */
|
|
505
|
+
/* @__PURE__ */ jsx8("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__ */ jsx8(UILoader, { label: loadingLabel }) : children }),
|
|
506
|
+
footer && /* @__PURE__ */ jsx8("div", { className: "fractal-modal-footer", children: footer })
|
|
458
507
|
]
|
|
459
508
|
}
|
|
460
509
|
) }),
|
|
@@ -463,17 +512,17 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
|
|
|
463
512
|
}
|
|
464
513
|
|
|
465
514
|
// src/components/DataTable/DataTable.tsx
|
|
466
|
-
import { jsx as
|
|
515
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
467
516
|
function DataTable({ columns, data, emptyMessage, header, size = "md", className }) {
|
|
468
|
-
return /* @__PURE__ */
|
|
469
|
-
header && /* @__PURE__ */
|
|
470
|
-
data.length === 0 ? /* @__PURE__ */
|
|
471
|
-
/* @__PURE__ */
|
|
472
|
-
/* @__PURE__ */
|
|
517
|
+
return /* @__PURE__ */ jsx9("div", { className: cn("fractal-datatable", `fractal-datatable--${size}`, className), children: /* @__PURE__ */ jsxs8("div", { className: "fractal-datatable-surface", children: [
|
|
518
|
+
header && /* @__PURE__ */ jsx9("div", { className: "fractal-datatable-header", children: header }),
|
|
519
|
+
data.length === 0 ? /* @__PURE__ */ jsx9("div", { className: "fractal-datatable-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ jsxs8("table", { className: "fractal-datatable-table", children: [
|
|
520
|
+
/* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsx9("tr", { className: "fractal-datatable-thead-row", children: columns.map((col) => /* @__PURE__ */ jsx9("th", { className: "fractal-datatable-th", style: { width: col.width }, children: col.header }, col.key)) }) }),
|
|
521
|
+
/* @__PURE__ */ jsx9("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ jsx9(
|
|
473
522
|
"tr",
|
|
474
523
|
{
|
|
475
524
|
className: "fractal-datatable-row",
|
|
476
|
-
children: columns.map((col) => /* @__PURE__ */
|
|
525
|
+
children: columns.map((col) => /* @__PURE__ */ jsx9("td", { className: "fractal-datatable-td", style: { width: col.width }, children: col.render(row, rowIndex) }, col.key))
|
|
477
526
|
},
|
|
478
527
|
rowIndex
|
|
479
528
|
)) })
|
|
@@ -484,7 +533,7 @@ function DataTable({ columns, data, emptyMessage, header, size = "md", className
|
|
|
484
533
|
// src/components/Dropdown/Dropdown.tsx
|
|
485
534
|
import * as React7 from "react";
|
|
486
535
|
import { ChevronDown, ChevronUp } from "@mirror-physics/fractal-icons";
|
|
487
|
-
import { Fragment as Fragment2, jsx as
|
|
536
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
488
537
|
var MARGIN = 4;
|
|
489
538
|
function Dropdown({
|
|
490
539
|
items,
|
|
@@ -495,13 +544,15 @@ function Dropdown({
|
|
|
495
544
|
align = "left",
|
|
496
545
|
triggerContent,
|
|
497
546
|
label,
|
|
547
|
+
iconOnly = false,
|
|
498
548
|
noChevron = false,
|
|
499
549
|
size = "md",
|
|
500
550
|
triggerVariant = "outline",
|
|
501
551
|
className,
|
|
502
552
|
triggerClassName,
|
|
503
553
|
panelClassName,
|
|
504
|
-
closeOnSelect = true
|
|
554
|
+
closeOnSelect = true,
|
|
555
|
+
disabled = false
|
|
505
556
|
}) {
|
|
506
557
|
const [open, setOpen] = React7.useState(false);
|
|
507
558
|
const triggerRef = React7.useRef(null);
|
|
@@ -559,12 +610,13 @@ function Dropdown({
|
|
|
559
610
|
document.addEventListener("mousedown", handleClickOutside);
|
|
560
611
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
561
612
|
}, [open]);
|
|
562
|
-
return /* @__PURE__ */
|
|
563
|
-
/* @__PURE__ */
|
|
613
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("fractal-dropdown", className), children: [
|
|
614
|
+
/* @__PURE__ */ jsxs9(
|
|
564
615
|
"button",
|
|
565
616
|
{
|
|
566
617
|
ref: triggerRef,
|
|
567
618
|
type: "button",
|
|
619
|
+
disabled,
|
|
568
620
|
"aria-haspopup": "listbox",
|
|
569
621
|
"aria-expanded": open,
|
|
570
622
|
"aria-label": triggerLabel,
|
|
@@ -573,18 +625,19 @@ function Dropdown({
|
|
|
573
625
|
"fractal-dropdown-trigger",
|
|
574
626
|
`fractal-dropdown-trigger--${size}`,
|
|
575
627
|
`fractal-dropdown-trigger--${triggerVariant}`,
|
|
628
|
+
iconOnly && "fractal-dropdown-trigger--icon-only",
|
|
576
629
|
triggerClassName
|
|
577
630
|
),
|
|
578
631
|
children: [
|
|
579
|
-
triggerContent != null ? triggerContent : /* @__PURE__ */
|
|
580
|
-
selected.icon != null && /* @__PURE__ */
|
|
581
|
-
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */
|
|
632
|
+
triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
633
|
+
selected.icon != null && /* @__PURE__ */ jsx10("span", { className: "fractal-dropdown-icon fractal-dropdown-icon--trigger", children: selected.icon }),
|
|
634
|
+
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ jsx10("span", { className: "fractal-dropdown-selected-text", children: selected.description })
|
|
582
635
|
] }),
|
|
583
|
-
!noChevron && /* @__PURE__ */
|
|
636
|
+
!noChevron && !iconOnly && /* @__PURE__ */ jsx10("span", { className: "fractal-dropdown-chevron", "aria-hidden": true, children: /* @__PURE__ */ jsx10(ChevronIcon, { size: size === "sm" ? 14 : 16 }) })
|
|
584
637
|
]
|
|
585
638
|
}
|
|
586
639
|
),
|
|
587
|
-
open && /* @__PURE__ */
|
|
640
|
+
open && /* @__PURE__ */ jsxs9(
|
|
588
641
|
"div",
|
|
589
642
|
{
|
|
590
643
|
ref: panelRef,
|
|
@@ -593,21 +646,21 @@ function Dropdown({
|
|
|
593
646
|
className: cn("fractal-dropdown-panel", `fractal-dropdown-panel--${size}`, panelClassName),
|
|
594
647
|
style: panelStyle,
|
|
595
648
|
children: [
|
|
596
|
-
label != null && /* @__PURE__ */
|
|
649
|
+
label != null && /* @__PURE__ */ jsx10("div", { className: "fractal-dropdown-label", children: label }),
|
|
597
650
|
visibleItems.map((item, index) => {
|
|
598
|
-
const topDivider = item.border === "top" ? /* @__PURE__ */
|
|
599
|
-
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */
|
|
651
|
+
const topDivider = item.border === "top" ? /* @__PURE__ */ jsx10("div", { className: "fractal-dropdown-separator" }) : null;
|
|
652
|
+
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ jsx10("div", { className: "fractal-dropdown-separator" }) : null;
|
|
600
653
|
if (item.kind === "header") {
|
|
601
|
-
return /* @__PURE__ */
|
|
654
|
+
return /* @__PURE__ */ jsxs9(React7.Fragment, { children: [
|
|
602
655
|
topDivider,
|
|
603
|
-
/* @__PURE__ */
|
|
656
|
+
/* @__PURE__ */ jsx10("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
|
|
604
657
|
bottomDivider
|
|
605
658
|
] }, `header-${index}`);
|
|
606
659
|
}
|
|
607
660
|
const isSelected = item.value === selectedValue;
|
|
608
|
-
return /* @__PURE__ */
|
|
661
|
+
return /* @__PURE__ */ jsxs9(React7.Fragment, { children: [
|
|
609
662
|
topDivider,
|
|
610
|
-
/* @__PURE__ */
|
|
663
|
+
/* @__PURE__ */ jsxs9(
|
|
611
664
|
"button",
|
|
612
665
|
{
|
|
613
666
|
type: "button",
|
|
@@ -619,9 +672,9 @@ function Dropdown({
|
|
|
619
672
|
},
|
|
620
673
|
className: "fractal-dropdown-option",
|
|
621
674
|
children: [
|
|
622
|
-
item.icon != null && /* @__PURE__ */
|
|
623
|
-
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */
|
|
624
|
-
item.trailing != null && /* @__PURE__ */
|
|
675
|
+
item.icon != null && /* @__PURE__ */ jsx10("span", { className: "fractal-dropdown-icon", children: item.icon }),
|
|
676
|
+
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ jsx10("span", { className: "fractal-dropdown-option-text", children: item.description }),
|
|
677
|
+
item.trailing != null && /* @__PURE__ */ jsx10("span", { className: "fractal-dropdown-trailing", children: item.trailing })
|
|
625
678
|
]
|
|
626
679
|
}
|
|
627
680
|
),
|
|
@@ -636,9 +689,9 @@ function Dropdown({
|
|
|
636
689
|
|
|
637
690
|
// src/components/Link/Link.tsx
|
|
638
691
|
import * as React8 from "react";
|
|
639
|
-
import { jsx as
|
|
692
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
640
693
|
var Link = React8.forwardRef(
|
|
641
|
-
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */
|
|
694
|
+
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ jsx11(
|
|
642
695
|
"a",
|
|
643
696
|
{
|
|
644
697
|
ref,
|
|
@@ -651,9 +704,9 @@ Link.displayName = "Link";
|
|
|
651
704
|
|
|
652
705
|
// src/components/Chip/Chip.tsx
|
|
653
706
|
import * as React9 from "react";
|
|
654
|
-
import { jsx as
|
|
707
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
655
708
|
var Chip = React9.forwardRef(
|
|
656
|
-
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */
|
|
709
|
+
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ jsx12(
|
|
657
710
|
"span",
|
|
658
711
|
{
|
|
659
712
|
ref,
|
|
@@ -664,35 +717,69 @@ var Chip = React9.forwardRef(
|
|
|
664
717
|
);
|
|
665
718
|
Chip.displayName = "Chip";
|
|
666
719
|
|
|
720
|
+
// src/components/Checkbox/Checkbox.tsx
|
|
721
|
+
import { Checkbox as CheckboxIcon, CheckboxChecked } from "@mirror-physics/fractal-icons";
|
|
722
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
723
|
+
function Checkbox({ checked, onCheckedChange, className, disabled, onClick, onKeyDown, ...props }) {
|
|
724
|
+
return /* @__PURE__ */ jsx13(
|
|
725
|
+
"button",
|
|
726
|
+
{
|
|
727
|
+
...props,
|
|
728
|
+
className: cn("fractal-checkbox", checked && "fractal-checkbox--checked", className),
|
|
729
|
+
type: "button",
|
|
730
|
+
role: "checkbox",
|
|
731
|
+
"aria-checked": checked,
|
|
732
|
+
disabled,
|
|
733
|
+
onClick: (event) => {
|
|
734
|
+
onClick?.(event);
|
|
735
|
+
if (!event.defaultPrevented) onCheckedChange(!checked);
|
|
736
|
+
},
|
|
737
|
+
onKeyDown: (event) => {
|
|
738
|
+
onKeyDown?.(event);
|
|
739
|
+
if (event.key === " " || event.key === "Enter") event.stopPropagation();
|
|
740
|
+
},
|
|
741
|
+
children: checked ? /* @__PURE__ */ jsx13(CheckboxChecked, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ jsx13(CheckboxIcon, { "aria-hidden": "true", size: 18 })
|
|
742
|
+
}
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
|
|
667
746
|
// src/components/SortableTable/SortableTable.tsx
|
|
668
747
|
import { useMemo, useState as useState3 } from "react";
|
|
669
748
|
import { ArrowUp, ArrowDown, ArrowsUpDown } from "@mirror-physics/fractal-icons";
|
|
670
|
-
import { jsx as
|
|
749
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
671
750
|
function SortableTable({
|
|
672
751
|
columns,
|
|
673
752
|
data,
|
|
674
753
|
emptyMessage,
|
|
675
754
|
header,
|
|
676
755
|
size = "md",
|
|
756
|
+
embedded = false,
|
|
677
757
|
className,
|
|
758
|
+
defaultSort,
|
|
678
759
|
defaultSortKey = void 0,
|
|
679
760
|
defaultSortDirection = null,
|
|
680
761
|
sortKey: controlledKey,
|
|
681
762
|
sortDirection: controlledDirection,
|
|
682
763
|
onSortChange,
|
|
683
|
-
highlightRow
|
|
764
|
+
highlightRow,
|
|
765
|
+
onRowClick,
|
|
766
|
+
rowAction
|
|
684
767
|
}) {
|
|
685
768
|
const [internalKey, setInternalKey] = useState3(defaultSortKey ?? null);
|
|
686
769
|
const [internalDirection, setInternalDirection] = useState3(defaultSortDirection);
|
|
687
770
|
const isControlled = controlledKey !== void 0 && controlledDirection !== void 0;
|
|
688
771
|
const activeKey = isControlled ? controlledKey : internalKey;
|
|
689
772
|
const activeDirection = isControlled ? controlledDirection : internalDirection;
|
|
773
|
+
const baselineKey = defaultSort?.key ?? null;
|
|
774
|
+
const baselineDirection = defaultSort?.direction ?? null;
|
|
775
|
+
const effectiveKey = activeKey && activeDirection ? activeKey : baselineKey;
|
|
776
|
+
const effectiveDirection = activeKey && activeDirection ? activeDirection : baselineDirection;
|
|
690
777
|
const sorted = useMemo(() => {
|
|
691
|
-
if (!
|
|
692
|
-
const col = columns.find((c) => c.key ===
|
|
778
|
+
if (!effectiveKey || !effectiveDirection) return data;
|
|
779
|
+
const col = columns.find((c) => c.key === effectiveKey);
|
|
693
780
|
if (!col) return data;
|
|
694
781
|
const accessor = col.sortAccessor ?? ((row) => {
|
|
695
|
-
const value = row[
|
|
782
|
+
const value = row[effectiveKey];
|
|
696
783
|
return typeof value === "string" || typeof value === "number" ? value : null;
|
|
697
784
|
});
|
|
698
785
|
const copy = [...data];
|
|
@@ -703,26 +790,28 @@ function SortableTable({
|
|
|
703
790
|
if (av == null) return 1;
|
|
704
791
|
if (bv == null) return -1;
|
|
705
792
|
if (typeof av === "number" && typeof bv === "number") {
|
|
706
|
-
return
|
|
793
|
+
return effectiveDirection === "asc" ? av - bv : bv - av;
|
|
707
794
|
}
|
|
708
795
|
const as = String(av).toLowerCase();
|
|
709
796
|
const bs = String(bv).toLowerCase();
|
|
710
|
-
if (as < bs) return
|
|
711
|
-
if (as > bs) return
|
|
797
|
+
if (as < bs) return effectiveDirection === "asc" ? -1 : 1;
|
|
798
|
+
if (as > bs) return effectiveDirection === "asc" ? 1 : -1;
|
|
712
799
|
return 0;
|
|
713
800
|
});
|
|
714
801
|
return copy;
|
|
715
|
-
}, [data, columns,
|
|
802
|
+
}, [data, columns, effectiveKey, effectiveDirection]);
|
|
716
803
|
const handleSortClick = (key) => {
|
|
717
804
|
let nextDirection;
|
|
718
|
-
if (activeKey
|
|
805
|
+
if (!activeKey || !activeDirection) {
|
|
806
|
+
nextDirection = baselineKey === key && baselineDirection ? baselineDirection : "asc";
|
|
807
|
+
} else if (activeKey !== key) {
|
|
719
808
|
nextDirection = "asc";
|
|
809
|
+
} else if (baselineKey === key && baselineDirection) {
|
|
810
|
+
nextDirection = activeDirection === baselineDirection ? baselineDirection === "asc" ? "desc" : "asc" : null;
|
|
720
811
|
} else if (activeDirection === "asc") {
|
|
721
812
|
nextDirection = "desc";
|
|
722
|
-
} else if (activeDirection === "desc") {
|
|
723
|
-
nextDirection = null;
|
|
724
813
|
} else {
|
|
725
|
-
nextDirection =
|
|
814
|
+
nextDirection = null;
|
|
726
815
|
}
|
|
727
816
|
const nextKey = nextDirection === null ? null : key;
|
|
728
817
|
if (isControlled) {
|
|
@@ -733,13 +822,13 @@ function SortableTable({
|
|
|
733
822
|
onSortChange?.(nextKey, nextDirection);
|
|
734
823
|
}
|
|
735
824
|
};
|
|
736
|
-
return /* @__PURE__ */
|
|
737
|
-
header && /* @__PURE__ */
|
|
738
|
-
sorted.length === 0 ? /* @__PURE__ */
|
|
739
|
-
/* @__PURE__ */
|
|
825
|
+
return /* @__PURE__ */ jsx14("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ jsxs10("div", { className: "fractal-sortable-table-surface", children: [
|
|
826
|
+
header && /* @__PURE__ */ jsx14("div", { className: "fractal-sortable-table-header", children: header }),
|
|
827
|
+
sorted.length === 0 ? /* @__PURE__ */ jsx14("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ jsxs10("table", { className: "fractal-sortable-table-table", children: [
|
|
828
|
+
/* @__PURE__ */ jsx14("thead", { children: /* @__PURE__ */ jsx14("tr", { className: "fractal-sortable-table-thead-row", children: columns.map((col) => {
|
|
740
829
|
const isActive = activeKey === col.key && activeDirection !== null;
|
|
741
830
|
if (!col.sortable) {
|
|
742
|
-
return /* @__PURE__ */
|
|
831
|
+
return /* @__PURE__ */ jsx14(
|
|
743
832
|
"th",
|
|
744
833
|
{
|
|
745
834
|
className: "fractal-sortable-table-th",
|
|
@@ -749,12 +838,12 @@ function SortableTable({
|
|
|
749
838
|
col.key
|
|
750
839
|
);
|
|
751
840
|
}
|
|
752
|
-
return /* @__PURE__ */
|
|
841
|
+
return /* @__PURE__ */ jsx14(
|
|
753
842
|
"th",
|
|
754
843
|
{
|
|
755
844
|
className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
|
|
756
845
|
style: { width: col.width },
|
|
757
|
-
children: /* @__PURE__ */
|
|
846
|
+
children: /* @__PURE__ */ jsxs10(
|
|
758
847
|
"button",
|
|
759
848
|
{
|
|
760
849
|
type: "button",
|
|
@@ -765,8 +854,8 @@ function SortableTable({
|
|
|
765
854
|
onClick: () => handleSortClick(col.key),
|
|
766
855
|
"aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
|
|
767
856
|
children: [
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
/* @__PURE__ */
|
|
857
|
+
/* @__PURE__ */ jsx14("span", { children: col.header }),
|
|
858
|
+
/* @__PURE__ */ jsx14("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ jsx14(ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ jsx14(ArrowDown, { size: 14 }) : /* @__PURE__ */ jsx14(ArrowsUpDown, { size: 14 }) })
|
|
770
859
|
]
|
|
771
860
|
}
|
|
772
861
|
)
|
|
@@ -774,21 +863,42 @@ function SortableTable({
|
|
|
774
863
|
col.key
|
|
775
864
|
);
|
|
776
865
|
}) }) }),
|
|
777
|
-
/* @__PURE__ */
|
|
866
|
+
/* @__PURE__ */ jsx14("tbody", { children: sorted.map((row, rowIndex) => {
|
|
778
867
|
const highlighted = highlightRow?.(row, rowIndex) ?? false;
|
|
779
|
-
|
|
868
|
+
const action = rowAction ? {
|
|
869
|
+
label: rowAction.label(row, rowIndex),
|
|
870
|
+
icon: rowAction.icon(row, rowIndex)
|
|
871
|
+
} : null;
|
|
872
|
+
return /* @__PURE__ */ jsx14(
|
|
780
873
|
"tr",
|
|
781
874
|
{
|
|
782
875
|
className: cn(
|
|
783
876
|
"fractal-sortable-table-row",
|
|
784
|
-
highlighted && "fractal-sortable-table-row--highlighted"
|
|
877
|
+
highlighted && "fractal-sortable-table-row--highlighted",
|
|
878
|
+
onRowClick && "fractal-sortable-table-row--interactive"
|
|
785
879
|
),
|
|
786
|
-
|
|
880
|
+
onClick: onRowClick ? () => onRowClick(row, rowIndex) : void 0,
|
|
881
|
+
onKeyDown: onRowClick ? (event) => {
|
|
882
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
883
|
+
event.preventDefault();
|
|
884
|
+
onRowClick(row, rowIndex);
|
|
885
|
+
}
|
|
886
|
+
} : void 0,
|
|
887
|
+
"aria-label": action?.label,
|
|
888
|
+
role: onRowClick ? "button" : void 0,
|
|
889
|
+
tabIndex: onRowClick ? 0 : void 0,
|
|
890
|
+
children: columns.map((col, columnIndex) => /* @__PURE__ */ jsxs10(
|
|
787
891
|
"td",
|
|
788
892
|
{
|
|
789
|
-
className:
|
|
893
|
+
className: cn(
|
|
894
|
+
"fractal-sortable-table-td",
|
|
895
|
+
action && columnIndex === columns.length - 1 && "fractal-sortable-table-td--row-action"
|
|
896
|
+
),
|
|
790
897
|
style: { width: col.width, textAlign: col.align ?? "left" },
|
|
791
|
-
children:
|
|
898
|
+
children: [
|
|
899
|
+
col.render(row, rowIndex),
|
|
900
|
+
action && columnIndex === columns.length - 1 && /* @__PURE__ */ jsx14("span", { className: "fractal-sortable-table-row-action", "aria-hidden": "true", children: /* @__PURE__ */ jsx14("span", { className: "fractal-sortable-table-row-action__icon", children: action.icon }) })
|
|
901
|
+
]
|
|
792
902
|
},
|
|
793
903
|
col.key
|
|
794
904
|
))
|
|
@@ -801,23 +911,39 @@ function SortableTable({
|
|
|
801
911
|
}
|
|
802
912
|
|
|
803
913
|
// src/components/Tabs/Tabs.tsx
|
|
804
|
-
import { useId, useRef as useRef3, useState as useState4 } from "react";
|
|
805
|
-
import { jsx as
|
|
914
|
+
import { useId as useId2, useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState4 } from "react";
|
|
915
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
806
916
|
function Tabs({
|
|
807
917
|
items,
|
|
808
918
|
defaultValue,
|
|
809
919
|
value: controlledValue,
|
|
810
920
|
onValueChange,
|
|
811
921
|
className,
|
|
812
|
-
ariaLabel
|
|
922
|
+
ariaLabel,
|
|
923
|
+
divider = false
|
|
813
924
|
}) {
|
|
814
|
-
const reactId =
|
|
925
|
+
const reactId = useId2();
|
|
815
926
|
const [internalValue, setInternalValue] = useState4(
|
|
816
927
|
defaultValue ?? items.find((i) => !i.disabled)?.id ?? items[0]?.id ?? ""
|
|
817
928
|
);
|
|
818
929
|
const isControlled = controlledValue !== void 0;
|
|
819
930
|
const activeId = isControlled ? controlledValue : internalValue;
|
|
931
|
+
const tabListRef = useRef3(null);
|
|
820
932
|
const tabRefs = useRef3({});
|
|
933
|
+
const [indicator, setIndicator] = useState4(null);
|
|
934
|
+
useLayoutEffect2(() => {
|
|
935
|
+
const updateIndicator = () => {
|
|
936
|
+
const activeTab = tabRefs.current[activeId];
|
|
937
|
+
if (!activeTab) return;
|
|
938
|
+
setIndicator({ offset: activeTab.offsetLeft, width: activeTab.offsetWidth });
|
|
939
|
+
};
|
|
940
|
+
updateIndicator();
|
|
941
|
+
const list = tabListRef.current;
|
|
942
|
+
if (!list || typeof ResizeObserver === "undefined") return;
|
|
943
|
+
const observer = new ResizeObserver(updateIndicator);
|
|
944
|
+
observer.observe(list);
|
|
945
|
+
return () => observer.disconnect();
|
|
946
|
+
}, [activeId, items.length]);
|
|
821
947
|
const selectTab = (id) => {
|
|
822
948
|
if (isControlled) {
|
|
823
949
|
onValueChange?.(id);
|
|
@@ -827,6 +953,10 @@ function Tabs({
|
|
|
827
953
|
}
|
|
828
954
|
};
|
|
829
955
|
const focusable = items.filter((i) => !i.disabled);
|
|
956
|
+
const indicatorStyle = indicator ? {
|
|
957
|
+
"--fractal-tabs-indicator-offset": `${indicator.offset}px`,
|
|
958
|
+
"--fractal-tabs-indicator-width": `${indicator.width}px`
|
|
959
|
+
} : void 0;
|
|
830
960
|
const onKeyDown = (event) => {
|
|
831
961
|
const currentIndex = focusable.findIndex((i) => i.id === activeId);
|
|
832
962
|
if (currentIndex === -1) return;
|
|
@@ -852,41 +982,52 @@ function Tabs({
|
|
|
852
982
|
selectTab(nextId2);
|
|
853
983
|
requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
|
|
854
984
|
};
|
|
855
|
-
return /* @__PURE__ */
|
|
856
|
-
/* @__PURE__ */
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
"
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
id
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
985
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("fractal-tabs", divider && "fractal-tabs--divider", className), children: [
|
|
986
|
+
/* @__PURE__ */ jsx15(
|
|
987
|
+
"div",
|
|
988
|
+
{
|
|
989
|
+
ref: tabListRef,
|
|
990
|
+
role: "tablist",
|
|
991
|
+
"aria-label": ariaLabel,
|
|
992
|
+
className: "fractal-tabs-list",
|
|
993
|
+
"data-indicator-ready": indicator ? "true" : void 0,
|
|
994
|
+
style: indicatorStyle,
|
|
995
|
+
children: items.map((item) => {
|
|
996
|
+
const isActive = item.id === activeId;
|
|
997
|
+
const tabId = `${reactId}-tab-${item.id}`;
|
|
998
|
+
const panelId = `${reactId}-panel-${item.id}`;
|
|
999
|
+
return /* @__PURE__ */ jsx15(
|
|
1000
|
+
"button",
|
|
1001
|
+
{
|
|
1002
|
+
ref: (el) => {
|
|
1003
|
+
tabRefs.current[item.id] = el;
|
|
1004
|
+
},
|
|
1005
|
+
id: tabId,
|
|
1006
|
+
role: "tab",
|
|
1007
|
+
type: "button",
|
|
1008
|
+
"aria-selected": isActive,
|
|
1009
|
+
"aria-controls": panelId,
|
|
1010
|
+
tabIndex: isActive ? 0 : -1,
|
|
1011
|
+
disabled: item.disabled,
|
|
1012
|
+
className: cn(
|
|
1013
|
+
"fractal-tabs-trigger",
|
|
1014
|
+
isActive && "fractal-tabs-trigger--active",
|
|
1015
|
+
item.disabled && "fractal-tabs-trigger--disabled"
|
|
1016
|
+
),
|
|
1017
|
+
onClick: () => !item.disabled && selectTab(item.id),
|
|
1018
|
+
onKeyDown,
|
|
1019
|
+
children: item.label
|
|
1020
|
+
},
|
|
1021
|
+
item.id
|
|
1022
|
+
);
|
|
1023
|
+
})
|
|
1024
|
+
}
|
|
1025
|
+
),
|
|
885
1026
|
items.map((item) => {
|
|
886
1027
|
const tabId = `${reactId}-tab-${item.id}`;
|
|
887
1028
|
const panelId = `${reactId}-panel-${item.id}`;
|
|
888
1029
|
const isActive = item.id === activeId;
|
|
889
|
-
return /* @__PURE__ */
|
|
1030
|
+
return /* @__PURE__ */ jsx15(
|
|
890
1031
|
"div",
|
|
891
1032
|
{
|
|
892
1033
|
id: panelId,
|
|
@@ -902,10 +1043,94 @@ function Tabs({
|
|
|
902
1043
|
] });
|
|
903
1044
|
}
|
|
904
1045
|
|
|
1046
|
+
// src/components/ContentSwitcher/ContentSwitcher.tsx
|
|
1047
|
+
import * as React10 from "react";
|
|
1048
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1049
|
+
function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
|
|
1050
|
+
const switcherRef = React10.useRef(null);
|
|
1051
|
+
const buttonRefs = React10.useRef([]);
|
|
1052
|
+
const activeIndex = items.findIndex((item) => item.value === value);
|
|
1053
|
+
React10.useLayoutEffect(() => {
|
|
1054
|
+
const switcher = switcherRef.current;
|
|
1055
|
+
const activeButton = buttonRefs.current[activeIndex];
|
|
1056
|
+
if (!switcher || !activeButton) {
|
|
1057
|
+
switcher?.removeAttribute("data-indicator-ready");
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
const updateIndicator = () => {
|
|
1061
|
+
const switcherRect = switcher.getBoundingClientRect();
|
|
1062
|
+
const activeButtonRect = activeButton.getBoundingClientRect();
|
|
1063
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-x", `${activeButtonRect.left - switcherRect.left - switcher.clientLeft}px`);
|
|
1064
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-y", `${activeButtonRect.top - switcherRect.top - switcher.clientTop}px`);
|
|
1065
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-width", `${activeButtonRect.width}px`);
|
|
1066
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-height", `${activeButtonRect.height}px`);
|
|
1067
|
+
switcher.setAttribute("data-indicator-ready", "true");
|
|
1068
|
+
};
|
|
1069
|
+
updateIndicator();
|
|
1070
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
1071
|
+
const resizeObserver = new ResizeObserver(updateIndicator);
|
|
1072
|
+
resizeObserver.observe(switcher);
|
|
1073
|
+
buttonRefs.current.forEach((button) => {
|
|
1074
|
+
if (button) resizeObserver.observe(button);
|
|
1075
|
+
});
|
|
1076
|
+
return () => resizeObserver.disconnect();
|
|
1077
|
+
}, [activeIndex, items.length]);
|
|
1078
|
+
const moveFocus = (index, direction) => {
|
|
1079
|
+
let nextIndex = index;
|
|
1080
|
+
do {
|
|
1081
|
+
nextIndex = (nextIndex + direction + items.length) % items.length;
|
|
1082
|
+
} while (items[nextIndex]?.disabled && nextIndex !== index);
|
|
1083
|
+
if (!items[nextIndex]?.disabled) {
|
|
1084
|
+
buttonRefs.current[nextIndex]?.focus();
|
|
1085
|
+
onValueChange(items[nextIndex].value);
|
|
1086
|
+
}
|
|
1087
|
+
};
|
|
1088
|
+
return /* @__PURE__ */ jsxs12(
|
|
1089
|
+
"div",
|
|
1090
|
+
{
|
|
1091
|
+
className: cn("fractal-content-switcher", fullWidth && "fractal-content-switcher--full-width", className),
|
|
1092
|
+
role: "group",
|
|
1093
|
+
"aria-label": ariaLabel,
|
|
1094
|
+
ref: switcherRef,
|
|
1095
|
+
children: [
|
|
1096
|
+
/* @__PURE__ */ jsx16("span", { className: "fractal-content-switcher__indicator", "aria-hidden": true }),
|
|
1097
|
+
items.map((item, index) => {
|
|
1098
|
+
const active = item.value === value;
|
|
1099
|
+
return /* @__PURE__ */ jsx16(
|
|
1100
|
+
"button",
|
|
1101
|
+
{
|
|
1102
|
+
className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
|
|
1103
|
+
type: "button",
|
|
1104
|
+
"aria-pressed": active,
|
|
1105
|
+
disabled: item.disabled,
|
|
1106
|
+
onClick: () => onValueChange(item.value),
|
|
1107
|
+
onKeyDown: (event) => {
|
|
1108
|
+
if (event.key === "ArrowRight") {
|
|
1109
|
+
event.preventDefault();
|
|
1110
|
+
moveFocus(index, 1);
|
|
1111
|
+
}
|
|
1112
|
+
if (event.key === "ArrowLeft") {
|
|
1113
|
+
event.preventDefault();
|
|
1114
|
+
moveFocus(index, -1);
|
|
1115
|
+
}
|
|
1116
|
+
},
|
|
1117
|
+
ref: (element) => {
|
|
1118
|
+
buttonRefs.current[index] = element;
|
|
1119
|
+
},
|
|
1120
|
+
children: item.label
|
|
1121
|
+
},
|
|
1122
|
+
item.value
|
|
1123
|
+
);
|
|
1124
|
+
})
|
|
1125
|
+
]
|
|
1126
|
+
}
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
905
1130
|
// src/components/Disclosure/Disclosure.tsx
|
|
906
|
-
import { useId as
|
|
1131
|
+
import { useId as useId3, useState as useState5 } from "react";
|
|
907
1132
|
import { ChevronRight, ChevronDown as ChevronDown2 } from "@mirror-physics/fractal-icons";
|
|
908
|
-
import { jsx as
|
|
1133
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
909
1134
|
function Disclosure({
|
|
910
1135
|
title,
|
|
911
1136
|
meta,
|
|
@@ -913,16 +1138,18 @@ function Disclosure({
|
|
|
913
1138
|
defaultOpen = false,
|
|
914
1139
|
open: controlledOpen,
|
|
915
1140
|
onOpenChange,
|
|
1141
|
+
disabled = false,
|
|
916
1142
|
className,
|
|
917
1143
|
variant = "card"
|
|
918
1144
|
}) {
|
|
919
|
-
const reactId =
|
|
1145
|
+
const reactId = useId3();
|
|
920
1146
|
const headerId = `${reactId}-header`;
|
|
921
1147
|
const panelId = `${reactId}-panel`;
|
|
922
1148
|
const [internalOpen, setInternalOpen] = useState5(defaultOpen);
|
|
923
1149
|
const isControlled = controlledOpen !== void 0;
|
|
924
1150
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
925
1151
|
const toggle = () => {
|
|
1152
|
+
if (disabled) return;
|
|
926
1153
|
const next = !isOpen;
|
|
927
1154
|
if (isControlled) {
|
|
928
1155
|
onOpenChange?.(next);
|
|
@@ -931,17 +1158,18 @@ function Disclosure({
|
|
|
931
1158
|
onOpenChange?.(next);
|
|
932
1159
|
}
|
|
933
1160
|
};
|
|
934
|
-
return /* @__PURE__ */
|
|
1161
|
+
return /* @__PURE__ */ jsxs13(
|
|
935
1162
|
"div",
|
|
936
1163
|
{
|
|
937
1164
|
className: cn(
|
|
938
1165
|
"fractal-disclosure",
|
|
939
1166
|
variant === "card" && "fractal-disclosure--card",
|
|
940
1167
|
isOpen && "fractal-disclosure--open",
|
|
1168
|
+
disabled && "fractal-disclosure--disabled",
|
|
941
1169
|
className
|
|
942
1170
|
),
|
|
943
1171
|
children: [
|
|
944
|
-
/* @__PURE__ */
|
|
1172
|
+
/* @__PURE__ */ jsxs13(
|
|
945
1173
|
"button",
|
|
946
1174
|
{
|
|
947
1175
|
type: "button",
|
|
@@ -949,15 +1177,16 @@ function Disclosure({
|
|
|
949
1177
|
className: "fractal-disclosure-trigger",
|
|
950
1178
|
"aria-expanded": isOpen,
|
|
951
1179
|
"aria-controls": panelId,
|
|
1180
|
+
disabled,
|
|
952
1181
|
onClick: toggle,
|
|
953
1182
|
children: [
|
|
954
|
-
/* @__PURE__ */
|
|
955
|
-
/* @__PURE__ */
|
|
956
|
-
meta && /* @__PURE__ */
|
|
1183
|
+
/* @__PURE__ */ jsx17("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ jsx17(ChevronDown2, { size: 16 }) : /* @__PURE__ */ jsx17(ChevronRight, { size: 16 }) }),
|
|
1184
|
+
/* @__PURE__ */ jsx17("span", { className: "fractal-disclosure-title", children: title }),
|
|
1185
|
+
meta && /* @__PURE__ */ jsx17("span", { className: "fractal-disclosure-meta", children: meta })
|
|
957
1186
|
]
|
|
958
1187
|
}
|
|
959
1188
|
),
|
|
960
|
-
/* @__PURE__ */
|
|
1189
|
+
/* @__PURE__ */ jsx17(
|
|
961
1190
|
"div",
|
|
962
1191
|
{
|
|
963
1192
|
id: panelId,
|
|
@@ -965,7 +1194,7 @@ function Disclosure({
|
|
|
965
1194
|
"aria-labelledby": headerId,
|
|
966
1195
|
className: "fractal-disclosure-panel",
|
|
967
1196
|
hidden: !isOpen,
|
|
968
|
-
children: /* @__PURE__ */
|
|
1197
|
+
children: /* @__PURE__ */ jsx17("div", { className: "fractal-disclosure-panel-inner", children })
|
|
969
1198
|
}
|
|
970
1199
|
)
|
|
971
1200
|
]
|
|
@@ -973,11 +1202,176 @@ function Disclosure({
|
|
|
973
1202
|
);
|
|
974
1203
|
}
|
|
975
1204
|
|
|
1205
|
+
// src/components/LatticeLoader/LatticeLoader.tsx
|
|
1206
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1207
|
+
var LATTICE_COUNT = 160;
|
|
1208
|
+
var WAVE_PERIOD = 80;
|
|
1209
|
+
function LatticeLoader({ className, label = "Loading", ...props }) {
|
|
1210
|
+
return /* @__PURE__ */ jsx18(
|
|
1211
|
+
"span",
|
|
1212
|
+
{
|
|
1213
|
+
"aria-label": label,
|
|
1214
|
+
className: cn("fractal-lattice-loader", className),
|
|
1215
|
+
role: "progressbar",
|
|
1216
|
+
...props,
|
|
1217
|
+
children: Array.from({ length: LATTICE_COUNT }, (_, index) => /* @__PURE__ */ jsx18(
|
|
1218
|
+
"span",
|
|
1219
|
+
{
|
|
1220
|
+
"aria-hidden": "true",
|
|
1221
|
+
className: "fractal-lattice-loader__cell",
|
|
1222
|
+
style: { "--fractal-lattice-index": index % WAVE_PERIOD }
|
|
1223
|
+
},
|
|
1224
|
+
index
|
|
1225
|
+
))
|
|
1226
|
+
}
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// src/components/Ghost/Ghost.tsx
|
|
1231
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1232
|
+
var toCssLength = (value) => typeof value === "number" ? `${value}px` : value;
|
|
1233
|
+
function Ghost({ className, width, height, radius, style, ...props }) {
|
|
1234
|
+
return /* @__PURE__ */ jsx19(
|
|
1235
|
+
"div",
|
|
1236
|
+
{
|
|
1237
|
+
"aria-hidden": "true",
|
|
1238
|
+
className: cn("fractal-ghost", className),
|
|
1239
|
+
style: {
|
|
1240
|
+
width: toCssLength(width),
|
|
1241
|
+
height: toCssLength(height),
|
|
1242
|
+
borderRadius: toCssLength(radius),
|
|
1243
|
+
...style
|
|
1244
|
+
},
|
|
1245
|
+
...props
|
|
1246
|
+
}
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
function GhostLine({ className, size = "md", width = "100%", ...props }) {
|
|
1250
|
+
return /* @__PURE__ */ jsx19(Ghost, { className: cn("fractal-ghost-line", `fractal-ghost-line--${size}`, className), width, ...props });
|
|
1251
|
+
}
|
|
1252
|
+
function ButtonGhost({ className, size = "md", iconOnly = false, width, ...props }) {
|
|
1253
|
+
return /* @__PURE__ */ jsx19(Ghost, { className: cn("fractal-ghost-button", `fractal-ghost-button--${size}`, iconOnly && "fractal-ghost-button--icon-only", className), width, ...props });
|
|
1254
|
+
}
|
|
1255
|
+
function CardGhost({ className, lines = 3, showHeader = true, ...props }) {
|
|
1256
|
+
return /* @__PURE__ */ jsxs14("div", { "aria-hidden": "true", className: cn("fractal-ghost-card", className), ...props, children: [
|
|
1257
|
+
showHeader && /* @__PURE__ */ jsx19(GhostLine, { width: "38%" }),
|
|
1258
|
+
/* @__PURE__ */ jsx19("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx19(GhostLine, { width: index === lines - 1 ? "62%" : "100%" }, index)) })
|
|
1259
|
+
] });
|
|
1260
|
+
}
|
|
1261
|
+
function DataTableGhost({
|
|
1262
|
+
className,
|
|
1263
|
+
showHeader = true,
|
|
1264
|
+
headers,
|
|
1265
|
+
columns = 4,
|
|
1266
|
+
rows = 5,
|
|
1267
|
+
columnWidths,
|
|
1268
|
+
size = "md",
|
|
1269
|
+
...props
|
|
1270
|
+
}) {
|
|
1271
|
+
const cells = Array.from({ length: columns }, (_, index) => index);
|
|
1272
|
+
return /* @__PURE__ */ jsx19("div", { "aria-busy": "true", "aria-label": "Loading table", className: cn("fractal-ghost-table", `fractal-ghost-table--${size}`, className), role: "status", ...props, children: /* @__PURE__ */ jsxs14("table", { className: "fractal-ghost-table__table", children: [
|
|
1273
|
+
(showHeader || headers) && /* @__PURE__ */ jsx19("thead", { children: /* @__PURE__ */ jsx19("tr", { className: "fractal-ghost-table__head-row", children: cells.map((index) => /* @__PURE__ */ jsx19("th", { style: { width: columnWidths?.[index] }, children: headers?.[index] ?? /* @__PURE__ */ jsx19(GhostLine, { size: "sm", width: index === columns - 1 ? "62%" : "76%" }) }, index)) }) }),
|
|
1274
|
+
/* @__PURE__ */ jsx19("tbody", { children: Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ jsx19("tr", { className: "fractal-ghost-table__row", children: cells.map((columnIndex) => /* @__PURE__ */ jsx19("td", { style: { width: columnWidths?.[columnIndex] }, children: /* @__PURE__ */ jsx19(GhostLine, { width: `${[72, 54, 82, 63, 46][(rowIndex + columnIndex) % 5]}%` }) }, columnIndex)) }, rowIndex)) })
|
|
1275
|
+
] }) });
|
|
1276
|
+
}
|
|
1277
|
+
function InputGhost({ className, labelWidth = "26%", ...props }) {
|
|
1278
|
+
return /* @__PURE__ */ jsx19(FormFieldGhost, { className, labelWidth, ...props });
|
|
1279
|
+
}
|
|
1280
|
+
function TextareaGhost({ className, labelWidth = "26%", ...props }) {
|
|
1281
|
+
return /* @__PURE__ */ jsx19(FormFieldGhost, { className, labelWidth, multiline: true, ...props });
|
|
1282
|
+
}
|
|
1283
|
+
function LabelGhost({ className, width = "26%", ...props }) {
|
|
1284
|
+
return /* @__PURE__ */ jsx19(GhostLine, { className: cn("fractal-ghost-label", className), size: "sm", width, ...props });
|
|
1285
|
+
}
|
|
1286
|
+
function FormFieldGhost({ className, labelWidth = "26%", multiline = false, ...props }) {
|
|
1287
|
+
return /* @__PURE__ */ jsxs14("div", { "aria-hidden": "true", className: cn("fractal-ghost-field", className), ...props, children: [
|
|
1288
|
+
/* @__PURE__ */ jsx19(LabelGhost, { width: labelWidth }),
|
|
1289
|
+
/* @__PURE__ */ jsx19(Ghost, { className: cn("fractal-ghost-field__control", multiline && "fractal-ghost-field__control--multiline") })
|
|
1290
|
+
] });
|
|
1291
|
+
}
|
|
1292
|
+
function AlertGhost({ className, ...props }) {
|
|
1293
|
+
return /* @__PURE__ */ jsxs14("div", { "aria-hidden": "true", className: cn("fractal-ghost-alert", className), ...props, children: [
|
|
1294
|
+
/* @__PURE__ */ jsx19(GhostLine, { width: "30%" }),
|
|
1295
|
+
/* @__PURE__ */ jsx19(GhostLine, { size: "sm", width: "78%" })
|
|
1296
|
+
] });
|
|
1297
|
+
}
|
|
1298
|
+
function CheckboxGhost({ className, ...props }) {
|
|
1299
|
+
return /* @__PURE__ */ jsxs14("div", { "aria-hidden": "true", className: cn("fractal-ghost-choice", className), ...props, children: [
|
|
1300
|
+
/* @__PURE__ */ jsx19(Ghost, { className: "fractal-ghost-choice__control" }),
|
|
1301
|
+
/* @__PURE__ */ jsx19(GhostLine, { width: "42%" })
|
|
1302
|
+
] });
|
|
1303
|
+
}
|
|
1304
|
+
var ToggleGhost = CheckboxGhost;
|
|
1305
|
+
function ChipGhost({ className, width = 74, ...props }) {
|
|
1306
|
+
return /* @__PURE__ */ jsx19(Ghost, { className: cn("fractal-ghost-chip", className), height: 24, width, ...props });
|
|
1307
|
+
}
|
|
1308
|
+
function LinkGhost({ className, width = 96, ...props }) {
|
|
1309
|
+
return /* @__PURE__ */ jsx19(GhostLine, { className: cn("fractal-ghost-link", className), size: "sm", width, ...props });
|
|
1310
|
+
}
|
|
1311
|
+
var TextButtonGhost = LinkGhost;
|
|
1312
|
+
function DropdownGhost({ className, ...props }) {
|
|
1313
|
+
return /* @__PURE__ */ jsxs14("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropdown", className), ...props, children: [
|
|
1314
|
+
/* @__PURE__ */ jsx19(GhostLine, { width: "38%" }),
|
|
1315
|
+
/* @__PURE__ */ jsx19(Ghost, { className: "fractal-ghost-dropdown__chevron" })
|
|
1316
|
+
] });
|
|
1317
|
+
}
|
|
1318
|
+
function ContentSwitcherGhost({ className, options = 3, ...props }) {
|
|
1319
|
+
return /* @__PURE__ */ jsx19("div", { "aria-hidden": "true", className: cn("fractal-ghost-switcher", className), ...props, children: Array.from({ length: options }, (_, index) => /* @__PURE__ */ jsx19(Ghost, {}, index)) });
|
|
1320
|
+
}
|
|
1321
|
+
var TabsGhost = ContentSwitcherGhost;
|
|
1322
|
+
function DisclosureGhost({ className, ...props }) {
|
|
1323
|
+
return /* @__PURE__ */ jsxs14("div", { "aria-hidden": "true", className: cn("fractal-ghost-disclosure", className), ...props, children: [
|
|
1324
|
+
/* @__PURE__ */ jsx19(Ghost, { className: "fractal-ghost-disclosure__icon" }),
|
|
1325
|
+
/* @__PURE__ */ jsx19(GhostLine, { width: "42%" })
|
|
1326
|
+
] });
|
|
1327
|
+
}
|
|
1328
|
+
function PaginationGhost({ className, pages = 5, ...props }) {
|
|
1329
|
+
return /* @__PURE__ */ jsx19("div", { "aria-hidden": "true", className: cn("fractal-ghost-pagination", className), ...props, children: Array.from({ length: pages }, (_, index) => /* @__PURE__ */ jsx19(Ghost, {}, index)) });
|
|
1330
|
+
}
|
|
1331
|
+
function FileDropzoneGhost({ className, ...props }) {
|
|
1332
|
+
return /* @__PURE__ */ jsxs14("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropzone", className), ...props, children: [
|
|
1333
|
+
/* @__PURE__ */ jsx19(Ghost, { className: "fractal-ghost-dropzone__icon" }),
|
|
1334
|
+
/* @__PURE__ */ jsx19(GhostLine, { width: "26%" }),
|
|
1335
|
+
/* @__PURE__ */ jsx19(GhostLine, { size: "sm", width: "46%" })
|
|
1336
|
+
] });
|
|
1337
|
+
}
|
|
1338
|
+
function PromptCardGhost({ className, ...props }) {
|
|
1339
|
+
return /* @__PURE__ */ jsx19(CardGhost, { className: cn("fractal-ghost-prompt-card", className), lines: 4, ...props });
|
|
1340
|
+
}
|
|
1341
|
+
function SortableTableGhost(props) {
|
|
1342
|
+
return /* @__PURE__ */ jsx19(DataTableGhost, { ...props });
|
|
1343
|
+
}
|
|
1344
|
+
function SidebarGhost({ className, items = 6, ...props }) {
|
|
1345
|
+
return /* @__PURE__ */ jsxs14("aside", { "aria-hidden": "true", className: cn("fractal-ghost-sidebar", className), ...props, children: [
|
|
1346
|
+
/* @__PURE__ */ jsx19(Ghost, { className: "fractal-ghost-sidebar__brand" }),
|
|
1347
|
+
/* @__PURE__ */ jsx19("div", { className: "fractal-ghost-sidebar__items", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsxs14("div", { className: "fractal-ghost-sidebar__item", children: [
|
|
1348
|
+
/* @__PURE__ */ jsx19(Ghost, {}),
|
|
1349
|
+
/* @__PURE__ */ jsx19(GhostLine, { width: `${[54, 68, 44, 61][index % 4]}%` })
|
|
1350
|
+
] }, index)) })
|
|
1351
|
+
] });
|
|
1352
|
+
}
|
|
1353
|
+
function ModalGhost({ className, title, lines = 3, ...props }) {
|
|
1354
|
+
return /* @__PURE__ */ jsx19(SurfaceGhost, { className: cn("fractal-ghost-modal", className), title, lines, ...props });
|
|
1355
|
+
}
|
|
1356
|
+
function SidePanelGhost({ className, title, lines = 5, ...props }) {
|
|
1357
|
+
return /* @__PURE__ */ jsx19(SurfaceGhost, { className: cn("fractal-ghost-side-panel", className), title, lines, ...props });
|
|
1358
|
+
}
|
|
1359
|
+
function SurfaceGhost({ className, title, lines = 3, ...props }) {
|
|
1360
|
+
return /* @__PURE__ */ jsxs14("div", { "aria-hidden": "true", className: cn("fractal-ghost-surface", className), ...props, children: [
|
|
1361
|
+
/* @__PURE__ */ jsxs14("div", { className: "fractal-ghost-surface__header", children: [
|
|
1362
|
+
/* @__PURE__ */ jsx19(GhostLine, { width: "42%" }),
|
|
1363
|
+
/* @__PURE__ */ jsx19(Ghost, { className: "fractal-ghost-surface__close" })
|
|
1364
|
+
] }),
|
|
1365
|
+
title && /* @__PURE__ */ jsx19("div", { className: "fractal-ghost-surface__title", children: title }),
|
|
1366
|
+
/* @__PURE__ */ jsx19("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx19(GhostLine, { width: index === lines - 1 ? "64%" : "100%" }, index)) })
|
|
1367
|
+
] });
|
|
1368
|
+
}
|
|
1369
|
+
|
|
976
1370
|
// src/components/Sidebar/Sidebar.tsx
|
|
977
|
-
import * as
|
|
978
|
-
import { jsx as
|
|
979
|
-
var Sidebar =
|
|
980
|
-
({ className, width, style, ...props }, ref) => /* @__PURE__ */
|
|
1371
|
+
import * as React11 from "react";
|
|
1372
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1373
|
+
var Sidebar = React11.forwardRef(
|
|
1374
|
+
({ className, width, style, ...props }, ref) => /* @__PURE__ */ jsx20(
|
|
981
1375
|
"aside",
|
|
982
1376
|
{
|
|
983
1377
|
ref,
|
|
@@ -988,24 +1382,47 @@ var Sidebar = React10.forwardRef(
|
|
|
988
1382
|
)
|
|
989
1383
|
);
|
|
990
1384
|
Sidebar.displayName = "Sidebar";
|
|
991
|
-
var SidebarHeader =
|
|
992
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1385
|
+
var SidebarHeader = React11.forwardRef(
|
|
1386
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx20("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
|
|
993
1387
|
);
|
|
994
1388
|
SidebarHeader.displayName = "SidebarHeader";
|
|
995
|
-
var SidebarBrand =
|
|
996
|
-
({ className, type = "button", ...props }, ref) => /* @__PURE__ */
|
|
1389
|
+
var SidebarBrand = React11.forwardRef(
|
|
1390
|
+
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ jsx20("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
|
|
997
1391
|
);
|
|
998
1392
|
SidebarBrand.displayName = "SidebarBrand";
|
|
999
|
-
|
|
1000
|
-
|
|
1393
|
+
function SidebarAccountMenu({
|
|
1394
|
+
name,
|
|
1395
|
+
items,
|
|
1396
|
+
onSelect,
|
|
1397
|
+
triggerLabel = "Account menu",
|
|
1398
|
+
className
|
|
1399
|
+
}) {
|
|
1400
|
+
return /* @__PURE__ */ jsx20(
|
|
1401
|
+
Dropdown,
|
|
1402
|
+
{
|
|
1403
|
+
align: "left",
|
|
1404
|
+
className: cn("fractal-sidebar__account", className),
|
|
1405
|
+
items,
|
|
1406
|
+
onSelect,
|
|
1407
|
+
panelClassName: "fractal-sidebar__account-panel",
|
|
1408
|
+
selectedValue: "",
|
|
1409
|
+
triggerClassName: "fractal-sidebar__account-trigger",
|
|
1410
|
+
triggerContent: /* @__PURE__ */ jsx20("span", { className: "fractal-sidebar__account-name", children: name }),
|
|
1411
|
+
triggerLabel,
|
|
1412
|
+
triggerVariant: "tertiary"
|
|
1413
|
+
}
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
var SidebarNav = React11.forwardRef(
|
|
1417
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx20("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
|
|
1001
1418
|
);
|
|
1002
1419
|
SidebarNav.displayName = "SidebarNav";
|
|
1003
|
-
var SidebarSection =
|
|
1004
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1420
|
+
var SidebarSection = React11.forwardRef(
|
|
1421
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx20("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
|
|
1005
1422
|
);
|
|
1006
1423
|
SidebarSection.displayName = "SidebarSection";
|
|
1007
|
-
var SidebarNavItem =
|
|
1008
|
-
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */
|
|
1424
|
+
var SidebarNavItem = React11.forwardRef(
|
|
1425
|
+
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ jsxs15(
|
|
1009
1426
|
"button",
|
|
1010
1427
|
{
|
|
1011
1428
|
ref,
|
|
@@ -1015,51 +1432,313 @@ var SidebarNavItem = React10.forwardRef(
|
|
|
1015
1432
|
"aria-current": active ? "page" : void 0,
|
|
1016
1433
|
...props,
|
|
1017
1434
|
children: [
|
|
1018
|
-
icon && /* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1020
|
-
endAdornment && /* @__PURE__ */
|
|
1435
|
+
icon && /* @__PURE__ */ jsx20("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
|
|
1436
|
+
/* @__PURE__ */ jsx20("span", { className: "fractal-sidebar__nav-item-label", children }),
|
|
1437
|
+
endAdornment && /* @__PURE__ */ jsx20("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
|
|
1021
1438
|
]
|
|
1022
1439
|
}
|
|
1023
1440
|
)
|
|
1024
1441
|
);
|
|
1025
1442
|
SidebarNavItem.displayName = "SidebarNavItem";
|
|
1026
|
-
var SidebarFooter =
|
|
1027
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1443
|
+
var SidebarFooter = React11.forwardRef(
|
|
1444
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx20("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
|
|
1028
1445
|
);
|
|
1029
1446
|
SidebarFooter.displayName = "SidebarFooter";
|
|
1447
|
+
|
|
1448
|
+
// src/components/SidePanel/SidePanel.tsx
|
|
1449
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
1450
|
+
import { Close } from "@mirror-physics/fractal-icons";
|
|
1451
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1452
|
+
function SidePanel({ open, onClose, title, description, children, footer, size = "md", loading = false, loadingLabel = "Loading", className }) {
|
|
1453
|
+
useEscapeDismiss(80, onClose, open);
|
|
1454
|
+
if (!open) return null;
|
|
1455
|
+
return createPortal2(
|
|
1456
|
+
/* @__PURE__ */ jsx21("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ jsxs16(
|
|
1457
|
+
"aside",
|
|
1458
|
+
{
|
|
1459
|
+
className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
|
|
1460
|
+
"aria-modal": "true",
|
|
1461
|
+
"aria-label": typeof title === "string" ? title : "Side panel",
|
|
1462
|
+
role: "dialog",
|
|
1463
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
1464
|
+
children: [
|
|
1465
|
+
/* @__PURE__ */ jsxs16("header", { className: "fractal-side-panel__header", children: [
|
|
1466
|
+
/* @__PURE__ */ jsxs16("div", { className: "fractal-side-panel__heading", children: [
|
|
1467
|
+
/* @__PURE__ */ jsx21("h2", { className: "fractal-side-panel__title", children: title }),
|
|
1468
|
+
description && /* @__PURE__ */ jsx21("p", { className: "fractal-side-panel__description", children: description })
|
|
1469
|
+
] }),
|
|
1470
|
+
/* @__PURE__ */ jsx21("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx21(Close, { size: 18 }) })
|
|
1471
|
+
] }),
|
|
1472
|
+
/* @__PURE__ */ jsx21("div", { "aria-busy": loading || void 0, className: cn("fractal-side-panel__body", loading && "fractal-side-panel__body--loading"), children: loading ? /* @__PURE__ */ jsx21(UILoader, { label: loadingLabel }) : children }),
|
|
1473
|
+
footer && /* @__PURE__ */ jsx21("footer", { className: "fractal-side-panel__footer", children: footer })
|
|
1474
|
+
]
|
|
1475
|
+
}
|
|
1476
|
+
) }),
|
|
1477
|
+
document.body
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
// src/components/Textarea/Textarea.tsx
|
|
1482
|
+
import * as React12 from "react";
|
|
1483
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1484
|
+
var Textarea = React12.forwardRef(
|
|
1485
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx22("textarea", { ref, className: cn("fractal-textarea", className), ...props })
|
|
1486
|
+
);
|
|
1487
|
+
Textarea.displayName = "Textarea";
|
|
1488
|
+
|
|
1489
|
+
// src/components/TextButton/TextButton.tsx
|
|
1490
|
+
import * as React13 from "react";
|
|
1491
|
+
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1492
|
+
var TextButton = React13.forwardRef(
|
|
1493
|
+
({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ jsxs17(
|
|
1494
|
+
"button",
|
|
1495
|
+
{
|
|
1496
|
+
ref,
|
|
1497
|
+
className: cn("fractal-text-button", `fractal-text-button--${size}`, `fractal-text-button--${tone}`, className),
|
|
1498
|
+
type: "button",
|
|
1499
|
+
...props,
|
|
1500
|
+
children: [
|
|
1501
|
+
icon && iconPosition === "start" && /* @__PURE__ */ jsx23("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
|
|
1502
|
+
/* @__PURE__ */ jsx23("span", { children }),
|
|
1503
|
+
icon && iconPosition === "end" && /* @__PURE__ */ jsx23("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
|
|
1504
|
+
]
|
|
1505
|
+
}
|
|
1506
|
+
)
|
|
1507
|
+
);
|
|
1508
|
+
TextButton.displayName = "TextButton";
|
|
1509
|
+
|
|
1510
|
+
// src/components/FileDropzone/FileDropzone.tsx
|
|
1511
|
+
import * as React14 from "react";
|
|
1512
|
+
import { Close as Close2, FileArrowUp } from "@mirror-physics/fractal-icons";
|
|
1513
|
+
import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1514
|
+
function FileDropzone({
|
|
1515
|
+
files,
|
|
1516
|
+
onFilesChange,
|
|
1517
|
+
accept,
|
|
1518
|
+
multiple = true,
|
|
1519
|
+
disabled = false,
|
|
1520
|
+
title = "Drop files here or click to browse",
|
|
1521
|
+
description = "Files stay attached to this record.",
|
|
1522
|
+
className
|
|
1523
|
+
}) {
|
|
1524
|
+
const inputId = React14.useId();
|
|
1525
|
+
const inputRef = React14.useRef(null);
|
|
1526
|
+
const [isDragging, setIsDragging] = React14.useState(false);
|
|
1527
|
+
const addFiles = (nextFiles) => {
|
|
1528
|
+
if (disabled) return;
|
|
1529
|
+
const additions = Array.from(nextFiles);
|
|
1530
|
+
if (additions.length === 0) return;
|
|
1531
|
+
onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
|
|
1532
|
+
};
|
|
1533
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("fractal-file-dropzone", className), children: [
|
|
1534
|
+
/* @__PURE__ */ jsx24(
|
|
1535
|
+
"input",
|
|
1536
|
+
{
|
|
1537
|
+
ref: inputRef,
|
|
1538
|
+
id: inputId,
|
|
1539
|
+
className: "fractal-file-dropzone__input",
|
|
1540
|
+
type: "file",
|
|
1541
|
+
accept,
|
|
1542
|
+
multiple,
|
|
1543
|
+
disabled,
|
|
1544
|
+
onChange: (event) => {
|
|
1545
|
+
if (event.target.files) addFiles(event.target.files);
|
|
1546
|
+
event.target.value = "";
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
),
|
|
1550
|
+
/* @__PURE__ */ jsxs18(
|
|
1551
|
+
"button",
|
|
1552
|
+
{
|
|
1553
|
+
className: "fractal-file-dropzone__target",
|
|
1554
|
+
"data-dragging": isDragging || void 0,
|
|
1555
|
+
type: "button",
|
|
1556
|
+
disabled,
|
|
1557
|
+
onClick: () => inputRef.current?.click(),
|
|
1558
|
+
onDragEnter: (event) => {
|
|
1559
|
+
event.preventDefault();
|
|
1560
|
+
if (!disabled) setIsDragging(true);
|
|
1561
|
+
},
|
|
1562
|
+
onDragOver: (event) => event.preventDefault(),
|
|
1563
|
+
onDragLeave: (event) => {
|
|
1564
|
+
event.preventDefault();
|
|
1565
|
+
setIsDragging(false);
|
|
1566
|
+
},
|
|
1567
|
+
onDrop: (event) => {
|
|
1568
|
+
event.preventDefault();
|
|
1569
|
+
setIsDragging(false);
|
|
1570
|
+
addFiles(event.dataTransfer.files);
|
|
1571
|
+
},
|
|
1572
|
+
children: [
|
|
1573
|
+
/* @__PURE__ */ jsx24(FileArrowUp, { "aria-hidden": "true", size: 20 }),
|
|
1574
|
+
/* @__PURE__ */ jsxs18("span", { className: "fractal-file-dropzone__copy", children: [
|
|
1575
|
+
/* @__PURE__ */ jsx24("span", { className: "fractal-file-dropzone__title", children: title }),
|
|
1576
|
+
description && /* @__PURE__ */ jsx24("span", { className: "fractal-file-dropzone__description", children: description })
|
|
1577
|
+
] })
|
|
1578
|
+
]
|
|
1579
|
+
}
|
|
1580
|
+
),
|
|
1581
|
+
files.length > 0 && /* @__PURE__ */ jsx24("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ jsxs18("li", { className: "fractal-file-dropzone__file", children: [
|
|
1582
|
+
/* @__PURE__ */ jsx24("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
|
|
1583
|
+
/* @__PURE__ */ jsx24("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
|
|
1584
|
+
/* @__PURE__ */ jsx24(
|
|
1585
|
+
"button",
|
|
1586
|
+
{
|
|
1587
|
+
className: "fractal-file-dropzone__remove",
|
|
1588
|
+
type: "button",
|
|
1589
|
+
"aria-label": `Remove ${file.name}`,
|
|
1590
|
+
disabled,
|
|
1591
|
+
onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
|
|
1592
|
+
children: /* @__PURE__ */ jsx24(Close2, { "aria-hidden": "true", size: 14 })
|
|
1593
|
+
}
|
|
1594
|
+
)
|
|
1595
|
+
] }, `${file.name}-${file.size}-${index}`)) })
|
|
1596
|
+
] });
|
|
1597
|
+
}
|
|
1598
|
+
function formatFileSize(bytes) {
|
|
1599
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1600
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
1601
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
// src/components/Pagination/Pagination.tsx
|
|
1605
|
+
import { ArrowLeft, ArrowRight } from "@mirror-physics/fractal-icons";
|
|
1606
|
+
import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1607
|
+
function Pagination({
|
|
1608
|
+
page,
|
|
1609
|
+
pageSize,
|
|
1610
|
+
totalItems,
|
|
1611
|
+
onPageChange,
|
|
1612
|
+
pageSizeOptions,
|
|
1613
|
+
onPageSizeChange,
|
|
1614
|
+
ariaLabel = "Pagination",
|
|
1615
|
+
className
|
|
1616
|
+
}) {
|
|
1617
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
1618
|
+
const currentPage = Math.min(Math.max(page, 1), totalPages);
|
|
1619
|
+
const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
|
|
1620
|
+
const end = Math.min(currentPage * pageSize, totalItems);
|
|
1621
|
+
const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
|
|
1622
|
+
return /* @__PURE__ */ jsxs19("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
|
|
1623
|
+
/* @__PURE__ */ jsx25("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
|
|
1624
|
+
/* @__PURE__ */ jsxs19("div", { className: "fractal-pagination__controls", children: [
|
|
1625
|
+
canChangePageSize && /* @__PURE__ */ jsx25(
|
|
1626
|
+
Dropdown,
|
|
1627
|
+
{
|
|
1628
|
+
align: "right",
|
|
1629
|
+
className: "fractal-pagination__page-size",
|
|
1630
|
+
direction: "up",
|
|
1631
|
+
items: pageSizeOptions.map((option) => ({
|
|
1632
|
+
value: String(option),
|
|
1633
|
+
description: `${option} per page`
|
|
1634
|
+
})),
|
|
1635
|
+
onSelect: (value) => onPageSizeChange(Number(value)),
|
|
1636
|
+
selectedValue: String(pageSize),
|
|
1637
|
+
size: "sm",
|
|
1638
|
+
triggerLabel: "Results per page",
|
|
1639
|
+
triggerVariant: "tertiary"
|
|
1640
|
+
}
|
|
1641
|
+
),
|
|
1642
|
+
/* @__PURE__ */ jsx25(
|
|
1643
|
+
"button",
|
|
1644
|
+
{
|
|
1645
|
+
className: "fractal-pagination__button",
|
|
1646
|
+
type: "button",
|
|
1647
|
+
"aria-label": "Previous page",
|
|
1648
|
+
title: "Previous page",
|
|
1649
|
+
disabled: currentPage === 1 || totalItems === 0,
|
|
1650
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
1651
|
+
children: /* @__PURE__ */ jsx25(ArrowLeft, { "aria-hidden": "true", size: 16 })
|
|
1652
|
+
}
|
|
1653
|
+
),
|
|
1654
|
+
/* @__PURE__ */ jsxs19("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
|
|
1655
|
+
currentPage,
|
|
1656
|
+
" of ",
|
|
1657
|
+
totalPages
|
|
1658
|
+
] }),
|
|
1659
|
+
/* @__PURE__ */ jsx25(
|
|
1660
|
+
"button",
|
|
1661
|
+
{
|
|
1662
|
+
className: "fractal-pagination__button",
|
|
1663
|
+
type: "button",
|
|
1664
|
+
"aria-label": "Next page",
|
|
1665
|
+
title: "Next page",
|
|
1666
|
+
disabled: currentPage === totalPages || totalItems === 0,
|
|
1667
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
1668
|
+
children: /* @__PURE__ */ jsx25(ArrowRight, { "aria-hidden": "true", size: 16 })
|
|
1669
|
+
}
|
|
1670
|
+
)
|
|
1671
|
+
] })
|
|
1672
|
+
] });
|
|
1673
|
+
}
|
|
1030
1674
|
export {
|
|
1031
1675
|
Alert,
|
|
1032
1676
|
AlertDescription,
|
|
1677
|
+
AlertGhost,
|
|
1033
1678
|
AlertTitle,
|
|
1034
1679
|
Button,
|
|
1680
|
+
ButtonGhost,
|
|
1035
1681
|
Card,
|
|
1036
1682
|
CardContent,
|
|
1037
1683
|
CardDescription,
|
|
1038
1684
|
CardFooter,
|
|
1685
|
+
CardGhost,
|
|
1039
1686
|
CardHeader,
|
|
1040
1687
|
CardTitle,
|
|
1688
|
+
Checkbox,
|
|
1689
|
+
CheckboxGhost,
|
|
1041
1690
|
Chip,
|
|
1691
|
+
ChipGhost,
|
|
1692
|
+
ContentSwitcher,
|
|
1693
|
+
ContentSwitcherGhost,
|
|
1042
1694
|
DataTable,
|
|
1695
|
+
DataTableGhost,
|
|
1043
1696
|
Disclosure,
|
|
1697
|
+
DisclosureGhost,
|
|
1044
1698
|
Dropdown,
|
|
1699
|
+
DropdownGhost,
|
|
1045
1700
|
FeatureCard,
|
|
1701
|
+
FileDropzone,
|
|
1702
|
+
FileDropzoneGhost,
|
|
1046
1703
|
FolderCard,
|
|
1704
|
+
Ghost,
|
|
1705
|
+
GhostLine,
|
|
1047
1706
|
Input,
|
|
1707
|
+
InputGhost,
|
|
1048
1708
|
Label,
|
|
1709
|
+
LabelGhost,
|
|
1710
|
+
LatticeLoader,
|
|
1049
1711
|
Link,
|
|
1712
|
+
LinkGhost,
|
|
1050
1713
|
Modal,
|
|
1714
|
+
ModalGhost,
|
|
1715
|
+
Pagination,
|
|
1716
|
+
PaginationGhost,
|
|
1051
1717
|
PromptCard,
|
|
1718
|
+
PromptCardGhost,
|
|
1052
1719
|
PromptGrid,
|
|
1720
|
+
SidePanel,
|
|
1721
|
+
SidePanelGhost,
|
|
1053
1722
|
Sidebar,
|
|
1723
|
+
SidebarAccountMenu,
|
|
1054
1724
|
SidebarBrand,
|
|
1055
1725
|
SidebarFooter,
|
|
1726
|
+
SidebarGhost,
|
|
1056
1727
|
SidebarHeader,
|
|
1057
1728
|
SidebarNav,
|
|
1058
1729
|
SidebarNavItem,
|
|
1059
1730
|
SidebarSection,
|
|
1060
1731
|
SortableTable,
|
|
1732
|
+
SortableTableGhost,
|
|
1061
1733
|
Tabs,
|
|
1734
|
+
TabsGhost,
|
|
1735
|
+
TextButton,
|
|
1736
|
+
TextButtonGhost,
|
|
1737
|
+
Textarea,
|
|
1738
|
+
TextareaGhost,
|
|
1062
1739
|
Toggle,
|
|
1740
|
+
ToggleGhost,
|
|
1741
|
+
UILoader,
|
|
1063
1742
|
cn,
|
|
1064
1743
|
useEscapeDismiss
|
|
1065
1744
|
};
|