import * as class_variance_authority_types from 'class-variance-authority/types'; import { VariantProps } from 'class-variance-authority'; import React__default from 'react'; /** * One entry in a `SideNav` tree. * * - `href` and no `links` — a leaf link. * - `links` — a branch. At the top level it renders as a section heading over an * always-visible list; at any deeper level it renders as a collapsible * trigger. A branch's own `href` is IGNORED (the row is a disclosure button, * not a link) — a dev-only warning flags it, mirroring the nswds-app * `SidebarNavigation` behaviour where branch rows only toggled. * - Neither — a dead entry; rendered as inert text and flagged with a dev-only * warning rather than a decoy `` with no destination. */ type SideNavItem = { /** Visible text for the link, section heading, or branch trigger. */ title: string; href?: string; links?: SideNavItem[]; }; /** * Row treatment shared by leaf links and branch triggers — the nswds-app * left-rail language: each row carries its own left border sitting exactly on * the list's rail (the `-ml-px` on the `
  • `), so hover and the current-page * state recolour the rail segment beside the row. * * Departures from the source, both deliberate: * - The idle border is `border-transparent` rather than the bare `border-l` * default: idle rows show the rail through their transparent border, so the * idle rail colour is defined once (on the list) instead of twice. * - The current row adds `dark:text-white`. The source left dark active text * to fall through to the idle `dark:text-grey-400`, which on the * `dark:bg-white/20` highlight is both low-contrast and cascade-order * dependent; bold white ink clears WCAG 2.2 AA (1.4.3) on that overlay. * * The source's hover font-weight change (`hover:font-semibold`) is NOT ported. * DESIGN.md's Derived State Rule has hover, active and focus deriving from one * ink via `color-mix`, and a weight jump is not a derivation: it changes glyph * advance widths, so a label sitting near its wrap point can reflow — and grow * the row — under the pointer. The remaining hover treatment (rail colour, * 10% ink tint, ink shift) already distinguishes the state without moving * anything. The persistent `current` row keeps `font-bold`: that is a resting * state, so it never reflows on interaction. * * Rows are floored at 44px on coarse pointers. DESIGN.md commits the system to * "44px+ touch floors", and the sibling PushMenu enforces it with `min-h-11` — * but the rail's own metrics (`py-1` over a 24px line box from `sm:` up) come * to 32px, so a tablet reader was tapping targets a third under the stated * floor. This clears WCAG 2.2 AA 2.5.8 either way (24px); the floor is the * design system's own promise, held here the same way `Button` holds it, on * pointer type rather than breakpoint so a desktop rail stays dense. * * Focus uses the house visible-focus pattern (outline-current, offset 2), so * the indicator always contrasts with whatever text colour the row currently * has (WCAG 2.2, 2.4.13 Focus Appearance). */ declare const sideNavRowVariants: (props?: ({ current?: boolean | null | undefined; } & class_variance_authority_types.ClassProp) | undefined) => string; type SideNavProps = Omit, 'children'> & { /** * The navigation tree. A top-level item with `links` renders as a section * heading over an always-visible rail; one without renders as a plain rail * link — mirroring nswds-app `Navigation`'s section shape. Deeper items with * `links` render as collapsible branches (nswds-app `SidebarNavigation`). */ sections: SideNavItem[]; /** * The current page's href. The matching leaf gets `aria-current='page'` and * the active rail treatment, and every branch on the path to it starts * expanded — at MOUNT only. Branches are `defaultOpen`, not controlled: a * later `currentHref` change (SPA navigation) re-highlights the leaf but * never re-expands a branch the reader has folded, so the highlight can * land inside a collapsed branch. Branch expansion is seeded from * `currentHref` on mount; pass a `key` (e.g. `key={currentHref}`) to * remount and re-open the path on navigation — the same contract as * PushMenu's level stack. Frameworkless replacement for the source's * `usePathname()` — pass your router's pathname in. */ currentHref?: string; /** * Fired from every leaf link (never from branch triggers). The mobile-drawer * close hook, as in the source's `onLinkClick`. */ onNavigate?: React__default.MouseEventHandler; /** * Heading level for section titles. Defaults to `2` — correct when the nav * sits at the top level of the document outline. Step it down when the page * nests the nav under another heading (WCAG 1.3.1). `1` is excluded: a * section-nav heading is never the page's own title. Same contract as * `FooterNavColumn`. */ headingLevel?: 2 | 3 | 4 | 5 | 6; /** * Shown when `sections` is empty. Defaults to "No navigation items * available."; pass `null` to render nothing. * * An empty tree is a legitimate runtime state (unpublished content, * permission-filtered menus, a failed fetch), not a data mistake — without a * message the rail renders an empty `
      ` and the reader is left with a * blank column and no explanation. */ emptyMessage?: React__default.ReactNode; ref?: React__default.Ref; }; /** * Left-rail section navigation — the consolidation of nswds-app's flat * `Navigation` and recursive `SidebarNavigation` into one tree-shaped * component. Renders a `