@mirror-physics/fractal-ui 0.2.0-next.2 → 0.2.0-next.21
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 +478 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +596 -13
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +98 -5
- package/dist/index.d.ts +98 -5
- package/dist/index.js +465 -75
- package/dist/index.js.map +1 -1
- package/dist/lattice-FAYE5KWW.svg +3 -0
- package/dist/tokens.css +2 -2
- 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
|
};
|
|
@@ -664,23 +664,52 @@ var Chip = React9.forwardRef(
|
|
|
664
664
|
);
|
|
665
665
|
Chip.displayName = "Chip";
|
|
666
666
|
|
|
667
|
+
// src/components/Checkbox/Checkbox.tsx
|
|
668
|
+
import { Checkbox as CheckboxIcon, CheckboxChecked } from "@mirror-physics/fractal-icons";
|
|
669
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
670
|
+
function Checkbox({ checked, onCheckedChange, className, disabled, onClick, onKeyDown, ...props }) {
|
|
671
|
+
return /* @__PURE__ */ jsx12(
|
|
672
|
+
"button",
|
|
673
|
+
{
|
|
674
|
+
...props,
|
|
675
|
+
className: cn("fractal-checkbox", checked && "fractal-checkbox--checked", className),
|
|
676
|
+
type: "button",
|
|
677
|
+
role: "checkbox",
|
|
678
|
+
"aria-checked": checked,
|
|
679
|
+
disabled,
|
|
680
|
+
onClick: (event) => {
|
|
681
|
+
onClick?.(event);
|
|
682
|
+
if (!event.defaultPrevented) onCheckedChange(!checked);
|
|
683
|
+
},
|
|
684
|
+
onKeyDown: (event) => {
|
|
685
|
+
onKeyDown?.(event);
|
|
686
|
+
if (event.key === " " || event.key === "Enter") event.stopPropagation();
|
|
687
|
+
},
|
|
688
|
+
children: checked ? /* @__PURE__ */ jsx12(CheckboxChecked, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ jsx12(CheckboxIcon, { "aria-hidden": "true", size: 18 })
|
|
689
|
+
}
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
|
|
667
693
|
// src/components/SortableTable/SortableTable.tsx
|
|
668
694
|
import { useMemo, useState as useState3 } from "react";
|
|
669
695
|
import { ArrowUp, ArrowDown, ArrowsUpDown } from "@mirror-physics/fractal-icons";
|
|
670
|
-
import { jsx as
|
|
696
|
+
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
671
697
|
function SortableTable({
|
|
672
698
|
columns,
|
|
673
699
|
data,
|
|
674
700
|
emptyMessage,
|
|
675
701
|
header,
|
|
676
702
|
size = "md",
|
|
703
|
+
embedded = false,
|
|
677
704
|
className,
|
|
678
705
|
defaultSortKey = void 0,
|
|
679
706
|
defaultSortDirection = null,
|
|
680
707
|
sortKey: controlledKey,
|
|
681
708
|
sortDirection: controlledDirection,
|
|
682
709
|
onSortChange,
|
|
683
|
-
highlightRow
|
|
710
|
+
highlightRow,
|
|
711
|
+
onRowClick,
|
|
712
|
+
rowAction
|
|
684
713
|
}) {
|
|
685
714
|
const [internalKey, setInternalKey] = useState3(defaultSortKey ?? null);
|
|
686
715
|
const [internalDirection, setInternalDirection] = useState3(defaultSortDirection);
|
|
@@ -733,13 +762,13 @@ function SortableTable({
|
|
|
733
762
|
onSortChange?.(nextKey, nextDirection);
|
|
734
763
|
}
|
|
735
764
|
};
|
|
736
|
-
return /* @__PURE__ */
|
|
737
|
-
header && /* @__PURE__ */
|
|
738
|
-
sorted.length === 0 ? /* @__PURE__ */
|
|
739
|
-
/* @__PURE__ */
|
|
765
|
+
return /* @__PURE__ */ jsx13("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ jsxs9("div", { className: "fractal-sortable-table-surface", children: [
|
|
766
|
+
header && /* @__PURE__ */ jsx13("div", { className: "fractal-sortable-table-header", children: header }),
|
|
767
|
+
sorted.length === 0 ? /* @__PURE__ */ jsx13("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ jsxs9("table", { className: "fractal-sortable-table-table", children: [
|
|
768
|
+
/* @__PURE__ */ jsx13("thead", { children: /* @__PURE__ */ jsx13("tr", { className: "fractal-sortable-table-thead-row", children: columns.map((col) => {
|
|
740
769
|
const isActive = activeKey === col.key && activeDirection !== null;
|
|
741
770
|
if (!col.sortable) {
|
|
742
|
-
return /* @__PURE__ */
|
|
771
|
+
return /* @__PURE__ */ jsx13(
|
|
743
772
|
"th",
|
|
744
773
|
{
|
|
745
774
|
className: "fractal-sortable-table-th",
|
|
@@ -749,7 +778,7 @@ function SortableTable({
|
|
|
749
778
|
col.key
|
|
750
779
|
);
|
|
751
780
|
}
|
|
752
|
-
return /* @__PURE__ */
|
|
781
|
+
return /* @__PURE__ */ jsx13(
|
|
753
782
|
"th",
|
|
754
783
|
{
|
|
755
784
|
className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
|
|
@@ -765,8 +794,8 @@ function SortableTable({
|
|
|
765
794
|
onClick: () => handleSortClick(col.key),
|
|
766
795
|
"aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
|
|
767
796
|
children: [
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
/* @__PURE__ */
|
|
797
|
+
/* @__PURE__ */ jsx13("span", { children: col.header }),
|
|
798
|
+
/* @__PURE__ */ jsx13("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ jsx13(ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ jsx13(ArrowDown, { size: 14 }) : /* @__PURE__ */ jsx13(ArrowsUpDown, { size: 14 }) })
|
|
770
799
|
]
|
|
771
800
|
}
|
|
772
801
|
)
|
|
@@ -774,21 +803,42 @@ function SortableTable({
|
|
|
774
803
|
col.key
|
|
775
804
|
);
|
|
776
805
|
}) }) }),
|
|
777
|
-
/* @__PURE__ */
|
|
806
|
+
/* @__PURE__ */ jsx13("tbody", { children: sorted.map((row, rowIndex) => {
|
|
778
807
|
const highlighted = highlightRow?.(row, rowIndex) ?? false;
|
|
779
|
-
|
|
808
|
+
const action = rowAction ? {
|
|
809
|
+
label: rowAction.label(row, rowIndex),
|
|
810
|
+
icon: rowAction.icon(row, rowIndex)
|
|
811
|
+
} : null;
|
|
812
|
+
return /* @__PURE__ */ jsx13(
|
|
780
813
|
"tr",
|
|
781
814
|
{
|
|
782
815
|
className: cn(
|
|
783
816
|
"fractal-sortable-table-row",
|
|
784
|
-
highlighted && "fractal-sortable-table-row--highlighted"
|
|
817
|
+
highlighted && "fractal-sortable-table-row--highlighted",
|
|
818
|
+
onRowClick && "fractal-sortable-table-row--interactive"
|
|
785
819
|
),
|
|
786
|
-
|
|
820
|
+
onClick: onRowClick ? () => onRowClick(row, rowIndex) : void 0,
|
|
821
|
+
onKeyDown: onRowClick ? (event) => {
|
|
822
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
823
|
+
event.preventDefault();
|
|
824
|
+
onRowClick(row, rowIndex);
|
|
825
|
+
}
|
|
826
|
+
} : void 0,
|
|
827
|
+
"aria-label": action?.label,
|
|
828
|
+
role: onRowClick ? "button" : void 0,
|
|
829
|
+
tabIndex: onRowClick ? 0 : void 0,
|
|
830
|
+
children: columns.map((col, columnIndex) => /* @__PURE__ */ jsxs9(
|
|
787
831
|
"td",
|
|
788
832
|
{
|
|
789
|
-
className:
|
|
833
|
+
className: cn(
|
|
834
|
+
"fractal-sortable-table-td",
|
|
835
|
+
action && columnIndex === columns.length - 1 && "fractal-sortable-table-td--row-action"
|
|
836
|
+
),
|
|
790
837
|
style: { width: col.width, textAlign: col.align ?? "left" },
|
|
791
|
-
children:
|
|
838
|
+
children: [
|
|
839
|
+
col.render(row, rowIndex),
|
|
840
|
+
action && columnIndex === columns.length - 1 && /* @__PURE__ */ jsx13("span", { className: "fractal-sortable-table-row-action", "aria-hidden": "true", children: /* @__PURE__ */ jsx13("span", { className: "fractal-sortable-table-row-action__icon", children: action.icon }) })
|
|
841
|
+
]
|
|
792
842
|
},
|
|
793
843
|
col.key
|
|
794
844
|
))
|
|
@@ -801,15 +851,16 @@ function SortableTable({
|
|
|
801
851
|
}
|
|
802
852
|
|
|
803
853
|
// src/components/Tabs/Tabs.tsx
|
|
804
|
-
import { useId, useRef as useRef3, useState as useState4 } from "react";
|
|
805
|
-
import { jsx as
|
|
854
|
+
import { useId, useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState4 } from "react";
|
|
855
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
806
856
|
function Tabs({
|
|
807
857
|
items,
|
|
808
858
|
defaultValue,
|
|
809
859
|
value: controlledValue,
|
|
810
860
|
onValueChange,
|
|
811
861
|
className,
|
|
812
|
-
ariaLabel
|
|
862
|
+
ariaLabel,
|
|
863
|
+
divider = false
|
|
813
864
|
}) {
|
|
814
865
|
const reactId = useId();
|
|
815
866
|
const [internalValue, setInternalValue] = useState4(
|
|
@@ -817,7 +868,22 @@ function Tabs({
|
|
|
817
868
|
);
|
|
818
869
|
const isControlled = controlledValue !== void 0;
|
|
819
870
|
const activeId = isControlled ? controlledValue : internalValue;
|
|
871
|
+
const tabListRef = useRef3(null);
|
|
820
872
|
const tabRefs = useRef3({});
|
|
873
|
+
const [indicator, setIndicator] = useState4(null);
|
|
874
|
+
useLayoutEffect2(() => {
|
|
875
|
+
const updateIndicator = () => {
|
|
876
|
+
const activeTab = tabRefs.current[activeId];
|
|
877
|
+
if (!activeTab) return;
|
|
878
|
+
setIndicator({ offset: activeTab.offsetLeft, width: activeTab.offsetWidth });
|
|
879
|
+
};
|
|
880
|
+
updateIndicator();
|
|
881
|
+
const list = tabListRef.current;
|
|
882
|
+
if (!list || typeof ResizeObserver === "undefined") return;
|
|
883
|
+
const observer = new ResizeObserver(updateIndicator);
|
|
884
|
+
observer.observe(list);
|
|
885
|
+
return () => observer.disconnect();
|
|
886
|
+
}, [activeId, items.length]);
|
|
821
887
|
const selectTab = (id) => {
|
|
822
888
|
if (isControlled) {
|
|
823
889
|
onValueChange?.(id);
|
|
@@ -827,6 +893,10 @@ function Tabs({
|
|
|
827
893
|
}
|
|
828
894
|
};
|
|
829
895
|
const focusable = items.filter((i) => !i.disabled);
|
|
896
|
+
const indicatorStyle = indicator ? {
|
|
897
|
+
"--fractal-tabs-indicator-offset": `${indicator.offset}px`,
|
|
898
|
+
"--fractal-tabs-indicator-width": `${indicator.width}px`
|
|
899
|
+
} : void 0;
|
|
830
900
|
const onKeyDown = (event) => {
|
|
831
901
|
const currentIndex = focusable.findIndex((i) => i.id === activeId);
|
|
832
902
|
if (currentIndex === -1) return;
|
|
@@ -852,41 +922,52 @@ function Tabs({
|
|
|
852
922
|
selectTab(nextId2);
|
|
853
923
|
requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
|
|
854
924
|
};
|
|
855
|
-
return /* @__PURE__ */ jsxs10("div", { className: cn("fractal-tabs", className), children: [
|
|
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
|
-
|
|
925
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn("fractal-tabs", divider && "fractal-tabs--divider", className), children: [
|
|
926
|
+
/* @__PURE__ */ jsx14(
|
|
927
|
+
"div",
|
|
928
|
+
{
|
|
929
|
+
ref: tabListRef,
|
|
930
|
+
role: "tablist",
|
|
931
|
+
"aria-label": ariaLabel,
|
|
932
|
+
className: "fractal-tabs-list",
|
|
933
|
+
"data-indicator-ready": indicator ? "true" : void 0,
|
|
934
|
+
style: indicatorStyle,
|
|
935
|
+
children: items.map((item) => {
|
|
936
|
+
const isActive = item.id === activeId;
|
|
937
|
+
const tabId = `${reactId}-tab-${item.id}`;
|
|
938
|
+
const panelId = `${reactId}-panel-${item.id}`;
|
|
939
|
+
return /* @__PURE__ */ jsx14(
|
|
940
|
+
"button",
|
|
941
|
+
{
|
|
942
|
+
ref: (el) => {
|
|
943
|
+
tabRefs.current[item.id] = el;
|
|
944
|
+
},
|
|
945
|
+
id: tabId,
|
|
946
|
+
role: "tab",
|
|
947
|
+
type: "button",
|
|
948
|
+
"aria-selected": isActive,
|
|
949
|
+
"aria-controls": panelId,
|
|
950
|
+
tabIndex: isActive ? 0 : -1,
|
|
951
|
+
disabled: item.disabled,
|
|
952
|
+
className: cn(
|
|
953
|
+
"fractal-tabs-trigger",
|
|
954
|
+
isActive && "fractal-tabs-trigger--active",
|
|
955
|
+
item.disabled && "fractal-tabs-trigger--disabled"
|
|
956
|
+
),
|
|
957
|
+
onClick: () => !item.disabled && selectTab(item.id),
|
|
958
|
+
onKeyDown,
|
|
959
|
+
children: item.label
|
|
960
|
+
},
|
|
961
|
+
item.id
|
|
962
|
+
);
|
|
963
|
+
})
|
|
964
|
+
}
|
|
965
|
+
),
|
|
885
966
|
items.map((item) => {
|
|
886
967
|
const tabId = `${reactId}-tab-${item.id}`;
|
|
887
968
|
const panelId = `${reactId}-panel-${item.id}`;
|
|
888
969
|
const isActive = item.id === activeId;
|
|
889
|
-
return /* @__PURE__ */
|
|
970
|
+
return /* @__PURE__ */ jsx14(
|
|
890
971
|
"div",
|
|
891
972
|
{
|
|
892
973
|
id: panelId,
|
|
@@ -902,10 +983,55 @@ function Tabs({
|
|
|
902
983
|
] });
|
|
903
984
|
}
|
|
904
985
|
|
|
986
|
+
// src/components/ContentSwitcher/ContentSwitcher.tsx
|
|
987
|
+
import * as React10 from "react";
|
|
988
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
989
|
+
function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
|
|
990
|
+
const buttonRefs = React10.useRef([]);
|
|
991
|
+
const moveFocus = (index, direction) => {
|
|
992
|
+
let nextIndex = index;
|
|
993
|
+
do {
|
|
994
|
+
nextIndex = (nextIndex + direction + items.length) % items.length;
|
|
995
|
+
} while (items[nextIndex]?.disabled && nextIndex !== index);
|
|
996
|
+
if (!items[nextIndex]?.disabled) {
|
|
997
|
+
buttonRefs.current[nextIndex]?.focus();
|
|
998
|
+
onValueChange(items[nextIndex].value);
|
|
999
|
+
}
|
|
1000
|
+
};
|
|
1001
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("fractal-content-switcher", fullWidth && "fractal-content-switcher--full-width", className), role: "group", "aria-label": ariaLabel, children: items.map((item, index) => {
|
|
1002
|
+
const active = item.value === value;
|
|
1003
|
+
return /* @__PURE__ */ jsx15(
|
|
1004
|
+
"button",
|
|
1005
|
+
{
|
|
1006
|
+
className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
|
|
1007
|
+
type: "button",
|
|
1008
|
+
"aria-pressed": active,
|
|
1009
|
+
disabled: item.disabled,
|
|
1010
|
+
onClick: () => onValueChange(item.value),
|
|
1011
|
+
onKeyDown: (event) => {
|
|
1012
|
+
if (event.key === "ArrowRight") {
|
|
1013
|
+
event.preventDefault();
|
|
1014
|
+
moveFocus(index, 1);
|
|
1015
|
+
}
|
|
1016
|
+
if (event.key === "ArrowLeft") {
|
|
1017
|
+
event.preventDefault();
|
|
1018
|
+
moveFocus(index, -1);
|
|
1019
|
+
}
|
|
1020
|
+
},
|
|
1021
|
+
ref: (element) => {
|
|
1022
|
+
buttonRefs.current[index] = element;
|
|
1023
|
+
},
|
|
1024
|
+
children: item.label
|
|
1025
|
+
},
|
|
1026
|
+
item.value
|
|
1027
|
+
);
|
|
1028
|
+
}) });
|
|
1029
|
+
}
|
|
1030
|
+
|
|
905
1031
|
// src/components/Disclosure/Disclosure.tsx
|
|
906
1032
|
import { useId as useId2, useState as useState5 } from "react";
|
|
907
1033
|
import { ChevronRight, ChevronDown as ChevronDown2 } from "@mirror-physics/fractal-icons";
|
|
908
|
-
import { jsx as
|
|
1034
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
909
1035
|
function Disclosure({
|
|
910
1036
|
title,
|
|
911
1037
|
meta,
|
|
@@ -913,6 +1039,7 @@ function Disclosure({
|
|
|
913
1039
|
defaultOpen = false,
|
|
914
1040
|
open: controlledOpen,
|
|
915
1041
|
onOpenChange,
|
|
1042
|
+
disabled = false,
|
|
916
1043
|
className,
|
|
917
1044
|
variant = "card"
|
|
918
1045
|
}) {
|
|
@@ -923,6 +1050,7 @@ function Disclosure({
|
|
|
923
1050
|
const isControlled = controlledOpen !== void 0;
|
|
924
1051
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
925
1052
|
const toggle = () => {
|
|
1053
|
+
if (disabled) return;
|
|
926
1054
|
const next = !isOpen;
|
|
927
1055
|
if (isControlled) {
|
|
928
1056
|
onOpenChange?.(next);
|
|
@@ -938,6 +1066,7 @@ function Disclosure({
|
|
|
938
1066
|
"fractal-disclosure",
|
|
939
1067
|
variant === "card" && "fractal-disclosure--card",
|
|
940
1068
|
isOpen && "fractal-disclosure--open",
|
|
1069
|
+
disabled && "fractal-disclosure--disabled",
|
|
941
1070
|
className
|
|
942
1071
|
),
|
|
943
1072
|
children: [
|
|
@@ -949,15 +1078,16 @@ function Disclosure({
|
|
|
949
1078
|
className: "fractal-disclosure-trigger",
|
|
950
1079
|
"aria-expanded": isOpen,
|
|
951
1080
|
"aria-controls": panelId,
|
|
1081
|
+
disabled,
|
|
952
1082
|
onClick: toggle,
|
|
953
1083
|
children: [
|
|
954
|
-
/* @__PURE__ */
|
|
955
|
-
/* @__PURE__ */
|
|
956
|
-
meta && /* @__PURE__ */
|
|
1084
|
+
/* @__PURE__ */ jsx16("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ jsx16(ChevronDown2, { size: 16 }) : /* @__PURE__ */ jsx16(ChevronRight, { size: 16 }) }),
|
|
1085
|
+
/* @__PURE__ */ jsx16("span", { className: "fractal-disclosure-title", children: title }),
|
|
1086
|
+
meta && /* @__PURE__ */ jsx16("span", { className: "fractal-disclosure-meta", children: meta })
|
|
957
1087
|
]
|
|
958
1088
|
}
|
|
959
1089
|
),
|
|
960
|
-
/* @__PURE__ */
|
|
1090
|
+
/* @__PURE__ */ jsx16(
|
|
961
1091
|
"div",
|
|
962
1092
|
{
|
|
963
1093
|
id: panelId,
|
|
@@ -965,7 +1095,7 @@ function Disclosure({
|
|
|
965
1095
|
"aria-labelledby": headerId,
|
|
966
1096
|
className: "fractal-disclosure-panel",
|
|
967
1097
|
hidden: !isOpen,
|
|
968
|
-
children: /* @__PURE__ */
|
|
1098
|
+
children: /* @__PURE__ */ jsx16("div", { className: "fractal-disclosure-panel-inner", children })
|
|
969
1099
|
}
|
|
970
1100
|
)
|
|
971
1101
|
]
|
|
@@ -973,11 +1103,36 @@ function Disclosure({
|
|
|
973
1103
|
);
|
|
974
1104
|
}
|
|
975
1105
|
|
|
1106
|
+
// src/components/LatticeLoader/LatticeLoader.tsx
|
|
1107
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1108
|
+
var LATTICE_COUNT = 160;
|
|
1109
|
+
var WAVE_PERIOD = 80;
|
|
1110
|
+
function LatticeLoader({ className, label = "Loading", ...props }) {
|
|
1111
|
+
return /* @__PURE__ */ jsx17(
|
|
1112
|
+
"span",
|
|
1113
|
+
{
|
|
1114
|
+
"aria-label": label,
|
|
1115
|
+
className: cn("fractal-lattice-loader", className),
|
|
1116
|
+
role: "progressbar",
|
|
1117
|
+
...props,
|
|
1118
|
+
children: Array.from({ length: LATTICE_COUNT }, (_, index) => /* @__PURE__ */ jsx17(
|
|
1119
|
+
"span",
|
|
1120
|
+
{
|
|
1121
|
+
"aria-hidden": "true",
|
|
1122
|
+
className: "fractal-lattice-loader__cell",
|
|
1123
|
+
style: { "--fractal-lattice-index": index % WAVE_PERIOD }
|
|
1124
|
+
},
|
|
1125
|
+
index
|
|
1126
|
+
))
|
|
1127
|
+
}
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
976
1131
|
// src/components/Sidebar/Sidebar.tsx
|
|
977
|
-
import * as
|
|
978
|
-
import { jsx as
|
|
979
|
-
var Sidebar =
|
|
980
|
-
({ className, width, style, ...props }, ref) => /* @__PURE__ */
|
|
1132
|
+
import * as React11 from "react";
|
|
1133
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1134
|
+
var Sidebar = React11.forwardRef(
|
|
1135
|
+
({ className, width, style, ...props }, ref) => /* @__PURE__ */ jsx18(
|
|
981
1136
|
"aside",
|
|
982
1137
|
{
|
|
983
1138
|
ref,
|
|
@@ -988,23 +1143,23 @@ var Sidebar = React10.forwardRef(
|
|
|
988
1143
|
)
|
|
989
1144
|
);
|
|
990
1145
|
Sidebar.displayName = "Sidebar";
|
|
991
|
-
var SidebarHeader =
|
|
992
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1146
|
+
var SidebarHeader = React11.forwardRef(
|
|
1147
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx18("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
|
|
993
1148
|
);
|
|
994
1149
|
SidebarHeader.displayName = "SidebarHeader";
|
|
995
|
-
var SidebarBrand =
|
|
996
|
-
({ className, type = "button", ...props }, ref) => /* @__PURE__ */
|
|
1150
|
+
var SidebarBrand = React11.forwardRef(
|
|
1151
|
+
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ jsx18("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
|
|
997
1152
|
);
|
|
998
1153
|
SidebarBrand.displayName = "SidebarBrand";
|
|
999
|
-
var SidebarNav =
|
|
1000
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1154
|
+
var SidebarNav = React11.forwardRef(
|
|
1155
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx18("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
|
|
1001
1156
|
);
|
|
1002
1157
|
SidebarNav.displayName = "SidebarNav";
|
|
1003
|
-
var SidebarSection =
|
|
1004
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1158
|
+
var SidebarSection = React11.forwardRef(
|
|
1159
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx18("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
|
|
1005
1160
|
);
|
|
1006
1161
|
SidebarSection.displayName = "SidebarSection";
|
|
1007
|
-
var SidebarNavItem =
|
|
1162
|
+
var SidebarNavItem = React11.forwardRef(
|
|
1008
1163
|
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ jsxs12(
|
|
1009
1164
|
"button",
|
|
1010
1165
|
{
|
|
@@ -1015,18 +1170,245 @@ var SidebarNavItem = React10.forwardRef(
|
|
|
1015
1170
|
"aria-current": active ? "page" : void 0,
|
|
1016
1171
|
...props,
|
|
1017
1172
|
children: [
|
|
1018
|
-
icon && /* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1020
|
-
endAdornment && /* @__PURE__ */
|
|
1173
|
+
icon && /* @__PURE__ */ jsx18("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
|
|
1174
|
+
/* @__PURE__ */ jsx18("span", { className: "fractal-sidebar__nav-item-label", children }),
|
|
1175
|
+
endAdornment && /* @__PURE__ */ jsx18("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
|
|
1021
1176
|
]
|
|
1022
1177
|
}
|
|
1023
1178
|
)
|
|
1024
1179
|
);
|
|
1025
1180
|
SidebarNavItem.displayName = "SidebarNavItem";
|
|
1026
|
-
var SidebarFooter =
|
|
1027
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1181
|
+
var SidebarFooter = React11.forwardRef(
|
|
1182
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx18("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
|
|
1028
1183
|
);
|
|
1029
1184
|
SidebarFooter.displayName = "SidebarFooter";
|
|
1185
|
+
|
|
1186
|
+
// src/components/SidePanel/SidePanel.tsx
|
|
1187
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
1188
|
+
import { Close } from "@mirror-physics/fractal-icons";
|
|
1189
|
+
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1190
|
+
function SidePanel({ open, onClose, title, description, children, footer, size = "md", className }) {
|
|
1191
|
+
useEscapeDismiss(80, onClose, open);
|
|
1192
|
+
if (!open) return null;
|
|
1193
|
+
return createPortal2(
|
|
1194
|
+
/* @__PURE__ */ jsx19("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ jsxs13(
|
|
1195
|
+
"aside",
|
|
1196
|
+
{
|
|
1197
|
+
className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
|
|
1198
|
+
"aria-modal": "true",
|
|
1199
|
+
"aria-label": typeof title === "string" ? title : "Side panel",
|
|
1200
|
+
role: "dialog",
|
|
1201
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
1202
|
+
children: [
|
|
1203
|
+
/* @__PURE__ */ jsxs13("header", { className: "fractal-side-panel__header", children: [
|
|
1204
|
+
/* @__PURE__ */ jsxs13("div", { className: "fractal-side-panel__heading", children: [
|
|
1205
|
+
/* @__PURE__ */ jsx19("h2", { className: "fractal-side-panel__title", children: title }),
|
|
1206
|
+
description && /* @__PURE__ */ jsx19("p", { className: "fractal-side-panel__description", children: description })
|
|
1207
|
+
] }),
|
|
1208
|
+
/* @__PURE__ */ jsx19("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx19(Close, { size: 18 }) })
|
|
1209
|
+
] }),
|
|
1210
|
+
/* @__PURE__ */ jsx19("div", { className: "fractal-side-panel__body", children }),
|
|
1211
|
+
footer && /* @__PURE__ */ jsx19("footer", { className: "fractal-side-panel__footer", children: footer })
|
|
1212
|
+
]
|
|
1213
|
+
}
|
|
1214
|
+
) }),
|
|
1215
|
+
document.body
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
// src/components/Textarea/Textarea.tsx
|
|
1220
|
+
import * as React12 from "react";
|
|
1221
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1222
|
+
var Textarea = React12.forwardRef(
|
|
1223
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx20("textarea", { ref, className: cn("fractal-textarea", className), ...props })
|
|
1224
|
+
);
|
|
1225
|
+
Textarea.displayName = "Textarea";
|
|
1226
|
+
|
|
1227
|
+
// src/components/TextButton/TextButton.tsx
|
|
1228
|
+
import * as React13 from "react";
|
|
1229
|
+
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1230
|
+
var TextButton = React13.forwardRef(
|
|
1231
|
+
({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ jsxs14(
|
|
1232
|
+
"button",
|
|
1233
|
+
{
|
|
1234
|
+
ref,
|
|
1235
|
+
className: cn("fractal-text-button", `fractal-text-button--${size}`, `fractal-text-button--${tone}`, className),
|
|
1236
|
+
type: "button",
|
|
1237
|
+
...props,
|
|
1238
|
+
children: [
|
|
1239
|
+
icon && iconPosition === "start" && /* @__PURE__ */ jsx21("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
|
|
1240
|
+
/* @__PURE__ */ jsx21("span", { children }),
|
|
1241
|
+
icon && iconPosition === "end" && /* @__PURE__ */ jsx21("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
|
|
1242
|
+
]
|
|
1243
|
+
}
|
|
1244
|
+
)
|
|
1245
|
+
);
|
|
1246
|
+
TextButton.displayName = "TextButton";
|
|
1247
|
+
|
|
1248
|
+
// src/components/FileDropzone/FileDropzone.tsx
|
|
1249
|
+
import * as React14 from "react";
|
|
1250
|
+
import { Close as Close2, FileArrowUp } from "@mirror-physics/fractal-icons";
|
|
1251
|
+
import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1252
|
+
function FileDropzone({
|
|
1253
|
+
files,
|
|
1254
|
+
onFilesChange,
|
|
1255
|
+
accept,
|
|
1256
|
+
multiple = true,
|
|
1257
|
+
disabled = false,
|
|
1258
|
+
title = "Drop files here or click to browse",
|
|
1259
|
+
description = "Files stay attached to this record.",
|
|
1260
|
+
className
|
|
1261
|
+
}) {
|
|
1262
|
+
const inputId = React14.useId();
|
|
1263
|
+
const inputRef = React14.useRef(null);
|
|
1264
|
+
const [isDragging, setIsDragging] = React14.useState(false);
|
|
1265
|
+
const addFiles = (nextFiles) => {
|
|
1266
|
+
if (disabled) return;
|
|
1267
|
+
const additions = Array.from(nextFiles);
|
|
1268
|
+
if (additions.length === 0) return;
|
|
1269
|
+
onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
|
|
1270
|
+
};
|
|
1271
|
+
return /* @__PURE__ */ jsxs15("div", { className: cn("fractal-file-dropzone", className), children: [
|
|
1272
|
+
/* @__PURE__ */ jsx22(
|
|
1273
|
+
"input",
|
|
1274
|
+
{
|
|
1275
|
+
ref: inputRef,
|
|
1276
|
+
id: inputId,
|
|
1277
|
+
className: "fractal-file-dropzone__input",
|
|
1278
|
+
type: "file",
|
|
1279
|
+
accept,
|
|
1280
|
+
multiple,
|
|
1281
|
+
disabled,
|
|
1282
|
+
onChange: (event) => {
|
|
1283
|
+
if (event.target.files) addFiles(event.target.files);
|
|
1284
|
+
event.target.value = "";
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
),
|
|
1288
|
+
/* @__PURE__ */ jsxs15(
|
|
1289
|
+
"button",
|
|
1290
|
+
{
|
|
1291
|
+
className: "fractal-file-dropzone__target",
|
|
1292
|
+
"data-dragging": isDragging || void 0,
|
|
1293
|
+
type: "button",
|
|
1294
|
+
disabled,
|
|
1295
|
+
onClick: () => inputRef.current?.click(),
|
|
1296
|
+
onDragEnter: (event) => {
|
|
1297
|
+
event.preventDefault();
|
|
1298
|
+
if (!disabled) setIsDragging(true);
|
|
1299
|
+
},
|
|
1300
|
+
onDragOver: (event) => event.preventDefault(),
|
|
1301
|
+
onDragLeave: (event) => {
|
|
1302
|
+
event.preventDefault();
|
|
1303
|
+
setIsDragging(false);
|
|
1304
|
+
},
|
|
1305
|
+
onDrop: (event) => {
|
|
1306
|
+
event.preventDefault();
|
|
1307
|
+
setIsDragging(false);
|
|
1308
|
+
addFiles(event.dataTransfer.files);
|
|
1309
|
+
},
|
|
1310
|
+
children: [
|
|
1311
|
+
/* @__PURE__ */ jsx22(FileArrowUp, { "aria-hidden": "true", size: 20 }),
|
|
1312
|
+
/* @__PURE__ */ jsxs15("span", { className: "fractal-file-dropzone__copy", children: [
|
|
1313
|
+
/* @__PURE__ */ jsx22("span", { className: "fractal-file-dropzone__title", children: title }),
|
|
1314
|
+
description && /* @__PURE__ */ jsx22("span", { className: "fractal-file-dropzone__description", children: description })
|
|
1315
|
+
] })
|
|
1316
|
+
]
|
|
1317
|
+
}
|
|
1318
|
+
),
|
|
1319
|
+
files.length > 0 && /* @__PURE__ */ jsx22("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ jsxs15("li", { className: "fractal-file-dropzone__file", children: [
|
|
1320
|
+
/* @__PURE__ */ jsx22("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
|
|
1321
|
+
/* @__PURE__ */ jsx22("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
|
|
1322
|
+
/* @__PURE__ */ jsx22(
|
|
1323
|
+
"button",
|
|
1324
|
+
{
|
|
1325
|
+
className: "fractal-file-dropzone__remove",
|
|
1326
|
+
type: "button",
|
|
1327
|
+
"aria-label": `Remove ${file.name}`,
|
|
1328
|
+
disabled,
|
|
1329
|
+
onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
|
|
1330
|
+
children: /* @__PURE__ */ jsx22(Close2, { "aria-hidden": "true", size: 14 })
|
|
1331
|
+
}
|
|
1332
|
+
)
|
|
1333
|
+
] }, `${file.name}-${file.size}-${index}`)) })
|
|
1334
|
+
] });
|
|
1335
|
+
}
|
|
1336
|
+
function formatFileSize(bytes) {
|
|
1337
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1338
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
1339
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
// src/components/Pagination/Pagination.tsx
|
|
1343
|
+
import { ArrowLeft, ArrowRight } from "@mirror-physics/fractal-icons";
|
|
1344
|
+
import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1345
|
+
function Pagination({
|
|
1346
|
+
page,
|
|
1347
|
+
pageSize,
|
|
1348
|
+
totalItems,
|
|
1349
|
+
onPageChange,
|
|
1350
|
+
pageSizeOptions,
|
|
1351
|
+
onPageSizeChange,
|
|
1352
|
+
ariaLabel = "Pagination",
|
|
1353
|
+
className
|
|
1354
|
+
}) {
|
|
1355
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
1356
|
+
const currentPage = Math.min(Math.max(page, 1), totalPages);
|
|
1357
|
+
const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
|
|
1358
|
+
const end = Math.min(currentPage * pageSize, totalItems);
|
|
1359
|
+
const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
|
|
1360
|
+
return /* @__PURE__ */ jsxs16("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
|
|
1361
|
+
/* @__PURE__ */ jsx23("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
|
|
1362
|
+
/* @__PURE__ */ jsxs16("div", { className: "fractal-pagination__controls", children: [
|
|
1363
|
+
canChangePageSize && /* @__PURE__ */ jsx23(
|
|
1364
|
+
Dropdown,
|
|
1365
|
+
{
|
|
1366
|
+
align: "right",
|
|
1367
|
+
className: "fractal-pagination__page-size",
|
|
1368
|
+
direction: "up",
|
|
1369
|
+
items: pageSizeOptions.map((option) => ({
|
|
1370
|
+
value: String(option),
|
|
1371
|
+
description: `${option} per page`
|
|
1372
|
+
})),
|
|
1373
|
+
onSelect: (value) => onPageSizeChange(Number(value)),
|
|
1374
|
+
selectedValue: String(pageSize),
|
|
1375
|
+
size: "sm",
|
|
1376
|
+
triggerLabel: "Results per page",
|
|
1377
|
+
triggerVariant: "tertiary"
|
|
1378
|
+
}
|
|
1379
|
+
),
|
|
1380
|
+
/* @__PURE__ */ jsx23(
|
|
1381
|
+
"button",
|
|
1382
|
+
{
|
|
1383
|
+
className: "fractal-pagination__button",
|
|
1384
|
+
type: "button",
|
|
1385
|
+
"aria-label": "Previous page",
|
|
1386
|
+
title: "Previous page",
|
|
1387
|
+
disabled: currentPage === 1 || totalItems === 0,
|
|
1388
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
1389
|
+
children: /* @__PURE__ */ jsx23(ArrowLeft, { "aria-hidden": "true", size: 16 })
|
|
1390
|
+
}
|
|
1391
|
+
),
|
|
1392
|
+
/* @__PURE__ */ jsxs16("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
|
|
1393
|
+
currentPage,
|
|
1394
|
+
" of ",
|
|
1395
|
+
totalPages
|
|
1396
|
+
] }),
|
|
1397
|
+
/* @__PURE__ */ jsx23(
|
|
1398
|
+
"button",
|
|
1399
|
+
{
|
|
1400
|
+
className: "fractal-pagination__button",
|
|
1401
|
+
type: "button",
|
|
1402
|
+
"aria-label": "Next page",
|
|
1403
|
+
title: "Next page",
|
|
1404
|
+
disabled: currentPage === totalPages || totalItems === 0,
|
|
1405
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
1406
|
+
children: /* @__PURE__ */ jsx23(ArrowRight, { "aria-hidden": "true", size: 16 })
|
|
1407
|
+
}
|
|
1408
|
+
)
|
|
1409
|
+
] })
|
|
1410
|
+
] });
|
|
1411
|
+
}
|
|
1030
1412
|
export {
|
|
1031
1413
|
Alert,
|
|
1032
1414
|
AlertDescription,
|
|
@@ -1038,18 +1420,24 @@ export {
|
|
|
1038
1420
|
CardFooter,
|
|
1039
1421
|
CardHeader,
|
|
1040
1422
|
CardTitle,
|
|
1423
|
+
Checkbox,
|
|
1041
1424
|
Chip,
|
|
1425
|
+
ContentSwitcher,
|
|
1042
1426
|
DataTable,
|
|
1043
1427
|
Disclosure,
|
|
1044
1428
|
Dropdown,
|
|
1045
1429
|
FeatureCard,
|
|
1430
|
+
FileDropzone,
|
|
1046
1431
|
FolderCard,
|
|
1047
1432
|
Input,
|
|
1048
1433
|
Label,
|
|
1434
|
+
LatticeLoader,
|
|
1049
1435
|
Link,
|
|
1050
1436
|
Modal,
|
|
1437
|
+
Pagination,
|
|
1051
1438
|
PromptCard,
|
|
1052
1439
|
PromptGrid,
|
|
1440
|
+
SidePanel,
|
|
1053
1441
|
Sidebar,
|
|
1054
1442
|
SidebarBrand,
|
|
1055
1443
|
SidebarFooter,
|
|
@@ -1059,6 +1447,8 @@ export {
|
|
|
1059
1447
|
SidebarSection,
|
|
1060
1448
|
SortableTable,
|
|
1061
1449
|
Tabs,
|
|
1450
|
+
TextButton,
|
|
1451
|
+
Textarea,
|
|
1062
1452
|
Toggle,
|
|
1063
1453
|
cn,
|
|
1064
1454
|
useEscapeDismiss
|