@mirror-physics/fractal-ui 0.2.0-next.64 → 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.cjs CHANGED
@@ -1031,6 +1031,7 @@ function Toggle({ checked, onChange, label, className }) {
1031
1031
  }
1032
1032
 
1033
1033
  // src/components/Modal/Modal.tsx
1034
+ var React10 = __toESM(require("react"), 1);
1034
1035
  var import_react_dom = require("react-dom");
1035
1036
 
1036
1037
  // src/hooks/useEscapeDismiss.ts
@@ -1132,7 +1133,11 @@ function UILoader({ size = 48, tone = "neutral", className, style, label = "Load
1132
1133
  var import_jsx_runtime14 = require("react/jsx-runtime");
1133
1134
  var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
1134
1135
  function Modal({ open, onClose, title, children, danger, warn, footer, noClose, closeDisabled = false, size = "sm", loading = false, loadingLabel = "Loading", scrollable = false, className }) {
1136
+ const [bodyScrolled, setBodyScrolled] = React10.useState(false);
1135
1137
  useEscapeDismiss(80, onClose, open && !noClose && !closeDisabled);
1138
+ React10.useEffect(() => {
1139
+ if (open) setBodyScrolled(false);
1140
+ }, [open]);
1136
1141
  if (!open) return null;
1137
1142
  const sizeClass = `fractal-modal-panel--${size}`;
1138
1143
  const accentClass = danger ? "fractal-modal-panel--danger" : warn ? "fractal-modal-panel--warn" : "";
@@ -1143,10 +1148,20 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
1143
1148
  className: cn("fractal-modal-panel", sizeClass, accentClass, scrollable && "fractal-modal-panel--scrollable", className),
1144
1149
  onClick: (e) => e.stopPropagation(),
1145
1150
  children: [
1146
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "fractal-modal-title-row", children: [
1147
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
1148
- !noClose && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseIcon, {}) })
1149
- ] }),
1151
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1152
+ "div",
1153
+ {
1154
+ className: cn(
1155
+ "fractal-modal-title-row",
1156
+ scrollable && "fractal-modal-title-row--scrollable",
1157
+ scrollable && bodyScrolled && "fractal-modal-title-row--scrolled"
1158
+ ),
1159
+ children: [
1160
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
1161
+ !noClose && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseIcon, {}) })
1162
+ ]
1163
+ }
1164
+ ),
1150
1165
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1151
1166
  "div",
1152
1167
  {
@@ -1157,6 +1172,7 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
1157
1172
  loading && "fractal-modal-body--loading",
1158
1173
  scrollable && "fractal-modal-body--scrollable"
1159
1174
  ),
1175
+ onScroll: scrollable ? (event) => setBodyScrolled(event.currentTarget.scrollTop > 0) : void 0,
1160
1176
  children: loading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(UILoader, { label: loadingLabel }) : children
1161
1177
  }
1162
1178
  ),
@@ -1188,7 +1204,7 @@ function DataTable({ columns, data, emptyMessage, header, size = "md", className
1188
1204
  }
1189
1205
 
1190
1206
  // src/components/Dropdown/Dropdown.tsx
1191
- var React10 = __toESM(require("react"), 1);
1207
+ var React11 = __toESM(require("react"), 1);
1192
1208
  var import_fractal_icons8 = require("@mirror-physics/fractal-icons");
1193
1209
  var import_jsx_runtime16 = require("react/jsx-runtime");
1194
1210
  var MARGIN = 4;
@@ -1212,10 +1228,10 @@ function Dropdown({
1212
1228
  closeOnSelect = true,
1213
1229
  disabled = false
1214
1230
  }) {
1215
- const [open, setOpen] = React10.useState(false);
1216
- const triggerRef = React10.useRef(null);
1217
- const panelRef = React10.useRef(null);
1218
- const [panelStyle, setPanelStyle] = React10.useState({});
1231
+ const [open, setOpen] = React11.useState(false);
1232
+ const triggerRef = React11.useRef(null);
1233
+ const panelRef = React11.useRef(null);
1234
+ const [panelStyle, setPanelStyle] = React11.useState({});
1219
1235
  const visibleItems = items.filter(
1220
1236
  (item) => item.icon != null || item.description != null && (typeof item.description === "string" ? item.description !== "" : true)
1221
1237
  );
@@ -1225,7 +1241,7 @@ function Dropdown({
1225
1241
  const isUp = direction === "up";
1226
1242
  const isHorizontalDirection = direction === "left" || direction === "right";
1227
1243
  const ChevronIcon = direction === "up" ? import_fractal_icons8.ChevronUp : direction === "left" ? import_fractal_icons8.ChevronLeft : direction === "right" ? import_fractal_icons8.ChevronRight : import_fractal_icons8.ChevronDown;
1228
- React10.useLayoutEffect(() => {
1244
+ React11.useLayoutEffect(() => {
1229
1245
  if (!open || !triggerRef.current || !panelRef.current) return;
1230
1246
  const triggerRect = triggerRef.current.getBoundingClientRect();
1231
1247
  const panelRect = panelRef.current.getBoundingClientRect();
@@ -1276,7 +1292,7 @@ function Dropdown({
1276
1292
  }
1277
1293
  setPanelStyle({ top, left, right });
1278
1294
  }, [open, direction, isHorizontalDirection, isUp, align]);
1279
- React10.useEffect(() => {
1295
+ React11.useEffect(() => {
1280
1296
  if (!open) return;
1281
1297
  const handleClickOutside = (e) => {
1282
1298
  const target = e.target;
@@ -1328,14 +1344,14 @@ function Dropdown({
1328
1344
  const topDivider = item.border === "top" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
1329
1345
  const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
1330
1346
  if (item.kind === "header") {
1331
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React10.Fragment, { children: [
1347
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React11.Fragment, { children: [
1332
1348
  topDivider,
1333
1349
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
1334
1350
  bottomDivider
1335
1351
  ] }, `header-${index}`);
1336
1352
  }
1337
1353
  const isSelected = item.value === selectedValue;
1338
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React10.Fragment, { children: [
1354
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React11.Fragment, { children: [
1339
1355
  topDivider,
1340
1356
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1341
1357
  "button",
@@ -1365,9 +1381,9 @@ function Dropdown({
1365
1381
  }
1366
1382
 
1367
1383
  // src/components/Link/Link.tsx
1368
- var React11 = __toESM(require("react"), 1);
1384
+ var React12 = __toESM(require("react"), 1);
1369
1385
  var import_jsx_runtime17 = require("react/jsx-runtime");
1370
- var Link = React11.forwardRef(
1386
+ var Link = React12.forwardRef(
1371
1387
  ({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1372
1388
  "a",
1373
1389
  {
@@ -1380,9 +1396,9 @@ var Link = React11.forwardRef(
1380
1396
  Link.displayName = "Link";
1381
1397
 
1382
1398
  // src/components/Chip/Chip.tsx
1383
- var React12 = __toESM(require("react"), 1);
1399
+ var React13 = __toESM(require("react"), 1);
1384
1400
  var import_jsx_runtime18 = require("react/jsx-runtime");
1385
- var Chip = React12.forwardRef(
1401
+ var Chip = React13.forwardRef(
1386
1402
  ({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1387
1403
  "span",
1388
1404
  {
@@ -1444,6 +1460,7 @@ var import_jsx_runtime20 = require("react/jsx-runtime");
1444
1460
  function SortableTable({
1445
1461
  columns,
1446
1462
  data,
1463
+ "aria-label": ariaLabel,
1447
1464
  emptyMessage,
1448
1465
  header,
1449
1466
  size = "md",
@@ -1534,7 +1551,7 @@ function SortableTable({
1534
1551
  };
1535
1552
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "fractal-sortable-table-surface", children: [
1536
1553
  header && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-sortable-table-header", children: header }),
1537
- visibleRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("table", { className: "fractal-sortable-table-table", children: [
1554
+ visibleRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("table", { "aria-label": ariaLabel, className: "fractal-sortable-table-table", children: [
1538
1555
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("tr", { className: "fractal-sortable-table-thead-row", children: [
1539
1556
  selection && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1540
1557
  "th",
@@ -1566,6 +1583,7 @@ function SortableTable({
1566
1583
  "th",
1567
1584
  {
1568
1585
  className: "fractal-sortable-table-th",
1586
+ scope: "col",
1569
1587
  style: { width: col.width },
1570
1588
  children: col.header
1571
1589
  },
@@ -1576,6 +1594,7 @@ function SortableTable({
1576
1594
  "th",
1577
1595
  {
1578
1596
  className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
1597
+ scope: "col",
1579
1598
  style: { width: col.width },
1580
1599
  children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1581
1600
  "button",
@@ -1801,14 +1820,14 @@ function Tabs({
1801
1820
  }
1802
1821
 
1803
1822
  // src/components/ContentSwitcher/ContentSwitcher.tsx
1804
- var React13 = __toESM(require("react"), 1);
1823
+ var React14 = __toESM(require("react"), 1);
1805
1824
  var import_jsx_runtime22 = require("react/jsx-runtime");
1806
1825
  function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
1807
- const switcherRef = React13.useRef(null);
1808
- const buttonRefs = React13.useRef([]);
1809
- const indicatorMotionReadyRef = React13.useRef(false);
1826
+ const switcherRef = React14.useRef(null);
1827
+ const buttonRefs = React14.useRef([]);
1828
+ const indicatorMotionReadyRef = React14.useRef(false);
1810
1829
  const activeIndex = items.findIndex((item) => item.value === value);
1811
- React13.useLayoutEffect(() => {
1830
+ React14.useLayoutEffect(() => {
1812
1831
  const switcher = switcherRef.current;
1813
1832
  const activeButton = buttonRefs.current[activeIndex];
1814
1833
  let motionFrame = 0;
@@ -2171,9 +2190,9 @@ function SurfaceGhost({ className, title, lines = 3, ...props }) {
2171
2190
  }
2172
2191
 
2173
2192
  // src/components/Sidebar/Sidebar.tsx
2174
- var React14 = __toESM(require("react"), 1);
2193
+ var React15 = __toESM(require("react"), 1);
2175
2194
  var import_jsx_runtime26 = require("react/jsx-runtime");
2176
- var Sidebar = React14.forwardRef(
2195
+ var Sidebar = React15.forwardRef(
2177
2196
  ({ className, width, compact = false, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2178
2197
  "aside",
2179
2198
  {
@@ -2186,11 +2205,11 @@ var Sidebar = React14.forwardRef(
2186
2205
  )
2187
2206
  );
2188
2207
  Sidebar.displayName = "Sidebar";
2189
- var SidebarHeader = React14.forwardRef(
2208
+ var SidebarHeader = React15.forwardRef(
2190
2209
  ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
2191
2210
  );
2192
2211
  SidebarHeader.displayName = "SidebarHeader";
2193
- var SidebarBrand = React14.forwardRef(
2212
+ var SidebarBrand = React15.forwardRef(
2194
2213
  ({ className, type = "button", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
2195
2214
  );
2196
2215
  SidebarBrand.displayName = "SidebarBrand";
@@ -2221,15 +2240,15 @@ function SidebarAccountMenu({
2221
2240
  }
2222
2241
  );
2223
2242
  }
2224
- var SidebarNav = React14.forwardRef(
2243
+ var SidebarNav = React15.forwardRef(
2225
2244
  ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
2226
2245
  );
2227
2246
  SidebarNav.displayName = "SidebarNav";
2228
- var SidebarSection = React14.forwardRef(
2247
+ var SidebarSection = React15.forwardRef(
2229
2248
  ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
2230
2249
  );
2231
2250
  SidebarSection.displayName = "SidebarSection";
2232
- var SidebarNavItem = React14.forwardRef(
2251
+ var SidebarNavItem = React15.forwardRef(
2233
2252
  ({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
2234
2253
  "button",
2235
2254
  {
@@ -2248,7 +2267,7 @@ var SidebarNavItem = React14.forwardRef(
2248
2267
  )
2249
2268
  );
2250
2269
  SidebarNavItem.displayName = "SidebarNavItem";
2251
- var SidebarFooter = React14.forwardRef(
2270
+ var SidebarFooter = React15.forwardRef(
2252
2271
  ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
2253
2272
  );
2254
2273
  SidebarFooter.displayName = "SidebarFooter";
@@ -2287,17 +2306,17 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
2287
2306
  }
2288
2307
 
2289
2308
  // src/components/Textarea/Textarea.tsx
2290
- var React15 = __toESM(require("react"), 1);
2309
+ var React16 = __toESM(require("react"), 1);
2291
2310
  var import_jsx_runtime28 = require("react/jsx-runtime");
2292
- var Textarea = React15.forwardRef(
2311
+ var Textarea = React16.forwardRef(
2293
2312
  ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("textarea", { ref, className: cn("fractal-textarea", className), ...props })
2294
2313
  );
2295
2314
  Textarea.displayName = "Textarea";
2296
2315
 
2297
2316
  // src/components/TextButton/TextButton.tsx
2298
- var React16 = __toESM(require("react"), 1);
2317
+ var React17 = __toESM(require("react"), 1);
2299
2318
  var import_jsx_runtime29 = require("react/jsx-runtime");
2300
- var TextButton = React16.forwardRef(
2319
+ var TextButton = React17.forwardRef(
2301
2320
  ({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2302
2321
  "button",
2303
2322
  {
@@ -2316,7 +2335,7 @@ var TextButton = React16.forwardRef(
2316
2335
  TextButton.displayName = "TextButton";
2317
2336
 
2318
2337
  // src/components/FileDropzone/FileDropzone.tsx
2319
- var React17 = __toESM(require("react"), 1);
2338
+ var React18 = __toESM(require("react"), 1);
2320
2339
  var import_fractal_icons13 = require("@mirror-physics/fractal-icons");
2321
2340
  var import_jsx_runtime30 = require("react/jsx-runtime");
2322
2341
  function FileDropzone({
@@ -2329,9 +2348,9 @@ function FileDropzone({
2329
2348
  description = "Files stay attached to this record.",
2330
2349
  className
2331
2350
  }) {
2332
- const inputId = React17.useId();
2333
- const inputRef = React17.useRef(null);
2334
- const [isDragging, setIsDragging] = React17.useState(false);
2351
+ const inputId = React18.useId();
2352
+ const inputRef = React18.useRef(null);
2353
+ const [isDragging, setIsDragging] = React18.useState(false);
2335
2354
  const addFiles = (nextFiles) => {
2336
2355
  if (disabled) return;
2337
2356
  const additions = Array.from(nextFiles);