@mirror-physics/fractal-ui 0.2.0-next.1 → 0.2.0-next.14
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 +392 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +524 -10
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +89 -3
- package/dist/index.d.ts +89 -3
- package/dist/index.js +378 -45
- package/dist/index.js.map +1 -1
- package/dist/tokens.css +6 -6
- 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
|
))
|
|
@@ -802,7 +852,7 @@ function SortableTable({
|
|
|
802
852
|
|
|
803
853
|
// src/components/Tabs/Tabs.tsx
|
|
804
854
|
import { useId, useRef as useRef3, useState as useState4 } from "react";
|
|
805
|
-
import { jsx as
|
|
855
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
806
856
|
function Tabs({
|
|
807
857
|
items,
|
|
808
858
|
defaultValue,
|
|
@@ -853,11 +903,11 @@ function Tabs({
|
|
|
853
903
|
requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
|
|
854
904
|
};
|
|
855
905
|
return /* @__PURE__ */ jsxs10("div", { className: cn("fractal-tabs", className), children: [
|
|
856
|
-
/* @__PURE__ */
|
|
906
|
+
/* @__PURE__ */ jsx14("div", { role: "tablist", "aria-label": ariaLabel, className: "fractal-tabs-list", children: items.map((item) => {
|
|
857
907
|
const isActive = item.id === activeId;
|
|
858
908
|
const tabId = `${reactId}-tab-${item.id}`;
|
|
859
909
|
const panelId = `${reactId}-panel-${item.id}`;
|
|
860
|
-
return /* @__PURE__ */
|
|
910
|
+
return /* @__PURE__ */ jsx14(
|
|
861
911
|
"button",
|
|
862
912
|
{
|
|
863
913
|
ref: (el) => {
|
|
@@ -886,7 +936,7 @@ function Tabs({
|
|
|
886
936
|
const tabId = `${reactId}-tab-${item.id}`;
|
|
887
937
|
const panelId = `${reactId}-panel-${item.id}`;
|
|
888
938
|
const isActive = item.id === activeId;
|
|
889
|
-
return /* @__PURE__ */
|
|
939
|
+
return /* @__PURE__ */ jsx14(
|
|
890
940
|
"div",
|
|
891
941
|
{
|
|
892
942
|
id: panelId,
|
|
@@ -902,10 +952,55 @@ function Tabs({
|
|
|
902
952
|
] });
|
|
903
953
|
}
|
|
904
954
|
|
|
955
|
+
// src/components/ContentSwitcher/ContentSwitcher.tsx
|
|
956
|
+
import * as React10 from "react";
|
|
957
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
958
|
+
function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
|
|
959
|
+
const buttonRefs = React10.useRef([]);
|
|
960
|
+
const moveFocus = (index, direction) => {
|
|
961
|
+
let nextIndex = index;
|
|
962
|
+
do {
|
|
963
|
+
nextIndex = (nextIndex + direction + items.length) % items.length;
|
|
964
|
+
} while (items[nextIndex]?.disabled && nextIndex !== index);
|
|
965
|
+
if (!items[nextIndex]?.disabled) {
|
|
966
|
+
buttonRefs.current[nextIndex]?.focus();
|
|
967
|
+
onValueChange(items[nextIndex].value);
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
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) => {
|
|
971
|
+
const active = item.value === value;
|
|
972
|
+
return /* @__PURE__ */ jsx15(
|
|
973
|
+
"button",
|
|
974
|
+
{
|
|
975
|
+
className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
|
|
976
|
+
type: "button",
|
|
977
|
+
"aria-pressed": active,
|
|
978
|
+
disabled: item.disabled,
|
|
979
|
+
onClick: () => onValueChange(item.value),
|
|
980
|
+
onKeyDown: (event) => {
|
|
981
|
+
if (event.key === "ArrowRight") {
|
|
982
|
+
event.preventDefault();
|
|
983
|
+
moveFocus(index, 1);
|
|
984
|
+
}
|
|
985
|
+
if (event.key === "ArrowLeft") {
|
|
986
|
+
event.preventDefault();
|
|
987
|
+
moveFocus(index, -1);
|
|
988
|
+
}
|
|
989
|
+
},
|
|
990
|
+
ref: (element) => {
|
|
991
|
+
buttonRefs.current[index] = element;
|
|
992
|
+
},
|
|
993
|
+
children: item.label
|
|
994
|
+
},
|
|
995
|
+
item.value
|
|
996
|
+
);
|
|
997
|
+
}) });
|
|
998
|
+
}
|
|
999
|
+
|
|
905
1000
|
// src/components/Disclosure/Disclosure.tsx
|
|
906
1001
|
import { useId as useId2, useState as useState5 } from "react";
|
|
907
1002
|
import { ChevronRight, ChevronDown as ChevronDown2 } from "@mirror-physics/fractal-icons";
|
|
908
|
-
import { jsx as
|
|
1003
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
909
1004
|
function Disclosure({
|
|
910
1005
|
title,
|
|
911
1006
|
meta,
|
|
@@ -913,6 +1008,7 @@ function Disclosure({
|
|
|
913
1008
|
defaultOpen = false,
|
|
914
1009
|
open: controlledOpen,
|
|
915
1010
|
onOpenChange,
|
|
1011
|
+
disabled = false,
|
|
916
1012
|
className,
|
|
917
1013
|
variant = "card"
|
|
918
1014
|
}) {
|
|
@@ -923,6 +1019,7 @@ function Disclosure({
|
|
|
923
1019
|
const isControlled = controlledOpen !== void 0;
|
|
924
1020
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
925
1021
|
const toggle = () => {
|
|
1022
|
+
if (disabled) return;
|
|
926
1023
|
const next = !isOpen;
|
|
927
1024
|
if (isControlled) {
|
|
928
1025
|
onOpenChange?.(next);
|
|
@@ -938,6 +1035,7 @@ function Disclosure({
|
|
|
938
1035
|
"fractal-disclosure",
|
|
939
1036
|
variant === "card" && "fractal-disclosure--card",
|
|
940
1037
|
isOpen && "fractal-disclosure--open",
|
|
1038
|
+
disabled && "fractal-disclosure--disabled",
|
|
941
1039
|
className
|
|
942
1040
|
),
|
|
943
1041
|
children: [
|
|
@@ -949,15 +1047,16 @@ function Disclosure({
|
|
|
949
1047
|
className: "fractal-disclosure-trigger",
|
|
950
1048
|
"aria-expanded": isOpen,
|
|
951
1049
|
"aria-controls": panelId,
|
|
1050
|
+
disabled,
|
|
952
1051
|
onClick: toggle,
|
|
953
1052
|
children: [
|
|
954
|
-
/* @__PURE__ */
|
|
955
|
-
/* @__PURE__ */
|
|
956
|
-
meta && /* @__PURE__ */
|
|
1053
|
+
/* @__PURE__ */ jsx16("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ jsx16(ChevronDown2, { size: 16 }) : /* @__PURE__ */ jsx16(ChevronRight, { size: 16 }) }),
|
|
1054
|
+
/* @__PURE__ */ jsx16("span", { className: "fractal-disclosure-title", children: title }),
|
|
1055
|
+
meta && /* @__PURE__ */ jsx16("span", { className: "fractal-disclosure-meta", children: meta })
|
|
957
1056
|
]
|
|
958
1057
|
}
|
|
959
1058
|
),
|
|
960
|
-
/* @__PURE__ */
|
|
1059
|
+
/* @__PURE__ */ jsx16(
|
|
961
1060
|
"div",
|
|
962
1061
|
{
|
|
963
1062
|
id: panelId,
|
|
@@ -965,7 +1064,7 @@ function Disclosure({
|
|
|
965
1064
|
"aria-labelledby": headerId,
|
|
966
1065
|
className: "fractal-disclosure-panel",
|
|
967
1066
|
hidden: !isOpen,
|
|
968
|
-
children: /* @__PURE__ */
|
|
1067
|
+
children: /* @__PURE__ */ jsx16("div", { className: "fractal-disclosure-panel-inner", children })
|
|
969
1068
|
}
|
|
970
1069
|
)
|
|
971
1070
|
]
|
|
@@ -974,10 +1073,10 @@ function Disclosure({
|
|
|
974
1073
|
}
|
|
975
1074
|
|
|
976
1075
|
// src/components/Sidebar/Sidebar.tsx
|
|
977
|
-
import * as
|
|
978
|
-
import { jsx as
|
|
979
|
-
var Sidebar =
|
|
980
|
-
({ className, width, style, ...props }, ref) => /* @__PURE__ */
|
|
1076
|
+
import * as React11 from "react";
|
|
1077
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1078
|
+
var Sidebar = React11.forwardRef(
|
|
1079
|
+
({ className, width, style, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
981
1080
|
"aside",
|
|
982
1081
|
{
|
|
983
1082
|
ref,
|
|
@@ -988,23 +1087,23 @@ var Sidebar = React10.forwardRef(
|
|
|
988
1087
|
)
|
|
989
1088
|
);
|
|
990
1089
|
Sidebar.displayName = "Sidebar";
|
|
991
|
-
var SidebarHeader =
|
|
992
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1090
|
+
var SidebarHeader = React11.forwardRef(
|
|
1091
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx17("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
|
|
993
1092
|
);
|
|
994
1093
|
SidebarHeader.displayName = "SidebarHeader";
|
|
995
|
-
var SidebarBrand =
|
|
996
|
-
({ className, type = "button", ...props }, ref) => /* @__PURE__ */
|
|
1094
|
+
var SidebarBrand = React11.forwardRef(
|
|
1095
|
+
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ jsx17("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
|
|
997
1096
|
);
|
|
998
1097
|
SidebarBrand.displayName = "SidebarBrand";
|
|
999
|
-
var SidebarNav =
|
|
1000
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1098
|
+
var SidebarNav = React11.forwardRef(
|
|
1099
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx17("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
|
|
1001
1100
|
);
|
|
1002
1101
|
SidebarNav.displayName = "SidebarNav";
|
|
1003
|
-
var SidebarSection =
|
|
1004
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1102
|
+
var SidebarSection = React11.forwardRef(
|
|
1103
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx17("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
|
|
1005
1104
|
);
|
|
1006
1105
|
SidebarSection.displayName = "SidebarSection";
|
|
1007
|
-
var SidebarNavItem =
|
|
1106
|
+
var SidebarNavItem = React11.forwardRef(
|
|
1008
1107
|
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ jsxs12(
|
|
1009
1108
|
"button",
|
|
1010
1109
|
{
|
|
@@ -1015,18 +1114,245 @@ var SidebarNavItem = React10.forwardRef(
|
|
|
1015
1114
|
"aria-current": active ? "page" : void 0,
|
|
1016
1115
|
...props,
|
|
1017
1116
|
children: [
|
|
1018
|
-
icon && /* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1020
|
-
endAdornment && /* @__PURE__ */
|
|
1117
|
+
icon && /* @__PURE__ */ jsx17("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
|
|
1118
|
+
/* @__PURE__ */ jsx17("span", { className: "fractal-sidebar__nav-item-label", children }),
|
|
1119
|
+
endAdornment && /* @__PURE__ */ jsx17("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
|
|
1021
1120
|
]
|
|
1022
1121
|
}
|
|
1023
1122
|
)
|
|
1024
1123
|
);
|
|
1025
1124
|
SidebarNavItem.displayName = "SidebarNavItem";
|
|
1026
|
-
var SidebarFooter =
|
|
1027
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1125
|
+
var SidebarFooter = React11.forwardRef(
|
|
1126
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx17("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
|
|
1028
1127
|
);
|
|
1029
1128
|
SidebarFooter.displayName = "SidebarFooter";
|
|
1129
|
+
|
|
1130
|
+
// src/components/SidePanel/SidePanel.tsx
|
|
1131
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
1132
|
+
import { Close } from "@mirror-physics/fractal-icons";
|
|
1133
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1134
|
+
function SidePanel({ open, onClose, title, description, children, footer, size = "md", className }) {
|
|
1135
|
+
useEscapeDismiss(80, onClose, open);
|
|
1136
|
+
if (!open) return null;
|
|
1137
|
+
return createPortal2(
|
|
1138
|
+
/* @__PURE__ */ jsx18("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ jsxs13(
|
|
1139
|
+
"aside",
|
|
1140
|
+
{
|
|
1141
|
+
className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
|
|
1142
|
+
"aria-modal": "true",
|
|
1143
|
+
"aria-label": typeof title === "string" ? title : "Side panel",
|
|
1144
|
+
role: "dialog",
|
|
1145
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
1146
|
+
children: [
|
|
1147
|
+
/* @__PURE__ */ jsxs13("header", { className: "fractal-side-panel__header", children: [
|
|
1148
|
+
/* @__PURE__ */ jsxs13("div", { className: "fractal-side-panel__heading", children: [
|
|
1149
|
+
/* @__PURE__ */ jsx18("h2", { className: "fractal-side-panel__title", children: title }),
|
|
1150
|
+
description && /* @__PURE__ */ jsx18("p", { className: "fractal-side-panel__description", children: description })
|
|
1151
|
+
] }),
|
|
1152
|
+
/* @__PURE__ */ jsx18("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx18(Close, { size: 18 }) })
|
|
1153
|
+
] }),
|
|
1154
|
+
/* @__PURE__ */ jsx18("div", { className: "fractal-side-panel__body", children }),
|
|
1155
|
+
footer && /* @__PURE__ */ jsx18("footer", { className: "fractal-side-panel__footer", children: footer })
|
|
1156
|
+
]
|
|
1157
|
+
}
|
|
1158
|
+
) }),
|
|
1159
|
+
document.body
|
|
1160
|
+
);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
// src/components/Textarea/Textarea.tsx
|
|
1164
|
+
import * as React12 from "react";
|
|
1165
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1166
|
+
var Textarea = React12.forwardRef(
|
|
1167
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx19("textarea", { ref, className: cn("fractal-textarea", className), ...props })
|
|
1168
|
+
);
|
|
1169
|
+
Textarea.displayName = "Textarea";
|
|
1170
|
+
|
|
1171
|
+
// src/components/TextButton/TextButton.tsx
|
|
1172
|
+
import * as React13 from "react";
|
|
1173
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1174
|
+
var TextButton = React13.forwardRef(
|
|
1175
|
+
({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ jsxs14(
|
|
1176
|
+
"button",
|
|
1177
|
+
{
|
|
1178
|
+
ref,
|
|
1179
|
+
className: cn("fractal-text-button", `fractal-text-button--${size}`, `fractal-text-button--${tone}`, className),
|
|
1180
|
+
type: "button",
|
|
1181
|
+
...props,
|
|
1182
|
+
children: [
|
|
1183
|
+
icon && iconPosition === "start" && /* @__PURE__ */ jsx20("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
|
|
1184
|
+
/* @__PURE__ */ jsx20("span", { children }),
|
|
1185
|
+
icon && iconPosition === "end" && /* @__PURE__ */ jsx20("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
|
|
1186
|
+
]
|
|
1187
|
+
}
|
|
1188
|
+
)
|
|
1189
|
+
);
|
|
1190
|
+
TextButton.displayName = "TextButton";
|
|
1191
|
+
|
|
1192
|
+
// src/components/FileDropzone/FileDropzone.tsx
|
|
1193
|
+
import * as React14 from "react";
|
|
1194
|
+
import { Close as Close2, FileArrowUp } from "@mirror-physics/fractal-icons";
|
|
1195
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1196
|
+
function FileDropzone({
|
|
1197
|
+
files,
|
|
1198
|
+
onFilesChange,
|
|
1199
|
+
accept,
|
|
1200
|
+
multiple = true,
|
|
1201
|
+
disabled = false,
|
|
1202
|
+
title = "Drop files here or click to browse",
|
|
1203
|
+
description = "Files stay attached to this record.",
|
|
1204
|
+
className
|
|
1205
|
+
}) {
|
|
1206
|
+
const inputId = React14.useId();
|
|
1207
|
+
const inputRef = React14.useRef(null);
|
|
1208
|
+
const [isDragging, setIsDragging] = React14.useState(false);
|
|
1209
|
+
const addFiles = (nextFiles) => {
|
|
1210
|
+
if (disabled) return;
|
|
1211
|
+
const additions = Array.from(nextFiles);
|
|
1212
|
+
if (additions.length === 0) return;
|
|
1213
|
+
onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
|
|
1214
|
+
};
|
|
1215
|
+
return /* @__PURE__ */ jsxs15("div", { className: cn("fractal-file-dropzone", className), children: [
|
|
1216
|
+
/* @__PURE__ */ jsx21(
|
|
1217
|
+
"input",
|
|
1218
|
+
{
|
|
1219
|
+
ref: inputRef,
|
|
1220
|
+
id: inputId,
|
|
1221
|
+
className: "fractal-file-dropzone__input",
|
|
1222
|
+
type: "file",
|
|
1223
|
+
accept,
|
|
1224
|
+
multiple,
|
|
1225
|
+
disabled,
|
|
1226
|
+
onChange: (event) => {
|
|
1227
|
+
if (event.target.files) addFiles(event.target.files);
|
|
1228
|
+
event.target.value = "";
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
),
|
|
1232
|
+
/* @__PURE__ */ jsxs15(
|
|
1233
|
+
"button",
|
|
1234
|
+
{
|
|
1235
|
+
className: "fractal-file-dropzone__target",
|
|
1236
|
+
"data-dragging": isDragging || void 0,
|
|
1237
|
+
type: "button",
|
|
1238
|
+
disabled,
|
|
1239
|
+
onClick: () => inputRef.current?.click(),
|
|
1240
|
+
onDragEnter: (event) => {
|
|
1241
|
+
event.preventDefault();
|
|
1242
|
+
if (!disabled) setIsDragging(true);
|
|
1243
|
+
},
|
|
1244
|
+
onDragOver: (event) => event.preventDefault(),
|
|
1245
|
+
onDragLeave: (event) => {
|
|
1246
|
+
event.preventDefault();
|
|
1247
|
+
setIsDragging(false);
|
|
1248
|
+
},
|
|
1249
|
+
onDrop: (event) => {
|
|
1250
|
+
event.preventDefault();
|
|
1251
|
+
setIsDragging(false);
|
|
1252
|
+
addFiles(event.dataTransfer.files);
|
|
1253
|
+
},
|
|
1254
|
+
children: [
|
|
1255
|
+
/* @__PURE__ */ jsx21(FileArrowUp, { "aria-hidden": "true", size: 20 }),
|
|
1256
|
+
/* @__PURE__ */ jsxs15("span", { className: "fractal-file-dropzone__copy", children: [
|
|
1257
|
+
/* @__PURE__ */ jsx21("span", { className: "fractal-file-dropzone__title", children: title }),
|
|
1258
|
+
description && /* @__PURE__ */ jsx21("span", { className: "fractal-file-dropzone__description", children: description })
|
|
1259
|
+
] })
|
|
1260
|
+
]
|
|
1261
|
+
}
|
|
1262
|
+
),
|
|
1263
|
+
files.length > 0 && /* @__PURE__ */ jsx21("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ jsxs15("li", { className: "fractal-file-dropzone__file", children: [
|
|
1264
|
+
/* @__PURE__ */ jsx21("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
|
|
1265
|
+
/* @__PURE__ */ jsx21("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
|
|
1266
|
+
/* @__PURE__ */ jsx21(
|
|
1267
|
+
"button",
|
|
1268
|
+
{
|
|
1269
|
+
className: "fractal-file-dropzone__remove",
|
|
1270
|
+
type: "button",
|
|
1271
|
+
"aria-label": `Remove ${file.name}`,
|
|
1272
|
+
disabled,
|
|
1273
|
+
onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
|
|
1274
|
+
children: /* @__PURE__ */ jsx21(Close2, { "aria-hidden": "true", size: 14 })
|
|
1275
|
+
}
|
|
1276
|
+
)
|
|
1277
|
+
] }, `${file.name}-${file.size}-${index}`)) })
|
|
1278
|
+
] });
|
|
1279
|
+
}
|
|
1280
|
+
function formatFileSize(bytes) {
|
|
1281
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1282
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
1283
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// src/components/Pagination/Pagination.tsx
|
|
1287
|
+
import { ArrowLeft, ArrowRight } from "@mirror-physics/fractal-icons";
|
|
1288
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1289
|
+
function Pagination({
|
|
1290
|
+
page,
|
|
1291
|
+
pageSize,
|
|
1292
|
+
totalItems,
|
|
1293
|
+
onPageChange,
|
|
1294
|
+
pageSizeOptions,
|
|
1295
|
+
onPageSizeChange,
|
|
1296
|
+
ariaLabel = "Pagination",
|
|
1297
|
+
className
|
|
1298
|
+
}) {
|
|
1299
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
1300
|
+
const currentPage = Math.min(Math.max(page, 1), totalPages);
|
|
1301
|
+
const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
|
|
1302
|
+
const end = Math.min(currentPage * pageSize, totalItems);
|
|
1303
|
+
const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
|
|
1304
|
+
return /* @__PURE__ */ jsxs16("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
|
|
1305
|
+
/* @__PURE__ */ jsx22("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
|
|
1306
|
+
/* @__PURE__ */ jsxs16("div", { className: "fractal-pagination__controls", children: [
|
|
1307
|
+
canChangePageSize && /* @__PURE__ */ jsx22(
|
|
1308
|
+
Dropdown,
|
|
1309
|
+
{
|
|
1310
|
+
align: "right",
|
|
1311
|
+
className: "fractal-pagination__page-size",
|
|
1312
|
+
direction: "up",
|
|
1313
|
+
items: pageSizeOptions.map((option) => ({
|
|
1314
|
+
value: String(option),
|
|
1315
|
+
description: `${option} per page`
|
|
1316
|
+
})),
|
|
1317
|
+
onSelect: (value) => onPageSizeChange(Number(value)),
|
|
1318
|
+
selectedValue: String(pageSize),
|
|
1319
|
+
size: "sm",
|
|
1320
|
+
triggerLabel: "Results per page",
|
|
1321
|
+
triggerVariant: "tertiary"
|
|
1322
|
+
}
|
|
1323
|
+
),
|
|
1324
|
+
/* @__PURE__ */ jsx22(
|
|
1325
|
+
"button",
|
|
1326
|
+
{
|
|
1327
|
+
className: "fractal-pagination__button",
|
|
1328
|
+
type: "button",
|
|
1329
|
+
"aria-label": "Previous page",
|
|
1330
|
+
title: "Previous page",
|
|
1331
|
+
disabled: currentPage === 1 || totalItems === 0,
|
|
1332
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
1333
|
+
children: /* @__PURE__ */ jsx22(ArrowLeft, { "aria-hidden": "true", size: 16 })
|
|
1334
|
+
}
|
|
1335
|
+
),
|
|
1336
|
+
/* @__PURE__ */ jsxs16("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
|
|
1337
|
+
currentPage,
|
|
1338
|
+
" of ",
|
|
1339
|
+
totalPages
|
|
1340
|
+
] }),
|
|
1341
|
+
/* @__PURE__ */ jsx22(
|
|
1342
|
+
"button",
|
|
1343
|
+
{
|
|
1344
|
+
className: "fractal-pagination__button",
|
|
1345
|
+
type: "button",
|
|
1346
|
+
"aria-label": "Next page",
|
|
1347
|
+
title: "Next page",
|
|
1348
|
+
disabled: currentPage === totalPages || totalItems === 0,
|
|
1349
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
1350
|
+
children: /* @__PURE__ */ jsx22(ArrowRight, { "aria-hidden": "true", size: 16 })
|
|
1351
|
+
}
|
|
1352
|
+
)
|
|
1353
|
+
] })
|
|
1354
|
+
] });
|
|
1355
|
+
}
|
|
1030
1356
|
export {
|
|
1031
1357
|
Alert,
|
|
1032
1358
|
AlertDescription,
|
|
@@ -1038,18 +1364,23 @@ export {
|
|
|
1038
1364
|
CardFooter,
|
|
1039
1365
|
CardHeader,
|
|
1040
1366
|
CardTitle,
|
|
1367
|
+
Checkbox,
|
|
1041
1368
|
Chip,
|
|
1369
|
+
ContentSwitcher,
|
|
1042
1370
|
DataTable,
|
|
1043
1371
|
Disclosure,
|
|
1044
1372
|
Dropdown,
|
|
1045
1373
|
FeatureCard,
|
|
1374
|
+
FileDropzone,
|
|
1046
1375
|
FolderCard,
|
|
1047
1376
|
Input,
|
|
1048
1377
|
Label,
|
|
1049
1378
|
Link,
|
|
1050
1379
|
Modal,
|
|
1380
|
+
Pagination,
|
|
1051
1381
|
PromptCard,
|
|
1052
1382
|
PromptGrid,
|
|
1383
|
+
SidePanel,
|
|
1053
1384
|
Sidebar,
|
|
1054
1385
|
SidebarBrand,
|
|
1055
1386
|
SidebarFooter,
|
|
@@ -1059,6 +1390,8 @@ export {
|
|
|
1059
1390
|
SidebarSection,
|
|
1060
1391
|
SortableTable,
|
|
1061
1392
|
Tabs,
|
|
1393
|
+
TextButton,
|
|
1394
|
+
Textarea,
|
|
1062
1395
|
Toggle,
|
|
1063
1396
|
cn,
|
|
1064
1397
|
useEscapeDismiss
|