@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.js CHANGED
@@ -709,6 +709,8 @@ function Modal({
709
709
  onCancel,
710
710
  okText = "Ok",
711
711
  cancelText = "Cancel",
712
+ okVariant = "primary",
713
+ cancelVariant = "ghost",
712
714
  hasFooter = true,
713
715
  title,
714
716
  children,
@@ -765,6 +767,7 @@ function Modal({
765
767
  Button_default,
766
768
  {
767
769
  style: { width: 90 },
770
+ variant: cancelVariant,
768
771
  content: cancelText,
769
772
  onClick: onCancel
770
773
  }
@@ -773,6 +776,7 @@ function Modal({
773
776
  Button_default,
774
777
  {
775
778
  style: { width: 90 },
779
+ variant: okVariant,
776
780
  content: okText,
777
781
  onClick: onOk
778
782
  }
@@ -799,6 +803,8 @@ function Drawer({
799
803
  width,
800
804
  okText = "Ok",
801
805
  cancelText = "Cancel",
806
+ okVariant = "primary",
807
+ cancelVariant = "ghost",
802
808
  onOk,
803
809
  onCancel,
804
810
  title,
@@ -854,8 +860,8 @@ function Drawer({
854
860
  ] }),
855
861
  /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto p-5", children }),
856
862
  hasFooter && /* @__PURE__ */ 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: [
857
- /* @__PURE__ */ jsx(Button_default, { style: { width: 90 }, content: cancelText, onClick: onCancel }),
858
- /* @__PURE__ */ jsx(Button_default, { style: { width: 90 }, content: okText, onClick: onOk })
863
+ /* @__PURE__ */ jsx(Button_default, { style: { width: 90 }, variant: cancelVariant, content: cancelText, onClick: onCancel }),
864
+ /* @__PURE__ */ jsx(Button_default, { style: { width: 90 }, variant: okVariant, content: okText, onClick: onOk })
859
865
  ] })
860
866
  ]
861
867
  }
@@ -1171,7 +1177,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
1171
1177
  {
1172
1178
  value,
1173
1179
  disabled,
1174
- className: cx(base, sz.trigger, layoutCls, closeable ? "pr-8" : "", variantCls, className),
1180
+ className: cx(base, sz.trigger, layoutCls, closeable ? "!pr-8" : "", variantCls, className),
1175
1181
  children: [
1176
1182
  variant === "segmented" && isActive && /* @__PURE__ */ jsx(
1177
1183
  motion.span,
@@ -1256,9 +1262,11 @@ function TreeNodeItem({
1256
1262
  item,
1257
1263
  onNodeClick,
1258
1264
  defaultExpandAll,
1259
- defaultExpandedKeys
1265
+ defaultExpandedKeys,
1266
+ leafIcon
1260
1267
  }) {
1261
1268
  if (!isParent(item)) {
1269
+ const glyph = item.icon ?? leafIcon;
1262
1270
  return /* @__PURE__ */ jsxs(
1263
1271
  "button",
1264
1272
  {
@@ -1272,7 +1280,10 @@ function TreeNodeItem({
1272
1280
  parentLabel: item.parentLabel
1273
1281
  }),
1274
1282
  children: [
1275
- /* @__PURE__ */ 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" }),
1283
+ glyph != null ? /* @__PURE__ */ 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 }) : (
1284
+ /* Default leaf bullet */
1285
+ /* @__PURE__ */ 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" })
1286
+ ),
1276
1287
  /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground-secondary group-hover:text-foreground transition-colors duration-150", children: item.label })
1277
1288
  ]
1278
1289
  }
@@ -1280,48 +1291,53 @@ function TreeNodeItem({
1280
1291
  }
1281
1292
  const initialOpen = defaultExpandAll || defaultExpandedKeys.includes(item.key) ? [item.key] : [];
1282
1293
  return /* @__PURE__ */ jsx(AccordionPrimitive.Root, { type: "multiple", defaultValue: initialOpen, children: /* @__PURE__ */ jsxs(AccordionPrimitive.Item, { value: item.key, className: "border-none", children: [
1283
- /* @__PURE__ */ jsxs(
1284
- AccordionPrimitive.Trigger,
1285
- {
1286
- onClick: () => onNodeClick({
1287
- isParent: true,
1288
- key: item.key,
1289
- label: item.label,
1290
- data: item.nodeData,
1291
- parentLabel: item.parentLabel
1292
- }),
1293
- 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",
1294
- children: [
1295
- /* @__PURE__ */ jsx(
1294
+ /* @__PURE__ */ jsx(AccordionPrimitive.Header, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center rounded-md hover:bg-surface-raised transition-colors duration-150", children: [
1295
+ /* @__PURE__ */ jsx(
1296
+ AccordionPrimitive.Trigger,
1297
+ {
1298
+ "aria-label": `Toggle ${item.label}`,
1299
+ 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",
1300
+ children: /* @__PURE__ */ jsx(
1296
1301
  "svg",
1297
1302
  {
1298
1303
  viewBox: "0 0 24 24",
1299
1304
  fill: "none",
1300
1305
  stroke: "currentColor",
1301
1306
  strokeWidth: 2.5,
1302
- 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",
1307
+ className: "h-3.5 w-3.5 transition-transform duration-200 group-data-[state=open]:rotate-0 group-data-[state=closed]:-rotate-90",
1303
1308
  "aria-hidden": "true",
1304
- children: /* @__PURE__ */ jsx(
1305
- "path",
1306
- {
1307
- strokeLinecap: "round",
1308
- strokeLinejoin: "round",
1309
- d: "M19 9l-7 7-7-7"
1310
- }
1311
- )
1309
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
1312
1310
  }
1313
- ),
1314
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground select-none", children: item.label })
1315
- ]
1316
- }
1317
- ),
1311
+ )
1312
+ }
1313
+ ),
1314
+ /* @__PURE__ */ jsxs(
1315
+ "button",
1316
+ {
1317
+ type: "button",
1318
+ onClick: () => onNodeClick({
1319
+ isParent: true,
1320
+ key: item.key,
1321
+ label: item.label,
1322
+ data: item.nodeData,
1323
+ parentLabel: item.parentLabel
1324
+ }),
1325
+ 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",
1326
+ children: [
1327
+ item.icon != null && /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 flex-shrink-0 items-center justify-center text-foreground-muted", children: item.icon }),
1328
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold text-foreground select-none", children: item.label })
1329
+ ]
1330
+ }
1331
+ )
1332
+ ] }) }),
1318
1333
  /* @__PURE__ */ jsx(AccordionPrimitive.Content, { className: "overflow-hidden data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up", children: /* @__PURE__ */ jsx("div", { className: "ml-3.5 border-l border-border py-0.5", children: item.children.map((child) => /* @__PURE__ */ jsx(
1319
1334
  TreeNodeItem,
1320
1335
  {
1321
1336
  item: child,
1322
1337
  onNodeClick,
1323
1338
  defaultExpandAll,
1324
- defaultExpandedKeys
1339
+ defaultExpandedKeys,
1340
+ leafIcon
1325
1341
  },
1326
1342
  child.key
1327
1343
  )) }) })
@@ -1332,6 +1348,7 @@ function Tree({
1332
1348
  onNodeClick,
1333
1349
  defaultExpandAll = false,
1334
1350
  defaultExpandedKeys = [],
1351
+ leafIcon,
1335
1352
  className = "",
1336
1353
  style
1337
1354
  }) {
@@ -1341,7 +1358,8 @@ function Tree({
1341
1358
  item,
1342
1359
  onNodeClick,
1343
1360
  defaultExpandAll,
1344
- defaultExpandedKeys
1361
+ defaultExpandedKeys,
1362
+ leafIcon
1345
1363
  },
1346
1364
  item.key
1347
1365
  )) });
@@ -4639,6 +4657,8 @@ var TOGGLE_POSITION_CLASS = {
4639
4657
  function ScalableContainer({
4640
4658
  width = "100%",
4641
4659
  height = "auto",
4660
+ targetWidth,
4661
+ targetHeight,
4642
4662
  expandedWidth = "100%",
4643
4663
  expandedHeight = "100%",
4644
4664
  expanded,
@@ -4648,100 +4668,40 @@ function ScalableContainer({
4648
4668
  expandIcon,
4649
4669
  collapseIcon,
4650
4670
  togglePosition = "top-right",
4651
- expandContainerRef,
4652
- expandRatio = 3,
4653
4671
  className = ""
4654
4672
  }) {
4655
4673
  const containerRef = useRef(null);
4656
4674
  const [internalScaled, setInternalScaled] = useState(false);
4657
4675
  const isScaled = expanded ?? internalScaled;
4658
4676
  const reduced = useReducedMotion();
4659
- const usePush = expandContainerRef != null;
4660
- const grownRef = useRef([]);
4661
4677
  const prevScaled = useRef(isScaled);
4662
- const kickResizeDuringTransition = () => {
4678
+ const expandW = targetWidth ?? expandedWidth;
4679
+ const expandH = targetHeight ?? expandedHeight;
4680
+ useEffect(() => {
4681
+ if (isScaled === prevScaled.current) return;
4682
+ prevScaled.current = isScaled;
4663
4683
  if (typeof window === "undefined") return;
4664
4684
  const kick = () => window.dispatchEvent(new Event("resize"));
4665
4685
  const interval = window.setInterval(kick, 80);
4666
- window.setTimeout(() => {
4686
+ const stop = window.setTimeout(() => {
4667
4687
  window.clearInterval(interval);
4668
4688
  kick();
4669
- }, reduced ? 0 : 400);
4670
- };
4671
- const growAncestors = () => {
4672
- const bound = expandContainerRef?.current;
4673
- if (!bound || !containerRef.current) return;
4674
- const grown = [];
4675
- let el = containerRef.current.parentElement;
4676
- while (el && el !== bound && bound.contains(el)) {
4677
- const parent = el.parentElement;
4678
- const parentStyle = parent ? getComputedStyle(parent) : null;
4679
- if (parent && parentStyle && parentStyle.display.includes("flex")) {
4680
- grown.push({
4681
- el,
4682
- parent,
4683
- prev: {
4684
- flexGrow: el.style.flexGrow,
4685
- flexBasis: el.style.flexBasis,
4686
- height: el.style.height,
4687
- transition: el.style.transition,
4688
- parentFlexWrap: parent.style.flexWrap
4689
- }
4690
- });
4691
- const t = (prop) => `${prop} ${reduced ? 0 : 0.32}s cubic-bezier(0.16, 1, 0.3, 1)`;
4692
- const ours = `${t("flex-grow")}, ${t("flex-basis")}, ${t("height")}`;
4693
- el.style.transition = el.style.transition ? `${el.style.transition}, ${ours}` : ours;
4694
- if (parentStyle.flexDirection.startsWith("row")) {
4695
- parent.style.flexWrap = "wrap";
4696
- el.style.flexBasis = "100%";
4697
- el.style.height = `${expandRatio / (expandRatio + 1) * 100}%`;
4698
- } else {
4699
- el.style.flexBasis = "0%";
4700
- el.style.flexGrow = String(expandRatio);
4701
- }
4702
- }
4703
- el = parent;
4704
- }
4705
- grownRef.current = grown;
4706
- };
4707
- const restoreAncestors = () => {
4708
- for (const { el, parent, prev } of grownRef.current) {
4709
- el.style.flexGrow = prev.flexGrow;
4710
- el.style.flexBasis = prev.flexBasis;
4711
- el.style.height = prev.height;
4712
- window.setTimeout(() => {
4713
- el.style.transition = prev.transition;
4714
- parent.style.flexWrap = prev.parentFlexWrap;
4715
- }, reduced ? 0 : 360);
4716
- }
4717
- grownRef.current = [];
4718
- };
4719
- useEffect(() => {
4720
- if (!usePush || isScaled === prevScaled.current) return;
4721
- prevScaled.current = isScaled;
4722
- if (isScaled) growAncestors();
4723
- else restoreAncestors();
4724
- kickResizeDuringTransition();
4725
- }, [isScaled, usePush]);
4726
- useEffect(() => () => {
4727
- for (const { el, parent, prev } of grownRef.current) {
4728
- el.style.flexGrow = prev.flexGrow;
4729
- el.style.flexBasis = prev.flexBasis;
4730
- el.style.height = prev.height;
4731
- el.style.transition = prev.transition;
4732
- parent.style.flexWrap = prev.parentFlexWrap;
4689
+ }, reduced ? 0 : 420);
4690
+ if (isScaled) {
4691
+ window.setTimeout(
4692
+ () => containerRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" }),
4693
+ reduced ? 0 : 360
4694
+ );
4733
4695
  }
4734
- }, []);
4696
+ return () => {
4697
+ window.clearInterval(interval);
4698
+ window.clearTimeout(stop);
4699
+ };
4700
+ }, [isScaled, reduced]);
4735
4701
  const onToggle = () => {
4736
4702
  const next = !isScaled;
4737
4703
  if (expanded === void 0) setInternalScaled(next);
4738
4704
  onExpandedChange?.(next);
4739
- if (next && !usePush) {
4740
- window.setTimeout(
4741
- () => containerRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" }),
4742
- reduced ? 0 : 340
4743
- );
4744
- }
4745
4705
  };
4746
4706
  const wrapperClass = isScaled ? assignClassOnClick : void 0;
4747
4707
  return /* @__PURE__ */ jsxs(
@@ -4749,24 +4709,20 @@ function ScalableContainer({
4749
4709
  {
4750
4710
  ref: containerRef,
4751
4711
  style: {
4752
- width: isScaled && !usePush ? expandedWidth : width,
4753
- height: isScaled && !usePush ? expandedHeight : height
4754
- },
4755
- animate: {
4756
- // Push mode keeps the container filling its (now growing)
4757
- // wrapper — the wrapper's flex-grow does the work.
4758
- width: isScaled && !usePush ? expandedWidth : width,
4759
- height: isScaled && !usePush ? expandedHeight : height
4712
+ width: isScaled ? expandW : width,
4713
+ height: isScaled ? expandH : height,
4714
+ flex: isScaled ? "none" : void 0
4760
4715
  },
4716
+ animate: { width: isScaled ? expandW : width, height: isScaled ? expandH : height },
4761
4717
  transition: reduced ? { duration: 0 } : {
4762
4718
  width: { type: "tween", duration: 0.32, ease: [0.16, 1, 0.3, 1] },
4763
4719
  height: { type: "tween", duration: 0.32, ease: [0.16, 1, 0.3, 1] }
4764
4720
  },
4765
4721
  className: cx(
4766
4722
  "relative rounded-lg overflow-hidden",
4767
- // OS-window aesthetic: subtle elevation at rest, lifted shadow
4768
- // when expanded. No background colour change.
4769
- isScaled ? "shadow-2xl" : "shadow-md",
4723
+ // OS-window aesthetic: subtle elevation at rest, lifted shadow +
4724
+ // raised stacking when expanded so it sits above neighbours.
4725
+ isScaled ? "z-raised shadow-2xl" : "shadow-md",
4770
4726
  "transition-shadow duration-300",
4771
4727
  className
4772
4728
  ),