@mirror-physics/fractal-ui 0.2.0-next.65 → 0.2.0-next.66

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.js CHANGED
@@ -927,6 +927,7 @@ function Toggle({ checked, onChange, label, className }) {
927
927
  }
928
928
 
929
929
  // src/components/Modal/Modal.tsx
930
+ import * as React10 from "react";
930
931
  import { createPortal } from "react-dom";
931
932
 
932
933
  // src/hooks/useEscapeDismiss.ts
@@ -1028,7 +1029,11 @@ function UILoader({ size = 48, tone = "neutral", className, style, label = "Load
1028
1029
  import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1029
1030
  var CloseIcon = () => /* @__PURE__ */ jsx13("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx13("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
1030
1031
  function Modal({ open, onClose, title, children, danger, warn, footer, noClose, closeDisabled = false, size = "sm", loading = false, loadingLabel = "Loading", scrollable = false, className }) {
1032
+ const [bodyScrolled, setBodyScrolled] = React10.useState(false);
1031
1033
  useEscapeDismiss(80, onClose, open && !noClose && !closeDisabled);
1034
+ React10.useEffect(() => {
1035
+ if (open) setBodyScrolled(false);
1036
+ }, [open]);
1032
1037
  if (!open) return null;
1033
1038
  const sizeClass = `fractal-modal-panel--${size}`;
1034
1039
  const accentClass = danger ? "fractal-modal-panel--danger" : warn ? "fractal-modal-panel--warn" : "";
@@ -1039,10 +1044,20 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
1039
1044
  className: cn("fractal-modal-panel", sizeClass, accentClass, scrollable && "fractal-modal-panel--scrollable", className),
1040
1045
  onClick: (e) => e.stopPropagation(),
1041
1046
  children: [
1042
- /* @__PURE__ */ jsxs12("div", { className: "fractal-modal-title-row", children: [
1043
- /* @__PURE__ */ jsx13("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
1044
- !noClose && /* @__PURE__ */ jsx13("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ jsx13(CloseIcon, {}) })
1045
- ] }),
1047
+ /* @__PURE__ */ jsxs12(
1048
+ "div",
1049
+ {
1050
+ className: cn(
1051
+ "fractal-modal-title-row",
1052
+ scrollable && "fractal-modal-title-row--scrollable",
1053
+ scrollable && bodyScrolled && "fractal-modal-title-row--scrolled"
1054
+ ),
1055
+ children: [
1056
+ /* @__PURE__ */ jsx13("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
1057
+ !noClose && /* @__PURE__ */ jsx13("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ jsx13(CloseIcon, {}) })
1058
+ ]
1059
+ }
1060
+ ),
1046
1061
  /* @__PURE__ */ jsx13(
1047
1062
  "div",
1048
1063
  {
@@ -1053,6 +1068,7 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
1053
1068
  loading && "fractal-modal-body--loading",
1054
1069
  scrollable && "fractal-modal-body--scrollable"
1055
1070
  ),
1071
+ onScroll: scrollable ? (event) => setBodyScrolled(event.currentTarget.scrollTop > 0) : void 0,
1056
1072
  children: loading ? /* @__PURE__ */ jsx13(UILoader, { label: loadingLabel }) : children
1057
1073
  }
1058
1074
  ),
@@ -1084,7 +1100,7 @@ function DataTable({ columns, data, emptyMessage, header, size = "md", className
1084
1100
  }
1085
1101
 
1086
1102
  // src/components/Dropdown/Dropdown.tsx
1087
- import * as React10 from "react";
1103
+ import * as React11 from "react";
1088
1104
  import { ChevronDown, ChevronLeft, ChevronRight as ChevronRight2, ChevronUp } from "@mirror-physics/fractal-icons";
1089
1105
  import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1090
1106
  var MARGIN = 4;
@@ -1108,10 +1124,10 @@ function Dropdown({
1108
1124
  closeOnSelect = true,
1109
1125
  disabled = false
1110
1126
  }) {
1111
- const [open, setOpen] = React10.useState(false);
1112
- const triggerRef = React10.useRef(null);
1113
- const panelRef = React10.useRef(null);
1114
- const [panelStyle, setPanelStyle] = React10.useState({});
1127
+ const [open, setOpen] = React11.useState(false);
1128
+ const triggerRef = React11.useRef(null);
1129
+ const panelRef = React11.useRef(null);
1130
+ const [panelStyle, setPanelStyle] = React11.useState({});
1115
1131
  const visibleItems = items.filter(
1116
1132
  (item) => item.icon != null || item.description != null && (typeof item.description === "string" ? item.description !== "" : true)
1117
1133
  );
@@ -1121,7 +1137,7 @@ function Dropdown({
1121
1137
  const isUp = direction === "up";
1122
1138
  const isHorizontalDirection = direction === "left" || direction === "right";
1123
1139
  const ChevronIcon = direction === "up" ? ChevronUp : direction === "left" ? ChevronLeft : direction === "right" ? ChevronRight2 : ChevronDown;
1124
- React10.useLayoutEffect(() => {
1140
+ React11.useLayoutEffect(() => {
1125
1141
  if (!open || !triggerRef.current || !panelRef.current) return;
1126
1142
  const triggerRect = triggerRef.current.getBoundingClientRect();
1127
1143
  const panelRect = panelRef.current.getBoundingClientRect();
@@ -1172,7 +1188,7 @@ function Dropdown({
1172
1188
  }
1173
1189
  setPanelStyle({ top, left, right });
1174
1190
  }, [open, direction, isHorizontalDirection, isUp, align]);
1175
- React10.useEffect(() => {
1191
+ React11.useEffect(() => {
1176
1192
  if (!open) return;
1177
1193
  const handleClickOutside = (e) => {
1178
1194
  const target = e.target;
@@ -1224,14 +1240,14 @@ function Dropdown({
1224
1240
  const topDivider = item.border === "top" ? /* @__PURE__ */ jsx15("div", { className: "fractal-dropdown-separator" }) : null;
1225
1241
  const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ jsx15("div", { className: "fractal-dropdown-separator" }) : null;
1226
1242
  if (item.kind === "header") {
1227
- return /* @__PURE__ */ jsxs14(React10.Fragment, { children: [
1243
+ return /* @__PURE__ */ jsxs14(React11.Fragment, { children: [
1228
1244
  topDivider,
1229
1245
  /* @__PURE__ */ jsx15("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
1230
1246
  bottomDivider
1231
1247
  ] }, `header-${index}`);
1232
1248
  }
1233
1249
  const isSelected = item.value === selectedValue;
1234
- return /* @__PURE__ */ jsxs14(React10.Fragment, { children: [
1250
+ return /* @__PURE__ */ jsxs14(React11.Fragment, { children: [
1235
1251
  topDivider,
1236
1252
  /* @__PURE__ */ jsxs14(
1237
1253
  "button",
@@ -1261,9 +1277,9 @@ function Dropdown({
1261
1277
  }
1262
1278
 
1263
1279
  // src/components/Link/Link.tsx
1264
- import * as React11 from "react";
1280
+ import * as React12 from "react";
1265
1281
  import { jsx as jsx16 } from "react/jsx-runtime";
1266
- var Link = React11.forwardRef(
1282
+ var Link = React12.forwardRef(
1267
1283
  ({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ jsx16(
1268
1284
  "a",
1269
1285
  {
@@ -1276,9 +1292,9 @@ var Link = React11.forwardRef(
1276
1292
  Link.displayName = "Link";
1277
1293
 
1278
1294
  // src/components/Chip/Chip.tsx
1279
- import * as React12 from "react";
1295
+ import * as React13 from "react";
1280
1296
  import { jsx as jsx17 } from "react/jsx-runtime";
1281
- var Chip = React12.forwardRef(
1297
+ var Chip = React13.forwardRef(
1282
1298
  ({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ jsx17(
1283
1299
  "span",
1284
1300
  {
@@ -1334,7 +1350,7 @@ function Checkbox({
1334
1350
  }
1335
1351
 
1336
1352
  // src/components/SortableTable/SortableTable.tsx
1337
- import { useMemo as useMemo2, useState as useState5 } from "react";
1353
+ import { useMemo as useMemo2, useState as useState6 } from "react";
1338
1354
  import { ArrowUp, ArrowDown, ArrowsUpDown } from "@mirror-physics/fractal-icons";
1339
1355
  import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
1340
1356
  function SortableTable({
@@ -1360,8 +1376,8 @@ function SortableTable({
1360
1376
  onRowDoubleClick,
1361
1377
  rowAction
1362
1378
  }) {
1363
- const [internalKey, setInternalKey] = useState5(defaultSortKey ?? null);
1364
- const [internalDirection, setInternalDirection] = useState5(defaultSortDirection);
1379
+ const [internalKey, setInternalKey] = useState6(defaultSortKey ?? null);
1380
+ const [internalDirection, setInternalDirection] = useState6(defaultSortDirection);
1365
1381
  const isControlled = controlledKey !== void 0 && controlledDirection !== void 0;
1366
1382
  const activeKey = isControlled ? controlledKey : internalKey;
1367
1383
  const activeDirection = isControlled ? controlledDirection : internalDirection;
@@ -1566,7 +1582,7 @@ function SortableTable({
1566
1582
  }
1567
1583
 
1568
1584
  // src/components/Tabs/Tabs.tsx
1569
- import { useId as useId2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState6 } from "react";
1585
+ import { useId as useId2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState7 } from "react";
1570
1586
  import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
1571
1587
  function Tabs({
1572
1588
  items,
@@ -1579,14 +1595,14 @@ function Tabs({
1579
1595
  variant = "line"
1580
1596
  }) {
1581
1597
  const reactId = useId2();
1582
- const [internalValue, setInternalValue] = useState6(
1598
+ const [internalValue, setInternalValue] = useState7(
1583
1599
  defaultValue ?? items.find((i) => !i.disabled)?.id ?? items[0]?.id ?? ""
1584
1600
  );
1585
1601
  const isControlled = controlledValue !== void 0;
1586
1602
  const activeId = isControlled ? controlledValue : internalValue;
1587
1603
  const tabListRef = useRef5(null);
1588
1604
  const tabRefs = useRef5({});
1589
- const [indicator, setIndicator] = useState6(null);
1605
+ const [indicator, setIndicator] = useState7(null);
1590
1606
  useLayoutEffect2(() => {
1591
1607
  const updateIndicator = () => {
1592
1608
  const activeTab = tabRefs.current[activeId];
@@ -1700,14 +1716,14 @@ function Tabs({
1700
1716
  }
1701
1717
 
1702
1718
  // src/components/ContentSwitcher/ContentSwitcher.tsx
1703
- import * as React13 from "react";
1719
+ import * as React14 from "react";
1704
1720
  import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
1705
1721
  function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
1706
- const switcherRef = React13.useRef(null);
1707
- const buttonRefs = React13.useRef([]);
1708
- const indicatorMotionReadyRef = React13.useRef(false);
1722
+ const switcherRef = React14.useRef(null);
1723
+ const buttonRefs = React14.useRef([]);
1724
+ const indicatorMotionReadyRef = React14.useRef(false);
1709
1725
  const activeIndex = items.findIndex((item) => item.value === value);
1710
- React13.useLayoutEffect(() => {
1726
+ React14.useLayoutEffect(() => {
1711
1727
  const switcher = switcherRef.current;
1712
1728
  const activeButton = buttonRefs.current[activeIndex];
1713
1729
  let motionFrame = 0;
@@ -1802,7 +1818,7 @@ function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = f
1802
1818
  }
1803
1819
 
1804
1820
  // src/components/Disclosure/Disclosure.tsx
1805
- import { useId as useId3, useState as useState7 } from "react";
1821
+ import { useId as useId3, useState as useState8 } from "react";
1806
1822
  import { ChevronRight as ChevronRight3, ChevronDown as ChevronDown2 } from "@mirror-physics/fractal-icons";
1807
1823
  import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
1808
1824
  function Disclosure({
@@ -1819,7 +1835,7 @@ function Disclosure({
1819
1835
  const reactId = useId3();
1820
1836
  const headerId = `${reactId}-header`;
1821
1837
  const panelId = `${reactId}-panel`;
1822
- const [internalOpen, setInternalOpen] = useState7(defaultOpen);
1838
+ const [internalOpen, setInternalOpen] = useState8(defaultOpen);
1823
1839
  const isControlled = controlledOpen !== void 0;
1824
1840
  const isOpen = isControlled ? controlledOpen : internalOpen;
1825
1841
  const toggle = () => {
@@ -2070,9 +2086,9 @@ function SurfaceGhost({ className, title, lines = 3, ...props }) {
2070
2086
  }
2071
2087
 
2072
2088
  // src/components/Sidebar/Sidebar.tsx
2073
- import * as React14 from "react";
2089
+ import * as React15 from "react";
2074
2090
  import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
2075
- var Sidebar = React14.forwardRef(
2091
+ var Sidebar = React15.forwardRef(
2076
2092
  ({ className, width, compact = false, style, ...props }, ref) => /* @__PURE__ */ jsx25(
2077
2093
  "aside",
2078
2094
  {
@@ -2085,11 +2101,11 @@ var Sidebar = React14.forwardRef(
2085
2101
  )
2086
2102
  );
2087
2103
  Sidebar.displayName = "Sidebar";
2088
- var SidebarHeader = React14.forwardRef(
2104
+ var SidebarHeader = React15.forwardRef(
2089
2105
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx25("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
2090
2106
  );
2091
2107
  SidebarHeader.displayName = "SidebarHeader";
2092
- var SidebarBrand = React14.forwardRef(
2108
+ var SidebarBrand = React15.forwardRef(
2093
2109
  ({ className, type = "button", ...props }, ref) => /* @__PURE__ */ jsx25("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
2094
2110
  );
2095
2111
  SidebarBrand.displayName = "SidebarBrand";
@@ -2120,15 +2136,15 @@ function SidebarAccountMenu({
2120
2136
  }
2121
2137
  );
2122
2138
  }
2123
- var SidebarNav = React14.forwardRef(
2139
+ var SidebarNav = React15.forwardRef(
2124
2140
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx25("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
2125
2141
  );
2126
2142
  SidebarNav.displayName = "SidebarNav";
2127
- var SidebarSection = React14.forwardRef(
2143
+ var SidebarSection = React15.forwardRef(
2128
2144
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx25("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
2129
2145
  );
2130
2146
  SidebarSection.displayName = "SidebarSection";
2131
- var SidebarNavItem = React14.forwardRef(
2147
+ var SidebarNavItem = React15.forwardRef(
2132
2148
  ({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ jsxs21(
2133
2149
  "button",
2134
2150
  {
@@ -2147,7 +2163,7 @@ var SidebarNavItem = React14.forwardRef(
2147
2163
  )
2148
2164
  );
2149
2165
  SidebarNavItem.displayName = "SidebarNavItem";
2150
- var SidebarFooter = React14.forwardRef(
2166
+ var SidebarFooter = React15.forwardRef(
2151
2167
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx25("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
2152
2168
  );
2153
2169
  SidebarFooter.displayName = "SidebarFooter";
@@ -2186,17 +2202,17 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
2186
2202
  }
2187
2203
 
2188
2204
  // src/components/Textarea/Textarea.tsx
2189
- import * as React15 from "react";
2205
+ import * as React16 from "react";
2190
2206
  import { jsx as jsx27 } from "react/jsx-runtime";
2191
- var Textarea = React15.forwardRef(
2207
+ var Textarea = React16.forwardRef(
2192
2208
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx27("textarea", { ref, className: cn("fractal-textarea", className), ...props })
2193
2209
  );
2194
2210
  Textarea.displayName = "Textarea";
2195
2211
 
2196
2212
  // src/components/TextButton/TextButton.tsx
2197
- import * as React16 from "react";
2213
+ import * as React17 from "react";
2198
2214
  import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
2199
- var TextButton = React16.forwardRef(
2215
+ var TextButton = React17.forwardRef(
2200
2216
  ({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ jsxs23(
2201
2217
  "button",
2202
2218
  {
@@ -2215,7 +2231,7 @@ var TextButton = React16.forwardRef(
2215
2231
  TextButton.displayName = "TextButton";
2216
2232
 
2217
2233
  // src/components/FileDropzone/FileDropzone.tsx
2218
- import * as React17 from "react";
2234
+ import * as React18 from "react";
2219
2235
  import { Close as Close2, FileArrowUp } from "@mirror-physics/fractal-icons";
2220
2236
  import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
2221
2237
  function FileDropzone({
@@ -2228,9 +2244,9 @@ function FileDropzone({
2228
2244
  description = "Files stay attached to this record.",
2229
2245
  className
2230
2246
  }) {
2231
- const inputId = React17.useId();
2232
- const inputRef = React17.useRef(null);
2233
- const [isDragging, setIsDragging] = React17.useState(false);
2247
+ const inputId = React18.useId();
2248
+ const inputRef = React18.useRef(null);
2249
+ const [isDragging, setIsDragging] = React18.useState(false);
2234
2250
  const addFiles = (nextFiles) => {
2235
2251
  if (disabled) return;
2236
2252
  const additions = Array.from(nextFiles);