@fairmint/ui 0.4.1 → 0.4.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.
@@ -1 +1 @@
1
- {"version":3,"file":"MobileNav.cjs","sources":["../../../../src/components/layout/MobileNav/MobileNav.tsx"],"sourcesContent":["import { IconChevronDown, IconX } from \"@tabler/icons-react\";\nimport { type ReactNode, useState } from \"react\";\nimport { fairmintVars, radii } from \"../../../theme\";\nimport { overlayZIndexAboveLegacyShell } from \"../../../theme/zIndex\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Drawer } from \"../../primitives/Drawer/Drawer\";\nimport { Box, Divider, Group, Stack, Text, UnstyledButton } from \"../../primitives/layout\";\nimport { getSideNavItemLabelText, type SideNavItem, type SideNavSection } from \"../SideNav/SideNav\";\nimport { MOBILE_NAV_LOGO_HEIGHT } from \"./MobileNavHeader\";\n\n/** Full-bleed mobile nav sheet width — not the 260px desktop rail. */\nexport const MOBILE_NAV_WIDTH = \"100%\";\n\n/** Minimum touch target for destination / profile rows. */\nexport const MOBILE_NAV_ROW_MIN_HEIGHT = 48;\n\nexport interface MobileNavProfile {\n /** Primary line (user name). */\n displayName: string;\n /** Secondary line (company / email). */\n subline?: string;\n /** Avatar name for initials. Defaults to `displayName`. */\n avatarName?: string;\n /** Leading avatar node. When omitted, a text fallback is shown. */\n avatar?: ReactNode;\n}\n\nexport interface MobileNavProps {\n /** Whether the navigation sheet is open. */\n opened: boolean;\n /** Close handler (backdrop / escape). */\n onClose: () => void;\n /** Flat destination list when sections are not needed. */\n items?: SideNavItem[];\n /** Grouped destinations (section labels are not rendered — same as SideNav). */\n sections?: SideNavSection[];\n /** Leaf destination selected. Parents with children only expand/collapse. */\n onItemClick: (id: string) => void;\n /** Logo / brand chrome above destinations. */\n header?: ReactNode;\n /** Primary CTA above the profile (e.g. Start / Add investment). */\n cta?: ReactNode;\n /** Profile trigger shown at the bottom. Tapping calls `onProfileClick`. */\n profile?: MobileNavProfile;\n /** Called when the profile row is pressed (typically opens AccountSheet). */\n onProfileClick?: () => void;\n /** Accessible label for the navigation landmark. @default \"Main navigation\" */\n ariaLabel?: string;\n /** Overlay z-index. @default overlayZIndexAboveLegacyShell */\n zIndex?: number;\n /**\n * Where the dismiss control sits in the header row.\n * `end` matches Studio (close on the far right). `start` keeps it beside the\n * logo so the page-header hamburger and overlay close occupy the same slot.\n * @default \"end\"\n */\n closePosition?: \"start\" | \"end\";\n}\n\nfunction MobileNavRow({\n item,\n depth,\n onItemClick,\n}: {\n item: SideNavItem;\n depth: number;\n onItemClick: (id: string) => void;\n}) {\n const hasChildren = Boolean(item.children?.length);\n const labelText = getSideNavItemLabelText(item);\n const childActive = item.children?.some((child) => child.active) ?? false;\n const [opened, setOpened] = useState(Boolean(item.open) || childActive);\n const active = Boolean(item.active) && !hasChildren;\n\n const paddingLeft = 12 + depth * 16;\n\n return (\n <Box>\n <UnstyledButton\n type=\"button\"\n disabled={item.disabled}\n aria-label={labelText}\n aria-current={active ? \"page\" : undefined}\n aria-expanded={hasChildren ? opened : undefined}\n onClick={() => {\n if (hasChildren) {\n setOpened((value) => !value);\n return;\n }\n onItemClick(item.id);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n minHeight: MOBILE_NAV_ROW_MIN_HEIGHT,\n paddingLeft,\n paddingRight: 12,\n borderRadius: radii.md,\n textAlign: \"left\",\n cursor: item.disabled ? \"not-allowed\" : \"pointer\",\n opacity: item.disabled ? 0.5 : 1,\n backgroundColor: active ? fairmintVars.colorSurfaceSelected : \"transparent\",\n color: active ? fairmintVars.colorIconOnSurfaceSelected : fairmintVars.colorTextPrimary,\n }}\n styles={{\n root: {\n \"&:hover:not(:disabled)\": {\n backgroundColor: active\n ? fairmintVars.colorSurfaceSelected\n : fairmintVars.colorBgHover,\n },\n },\n }}\n >\n {item.icon ? (\n <Box\n component=\"span\"\n style={{\n display: \"inline-flex\",\n color: active\n ? fairmintVars.colorIconOnSurfaceSelected\n : fairmintVars.colorIconSecondary,\n flexShrink: 0,\n }}\n >\n {item.icon}\n </Box>\n ) : null}\n <Text\n size=\"md\"\n fw={active ? 600 : 500}\n style={{\n flex: 1,\n minWidth: 0,\n color: active ? fairmintVars.colorIconOnSurfaceSelected : undefined,\n }}\n truncate\n >\n {item.label}\n </Text>\n {item.rightSection}\n {hasChildren ? (\n <IconChevronDown\n size={18}\n stroke={1.5}\n aria-hidden\n style={{\n flexShrink: 0,\n transform: opened ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 120ms ease\",\n color: fairmintVars.colorIconTertiary,\n }}\n />\n ) : null}\n </UnstyledButton>\n\n {hasChildren && opened ? (\n <Stack gap={4} mt={4}>\n {item.children?.map((child) => (\n <MobileNavRow key={child.id} item={child} depth={depth + 1} onItemClick={onItemClick} />\n ))}\n </Stack>\n ) : null}\n </Box>\n );\n}\n\n/**\n * Mobile-optimized navigation sheet for product shells.\n *\n * Full-bleed left drawer with 48px touch rows, pinned CTA + profile, and an\n * always-visible close control (full-bleed leaves no backdrop to dismiss).\n * Pair `onProfileClick` with {@link AccountSheet} for Sign out.\n */\nexport function MobileNav({\n opened,\n onClose,\n items = [],\n sections,\n onItemClick,\n header,\n cta,\n profile,\n onProfileClick,\n ariaLabel = \"Main navigation\",\n zIndex = overlayZIndexAboveLegacyShell,\n closePosition = \"end\",\n}: MobileNavProps) {\n const resolvedSections = sections ?? [{ id: \"main\", items }];\n\n const handleItemClick = (id: string) => {\n onItemClick(id);\n onClose();\n };\n\n return (\n <Drawer\n opened={opened}\n onClose={onClose}\n position=\"left\"\n size={MOBILE_NAV_WIDTH}\n padding={0}\n withCloseButton={false}\n zIndex={zIndex}\n styles={{\n content: {\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n },\n body: {\n display: \"flex\",\n flexDirection: \"column\",\n flex: 1,\n height: \"100%\",\n minHeight: 0,\n overflow: \"hidden\",\n padding: 0,\n },\n header: {\n display: \"none\",\n },\n }}\n >\n <Stack\n component=\"nav\"\n gap=\"md\"\n aria-label={ariaLabel}\n style={{\n height: \"100%\",\n padding: 16,\n paddingBottom: \"max(16px, env(safe-area-inset-bottom))\",\n boxSizing: \"border-box\",\n }}\n >\n <Group\n justify={closePosition === \"end\" ? \"space-between\" : \"flex-start\"}\n wrap=\"nowrap\"\n align=\"center\"\n gap=\"md\"\n style={{ flexShrink: 0, minHeight: 32 }}\n >\n <Box\n style={{\n flex: closePosition === \"end\" ? 1 : undefined,\n minWidth: 0,\n display: \"flex\",\n alignItems: \"center\",\n minHeight: MOBILE_NAV_LOGO_HEIGHT,\n }}\n >\n {header}\n </Box>\n <ActionIcon\n type=\"button\"\n aria-label=\"Close navigation\"\n color=\"gray\"\n variant=\"subtle\"\n size=\"lg\"\n onClick={onClose}\n >\n <IconX size={20} stroke={1.5} />\n </ActionIcon>\n </Group>\n\n <Stack gap={4} style={{ flex: 1, minHeight: 0, overflow: \"auto\" }}>\n {resolvedSections.flatMap((section) =>\n section.items.map((item) => (\n <MobileNavRow\n key={`${section.id}:${item.id}`}\n item={item}\n depth={0}\n onItemClick={handleItemClick}\n />\n )),\n )}\n </Stack>\n\n {(cta || profile) && (\n <Stack gap=\"sm\" style={{ flexShrink: 0 }}>\n {cta ? <Box style={{ width: \"100%\" }}>{cta}</Box> : null}\n {cta && profile ? <Divider color={fairmintVars.colorBorderDefault} /> : null}\n {profile ? (\n <UnstyledButton\n type=\"button\"\n aria-label=\"Account menu\"\n aria-haspopup=\"dialog\"\n onClick={onProfileClick}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n minHeight: MOBILE_NAV_ROW_MIN_HEIGHT,\n padding: 8,\n borderRadius: radii.md,\n textAlign: \"left\",\n cursor: onProfileClick ? \"pointer\" : \"default\",\n }}\n styles={{\n root: {\n \"&:hover\": {\n backgroundColor: fairmintVars.colorBgHover,\n },\n },\n }}\n >\n {profile.avatar}\n <Stack gap={0} style={{ minWidth: 0, flex: 1 }}>\n <Text size=\"sm\" fw={600} truncate>\n {profile.displayName}\n </Text>\n {profile.subline && profile.subline !== profile.displayName ? (\n <Text size=\"xs\" c=\"dimmed\" truncate>\n {profile.subline}\n </Text>\n ) : null}\n </Stack>\n <IconChevronDown\n size={18}\n stroke={1.5}\n aria-hidden\n style={{ color: fairmintVars.colorIconTertiary, flexShrink: 0 }}\n />\n </UnstyledButton>\n ) : null}\n </Stack>\n )}\n </Stack>\n </Drawer>\n );\n}\n"],"names":["getSideNavItemLabelText","useState","Box","jsxs","UnstyledButton","radii","fairmintVars","jsx","Text","IconChevronDown","Stack","zIndex","overlayZIndexAboveLegacyShell","Drawer","Group","MOBILE_NAV_LOGO_HEIGHT","ActionIcon","IconX","Divider"],"mappings":"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"}
1
+ {"version":3,"file":"MobileNav.cjs","sources":["../../../../src/components/layout/MobileNav/MobileNav.tsx"],"sourcesContent":["import { IconChevronDown, IconX } from \"@tabler/icons-react\";\nimport { type ReactNode, useState } from \"react\";\nimport { fairmintVars, radii } from \"../../../theme\";\nimport { overlayZIndexAboveLegacyShell } from \"../../../theme/zIndex\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Drawer } from \"../../primitives/Drawer/Drawer\";\nimport { Box, Divider, Group, Stack, Text, UnstyledButton } from \"../../primitives/layout\";\nimport { getSideNavItemLabelText, type SideNavItem, type SideNavSection } from \"../SideNav/SideNav\";\nimport { MOBILE_NAV_LOGO_HEIGHT } from \"./MobileNavHeader\";\n\n/** Full-bleed mobile nav sheet width — not the 260px desktop rail. */\nexport const MOBILE_NAV_WIDTH = \"100%\";\n\n/** Minimum touch target for destination / profile rows. */\nexport const MOBILE_NAV_ROW_MIN_HEIGHT = 48;\n\nexport interface MobileNavProfile {\n /** Primary line (user name). */\n displayName: string;\n /** Secondary line (company / email). */\n subline?: string;\n /** Avatar name for initials. Defaults to `displayName`. */\n avatarName?: string;\n /** Leading avatar node. When omitted, a text fallback is shown. */\n avatar?: ReactNode;\n}\n\nexport interface MobileNavProps {\n /** Whether the navigation sheet is open. */\n opened: boolean;\n /** Close handler (backdrop / escape). */\n onClose: () => void;\n /** Flat destination list when sections are not needed. */\n items?: SideNavItem[];\n /** Grouped destinations (section labels are not rendered — same as SideNav). */\n sections?: SideNavSection[];\n /** Leaf destination selected. Parents with children only expand/collapse. */\n onItemClick: (id: string) => void;\n /** Logo / brand chrome above destinations. */\n header?: ReactNode;\n /** Primary CTA above the profile (e.g. Start / Add investment). */\n cta?: ReactNode;\n /** Profile trigger shown at the bottom. Tapping calls `onProfileClick`. */\n profile?: MobileNavProfile;\n /** Called when the profile row is pressed (typically opens AccountSheet). */\n onProfileClick?: () => void;\n /** Accessible label for the navigation landmark. @default \"Main navigation\" */\n ariaLabel?: string;\n /** Overlay z-index. @default overlayZIndexAboveLegacyShell */\n zIndex?: number;\n /**\n * Where the dismiss control sits in the header row.\n * `end` (default) matches the page-header hamburger on the far right.\n * `start` places close beside the logo (legacy / white-label layouts).\n * @default \"end\"\n */\n closePosition?: \"start\" | \"end\";\n}\n\nfunction MobileNavRow({\n item,\n depth,\n onItemClick,\n}: {\n item: SideNavItem;\n depth: number;\n onItemClick: (id: string) => void;\n}) {\n const hasChildren = Boolean(item.children?.length);\n const labelText = getSideNavItemLabelText(item);\n const childActive = item.children?.some((child) => child.active) ?? false;\n const [opened, setOpened] = useState(Boolean(item.open) || childActive);\n const active = Boolean(item.active) && !hasChildren;\n\n const paddingLeft = 12 + depth * 16;\n\n return (\n <Box>\n <UnstyledButton\n type=\"button\"\n disabled={item.disabled}\n aria-label={labelText}\n aria-current={active ? \"page\" : undefined}\n aria-expanded={hasChildren ? opened : undefined}\n onClick={() => {\n if (hasChildren) {\n setOpened((value) => !value);\n return;\n }\n onItemClick(item.id);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n minHeight: MOBILE_NAV_ROW_MIN_HEIGHT,\n paddingLeft,\n paddingRight: 12,\n borderRadius: radii.md,\n textAlign: \"left\",\n cursor: item.disabled ? \"not-allowed\" : \"pointer\",\n opacity: item.disabled ? 0.5 : 1,\n backgroundColor: active ? fairmintVars.colorSurfaceSelected : \"transparent\",\n color: active ? fairmintVars.colorIconOnSurfaceSelected : fairmintVars.colorTextPrimary,\n }}\n styles={{\n root: {\n \"&:hover:not(:disabled)\": {\n backgroundColor: active\n ? fairmintVars.colorSurfaceSelected\n : fairmintVars.colorBgHover,\n },\n },\n }}\n >\n {item.icon ? (\n <Box\n component=\"span\"\n style={{\n display: \"inline-flex\",\n color: active\n ? fairmintVars.colorIconOnSurfaceSelected\n : fairmintVars.colorIconSecondary,\n flexShrink: 0,\n }}\n >\n {item.icon}\n </Box>\n ) : null}\n <Text\n size=\"md\"\n fw={active ? 600 : 500}\n style={{\n flex: 1,\n minWidth: 0,\n color: active ? fairmintVars.colorIconOnSurfaceSelected : undefined,\n }}\n truncate\n >\n {item.label}\n </Text>\n {item.rightSection}\n {hasChildren ? (\n <IconChevronDown\n size={18}\n stroke={1.5}\n aria-hidden\n style={{\n flexShrink: 0,\n transform: opened ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 120ms ease\",\n color: fairmintVars.colorIconTertiary,\n }}\n />\n ) : null}\n </UnstyledButton>\n\n {hasChildren && opened ? (\n <Stack gap={4} mt={4}>\n {item.children?.map((child) => (\n <MobileNavRow key={child.id} item={child} depth={depth + 1} onItemClick={onItemClick} />\n ))}\n </Stack>\n ) : null}\n </Box>\n );\n}\n\n/**\n * Mobile-optimized navigation sheet for product shells.\n *\n * Full-bleed left drawer with 48px touch rows, pinned CTA + profile, and an\n * always-visible close control (full-bleed leaves no backdrop to dismiss).\n * Pair `onProfileClick` with {@link AccountSheet} for Sign out.\n */\nexport function MobileNav({\n opened,\n onClose,\n items = [],\n sections,\n onItemClick,\n header,\n cta,\n profile,\n onProfileClick,\n ariaLabel = \"Main navigation\",\n zIndex = overlayZIndexAboveLegacyShell,\n closePosition = \"end\",\n}: MobileNavProps) {\n const resolvedSections = sections ?? [{ id: \"main\", items }];\n\n const handleItemClick = (id: string) => {\n onItemClick(id);\n onClose();\n };\n\n return (\n <Drawer\n opened={opened}\n onClose={onClose}\n position=\"left\"\n size={MOBILE_NAV_WIDTH}\n padding={0}\n withCloseButton={false}\n zIndex={zIndex}\n styles={{\n content: {\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n },\n body: {\n display: \"flex\",\n flexDirection: \"column\",\n flex: 1,\n height: \"100%\",\n minHeight: 0,\n overflow: \"hidden\",\n padding: 0,\n },\n header: {\n display: \"none\",\n },\n }}\n >\n <Stack\n component=\"nav\"\n gap=\"md\"\n aria-label={ariaLabel}\n style={{\n height: \"100%\",\n padding: 16,\n paddingBottom: \"max(16px, env(safe-area-inset-bottom))\",\n boxSizing: \"border-box\",\n }}\n >\n <Group\n justify={closePosition === \"end\" ? \"space-between\" : \"flex-start\"}\n wrap=\"nowrap\"\n align=\"center\"\n gap=\"md\"\n style={{ flexShrink: 0, minHeight: 32 }}\n >\n <Box\n style={{\n flex: closePosition === \"end\" ? 1 : undefined,\n minWidth: 0,\n display: \"flex\",\n alignItems: \"center\",\n minHeight: MOBILE_NAV_LOGO_HEIGHT,\n }}\n >\n {header}\n </Box>\n <ActionIcon\n type=\"button\"\n aria-label=\"Close navigation\"\n color=\"gray\"\n variant=\"subtle\"\n size=\"lg\"\n onClick={onClose}\n >\n <IconX size={20} stroke={1.5} />\n </ActionIcon>\n </Group>\n\n <Stack gap={4} style={{ flex: 1, minHeight: 0, overflow: \"auto\" }}>\n {resolvedSections.flatMap((section) =>\n section.items.map((item) => (\n <MobileNavRow\n key={`${section.id}:${item.id}`}\n item={item}\n depth={0}\n onItemClick={handleItemClick}\n />\n )),\n )}\n </Stack>\n\n {(cta || profile) && (\n <Stack gap=\"sm\" style={{ flexShrink: 0 }}>\n {cta ? <Box style={{ width: \"100%\" }}>{cta}</Box> : null}\n {cta && profile ? <Divider color={fairmintVars.colorBorderDefault} /> : null}\n {profile ? (\n <UnstyledButton\n type=\"button\"\n aria-label=\"Account menu\"\n aria-haspopup=\"dialog\"\n onClick={onProfileClick}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n minHeight: MOBILE_NAV_ROW_MIN_HEIGHT,\n padding: 8,\n borderRadius: radii.md,\n textAlign: \"left\",\n cursor: onProfileClick ? \"pointer\" : \"default\",\n }}\n styles={{\n root: {\n \"&:hover\": {\n backgroundColor: fairmintVars.colorBgHover,\n },\n },\n }}\n >\n {profile.avatar}\n <Stack gap={0} style={{ minWidth: 0, flex: 1 }}>\n <Text size=\"sm\" fw={600} truncate>\n {profile.displayName}\n </Text>\n {profile.subline && profile.subline !== profile.displayName ? (\n <Text size=\"xs\" c=\"dimmed\" truncate>\n {profile.subline}\n </Text>\n ) : null}\n </Stack>\n <IconChevronDown\n size={18}\n stroke={1.5}\n aria-hidden\n style={{ color: fairmintVars.colorIconTertiary, flexShrink: 0 }}\n />\n </UnstyledButton>\n ) : null}\n </Stack>\n )}\n </Stack>\n </Drawer>\n );\n}\n"],"names":["getSideNavItemLabelText","useState","Box","jsxs","UnstyledButton","radii","fairmintVars","jsx","Text","IconChevronDown","Stack","zIndex","overlayZIndexAboveLegacyShell","Drawer","Group","MOBILE_NAV_LOGO_HEIGHT","ActionIcon","IconX","Divider"],"mappings":"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"}
@@ -39,8 +39,8 @@ export interface MobileNavProps {
39
39
  zIndex?: number;
40
40
  /**
41
41
  * Where the dismiss control sits in the header row.
42
- * `end` matches Studio (close on the far right). `start` keeps it beside the
43
- * logo so the page-header hamburger and overlay close occupy the same slot.
42
+ * `end` (default) matches the page-header hamburger on the far right.
43
+ * `start` places close beside the logo (legacy / white-label layouts).
44
44
  * @default "end"
45
45
  */
46
46
  closePosition?: "start" | "end";
@@ -1 +1 @@
1
- {"version":3,"file":"MobileNav.js","sources":["../../../../src/components/layout/MobileNav/MobileNav.tsx"],"sourcesContent":["import { IconChevronDown, IconX } from \"@tabler/icons-react\";\nimport { type ReactNode, useState } from \"react\";\nimport { fairmintVars, radii } from \"../../../theme\";\nimport { overlayZIndexAboveLegacyShell } from \"../../../theme/zIndex\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Drawer } from \"../../primitives/Drawer/Drawer\";\nimport { Box, Divider, Group, Stack, Text, UnstyledButton } from \"../../primitives/layout\";\nimport { getSideNavItemLabelText, type SideNavItem, type SideNavSection } from \"../SideNav/SideNav\";\nimport { MOBILE_NAV_LOGO_HEIGHT } from \"./MobileNavHeader\";\n\n/** Full-bleed mobile nav sheet width — not the 260px desktop rail. */\nexport const MOBILE_NAV_WIDTH = \"100%\";\n\n/** Minimum touch target for destination / profile rows. */\nexport const MOBILE_NAV_ROW_MIN_HEIGHT = 48;\n\nexport interface MobileNavProfile {\n /** Primary line (user name). */\n displayName: string;\n /** Secondary line (company / email). */\n subline?: string;\n /** Avatar name for initials. Defaults to `displayName`. */\n avatarName?: string;\n /** Leading avatar node. When omitted, a text fallback is shown. */\n avatar?: ReactNode;\n}\n\nexport interface MobileNavProps {\n /** Whether the navigation sheet is open. */\n opened: boolean;\n /** Close handler (backdrop / escape). */\n onClose: () => void;\n /** Flat destination list when sections are not needed. */\n items?: SideNavItem[];\n /** Grouped destinations (section labels are not rendered — same as SideNav). */\n sections?: SideNavSection[];\n /** Leaf destination selected. Parents with children only expand/collapse. */\n onItemClick: (id: string) => void;\n /** Logo / brand chrome above destinations. */\n header?: ReactNode;\n /** Primary CTA above the profile (e.g. Start / Add investment). */\n cta?: ReactNode;\n /** Profile trigger shown at the bottom. Tapping calls `onProfileClick`. */\n profile?: MobileNavProfile;\n /** Called when the profile row is pressed (typically opens AccountSheet). */\n onProfileClick?: () => void;\n /** Accessible label for the navigation landmark. @default \"Main navigation\" */\n ariaLabel?: string;\n /** Overlay z-index. @default overlayZIndexAboveLegacyShell */\n zIndex?: number;\n /**\n * Where the dismiss control sits in the header row.\n * `end` matches Studio (close on the far right). `start` keeps it beside the\n * logo so the page-header hamburger and overlay close occupy the same slot.\n * @default \"end\"\n */\n closePosition?: \"start\" | \"end\";\n}\n\nfunction MobileNavRow({\n item,\n depth,\n onItemClick,\n}: {\n item: SideNavItem;\n depth: number;\n onItemClick: (id: string) => void;\n}) {\n const hasChildren = Boolean(item.children?.length);\n const labelText = getSideNavItemLabelText(item);\n const childActive = item.children?.some((child) => child.active) ?? false;\n const [opened, setOpened] = useState(Boolean(item.open) || childActive);\n const active = Boolean(item.active) && !hasChildren;\n\n const paddingLeft = 12 + depth * 16;\n\n return (\n <Box>\n <UnstyledButton\n type=\"button\"\n disabled={item.disabled}\n aria-label={labelText}\n aria-current={active ? \"page\" : undefined}\n aria-expanded={hasChildren ? opened : undefined}\n onClick={() => {\n if (hasChildren) {\n setOpened((value) => !value);\n return;\n }\n onItemClick(item.id);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n minHeight: MOBILE_NAV_ROW_MIN_HEIGHT,\n paddingLeft,\n paddingRight: 12,\n borderRadius: radii.md,\n textAlign: \"left\",\n cursor: item.disabled ? \"not-allowed\" : \"pointer\",\n opacity: item.disabled ? 0.5 : 1,\n backgroundColor: active ? fairmintVars.colorSurfaceSelected : \"transparent\",\n color: active ? fairmintVars.colorIconOnSurfaceSelected : fairmintVars.colorTextPrimary,\n }}\n styles={{\n root: {\n \"&:hover:not(:disabled)\": {\n backgroundColor: active\n ? fairmintVars.colorSurfaceSelected\n : fairmintVars.colorBgHover,\n },\n },\n }}\n >\n {item.icon ? (\n <Box\n component=\"span\"\n style={{\n display: \"inline-flex\",\n color: active\n ? fairmintVars.colorIconOnSurfaceSelected\n : fairmintVars.colorIconSecondary,\n flexShrink: 0,\n }}\n >\n {item.icon}\n </Box>\n ) : null}\n <Text\n size=\"md\"\n fw={active ? 600 : 500}\n style={{\n flex: 1,\n minWidth: 0,\n color: active ? fairmintVars.colorIconOnSurfaceSelected : undefined,\n }}\n truncate\n >\n {item.label}\n </Text>\n {item.rightSection}\n {hasChildren ? (\n <IconChevronDown\n size={18}\n stroke={1.5}\n aria-hidden\n style={{\n flexShrink: 0,\n transform: opened ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 120ms ease\",\n color: fairmintVars.colorIconTertiary,\n }}\n />\n ) : null}\n </UnstyledButton>\n\n {hasChildren && opened ? (\n <Stack gap={4} mt={4}>\n {item.children?.map((child) => (\n <MobileNavRow key={child.id} item={child} depth={depth + 1} onItemClick={onItemClick} />\n ))}\n </Stack>\n ) : null}\n </Box>\n );\n}\n\n/**\n * Mobile-optimized navigation sheet for product shells.\n *\n * Full-bleed left drawer with 48px touch rows, pinned CTA + profile, and an\n * always-visible close control (full-bleed leaves no backdrop to dismiss).\n * Pair `onProfileClick` with {@link AccountSheet} for Sign out.\n */\nexport function MobileNav({\n opened,\n onClose,\n items = [],\n sections,\n onItemClick,\n header,\n cta,\n profile,\n onProfileClick,\n ariaLabel = \"Main navigation\",\n zIndex = overlayZIndexAboveLegacyShell,\n closePosition = \"end\",\n}: MobileNavProps) {\n const resolvedSections = sections ?? [{ id: \"main\", items }];\n\n const handleItemClick = (id: string) => {\n onItemClick(id);\n onClose();\n };\n\n return (\n <Drawer\n opened={opened}\n onClose={onClose}\n position=\"left\"\n size={MOBILE_NAV_WIDTH}\n padding={0}\n withCloseButton={false}\n zIndex={zIndex}\n styles={{\n content: {\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n },\n body: {\n display: \"flex\",\n flexDirection: \"column\",\n flex: 1,\n height: \"100%\",\n minHeight: 0,\n overflow: \"hidden\",\n padding: 0,\n },\n header: {\n display: \"none\",\n },\n }}\n >\n <Stack\n component=\"nav\"\n gap=\"md\"\n aria-label={ariaLabel}\n style={{\n height: \"100%\",\n padding: 16,\n paddingBottom: \"max(16px, env(safe-area-inset-bottom))\",\n boxSizing: \"border-box\",\n }}\n >\n <Group\n justify={closePosition === \"end\" ? \"space-between\" : \"flex-start\"}\n wrap=\"nowrap\"\n align=\"center\"\n gap=\"md\"\n style={{ flexShrink: 0, minHeight: 32 }}\n >\n <Box\n style={{\n flex: closePosition === \"end\" ? 1 : undefined,\n minWidth: 0,\n display: \"flex\",\n alignItems: \"center\",\n minHeight: MOBILE_NAV_LOGO_HEIGHT,\n }}\n >\n {header}\n </Box>\n <ActionIcon\n type=\"button\"\n aria-label=\"Close navigation\"\n color=\"gray\"\n variant=\"subtle\"\n size=\"lg\"\n onClick={onClose}\n >\n <IconX size={20} stroke={1.5} />\n </ActionIcon>\n </Group>\n\n <Stack gap={4} style={{ flex: 1, minHeight: 0, overflow: \"auto\" }}>\n {resolvedSections.flatMap((section) =>\n section.items.map((item) => (\n <MobileNavRow\n key={`${section.id}:${item.id}`}\n item={item}\n depth={0}\n onItemClick={handleItemClick}\n />\n )),\n )}\n </Stack>\n\n {(cta || profile) && (\n <Stack gap=\"sm\" style={{ flexShrink: 0 }}>\n {cta ? <Box style={{ width: \"100%\" }}>{cta}</Box> : null}\n {cta && profile ? <Divider color={fairmintVars.colorBorderDefault} /> : null}\n {profile ? (\n <UnstyledButton\n type=\"button\"\n aria-label=\"Account menu\"\n aria-haspopup=\"dialog\"\n onClick={onProfileClick}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n minHeight: MOBILE_NAV_ROW_MIN_HEIGHT,\n padding: 8,\n borderRadius: radii.md,\n textAlign: \"left\",\n cursor: onProfileClick ? \"pointer\" : \"default\",\n }}\n styles={{\n root: {\n \"&:hover\": {\n backgroundColor: fairmintVars.colorBgHover,\n },\n },\n }}\n >\n {profile.avatar}\n <Stack gap={0} style={{ minWidth: 0, flex: 1 }}>\n <Text size=\"sm\" fw={600} truncate>\n {profile.displayName}\n </Text>\n {profile.subline && profile.subline !== profile.displayName ? (\n <Text size=\"xs\" c=\"dimmed\" truncate>\n {profile.subline}\n </Text>\n ) : null}\n </Stack>\n <IconChevronDown\n size={18}\n stroke={1.5}\n aria-hidden\n style={{ color: fairmintVars.colorIconTertiary, flexShrink: 0 }}\n />\n </UnstyledButton>\n ) : null}\n </Stack>\n )}\n </Stack>\n </Drawer>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MobileNav.js","sources":["../../../../src/components/layout/MobileNav/MobileNav.tsx"],"sourcesContent":["import { IconChevronDown, IconX } from \"@tabler/icons-react\";\nimport { type ReactNode, useState } from \"react\";\nimport { fairmintVars, radii } from \"../../../theme\";\nimport { overlayZIndexAboveLegacyShell } from \"../../../theme/zIndex\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Drawer } from \"../../primitives/Drawer/Drawer\";\nimport { Box, Divider, Group, Stack, Text, UnstyledButton } from \"../../primitives/layout\";\nimport { getSideNavItemLabelText, type SideNavItem, type SideNavSection } from \"../SideNav/SideNav\";\nimport { MOBILE_NAV_LOGO_HEIGHT } from \"./MobileNavHeader\";\n\n/** Full-bleed mobile nav sheet width — not the 260px desktop rail. */\nexport const MOBILE_NAV_WIDTH = \"100%\";\n\n/** Minimum touch target for destination / profile rows. */\nexport const MOBILE_NAV_ROW_MIN_HEIGHT = 48;\n\nexport interface MobileNavProfile {\n /** Primary line (user name). */\n displayName: string;\n /** Secondary line (company / email). */\n subline?: string;\n /** Avatar name for initials. Defaults to `displayName`. */\n avatarName?: string;\n /** Leading avatar node. When omitted, a text fallback is shown. */\n avatar?: ReactNode;\n}\n\nexport interface MobileNavProps {\n /** Whether the navigation sheet is open. */\n opened: boolean;\n /** Close handler (backdrop / escape). */\n onClose: () => void;\n /** Flat destination list when sections are not needed. */\n items?: SideNavItem[];\n /** Grouped destinations (section labels are not rendered — same as SideNav). */\n sections?: SideNavSection[];\n /** Leaf destination selected. Parents with children only expand/collapse. */\n onItemClick: (id: string) => void;\n /** Logo / brand chrome above destinations. */\n header?: ReactNode;\n /** Primary CTA above the profile (e.g. Start / Add investment). */\n cta?: ReactNode;\n /** Profile trigger shown at the bottom. Tapping calls `onProfileClick`. */\n profile?: MobileNavProfile;\n /** Called when the profile row is pressed (typically opens AccountSheet). */\n onProfileClick?: () => void;\n /** Accessible label for the navigation landmark. @default \"Main navigation\" */\n ariaLabel?: string;\n /** Overlay z-index. @default overlayZIndexAboveLegacyShell */\n zIndex?: number;\n /**\n * Where the dismiss control sits in the header row.\n * `end` (default) matches the page-header hamburger on the far right.\n * `start` places close beside the logo (legacy / white-label layouts).\n * @default \"end\"\n */\n closePosition?: \"start\" | \"end\";\n}\n\nfunction MobileNavRow({\n item,\n depth,\n onItemClick,\n}: {\n item: SideNavItem;\n depth: number;\n onItemClick: (id: string) => void;\n}) {\n const hasChildren = Boolean(item.children?.length);\n const labelText = getSideNavItemLabelText(item);\n const childActive = item.children?.some((child) => child.active) ?? false;\n const [opened, setOpened] = useState(Boolean(item.open) || childActive);\n const active = Boolean(item.active) && !hasChildren;\n\n const paddingLeft = 12 + depth * 16;\n\n return (\n <Box>\n <UnstyledButton\n type=\"button\"\n disabled={item.disabled}\n aria-label={labelText}\n aria-current={active ? \"page\" : undefined}\n aria-expanded={hasChildren ? opened : undefined}\n onClick={() => {\n if (hasChildren) {\n setOpened((value) => !value);\n return;\n }\n onItemClick(item.id);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n minHeight: MOBILE_NAV_ROW_MIN_HEIGHT,\n paddingLeft,\n paddingRight: 12,\n borderRadius: radii.md,\n textAlign: \"left\",\n cursor: item.disabled ? \"not-allowed\" : \"pointer\",\n opacity: item.disabled ? 0.5 : 1,\n backgroundColor: active ? fairmintVars.colorSurfaceSelected : \"transparent\",\n color: active ? fairmintVars.colorIconOnSurfaceSelected : fairmintVars.colorTextPrimary,\n }}\n styles={{\n root: {\n \"&:hover:not(:disabled)\": {\n backgroundColor: active\n ? fairmintVars.colorSurfaceSelected\n : fairmintVars.colorBgHover,\n },\n },\n }}\n >\n {item.icon ? (\n <Box\n component=\"span\"\n style={{\n display: \"inline-flex\",\n color: active\n ? fairmintVars.colorIconOnSurfaceSelected\n : fairmintVars.colorIconSecondary,\n flexShrink: 0,\n }}\n >\n {item.icon}\n </Box>\n ) : null}\n <Text\n size=\"md\"\n fw={active ? 600 : 500}\n style={{\n flex: 1,\n minWidth: 0,\n color: active ? fairmintVars.colorIconOnSurfaceSelected : undefined,\n }}\n truncate\n >\n {item.label}\n </Text>\n {item.rightSection}\n {hasChildren ? (\n <IconChevronDown\n size={18}\n stroke={1.5}\n aria-hidden\n style={{\n flexShrink: 0,\n transform: opened ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 120ms ease\",\n color: fairmintVars.colorIconTertiary,\n }}\n />\n ) : null}\n </UnstyledButton>\n\n {hasChildren && opened ? (\n <Stack gap={4} mt={4}>\n {item.children?.map((child) => (\n <MobileNavRow key={child.id} item={child} depth={depth + 1} onItemClick={onItemClick} />\n ))}\n </Stack>\n ) : null}\n </Box>\n );\n}\n\n/**\n * Mobile-optimized navigation sheet for product shells.\n *\n * Full-bleed left drawer with 48px touch rows, pinned CTA + profile, and an\n * always-visible close control (full-bleed leaves no backdrop to dismiss).\n * Pair `onProfileClick` with {@link AccountSheet} for Sign out.\n */\nexport function MobileNav({\n opened,\n onClose,\n items = [],\n sections,\n onItemClick,\n header,\n cta,\n profile,\n onProfileClick,\n ariaLabel = \"Main navigation\",\n zIndex = overlayZIndexAboveLegacyShell,\n closePosition = \"end\",\n}: MobileNavProps) {\n const resolvedSections = sections ?? [{ id: \"main\", items }];\n\n const handleItemClick = (id: string) => {\n onItemClick(id);\n onClose();\n };\n\n return (\n <Drawer\n opened={opened}\n onClose={onClose}\n position=\"left\"\n size={MOBILE_NAV_WIDTH}\n padding={0}\n withCloseButton={false}\n zIndex={zIndex}\n styles={{\n content: {\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n },\n body: {\n display: \"flex\",\n flexDirection: \"column\",\n flex: 1,\n height: \"100%\",\n minHeight: 0,\n overflow: \"hidden\",\n padding: 0,\n },\n header: {\n display: \"none\",\n },\n }}\n >\n <Stack\n component=\"nav\"\n gap=\"md\"\n aria-label={ariaLabel}\n style={{\n height: \"100%\",\n padding: 16,\n paddingBottom: \"max(16px, env(safe-area-inset-bottom))\",\n boxSizing: \"border-box\",\n }}\n >\n <Group\n justify={closePosition === \"end\" ? \"space-between\" : \"flex-start\"}\n wrap=\"nowrap\"\n align=\"center\"\n gap=\"md\"\n style={{ flexShrink: 0, minHeight: 32 }}\n >\n <Box\n style={{\n flex: closePosition === \"end\" ? 1 : undefined,\n minWidth: 0,\n display: \"flex\",\n alignItems: \"center\",\n minHeight: MOBILE_NAV_LOGO_HEIGHT,\n }}\n >\n {header}\n </Box>\n <ActionIcon\n type=\"button\"\n aria-label=\"Close navigation\"\n color=\"gray\"\n variant=\"subtle\"\n size=\"lg\"\n onClick={onClose}\n >\n <IconX size={20} stroke={1.5} />\n </ActionIcon>\n </Group>\n\n <Stack gap={4} style={{ flex: 1, minHeight: 0, overflow: \"auto\" }}>\n {resolvedSections.flatMap((section) =>\n section.items.map((item) => (\n <MobileNavRow\n key={`${section.id}:${item.id}`}\n item={item}\n depth={0}\n onItemClick={handleItemClick}\n />\n )),\n )}\n </Stack>\n\n {(cta || profile) && (\n <Stack gap=\"sm\" style={{ flexShrink: 0 }}>\n {cta ? <Box style={{ width: \"100%\" }}>{cta}</Box> : null}\n {cta && profile ? <Divider color={fairmintVars.colorBorderDefault} /> : null}\n {profile ? (\n <UnstyledButton\n type=\"button\"\n aria-label=\"Account menu\"\n aria-haspopup=\"dialog\"\n onClick={onProfileClick}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n minHeight: MOBILE_NAV_ROW_MIN_HEIGHT,\n padding: 8,\n borderRadius: radii.md,\n textAlign: \"left\",\n cursor: onProfileClick ? \"pointer\" : \"default\",\n }}\n styles={{\n root: {\n \"&:hover\": {\n backgroundColor: fairmintVars.colorBgHover,\n },\n },\n }}\n >\n {profile.avatar}\n <Stack gap={0} style={{ minWidth: 0, flex: 1 }}>\n <Text size=\"sm\" fw={600} truncate>\n {profile.displayName}\n </Text>\n {profile.subline && profile.subline !== profile.displayName ? (\n <Text size=\"xs\" c=\"dimmed\" truncate>\n {profile.subline}\n </Text>\n ) : null}\n </Stack>\n <IconChevronDown\n size={18}\n stroke={1.5}\n aria-hidden\n style={{ color: fairmintVars.colorIconTertiary, flexShrink: 0 }}\n />\n </UnstyledButton>\n ) : null}\n </Stack>\n )}\n </Stack>\n </Drawer>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAWO,MAAM,mBAAmB;AAGzB,MAAM,4BAA4B;AA6CzC,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,cAAc,QAAQ,KAAK,UAAU,MAAM;AACjD,QAAM,YAAY,wBAAwB,IAAI;AAC9C,QAAM,cAAc,KAAK,UAAU,KAAK,CAAC,UAAU,MAAM,MAAM,KAAK;AACpE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,QAAQ,KAAK,IAAI,KAAK,WAAW;AACtE,QAAM,SAAS,QAAQ,KAAK,MAAM,KAAK,CAAC;AAExC,QAAM,cAAc,KAAK,QAAQ;AAEjC,8BACG,KAAA,EACC,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAU,KAAK;AAAA,QACf,cAAY;AAAA,QACZ,gBAAc,SAAS,SAAS;AAAA,QAChC,iBAAe,cAAc,SAAS;AAAA,QACtC,SAAS,MAAM;AACb,cAAI,aAAa;AACf,sBAAU,CAAC,UAAU,CAAC,KAAK;AAC3B;AAAA,UACF;AACA,sBAAY,KAAK,EAAE;AAAA,QACrB;AAAA,QACA,OAAO;AAAA,UACL,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,OAAO;AAAA,UACP,WAAW;AAAA,UACX;AAAA,UACA,cAAc;AAAA,UACd,cAAc,MAAM;AAAA,UACpB,WAAW;AAAA,UACX,QAAQ,KAAK,WAAW,gBAAgB;AAAA,UACxC,SAAS,KAAK,WAAW,MAAM;AAAA,UAC/B,iBAAiB,SAAS,aAAa,uBAAuB;AAAA,UAC9D,OAAO,SAAS,aAAa,6BAA6B,aAAa;AAAA,QAAA;AAAA,QAEzE,QAAQ;AAAA,UACN,MAAM;AAAA,YACJ,0BAA0B;AAAA,cACxB,iBAAiB,SACb,aAAa,uBACb,aAAa;AAAA,YAAA;AAAA,UACnB;AAAA,QACF;AAAA,QAGD,UAAA;AAAA,UAAA,KAAK,OACJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,OAAO,SACH,aAAa,6BACb,aAAa;AAAA,gBACjB,YAAY;AAAA,cAAA;AAAA,cAGb,UAAA,KAAK;AAAA,YAAA;AAAA,UAAA,IAEN;AAAA,UACJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,IAAI,SAAS,MAAM;AAAA,cACnB,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,UAAU;AAAA,gBACV,OAAO,SAAS,aAAa,6BAA6B;AAAA,cAAA;AAAA,cAE5D,UAAQ;AAAA,cAEP,UAAA,KAAK;AAAA,YAAA;AAAA,UAAA;AAAA,UAEP,KAAK;AAAA,UACL,cACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,QAAQ;AAAA,cACR,eAAW;AAAA,cACX,OAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,WAAW,SAAS,mBAAmB;AAAA,gBACvC,YAAY;AAAA,gBACZ,OAAO,aAAa;AAAA,cAAA;AAAA,YACtB;AAAA,UAAA,IAEA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGL,eAAe,SACd,oBAAC,OAAA,EAAM,KAAK,GAAG,IAAI,GAChB,UAAA,KAAK,UAAU,IAAI,CAAC,UACnB,oBAAC,cAAA,EAA4B,MAAM,OAAO,OAAO,QAAQ,GAAG,YAAA,GAAzC,MAAM,EAA6D,CACvF,EAAA,CACH,IACE;AAAA,EAAA,GACN;AAEJ;AASO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA,QAAQ,CAAA;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,gBAAgB;AAClB,GAAmB;AACjB,QAAM,mBAAmB,YAAY,CAAC,EAAE,IAAI,QAAQ,OAAO;AAE3D,QAAM,kBAAkB,CAAC,OAAe;AACtC,gBAAY,EAAE;AACd,YAAA;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,UAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB;AAAA,MACA,QAAQ;AAAA,QACN,SAAS;AAAA,UACP,SAAS;AAAA,UACT,eAAe;AAAA,UACf,QAAQ;AAAA,QAAA;AAAA,QAEV,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,eAAe;AAAA,UACf,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,UAAU;AAAA,UACV,SAAS;AAAA,QAAA;AAAA,QAEX,QAAQ;AAAA,UACN,SAAS;AAAA,QAAA;AAAA,MACX;AAAA,MAGF,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,KAAI;AAAA,UACJ,cAAY;AAAA,UACZ,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,eAAe;AAAA,YACf,WAAW;AAAA,UAAA;AAAA,UAGb,UAAA;AAAA,YAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS,kBAAkB,QAAQ,kBAAkB;AAAA,gBACrD,MAAK;AAAA,gBACL,OAAM;AAAA,gBACN,KAAI;AAAA,gBACJ,OAAO,EAAE,YAAY,GAAG,WAAW,GAAA;AAAA,gBAEnC,UAAA;AAAA,kBAAA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,OAAO;AAAA,wBACL,MAAM,kBAAkB,QAAQ,IAAI;AAAA,wBACpC,UAAU;AAAA,wBACV,SAAS;AAAA,wBACT,YAAY;AAAA,wBACZ,WAAW;AAAA,sBAAA;AAAA,sBAGZ,UAAA;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAEH;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,MAAK;AAAA,sBACL,cAAW;AAAA,sBACX,OAAM;AAAA,sBACN,SAAQ;AAAA,sBACR,MAAK;AAAA,sBACL,SAAS;AAAA,sBAET,UAAA,oBAAC,OAAA,EAAM,MAAM,IAAI,QAAQ,IAAA,CAAK;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAChC;AAAA,cAAA;AAAA,YAAA;AAAA,YAGF,oBAAC,OAAA,EAAM,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,OAAA,GACtD,UAAA,iBAAiB;AAAA,cAAQ,CAAC,YACzB,QAAQ,MAAM,IAAI,CAAC,SACjB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC;AAAA,kBACA,OAAO;AAAA,kBACP,aAAa;AAAA,gBAAA;AAAA,gBAHR,GAAG,QAAQ,EAAE,IAAI,KAAK,EAAE;AAAA,cAAA,CAKhC;AAAA,YAAA,GAEL;AAAA,aAEE,OAAO,YACP,qBAAC,OAAA,EAAM,KAAI,MAAK,OAAO,EAAE,YAAY,EAAA,GAClC,UAAA;AAAA,cAAA,MAAM,oBAAC,OAAI,OAAO,EAAE,OAAO,UAAW,eAAI,IAAS;AAAA,cACnD,OAAO,UAAU,oBAAC,WAAQ,OAAO,aAAa,oBAAoB,IAAK;AAAA,cACvE,UACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,cAAW;AAAA,kBACX,iBAAc;AAAA,kBACd,SAAS;AAAA,kBACT,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,KAAK;AAAA,oBACL,OAAO;AAAA,oBACP,WAAW;AAAA,oBACX,SAAS;AAAA,oBACT,cAAc,MAAM;AAAA,oBACpB,WAAW;AAAA,oBACX,QAAQ,iBAAiB,YAAY;AAAA,kBAAA;AAAA,kBAEvC,QAAQ;AAAA,oBACN,MAAM;AAAA,sBACJ,WAAW;AAAA,wBACT,iBAAiB,aAAa;AAAA,sBAAA;AAAA,oBAChC;AAAA,kBACF;AAAA,kBAGD,UAAA;AAAA,oBAAA,QAAQ;AAAA,oBACT,qBAAC,OAAA,EAAM,KAAK,GAAG,OAAO,EAAE,UAAU,GAAG,MAAM,EAAA,GACzC,UAAA;AAAA,sBAAA,oBAAC,MAAA,EAAK,MAAK,MAAK,IAAI,KAAK,UAAQ,MAC9B,kBAAQ,YAAA,CACX;AAAA,sBACC,QAAQ,WAAW,QAAQ,YAAY,QAAQ,cAC9C,oBAAC,MAAA,EAAK,MAAK,MAAK,GAAE,UAAS,UAAQ,MAChC,UAAA,QAAQ,SACX,IACE;AAAA,oBAAA,GACN;AAAA,oBACA;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,MAAM;AAAA,wBACN,QAAQ;AAAA,wBACR,eAAW;AAAA,wBACX,OAAO,EAAE,OAAO,aAAa,mBAAmB,YAAY,EAAA;AAAA,sBAAE;AAAA,oBAAA;AAAA,kBAChE;AAAA,gBAAA;AAAA,cAAA,IAEA;AAAA,YAAA,EAAA,CACN;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA;AAGN;"}
@@ -3,8 +3,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const FairmintLogo = require("../../FairmintLogo/FairmintLogo.cjs");
5
5
  const ActionIcon = require("../../primitives/ActionIcon/ActionIcon.cjs");
6
- const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
7
6
  const colors = require("../../../theme/colors.cjs");
7
+ const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
8
8
  const MOBILE_NAV_HEADER_HEIGHT = 60;
9
9
  const MOBILE_NAV_LOGO_WIDTH = 120;
10
10
  const MOBILE_NAV_LOGO_HEIGHT = 28;
@@ -44,6 +44,23 @@ function MobileNavHeader({
44
44
  style: { display: "block" }
45
45
  }
46
46
  ) : null);
47
+ const menu = onMenuClick != null ? /* @__PURE__ */ jsxRuntime.jsx(
48
+ ActionIcon.ActionIcon,
49
+ {
50
+ type: "button",
51
+ "aria-label": "Open navigation",
52
+ color: colors.colors.neutral,
53
+ variant: "subtle",
54
+ w: MOBILE_NAV_MENU_SIZE,
55
+ h: MOBILE_NAV_MENU_SIZE,
56
+ onClick: onMenuClick,
57
+ children: menuIcon ?? defaultMenuIcon
58
+ }
59
+ ) : null;
60
+ const trailing = rightSection != null || menu != null ? /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { wrap: "nowrap", gap: MOBILE_NAV_BRAND_GAP, align: "center", children: [
61
+ rightSection,
62
+ menu
63
+ ] }) : null;
47
64
  return /* @__PURE__ */ jsxRuntime.jsxs(
48
65
  Group.Group,
49
66
  {
@@ -56,23 +73,8 @@ function MobileNavHeader({
56
73
  w: "100%",
57
74
  bg: "body",
58
75
  children: [
59
- /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { wrap: "nowrap", gap: MOBILE_NAV_BRAND_GAP, align: "center", children: [
60
- mark,
61
- onMenuClick ? /* @__PURE__ */ jsxRuntime.jsx(
62
- ActionIcon.ActionIcon,
63
- {
64
- type: "button",
65
- "aria-label": "Open navigation",
66
- color: colors.colors.neutral,
67
- variant: "subtle",
68
- w: MOBILE_NAV_MENU_SIZE,
69
- h: MOBILE_NAV_MENU_SIZE,
70
- onClick: onMenuClick,
71
- children: menuIcon ?? defaultMenuIcon
72
- }
73
- ) : null
74
- ] }),
75
- rightSection
76
+ mark,
77
+ trailing
76
78
  ]
77
79
  }
78
80
  );
@@ -1 +1 @@
1
- {"version":3,"file":"MobileNavHeader.cjs","sources":["../../../../src/components/layout/MobileNav/MobileNavHeader.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { colors } from \"../../../theme\";\nimport { FairmintLogo } from \"../../FairmintLogo/FairmintLogo\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Group } from \"../../primitives/layout\";\n\n/** Product-shell mobile header height (Studio + Investor). */\nexport const MOBILE_NAV_HEADER_HEIGHT = 60;\n/** Fairmint wordmark width in the mobile header and sheet. */\nexport const MOBILE_NAV_LOGO_WIDTH = 120;\n/** Fairmint wordmark height in the mobile header and sheet. */\nexport const MOBILE_NAV_LOGO_HEIGHT = 28;\n/** Space between the wordmark and the menu control. */\nexport const MOBILE_NAV_BRAND_GAP = 16;\n/** Header horizontal padding. */\nexport const MOBILE_NAV_HEADER_PADDING_X = 16;\n/** Menu control hit target (Mantine `lg`). */\nexport const MOBILE_NAV_MENU_SIZE = 36;\n\nconst defaultMenuIcon = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6h16\" />\n <path d=\"M4 12h16\" />\n <path d=\"M4 18h16\" />\n </svg>\n);\n\nexport interface MobileNavHeaderProps {\n /**\n * Override the default Fairmint wordmark (white-label portals).\n * When omitted and `onMenuClick` is set, the canonical 120×28 Fairmint logo is used.\n */\n logo?: ReactNode;\n /** Opens the MobileNav sheet. Omit on desktop where SideNav owns destinations. */\n onMenuClick?: () => void;\n /** Right-aligned header actions (notifications, Ask AI). */\n rightSection?: ReactNode;\n /** Menu glyph. Defaults to an outlined hamburger so the component never imports an icon library. */\n menuIcon?: ReactNode;\n}\n\n/**\n * Canonical mobile page header for Fairmint product shells.\n *\n * Logo then hamburger at a 16px gap, optional actions on the far right.\n * Pixel metrics are fixed so Studio and Investor cannot drift via theme tokens\n * or extra wrappers.\n */\nexport function MobileNavHeader({\n logo,\n onMenuClick,\n rightSection,\n menuIcon,\n}: MobileNavHeaderProps) {\n const mark =\n logo ??\n (onMenuClick ? (\n <FairmintLogo\n width={MOBILE_NAV_LOGO_WIDTH}\n height={MOBILE_NAV_LOGO_HEIGHT}\n style={{ display: \"block\" }}\n />\n ) : null);\n\n return (\n <Group\n h={MOBILE_NAV_HEADER_HEIGHT}\n px={MOBILE_NAV_HEADER_PADDING_X}\n justify=\"space-between\"\n wrap=\"nowrap\"\n align=\"center\"\n gap={0}\n w=\"100%\"\n bg=\"body\"\n >\n <Group wrap=\"nowrap\" gap={MOBILE_NAV_BRAND_GAP} align=\"center\">\n {mark}\n {onMenuClick ? (\n <ActionIcon\n type=\"button\"\n aria-label=\"Open navigation\"\n color={colors.neutral}\n variant=\"subtle\"\n w={MOBILE_NAV_MENU_SIZE}\n h={MOBILE_NAV_MENU_SIZE}\n onClick={onMenuClick}\n >\n {menuIcon ?? defaultMenuIcon}\n </ActionIcon>\n ) : null}\n </Group>\n {rightSection}\n </Group>\n );\n}\n"],"names":["jsxs","jsx","FairmintLogo","Group","ActionIcon","colors"],"mappings":";;;;;;;AAOO,MAAM,2BAA2B;AAEjC,MAAM,wBAAwB;AAE9B,MAAM,yBAAyB;AAE/B,MAAM,uBAAuB;AAE7B,MAAM,8BAA8B;AAEpC,MAAM,uBAAuB;AAEpC,MAAM,kBACJA,2BAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IAEZ,UAAA;AAAA,MAAAC,2BAAAA,IAAC,QAAA,EAAK,GAAE,UAAA,CAAU;AAAA,MAClBA,2BAAAA,IAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,MACnBA,2BAAAA,IAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,IAAA;AAAA,EAAA;AACrB;AAwBK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,OACJ,SACC,cACCA,2BAAAA;AAAAA,IAACC,aAAAA;AAAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,EAAE,SAAS,QAAA;AAAA,IAAQ;AAAA,EAAA,IAE1B;AAEN,SACEF,2BAAAA;AAAAA,IAACG,MAAAA;AAAAA,IAAA;AAAA,MACC,GAAG;AAAA,MACH,IAAI;AAAA,MACJ,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,KAAK;AAAA,MACL,GAAE;AAAA,MACF,IAAG;AAAA,MAEH,UAAA;AAAA,QAAAH,gCAACG,MAAAA,SAAM,MAAK,UAAS,KAAK,sBAAsB,OAAM,UACnD,UAAA;AAAA,UAAA;AAAA,UACA,cACCF,2BAAAA;AAAAA,YAACG,WAAAA;AAAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,OAAOC,OAAAA,OAAO;AAAA,cACd,SAAQ;AAAA,cACR,GAAG;AAAA,cACH,GAAG;AAAA,cACH,SAAS;AAAA,cAER,UAAA,YAAY;AAAA,YAAA;AAAA,UAAA,IAEb;AAAA,QAAA,GACN;AAAA,QACC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;;;;;;;;"}
1
+ {"version":3,"file":"MobileNavHeader.cjs","sources":["../../../../src/components/layout/MobileNav/MobileNavHeader.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { colors } from \"../../../theme\";\nimport { FairmintLogo } from \"../../FairmintLogo/FairmintLogo\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Group } from \"../../primitives/layout\";\n\n/** Product-shell mobile header height (Studio + Investor). */\nexport const MOBILE_NAV_HEADER_HEIGHT = 60;\n/** Fairmint wordmark width in the mobile header and sheet. */\nexport const MOBILE_NAV_LOGO_WIDTH = 120;\n/** Fairmint wordmark height in the mobile header and sheet. */\nexport const MOBILE_NAV_LOGO_HEIGHT = 28;\n/** Space between trailing actions and the menu control. */\nexport const MOBILE_NAV_BRAND_GAP = 16;\n/** Header horizontal padding. */\nexport const MOBILE_NAV_HEADER_PADDING_X = 16;\n/** Menu control hit target (Mantine `lg`). */\nexport const MOBILE_NAV_MENU_SIZE = 36;\n\nconst defaultMenuIcon = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6h16\" />\n <path d=\"M4 12h16\" />\n <path d=\"M4 18h16\" />\n </svg>\n);\n\nexport interface MobileNavHeaderProps {\n /**\n * Override the default Fairmint wordmark (white-label portals).\n * When omitted and `onMenuClick` is set, the canonical 120×28 Fairmint logo is used.\n */\n logo?: ReactNode;\n /** Opens the MobileNav sheet. Omit on desktop where SideNav owns destinations. */\n onMenuClick?: () => void;\n /** Trailing header actions before the hamburger (notifications, Ask AI). */\n rightSection?: ReactNode;\n /** Menu glyph. Defaults to an outlined hamburger so the component never imports an icon library. */\n menuIcon?: ReactNode;\n}\n\n/**\n * Canonical mobile page header for Fairmint product shells.\n *\n * Logo on the left; optional `rightSection` then hamburger on the far right.\n * Pixel metrics are fixed so Studio and Investor cannot drift via theme tokens\n * or extra wrappers. Sign out belongs in AccountSheet / the user menu — not here.\n */\nexport function MobileNavHeader({\n logo,\n onMenuClick,\n rightSection,\n menuIcon,\n}: MobileNavHeaderProps) {\n const mark =\n logo ??\n (onMenuClick ? (\n <FairmintLogo\n width={MOBILE_NAV_LOGO_WIDTH}\n height={MOBILE_NAV_LOGO_HEIGHT}\n style={{ display: \"block\" }}\n />\n ) : null);\n\n const menu =\n onMenuClick != null ? (\n <ActionIcon\n type=\"button\"\n aria-label=\"Open navigation\"\n color={colors.neutral}\n variant=\"subtle\"\n w={MOBILE_NAV_MENU_SIZE}\n h={MOBILE_NAV_MENU_SIZE}\n onClick={onMenuClick}\n >\n {menuIcon ?? defaultMenuIcon}\n </ActionIcon>\n ) : null;\n\n const trailing =\n rightSection != null || menu != null ? (\n <Group wrap=\"nowrap\" gap={MOBILE_NAV_BRAND_GAP} align=\"center\">\n {rightSection}\n {menu}\n </Group>\n ) : null;\n\n return (\n <Group\n h={MOBILE_NAV_HEADER_HEIGHT}\n px={MOBILE_NAV_HEADER_PADDING_X}\n justify=\"space-between\"\n wrap=\"nowrap\"\n align=\"center\"\n gap={0}\n w=\"100%\"\n bg=\"body\"\n >\n {mark}\n {trailing}\n </Group>\n );\n}\n"],"names":["jsxs","jsx","FairmintLogo","ActionIcon","colors","Group"],"mappings":";;;;;;;AAOO,MAAM,2BAA2B;AAEjC,MAAM,wBAAwB;AAE9B,MAAM,yBAAyB;AAE/B,MAAM,uBAAuB;AAE7B,MAAM,8BAA8B;AAEpC,MAAM,uBAAuB;AAEpC,MAAM,kBACJA,2BAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IAEZ,UAAA;AAAA,MAAAC,2BAAAA,IAAC,QAAA,EAAK,GAAE,UAAA,CAAU;AAAA,MAClBA,2BAAAA,IAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,MACnBA,2BAAAA,IAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,IAAA;AAAA,EAAA;AACrB;AAwBK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,OACJ,SACC,cACCA,2BAAAA;AAAAA,IAACC,aAAAA;AAAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,EAAE,SAAS,QAAA;AAAA,IAAQ;AAAA,EAAA,IAE1B;AAEN,QAAM,OACJ,eAAe,OACbD,2BAAAA;AAAAA,IAACE,WAAAA;AAAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAW;AAAA,MACX,OAAOC,OAAAA,OAAO;AAAA,MACd,SAAQ;AAAA,MACR,GAAG;AAAA,MACH,GAAG;AAAA,MACH,SAAS;AAAA,MAER,UAAA,YAAY;AAAA,IAAA;AAAA,EAAA,IAEb;AAEN,QAAM,WACJ,gBAAgB,QAAQ,QAAQ,OAC9BJ,2BAAAA,KAACK,MAAAA,OAAA,EAAM,MAAK,UAAS,KAAK,sBAAsB,OAAM,UACnD,UAAA;AAAA,IAAA;AAAA,IACA;AAAA,EAAA,EAAA,CACH,IACE;AAEN,SACEL,2BAAAA;AAAAA,IAACK,MAAAA;AAAAA,IAAA;AAAA,MACC,GAAG;AAAA,MACH,IAAI;AAAA,MACJ,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,KAAK;AAAA,MACL,GAAE;AAAA,MACF,IAAG;AAAA,MAEF,UAAA;AAAA,QAAA;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;;;;;;;;"}
@@ -5,7 +5,7 @@ export declare const MOBILE_NAV_HEADER_HEIGHT = 60;
5
5
  export declare const MOBILE_NAV_LOGO_WIDTH = 120;
6
6
  /** Fairmint wordmark height in the mobile header and sheet. */
7
7
  export declare const MOBILE_NAV_LOGO_HEIGHT = 28;
8
- /** Space between the wordmark and the menu control. */
8
+ /** Space between trailing actions and the menu control. */
9
9
  export declare const MOBILE_NAV_BRAND_GAP = 16;
10
10
  /** Header horizontal padding. */
11
11
  export declare const MOBILE_NAV_HEADER_PADDING_X = 16;
@@ -19,7 +19,7 @@ export interface MobileNavHeaderProps {
19
19
  logo?: ReactNode;
20
20
  /** Opens the MobileNav sheet. Omit on desktop where SideNav owns destinations. */
21
21
  onMenuClick?: () => void;
22
- /** Right-aligned header actions (notifications, Ask AI). */
22
+ /** Trailing header actions before the hamburger (notifications, Ask AI). */
23
23
  rightSection?: ReactNode;
24
24
  /** Menu glyph. Defaults to an outlined hamburger so the component never imports an icon library. */
25
25
  menuIcon?: ReactNode;
@@ -27,9 +27,9 @@ export interface MobileNavHeaderProps {
27
27
  /**
28
28
  * Canonical mobile page header for Fairmint product shells.
29
29
  *
30
- * Logo then hamburger at a 16px gap, optional actions on the far right.
30
+ * Logo on the left; optional `rightSection` then hamburger on the far right.
31
31
  * Pixel metrics are fixed so Studio and Investor cannot drift via theme tokens
32
- * or extra wrappers.
32
+ * or extra wrappers. Sign out belongs in AccountSheet / the user menu — not here.
33
33
  */
34
34
  export declare function MobileNavHeader({ logo, onMenuClick, rightSection, menuIcon, }: MobileNavHeaderProps): import("react").JSX.Element;
35
35
  //# sourceMappingURL=MobileNavHeader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MobileNavHeader.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/MobileNav/MobileNavHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,8DAA8D;AAC9D,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,uDAAuD;AACvD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,iCAAiC;AACjC,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAC9C,8CAA8C;AAC9C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAoBvC,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,oGAAoG;IACpG,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,QAAQ,GACT,EAAE,oBAAoB,+BAyCtB"}
1
+ {"version":3,"file":"MobileNavHeader.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/MobileNav/MobileNavHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,8DAA8D;AAC9D,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,iCAAiC;AACjC,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAC9C,8CAA8C;AAC9C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAoBvC,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,oGAAoG;IACpG,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,QAAQ,GACT,EAAE,oBAAoB,+BAiDtB"}
@@ -1,8 +1,8 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { FairmintLogo } from "../../FairmintLogo/FairmintLogo.js";
3
3
  import { ActionIcon } from "../../primitives/ActionIcon/ActionIcon.js";
4
- import { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.js";
5
4
  import { colors } from "../../../theme/colors.js";
5
+ import { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.js";
6
6
  const MOBILE_NAV_HEADER_HEIGHT = 60;
7
7
  const MOBILE_NAV_LOGO_WIDTH = 120;
8
8
  const MOBILE_NAV_LOGO_HEIGHT = 28;
@@ -42,6 +42,23 @@ function MobileNavHeader({
42
42
  style: { display: "block" }
43
43
  }
44
44
  ) : null);
45
+ const menu = onMenuClick != null ? /* @__PURE__ */ jsx(
46
+ ActionIcon,
47
+ {
48
+ type: "button",
49
+ "aria-label": "Open navigation",
50
+ color: colors.neutral,
51
+ variant: "subtle",
52
+ w: MOBILE_NAV_MENU_SIZE,
53
+ h: MOBILE_NAV_MENU_SIZE,
54
+ onClick: onMenuClick,
55
+ children: menuIcon ?? defaultMenuIcon
56
+ }
57
+ ) : null;
58
+ const trailing = rightSection != null || menu != null ? /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", gap: MOBILE_NAV_BRAND_GAP, align: "center", children: [
59
+ rightSection,
60
+ menu
61
+ ] }) : null;
45
62
  return /* @__PURE__ */ jsxs(
46
63
  Group,
47
64
  {
@@ -54,23 +71,8 @@ function MobileNavHeader({
54
71
  w: "100%",
55
72
  bg: "body",
56
73
  children: [
57
- /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", gap: MOBILE_NAV_BRAND_GAP, align: "center", children: [
58
- mark,
59
- onMenuClick ? /* @__PURE__ */ jsx(
60
- ActionIcon,
61
- {
62
- type: "button",
63
- "aria-label": "Open navigation",
64
- color: colors.neutral,
65
- variant: "subtle",
66
- w: MOBILE_NAV_MENU_SIZE,
67
- h: MOBILE_NAV_MENU_SIZE,
68
- onClick: onMenuClick,
69
- children: menuIcon ?? defaultMenuIcon
70
- }
71
- ) : null
72
- ] }),
73
- rightSection
74
+ mark,
75
+ trailing
74
76
  ]
75
77
  }
76
78
  );
@@ -1 +1 @@
1
- {"version":3,"file":"MobileNavHeader.js","sources":["../../../../src/components/layout/MobileNav/MobileNavHeader.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { colors } from \"../../../theme\";\nimport { FairmintLogo } from \"../../FairmintLogo/FairmintLogo\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Group } from \"../../primitives/layout\";\n\n/** Product-shell mobile header height (Studio + Investor). */\nexport const MOBILE_NAV_HEADER_HEIGHT = 60;\n/** Fairmint wordmark width in the mobile header and sheet. */\nexport const MOBILE_NAV_LOGO_WIDTH = 120;\n/** Fairmint wordmark height in the mobile header and sheet. */\nexport const MOBILE_NAV_LOGO_HEIGHT = 28;\n/** Space between the wordmark and the menu control. */\nexport const MOBILE_NAV_BRAND_GAP = 16;\n/** Header horizontal padding. */\nexport const MOBILE_NAV_HEADER_PADDING_X = 16;\n/** Menu control hit target (Mantine `lg`). */\nexport const MOBILE_NAV_MENU_SIZE = 36;\n\nconst defaultMenuIcon = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6h16\" />\n <path d=\"M4 12h16\" />\n <path d=\"M4 18h16\" />\n </svg>\n);\n\nexport interface MobileNavHeaderProps {\n /**\n * Override the default Fairmint wordmark (white-label portals).\n * When omitted and `onMenuClick` is set, the canonical 120×28 Fairmint logo is used.\n */\n logo?: ReactNode;\n /** Opens the MobileNav sheet. Omit on desktop where SideNav owns destinations. */\n onMenuClick?: () => void;\n /** Right-aligned header actions (notifications, Ask AI). */\n rightSection?: ReactNode;\n /** Menu glyph. Defaults to an outlined hamburger so the component never imports an icon library. */\n menuIcon?: ReactNode;\n}\n\n/**\n * Canonical mobile page header for Fairmint product shells.\n *\n * Logo then hamburger at a 16px gap, optional actions on the far right.\n * Pixel metrics are fixed so Studio and Investor cannot drift via theme tokens\n * or extra wrappers.\n */\nexport function MobileNavHeader({\n logo,\n onMenuClick,\n rightSection,\n menuIcon,\n}: MobileNavHeaderProps) {\n const mark =\n logo ??\n (onMenuClick ? (\n <FairmintLogo\n width={MOBILE_NAV_LOGO_WIDTH}\n height={MOBILE_NAV_LOGO_HEIGHT}\n style={{ display: \"block\" }}\n />\n ) : null);\n\n return (\n <Group\n h={MOBILE_NAV_HEADER_HEIGHT}\n px={MOBILE_NAV_HEADER_PADDING_X}\n justify=\"space-between\"\n wrap=\"nowrap\"\n align=\"center\"\n gap={0}\n w=\"100%\"\n bg=\"body\"\n >\n <Group wrap=\"nowrap\" gap={MOBILE_NAV_BRAND_GAP} align=\"center\">\n {mark}\n {onMenuClick ? (\n <ActionIcon\n type=\"button\"\n aria-label=\"Open navigation\"\n color={colors.neutral}\n variant=\"subtle\"\n w={MOBILE_NAV_MENU_SIZE}\n h={MOBILE_NAV_MENU_SIZE}\n onClick={onMenuClick}\n >\n {menuIcon ?? defaultMenuIcon}\n </ActionIcon>\n ) : null}\n </Group>\n {rightSection}\n </Group>\n );\n}\n"],"names":[],"mappings":";;;;;AAOO,MAAM,2BAA2B;AAEjC,MAAM,wBAAwB;AAE9B,MAAM,yBAAyB;AAE/B,MAAM,uBAAuB;AAE7B,MAAM,8BAA8B;AAEpC,MAAM,uBAAuB;AAEpC,MAAM,kBACJ;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IAEZ,UAAA;AAAA,MAAA,oBAAC,QAAA,EAAK,GAAE,UAAA,CAAU;AAAA,MAClB,oBAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,MACnB,oBAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,IAAA;AAAA,EAAA;AACrB;AAwBK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,OACJ,SACC,cACC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,EAAE,SAAS,QAAA;AAAA,IAAQ;AAAA,EAAA,IAE1B;AAEN,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,GAAG;AAAA,MACH,IAAI;AAAA,MACJ,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,KAAK;AAAA,MACL,GAAE;AAAA,MACF,IAAG;AAAA,MAEH,UAAA;AAAA,QAAA,qBAAC,SAAM,MAAK,UAAS,KAAK,sBAAsB,OAAM,UACnD,UAAA;AAAA,UAAA;AAAA,UACA,cACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,OAAO,OAAO;AAAA,cACd,SAAQ;AAAA,cACR,GAAG;AAAA,cACH,GAAG;AAAA,cACH,SAAS;AAAA,cAER,UAAA,YAAY;AAAA,YAAA;AAAA,UAAA,IAEb;AAAA,QAAA,GACN;AAAA,QACC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"MobileNavHeader.js","sources":["../../../../src/components/layout/MobileNav/MobileNavHeader.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { colors } from \"../../../theme\";\nimport { FairmintLogo } from \"../../FairmintLogo/FairmintLogo\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Group } from \"../../primitives/layout\";\n\n/** Product-shell mobile header height (Studio + Investor). */\nexport const MOBILE_NAV_HEADER_HEIGHT = 60;\n/** Fairmint wordmark width in the mobile header and sheet. */\nexport const MOBILE_NAV_LOGO_WIDTH = 120;\n/** Fairmint wordmark height in the mobile header and sheet. */\nexport const MOBILE_NAV_LOGO_HEIGHT = 28;\n/** Space between trailing actions and the menu control. */\nexport const MOBILE_NAV_BRAND_GAP = 16;\n/** Header horizontal padding. */\nexport const MOBILE_NAV_HEADER_PADDING_X = 16;\n/** Menu control hit target (Mantine `lg`). */\nexport const MOBILE_NAV_MENU_SIZE = 36;\n\nconst defaultMenuIcon = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M4 6h16\" />\n <path d=\"M4 12h16\" />\n <path d=\"M4 18h16\" />\n </svg>\n);\n\nexport interface MobileNavHeaderProps {\n /**\n * Override the default Fairmint wordmark (white-label portals).\n * When omitted and `onMenuClick` is set, the canonical 120×28 Fairmint logo is used.\n */\n logo?: ReactNode;\n /** Opens the MobileNav sheet. Omit on desktop where SideNav owns destinations. */\n onMenuClick?: () => void;\n /** Trailing header actions before the hamburger (notifications, Ask AI). */\n rightSection?: ReactNode;\n /** Menu glyph. Defaults to an outlined hamburger so the component never imports an icon library. */\n menuIcon?: ReactNode;\n}\n\n/**\n * Canonical mobile page header for Fairmint product shells.\n *\n * Logo on the left; optional `rightSection` then hamburger on the far right.\n * Pixel metrics are fixed so Studio and Investor cannot drift via theme tokens\n * or extra wrappers. Sign out belongs in AccountSheet / the user menu — not here.\n */\nexport function MobileNavHeader({\n logo,\n onMenuClick,\n rightSection,\n menuIcon,\n}: MobileNavHeaderProps) {\n const mark =\n logo ??\n (onMenuClick ? (\n <FairmintLogo\n width={MOBILE_NAV_LOGO_WIDTH}\n height={MOBILE_NAV_LOGO_HEIGHT}\n style={{ display: \"block\" }}\n />\n ) : null);\n\n const menu =\n onMenuClick != null ? (\n <ActionIcon\n type=\"button\"\n aria-label=\"Open navigation\"\n color={colors.neutral}\n variant=\"subtle\"\n w={MOBILE_NAV_MENU_SIZE}\n h={MOBILE_NAV_MENU_SIZE}\n onClick={onMenuClick}\n >\n {menuIcon ?? defaultMenuIcon}\n </ActionIcon>\n ) : null;\n\n const trailing =\n rightSection != null || menu != null ? (\n <Group wrap=\"nowrap\" gap={MOBILE_NAV_BRAND_GAP} align=\"center\">\n {rightSection}\n {menu}\n </Group>\n ) : null;\n\n return (\n <Group\n h={MOBILE_NAV_HEADER_HEIGHT}\n px={MOBILE_NAV_HEADER_PADDING_X}\n justify=\"space-between\"\n wrap=\"nowrap\"\n align=\"center\"\n gap={0}\n w=\"100%\"\n bg=\"body\"\n >\n {mark}\n {trailing}\n </Group>\n );\n}\n"],"names":[],"mappings":";;;;;AAOO,MAAM,2BAA2B;AAEjC,MAAM,wBAAwB;AAE9B,MAAM,yBAAyB;AAE/B,MAAM,uBAAuB;AAE7B,MAAM,8BAA8B;AAEpC,MAAM,uBAAuB;AAEpC,MAAM,kBACJ;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IAEZ,UAAA;AAAA,MAAA,oBAAC,QAAA,EAAK,GAAE,UAAA,CAAU;AAAA,MAClB,oBAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,MACnB,oBAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,IAAA;AAAA,EAAA;AACrB;AAwBK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,OACJ,SACC,cACC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,EAAE,SAAS,QAAA;AAAA,IAAQ;AAAA,EAAA,IAE1B;AAEN,QAAM,OACJ,eAAe,OACb;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAW;AAAA,MACX,OAAO,OAAO;AAAA,MACd,SAAQ;AAAA,MACR,GAAG;AAAA,MACH,GAAG;AAAA,MACH,SAAS;AAAA,MAER,UAAA,YAAY;AAAA,IAAA;AAAA,EAAA,IAEb;AAEN,QAAM,WACJ,gBAAgB,QAAQ,QAAQ,OAC9B,qBAAC,OAAA,EAAM,MAAK,UAAS,KAAK,sBAAsB,OAAM,UACnD,UAAA;AAAA,IAAA;AAAA,IACA;AAAA,EAAA,EAAA,CACH,IACE;AAEN,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,GAAG;AAAA,MACH,IAAI;AAAA,MACJ,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACN,KAAK;AAAA,MACL,GAAE;AAAA,MACF,IAAG;AAAA,MAEF,UAAA;AAAA,QAAA;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fairmint/ui",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "type": "module",
5
5
  "description": "Fairmint design system and UI component library",
6
6
  "license": "UNLICENSED",