import React__default from 'react';
/** A single searchable destination. `keywords` extend matching beyond the title. */
type SiteSearchItem = {
title: string;
href: string;
keywords?: string[];
};
/** A titled section of results, rendered with a muted group heading. */
type SiteSearchGroup = {
title: string;
items: SiteSearchItem[];
};
type SiteSearchProps = {
/** The searchable site map, as titled groups of items. */
groups: SiteSearchGroup[];
/**
* Called with the chosen item on click or Enter, after the palette closes.
* Navigation is the APP's job — call your router here (e.g. next/navigation's
* `router.push(item.href)`). The design system ships no framework code, so it
* never navigates itself; this mirrors the DS-wide framework-free rule
* (see `Link` / `LinkProvider`).
*/
onSelect: (item: SiteSearchItem) => void;
/** Whether the palette is open. Use when controlled. */
open?: boolean;
/** Called whenever the palette asks to open or close. */
onOpenChange?: (open: boolean) => void;
/** Whether the palette is initially open (uncontrolled). */
defaultOpen?: boolean;
/**
* Wire the global Cmd/Ctrl-K toggle on `document`, with cleanup on unmount.
* Defaults to true. Only one shortcut-enabled SiteSearch should be mounted
* per page, or each press toggles all of them.
*/
shortcut?: boolean;
/**
* Accessible name for the palette, applied as `aria-label` to the dialog
* panel, the search input and the default trigger. Defaults to
* `'Search site'`. Mirrors ExpandableSearch's `label` prop — localise it
* rather than hardcoding English into consumers' pages.
*/
label?: string;
/** Placeholder for the search input. */
placeholder?: string;
/** Message shown when no items match the query. */
emptyMessage?: string;
/**
* The element that opens the palette. Defaults to a ghost icon `Button`
* named by `label`. Pass an element to replace it — it is composed via Base
* UI's `render` prop, so it inherits the trigger behaviour and ARIA — or
* `null` to render no trigger at all (open via `open` or the shortcut).
* A custom trigger owns its own accessible name — `label` is applied as
* `aria-label` to the default icon button only, since overriding a visible
* label that way fails WCAG 2.2, 2.5.3 Label in Name.
*
* Conditional triggers must resolve to `null`, not `false`: write
* `cond ? : null`, since `cond && ` yields `false`, which
* Base UI's `render` prop rejects with an invalid-element error. TypeScript
* catches it (`false` is not assignable here); plain-JS consumers see the
* error at render.
*/
trigger?: React__default.ReactElement | null;
/**
* Extra content rendered at the foot of the panel, below the results —
* e.g. shortcut hints or a "browse all" link.
*/
children?: React__default.ReactNode;
/** Extra classes for the centred panel. */
className?: string;
};
/**
* Cmd/Ctrl-K command-palette site search: a centred modal panel with a
* filter-as-you-type input over a grouped list of destinations.
*
* Ported from nswds-app's `MobileSearch`, rebuilt framework-free: the app
* version composed cmdk's `Command*` widgets with next/navigation's router;
* this version composes Base UI's Autocomplete (the combobox/listbox pattern)
* inside Base UI's Dialog, and hands the chosen item to `onSelect` instead of
* navigating. The Autocomplete renders in `inline` mode — its input and list
* sit statically inside the dialog panel with no popup of their own — which is
* Base UI's documented composition for palettes (it avoids any portal /
* focus-trap interplay between the two primitives; the always-`open` inline
* root unmounts with the dialog, so the query and highlight reset on close).
*
* Accessibility contract (inherited, not hand-rolled):
* - Dialog provides the modal behaviour: focus trap, scroll lock, Escape and
* backdrop-press dismissal, and focus restoration to the trigger on close.
* The panel is named via `aria-label` (WCAG 2.2, 4.1.2).
* - Autocomplete provides the combobox pattern: the input is announced as a
* combobox controlling a listbox, arrow keys move `aria-activedescendant`
* highlight while DOM focus stays in the input, Enter activates the
* highlighted item, and the empty state is announced politely.
* - The trigger (default or custom) renders through `Dialog.Trigger`, so it
* carries `aria-haspopup="dialog"` / `aria-expanded` automatically.
* - Result rows are at least 44px tall (2.5.8 Target Size, AAA-sized).
* - Panel and backdrop transitions honour `prefers-reduced-motion` (2.3.3).
*
* Departures from the nswds-app source, beyond the rebuild above:
* - `groups`/`onSelect` replace the app's `NavigationItem[]` + router: the
* data shape is explicit (`title`/`href`/`keywords`) instead of the app's
* nav config, and untitled/unlinked entries can't exist by construction
* (the source filtered them at render time).
* - Filtering matches `title` AND `keywords`, case-insensitively, via the
* Autocomplete `filter` prop. Base UI's `useFilter` helper only matches one
* string per item, so a custom predicate is the documented escape hatch for
* multi-field matching; groups with no matching items are dropped by the
* primitive, headings included.
* - The Cmd/Ctrl-K listener can be disabled (`shortcut={false}`) — required
* for pages that mount more than one instance. It still toggles, per the
* source.
*/
declare function SiteSearch({ groups, onSelect, open: openProp, onOpenChange, defaultOpen, shortcut, label, placeholder, emptyMessage, trigger, children, className, }: SiteSearchProps): React__default.JSX.Element;
export { SiteSearch, type SiteSearchGroup, type SiteSearchItem, type SiteSearchProps };