@geomak/ui 7.6.3 → 7.7.1

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
@@ -745,6 +745,8 @@ function Modal({
745
745
  onCancel,
746
746
  okText = "Ok",
747
747
  cancelText = "Cancel",
748
+ okVariant = "primary",
749
+ cancelVariant = "ghost",
748
750
  hasFooter = true,
749
751
  title,
750
752
  children,
@@ -801,6 +803,7 @@ function Modal({
801
803
  Button_default,
802
804
  {
803
805
  style: { width: 90 },
806
+ variant: cancelVariant,
804
807
  content: cancelText,
805
808
  onClick: onCancel
806
809
  }
@@ -809,6 +812,7 @@ function Modal({
809
812
  Button_default,
810
813
  {
811
814
  style: { width: 90 },
815
+ variant: okVariant,
812
816
  content: okText,
813
817
  onClick: onOk
814
818
  }
@@ -835,6 +839,8 @@ function Drawer({
835
839
  width,
836
840
  okText = "Ok",
837
841
  cancelText = "Cancel",
842
+ okVariant = "primary",
843
+ cancelVariant = "ghost",
838
844
  onOk,
839
845
  onCancel,
840
846
  title,
@@ -890,8 +896,8 @@ function Drawer({
890
896
  ] }),
891
897
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto p-5", children }),
892
898
  hasFooter && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-shrink-0 items-center gap-3 border-t border-border px-5 py-3 ${isRight ? "justify-start" : "justify-end"}`, children: [
893
- /* @__PURE__ */ jsxRuntime.jsx(Button_default, { style: { width: 90 }, content: cancelText, onClick: onCancel }),
894
- /* @__PURE__ */ jsxRuntime.jsx(Button_default, { style: { width: 90 }, content: okText, onClick: onOk })
899
+ /* @__PURE__ */ jsxRuntime.jsx(Button_default, { style: { width: 90 }, variant: cancelVariant, content: cancelText, onClick: onCancel }),
900
+ /* @__PURE__ */ jsxRuntime.jsx(Button_default, { style: { width: 90 }, variant: okVariant, content: okText, onClick: onOk })
895
901
  ] })
896
902
  ]
897
903
  }
@@ -1207,7 +1213,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
1207
1213
  {
1208
1214
  value,
1209
1215
  disabled,
1210
- className: cx(base, sz.trigger, layoutCls, closeable ? "pr-8" : "", variantCls, className),
1216
+ className: cx(base, sz.trigger, layoutCls, closeable ? "!pr-8" : "", variantCls, className),
1211
1217
  children: [
1212
1218
  variant === "segmented" && isActive && /* @__PURE__ */ jsxRuntime.jsx(
1213
1219
  framerMotion.motion.span,
@@ -1292,9 +1298,11 @@ function TreeNodeItem({
1292
1298
  item,
1293
1299
  onNodeClick,
1294
1300
  defaultExpandAll,
1295
- defaultExpandedKeys
1301
+ defaultExpandedKeys,
1302
+ leafIcon
1296
1303
  }) {
1297
1304
  if (!isParent(item)) {
1305
+ const glyph = item.icon ?? leafIcon;
1298
1306
  return /* @__PURE__ */ jsxRuntime.jsxs(
1299
1307
  "button",
1300
1308
  {
@@ -1308,7 +1316,10 @@ function TreeNodeItem({
1308
1316
  parentLabel: item.parentLabel
1309
1317
  }),
1310
1318
  children: [
1311
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-1.5 h-1.5 rounded-full flex-shrink-0 bg-foreground-muted group-hover:bg-accent transition-colors duration-150" }),
1319
+ glyph != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-4 w-4 flex-shrink-0 items-center justify-center text-foreground-muted group-hover:text-accent transition-colors duration-150", children: glyph }) : (
1320
+ /* Default leaf bullet */
1321
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-1.5 h-1.5 rounded-full flex-shrink-0 bg-foreground-muted group-hover:bg-accent transition-colors duration-150" })
1322
+ ),
1312
1323
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-foreground-secondary group-hover:text-foreground transition-colors duration-150", children: item.label })
1313
1324
  ]
1314
1325
  }
@@ -1316,48 +1327,53 @@ function TreeNodeItem({
1316
1327
  }
1317
1328
  const initialOpen = defaultExpandAll || defaultExpandedKeys.includes(item.key) ? [item.key] : [];
1318
1329
  return /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Root, { type: "multiple", defaultValue: initialOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(AccordionPrimitive__namespace.Item, { value: item.key, className: "border-none", children: [
1319
- /* @__PURE__ */ jsxRuntime.jsxs(
1320
- AccordionPrimitive__namespace.Trigger,
1321
- {
1322
- onClick: () => onNodeClick({
1323
- isParent: true,
1324
- key: item.key,
1325
- label: item.label,
1326
- data: item.nodeData,
1327
- parentLabel: item.parentLabel
1328
- }),
1329
- className: "flex items-center gap-2 cursor-pointer py-1.5 px-2 group focus:outline-none focus-visible:ring-2 focus-visible:ring-accent w-full text-left rounded-md hover:bg-surface-raised transition-colors duration-150",
1330
- children: [
1331
- /* @__PURE__ */ jsxRuntime.jsx(
1330
+ /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Header, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center rounded-md hover:bg-surface-raised transition-colors duration-150", children: [
1331
+ /* @__PURE__ */ jsxRuntime.jsx(
1332
+ AccordionPrimitive__namespace.Trigger,
1333
+ {
1334
+ "aria-label": `Toggle ${item.label}`,
1335
+ className: "group flex flex-shrink-0 items-center justify-center rounded-md p-1.5 cursor-pointer text-foreground-muted hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-inset transition-colors duration-150",
1336
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1332
1337
  "svg",
1333
1338
  {
1334
1339
  viewBox: "0 0 24 24",
1335
1340
  fill: "none",
1336
1341
  stroke: "currentColor",
1337
1342
  strokeWidth: 2.5,
1338
- className: "h-3.5 w-3.5 flex-shrink-0 text-foreground-muted transition-transform duration-200 group-data-[state=open]:rotate-0 group-data-[state=closed]:-rotate-90",
1343
+ className: "h-3.5 w-3.5 transition-transform duration-200 group-data-[state=open]:rotate-0 group-data-[state=closed]:-rotate-90",
1339
1344
  "aria-hidden": "true",
1340
- children: /* @__PURE__ */ jsxRuntime.jsx(
1341
- "path",
1342
- {
1343
- strokeLinecap: "round",
1344
- strokeLinejoin: "round",
1345
- d: "M19 9l-7 7-7-7"
1346
- }
1347
- )
1345
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
1348
1346
  }
1349
- ),
1350
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-foreground select-none", children: item.label })
1351
- ]
1352
- }
1353
- ),
1347
+ )
1348
+ }
1349
+ ),
1350
+ /* @__PURE__ */ jsxRuntime.jsxs(
1351
+ "button",
1352
+ {
1353
+ type: "button",
1354
+ onClick: () => onNodeClick({
1355
+ isParent: true,
1356
+ key: item.key,
1357
+ label: item.label,
1358
+ data: item.nodeData,
1359
+ parentLabel: item.parentLabel
1360
+ }),
1361
+ className: "flex flex-1 min-w-0 items-center gap-2 py-1.5 pr-2 text-left cursor-pointer rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-inset",
1362
+ children: [
1363
+ item.icon != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-4 w-4 flex-shrink-0 items-center justify-center text-foreground-muted", children: item.icon }),
1364
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-semibold text-foreground select-none", children: item.label })
1365
+ ]
1366
+ }
1367
+ )
1368
+ ] }) }),
1354
1369
  /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Content, { className: "overflow-hidden data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-3.5 border-l border-border py-0.5", children: item.children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
1355
1370
  TreeNodeItem,
1356
1371
  {
1357
1372
  item: child,
1358
1373
  onNodeClick,
1359
1374
  defaultExpandAll,
1360
- defaultExpandedKeys
1375
+ defaultExpandedKeys,
1376
+ leafIcon
1361
1377
  },
1362
1378
  child.key
1363
1379
  )) }) })
@@ -1368,6 +1384,7 @@ function Tree({
1368
1384
  onNodeClick,
1369
1385
  defaultExpandAll = false,
1370
1386
  defaultExpandedKeys = [],
1387
+ leafIcon,
1371
1388
  className = "",
1372
1389
  style
1373
1390
  }) {
@@ -1377,7 +1394,8 @@ function Tree({
1377
1394
  item,
1378
1395
  onNodeClick,
1379
1396
  defaultExpandAll,
1380
- defaultExpandedKeys
1397
+ defaultExpandedKeys,
1398
+ leafIcon
1381
1399
  },
1382
1400
  item.key
1383
1401
  )) });
@@ -4675,6 +4693,8 @@ var TOGGLE_POSITION_CLASS = {
4675
4693
  function ScalableContainer({
4676
4694
  width = "100%",
4677
4695
  height = "auto",
4696
+ targetWidth,
4697
+ targetHeight,
4678
4698
  expandedWidth = "100%",
4679
4699
  expandedHeight = "100%",
4680
4700
  expanded,
@@ -4684,100 +4704,40 @@ function ScalableContainer({
4684
4704
  expandIcon,
4685
4705
  collapseIcon,
4686
4706
  togglePosition = "top-right",
4687
- expandContainerRef,
4688
- expandRatio = 3,
4689
4707
  className = ""
4690
4708
  }) {
4691
4709
  const containerRef = React31.useRef(null);
4692
4710
  const [internalScaled, setInternalScaled] = React31.useState(false);
4693
4711
  const isScaled = expanded ?? internalScaled;
4694
4712
  const reduced = framerMotion.useReducedMotion();
4695
- const usePush = expandContainerRef != null;
4696
- const grownRef = React31.useRef([]);
4697
4713
  const prevScaled = React31.useRef(isScaled);
4698
- const kickResizeDuringTransition = () => {
4714
+ const expandW = targetWidth ?? expandedWidth;
4715
+ const expandH = targetHeight ?? expandedHeight;
4716
+ React31.useEffect(() => {
4717
+ if (isScaled === prevScaled.current) return;
4718
+ prevScaled.current = isScaled;
4699
4719
  if (typeof window === "undefined") return;
4700
4720
  const kick = () => window.dispatchEvent(new Event("resize"));
4701
4721
  const interval = window.setInterval(kick, 80);
4702
- window.setTimeout(() => {
4722
+ const stop = window.setTimeout(() => {
4703
4723
  window.clearInterval(interval);
4704
4724
  kick();
4705
- }, reduced ? 0 : 400);
4706
- };
4707
- const growAncestors = () => {
4708
- const bound = expandContainerRef?.current;
4709
- if (!bound || !containerRef.current) return;
4710
- const grown = [];
4711
- let el = containerRef.current.parentElement;
4712
- while (el && el !== bound && bound.contains(el)) {
4713
- const parent = el.parentElement;
4714
- const parentStyle = parent ? getComputedStyle(parent) : null;
4715
- if (parent && parentStyle && parentStyle.display.includes("flex")) {
4716
- grown.push({
4717
- el,
4718
- parent,
4719
- prev: {
4720
- flexGrow: el.style.flexGrow,
4721
- flexBasis: el.style.flexBasis,
4722
- height: el.style.height,
4723
- transition: el.style.transition,
4724
- parentFlexWrap: parent.style.flexWrap
4725
- }
4726
- });
4727
- const t = (prop) => `${prop} ${reduced ? 0 : 0.32}s cubic-bezier(0.16, 1, 0.3, 1)`;
4728
- const ours = `${t("flex-grow")}, ${t("flex-basis")}, ${t("height")}`;
4729
- el.style.transition = el.style.transition ? `${el.style.transition}, ${ours}` : ours;
4730
- if (parentStyle.flexDirection.startsWith("row")) {
4731
- parent.style.flexWrap = "wrap";
4732
- el.style.flexBasis = "100%";
4733
- el.style.height = `${expandRatio / (expandRatio + 1) * 100}%`;
4734
- } else {
4735
- el.style.flexBasis = "0%";
4736
- el.style.flexGrow = String(expandRatio);
4737
- }
4738
- }
4739
- el = parent;
4740
- }
4741
- grownRef.current = grown;
4742
- };
4743
- const restoreAncestors = () => {
4744
- for (const { el, parent, prev } of grownRef.current) {
4745
- el.style.flexGrow = prev.flexGrow;
4746
- el.style.flexBasis = prev.flexBasis;
4747
- el.style.height = prev.height;
4748
- window.setTimeout(() => {
4749
- el.style.transition = prev.transition;
4750
- parent.style.flexWrap = prev.parentFlexWrap;
4751
- }, reduced ? 0 : 360);
4752
- }
4753
- grownRef.current = [];
4754
- };
4755
- React31.useEffect(() => {
4756
- if (!usePush || isScaled === prevScaled.current) return;
4757
- prevScaled.current = isScaled;
4758
- if (isScaled) growAncestors();
4759
- else restoreAncestors();
4760
- kickResizeDuringTransition();
4761
- }, [isScaled, usePush]);
4762
- React31.useEffect(() => () => {
4763
- for (const { el, parent, prev } of grownRef.current) {
4764
- el.style.flexGrow = prev.flexGrow;
4765
- el.style.flexBasis = prev.flexBasis;
4766
- el.style.height = prev.height;
4767
- el.style.transition = prev.transition;
4768
- parent.style.flexWrap = prev.parentFlexWrap;
4725
+ }, reduced ? 0 : 420);
4726
+ if (isScaled) {
4727
+ window.setTimeout(
4728
+ () => containerRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" }),
4729
+ reduced ? 0 : 360
4730
+ );
4769
4731
  }
4770
- }, []);
4732
+ return () => {
4733
+ window.clearInterval(interval);
4734
+ window.clearTimeout(stop);
4735
+ };
4736
+ }, [isScaled, reduced]);
4771
4737
  const onToggle = () => {
4772
4738
  const next = !isScaled;
4773
4739
  if (expanded === void 0) setInternalScaled(next);
4774
4740
  onExpandedChange?.(next);
4775
- if (next && !usePush) {
4776
- window.setTimeout(
4777
- () => containerRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" }),
4778
- reduced ? 0 : 340
4779
- );
4780
- }
4781
4741
  };
4782
4742
  const wrapperClass = isScaled ? assignClassOnClick : void 0;
4783
4743
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -4785,24 +4745,20 @@ function ScalableContainer({
4785
4745
  {
4786
4746
  ref: containerRef,
4787
4747
  style: {
4788
- width: isScaled && !usePush ? expandedWidth : width,
4789
- height: isScaled && !usePush ? expandedHeight : height
4790
- },
4791
- animate: {
4792
- // Push mode keeps the container filling its (now growing)
4793
- // wrapper — the wrapper's flex-grow does the work.
4794
- width: isScaled && !usePush ? expandedWidth : width,
4795
- height: isScaled && !usePush ? expandedHeight : height
4748
+ width: isScaled ? expandW : width,
4749
+ height: isScaled ? expandH : height,
4750
+ flex: isScaled ? "none" : void 0
4796
4751
  },
4752
+ animate: { width: isScaled ? expandW : width, height: isScaled ? expandH : height },
4797
4753
  transition: reduced ? { duration: 0 } : {
4798
4754
  width: { type: "tween", duration: 0.32, ease: [0.16, 1, 0.3, 1] },
4799
4755
  height: { type: "tween", duration: 0.32, ease: [0.16, 1, 0.3, 1] }
4800
4756
  },
4801
4757
  className: cx(
4802
4758
  "relative rounded-lg overflow-hidden",
4803
- // OS-window aesthetic: subtle elevation at rest, lifted shadow
4804
- // when expanded. No background colour change.
4805
- isScaled ? "shadow-2xl" : "shadow-md",
4759
+ // OS-window aesthetic: subtle elevation at rest, lifted shadow +
4760
+ // raised stacking when expanded so it sits above neighbours.
4761
+ isScaled ? "z-raised shadow-2xl" : "shadow-md",
4806
4762
  "transition-shadow duration-300",
4807
4763
  className
4808
4764
  ),