@geomak/ui 6.2.1 → 6.2.2

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.d.cts CHANGED
@@ -1648,6 +1648,16 @@ interface MegaMenuProps {
1648
1648
  align?: 'start' | 'center' | 'end';
1649
1649
  /** Delay (ms) before a hovered item opens. Default `200`. */
1650
1650
  delayDuration?: number;
1651
+ /**
1652
+ * Below the `md` breakpoint, collapse the hover bar into a tap-friendly
1653
+ * hamburger disclosure (a vertical accordion of the same items). Hover
1654
+ * mega-panels don't work on touch, so this is the graceful fallback.
1655
+ * Set `false` to render the desktop bar at every width (e.g. when you
1656
+ * provide your own mobile navigation). Default `true`.
1657
+ */
1658
+ responsive?: boolean;
1659
+ /** Label for the mobile disclosure toggle. Default `'Menu'`. */
1660
+ mobileLabel?: React__default.ReactNode;
1651
1661
  /** Extra classes merged onto the menu bar root. */
1652
1662
  className?: string;
1653
1663
  style?: React__default.CSSProperties;
@@ -1680,7 +1690,7 @@ interface MegaMenuProps {
1680
1690
  * </MegaMenu>
1681
1691
  * ```
1682
1692
  */
1683
- declare function MegaMenu({ children, align, delayDuration, className, style, 'aria-label': ariaLabel }: MegaMenuProps): react_jsx_runtime.JSX.Element;
1693
+ declare function MegaMenu({ children, align, delayDuration, responsive, mobileLabel, className, style, 'aria-label': ariaLabel, }: MegaMenuProps): react_jsx_runtime.JSX.Element;
1684
1694
  declare namespace MegaMenu {
1685
1695
  var Item: typeof MegaMenuItem;
1686
1696
  var Panel: typeof MegaMenuPanel;
package/dist/index.d.ts CHANGED
@@ -1648,6 +1648,16 @@ interface MegaMenuProps {
1648
1648
  align?: 'start' | 'center' | 'end';
1649
1649
  /** Delay (ms) before a hovered item opens. Default `200`. */
1650
1650
  delayDuration?: number;
1651
+ /**
1652
+ * Below the `md` breakpoint, collapse the hover bar into a tap-friendly
1653
+ * hamburger disclosure (a vertical accordion of the same items). Hover
1654
+ * mega-panels don't work on touch, so this is the graceful fallback.
1655
+ * Set `false` to render the desktop bar at every width (e.g. when you
1656
+ * provide your own mobile navigation). Default `true`.
1657
+ */
1658
+ responsive?: boolean;
1659
+ /** Label for the mobile disclosure toggle. Default `'Menu'`. */
1660
+ mobileLabel?: React__default.ReactNode;
1651
1661
  /** Extra classes merged onto the menu bar root. */
1652
1662
  className?: string;
1653
1663
  style?: React__default.CSSProperties;
@@ -1680,7 +1690,7 @@ interface MegaMenuProps {
1680
1690
  * </MegaMenu>
1681
1691
  * ```
1682
1692
  */
1683
- declare function MegaMenu({ children, align, delayDuration, className, style, 'aria-label': ariaLabel }: MegaMenuProps): react_jsx_runtime.JSX.Element;
1693
+ declare function MegaMenu({ children, align, delayDuration, responsive, mobileLabel, className, style, 'aria-label': ariaLabel, }: MegaMenuProps): react_jsx_runtime.JSX.Element;
1684
1694
  declare namespace MegaMenu {
1685
1695
  var Item: typeof MegaMenuItem;
1686
1696
  var Panel: typeof MegaMenuPanel;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { colors_default } from './chunk-GKXP6OJJ.js';
2
2
  export { colors_default as COLORS, PALETTE as palette, semanticTokens, vars } from './chunk-GKXP6OJJ.js';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import React8, { createContext, useState, useEffect, useMemo, useId, useCallback, useRef, useContext, useLayoutEffect, useSyncExternalStore } from 'react';
4
+ import React12, { createContext, useState, useEffect, useMemo, useId, useCallback, useRef, useContext, useLayoutEffect, useSyncExternalStore } from 'react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
7
7
  import * as Dialog from '@radix-ui/react-dialog';
@@ -2471,7 +2471,7 @@ function Field({
2471
2471
  );
2472
2472
  }
2473
2473
  var SearchIcon = /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "w-4 h-4", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z", clipRule: "evenodd" }) });
2474
- var SearchInput = React8.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
2474
+ var SearchInput = React12.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
2475
2475
  return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxs(
2476
2476
  "div",
2477
2477
  {
@@ -2971,7 +2971,7 @@ function TableBody({
2971
2971
  return /* @__PURE__ */ jsx("tbody", { children: rows.map((row, i) => {
2972
2972
  const rowKey = getRowKey(row, i);
2973
2973
  const isExpanded = expanded.has(rowKey);
2974
- return /* @__PURE__ */ jsxs(React8.Fragment, { children: [
2974
+ return /* @__PURE__ */ jsxs(React12.Fragment, { children: [
2975
2975
  /* @__PURE__ */ jsxs(
2976
2976
  "tr",
2977
2977
  {
@@ -3388,17 +3388,33 @@ function Sidebar({
3388
3388
  ) });
3389
3389
  }
3390
3390
  var MegaMenuContext = createContext({ align: "start" });
3391
- function MegaMenu({ children, align = "start", delayDuration = 200, className = "", style, "aria-label": ariaLabel }) {
3392
- return /* @__PURE__ */ jsx(MegaMenuContext.Provider, { value: { align }, children: /* @__PURE__ */ jsx(
3393
- NavigationMenu.Root,
3394
- {
3395
- delayDuration,
3396
- "aria-label": ariaLabel,
3397
- className: ["relative z-10 flex w-full", className].filter(Boolean).join(" "),
3398
- style,
3399
- children: /* @__PURE__ */ jsx(NavigationMenu.List, { className: "flex items-center gap-1", children })
3400
- }
3401
- ) });
3391
+ function MegaMenu({
3392
+ children,
3393
+ align = "start",
3394
+ delayDuration = 200,
3395
+ responsive = true,
3396
+ mobileLabel = "Menu",
3397
+ className = "",
3398
+ style,
3399
+ "aria-label": ariaLabel
3400
+ }) {
3401
+ return /* @__PURE__ */ jsxs(MegaMenuContext.Provider, { value: { align }, children: [
3402
+ /* @__PURE__ */ jsx(
3403
+ NavigationMenu.Root,
3404
+ {
3405
+ delayDuration,
3406
+ "aria-label": ariaLabel,
3407
+ className: [
3408
+ "relative z-10 w-full",
3409
+ responsive ? "hidden md:flex" : "flex",
3410
+ className
3411
+ ].filter(Boolean).join(" "),
3412
+ style,
3413
+ children: /* @__PURE__ */ jsx(NavigationMenu.List, { className: "flex items-center gap-1", children })
3414
+ }
3415
+ ),
3416
+ responsive && /* @__PURE__ */ jsx(MegaMenuMobile, { label: mobileLabel, children })
3417
+ ] });
3402
3418
  }
3403
3419
  var TOP_ITEM = "group/top inline-flex items-center gap-1.5 h-10 px-3 rounded-md text-sm font-medium select-none text-foreground-secondary hover:text-foreground hover:bg-surface-raised data-[state=open]:text-accent data-[active]:text-accent transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent";
3404
3420
  function MegaMenuItem({ label, icon, href, children, className = "" }) {
@@ -3439,18 +3455,24 @@ function MegaMenuItem({ label, icon, href, children, className = "" }) {
3439
3455
  ] });
3440
3456
  }
3441
3457
  function MegaMenuPanel({ children, columns, className = "", style }) {
3442
- const maxWidth = columns ? `${columns * 248}px` : "min(92vw, 880px)";
3458
+ const layout = columns ? {
3459
+ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
3460
+ width: `min(92vw, ${columns * 272}px)`
3461
+ } : {
3462
+ gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))",
3463
+ width: "min(92vw, 760px)"
3464
+ };
3443
3465
  return /* @__PURE__ */ jsx(
3444
3466
  "div",
3445
3467
  {
3446
- className: ["flex flex-wrap gap-6 p-6", className].filter(Boolean).join(" "),
3447
- style: { maxWidth, ...style },
3468
+ className: ["grid gap-6 p-6", className].filter(Boolean).join(" "),
3469
+ style: { ...layout, maxWidth: "min(92vw, 960px)", ...style },
3448
3470
  children
3449
3471
  }
3450
3472
  );
3451
3473
  }
3452
3474
  function MegaMenuSection({ title, children, className = "" }) {
3453
- return /* @__PURE__ */ jsxs("div", { className: ["min-w-[200px] flex flex-col", className].filter(Boolean).join(" "), children: [
3475
+ return /* @__PURE__ */ jsxs("div", { className: ["min-w-0 flex flex-col", className].filter(Boolean).join(" "), children: [
3454
3476
  title && /* @__PURE__ */ jsx("p", { className: "px-3 pb-1.5 text-[11px] font-semibold uppercase tracking-widest text-foreground-muted select-none", children: title }),
3455
3477
  /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children })
3456
3478
  ] });
@@ -3479,7 +3501,124 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
3479
3501
  );
3480
3502
  }
3481
3503
  function MegaMenuFeatured({ children, className = "" }) {
3482
- return /* @__PURE__ */ jsx("div", { className: ["min-w-[220px] rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className].filter(Boolean).join(" "), children });
3504
+ return /* @__PURE__ */ jsx("div", { className: ["min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className].filter(Boolean).join(" "), children });
3505
+ }
3506
+ var elementsOfType = (children, type) => React12.Children.toArray(children).filter(
3507
+ (c) => React12.isValidElement(c) && c.type === type
3508
+ );
3509
+ var MOBILE_CHEVRON = /* @__PURE__ */ jsx(
3510
+ "svg",
3511
+ {
3512
+ viewBox: "0 0 24 24",
3513
+ fill: "none",
3514
+ stroke: "currentColor",
3515
+ strokeWidth: 2,
3516
+ "aria-hidden": "true",
3517
+ className: "h-4 w-4 flex-shrink-0 text-foreground-muted transition-transform duration-200",
3518
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
3519
+ }
3520
+ );
3521
+ function MobileLinkRow({ link, onNavigate }) {
3522
+ const { href, icon, description, active, onClick, children } = link.props;
3523
+ return /* @__PURE__ */ jsxs(
3524
+ "a",
3525
+ {
3526
+ href,
3527
+ onClick: (e) => {
3528
+ onClick?.(e);
3529
+ onNavigate();
3530
+ },
3531
+ "data-active": active ? "" : void 0,
3532
+ className: "flex items-start gap-3 rounded-md p-2.5 transition-colors select-none\n hover:bg-surface-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-accent\n data-[active]:bg-surface-raised",
3533
+ children: [
3534
+ icon && /* @__PURE__ */ jsx("span", { className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md bg-surface-raised text-accent", children: /* @__PURE__ */ jsx("span", { className: "h-[17px] w-[17px] inline-flex items-center justify-center", children: icon }) }),
3535
+ /* @__PURE__ */ jsxs("span", { className: "flex flex-col min-w-0", children: [
3536
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground data-[active]:text-accent", children }),
3537
+ description && /* @__PURE__ */ jsx("span", { className: "text-xs text-foreground-muted leading-snug mt-0.5", children: description })
3538
+ ] })
3539
+ ]
3540
+ }
3541
+ );
3542
+ }
3543
+ function MobilePanel({ panel, onNavigate }) {
3544
+ const nodes = React12.Children.toArray(panel.props.children);
3545
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
3546
+ if (!React12.isValidElement(node)) return null;
3547
+ const el = node;
3548
+ if (el.type === MegaMenuSection) {
3549
+ const { title, children } = el.props;
3550
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
3551
+ title && /* @__PURE__ */ jsx("p", { className: "px-2.5 pb-1 text-[11px] font-semibold uppercase tracking-widest text-foreground-muted select-none", children: title }),
3552
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: elementsOfType(children, MegaMenuLink).map((lnk, j) => /* @__PURE__ */ jsx(MobileLinkRow, { link: lnk, onNavigate }, j)) })
3553
+ ] }, i);
3554
+ }
3555
+ if (el.type === MegaMenuFeatured) {
3556
+ return /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-surface-raised border border-border p-3 flex flex-col", children: el.props.children }, i);
3557
+ }
3558
+ return /* @__PURE__ */ jsx("div", { children: node }, i);
3559
+ }) });
3560
+ }
3561
+ function MegaMenuMobile({
3562
+ children,
3563
+ label
3564
+ }) {
3565
+ const [open, setOpen] = useState(false);
3566
+ const [expanded, setExpanded] = useState(null);
3567
+ const items = elementsOfType(children, MegaMenuItem);
3568
+ return /* @__PURE__ */ jsxs("div", { className: "md:hidden w-full", children: [
3569
+ /* @__PURE__ */ jsxs(
3570
+ "button",
3571
+ {
3572
+ type: "button",
3573
+ onClick: () => setOpen((o) => !o),
3574
+ "aria-expanded": open,
3575
+ className: "inline-flex items-center gap-2 h-10 px-3 rounded-md text-sm font-medium\n text-foreground-secondary hover:text-foreground hover:bg-surface-raised\n focus:outline-none focus-visible:ring-2 focus-visible:ring-accent transition-colors",
3576
+ children: [
3577
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-5 w-5", children: open ? /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 6l12 12M18 6L6 18" }) : /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 7h16M4 12h16M4 17h16" }) }),
3578
+ label
3579
+ ]
3580
+ }
3581
+ ),
3582
+ open && /* @__PURE__ */ jsx("div", { className: "mt-2 overflow-hidden rounded-lg border border-border bg-surface shadow-lg", children: items.map((item, i) => {
3583
+ const { label: itemLabel, icon, href, children: panel } = item.props;
3584
+ const hasPanel = panel != null;
3585
+ const isOpen = expanded === i;
3586
+ const rowBase = "flex w-full items-center gap-2 px-3 h-11 text-sm font-medium text-foreground-secondary hover:bg-surface-raised hover:text-foreground transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent";
3587
+ const divider = i > 0 ? "border-t border-border" : "";
3588
+ if (!hasPanel) {
3589
+ return /* @__PURE__ */ jsxs(
3590
+ "a",
3591
+ {
3592
+ href,
3593
+ onClick: () => setOpen(false),
3594
+ className: [rowBase, divider].filter(Boolean).join(" "),
3595
+ children: [
3596
+ icon && /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 flex-shrink-0 items-center justify-center", children: icon }),
3597
+ itemLabel
3598
+ ]
3599
+ },
3600
+ i
3601
+ );
3602
+ }
3603
+ return /* @__PURE__ */ jsxs("div", { className: divider || void 0, children: [
3604
+ /* @__PURE__ */ jsxs(
3605
+ "button",
3606
+ {
3607
+ type: "button",
3608
+ onClick: () => setExpanded(isOpen ? null : i),
3609
+ "aria-expanded": isOpen,
3610
+ className: [rowBase, isOpen ? "text-accent" : ""].filter(Boolean).join(" "),
3611
+ children: [
3612
+ icon && /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 flex-shrink-0 items-center justify-center", children: icon }),
3613
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: itemLabel }),
3614
+ /* @__PURE__ */ jsx("span", { className: isOpen ? "rotate-180" : "", children: MOBILE_CHEVRON })
3615
+ ]
3616
+ }
3617
+ ),
3618
+ isOpen && /* @__PURE__ */ jsx(MobilePanel, { panel, onNavigate: () => setOpen(false) })
3619
+ ] }, i);
3620
+ }) })
3621
+ ] });
3483
3622
  }
3484
3623
  MegaMenu.Item = MegaMenuItem;
3485
3624
  MegaMenu.Panel = MegaMenuPanel;
@@ -3697,7 +3836,7 @@ function ThemeProvider({
3697
3836
  className = "",
3698
3837
  style
3699
3838
  }) {
3700
- const id = React8.useId().replace(/:/g, "");
3839
+ const id = React12.useId().replace(/:/g, "");
3701
3840
  const scopeClass = `geo-th-${id}`;
3702
3841
  const divRef = useRef(null);
3703
3842
  useEffect(() => {
@@ -5701,7 +5840,7 @@ function OtpInput({
5701
5840
  emit(valid.join(""));
5702
5841
  focusBox(valid.length);
5703
5842
  };
5704
- return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxs(React8.Fragment, { children: [
5843
+ return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxs(React12.Fragment, { children: [
5705
5844
  /* @__PURE__ */ jsx(
5706
5845
  "input",
5707
5846
  {