import { type TextMatchRange } from "@charcuterie/logic"; import type { ReactNode } from "react"; /** * One thing the palette can open or run. * * A folder's members are items like any other: the caller flattens * them into `items`, and puts the folder's name in `description` so a * hit inside a folder still says where it lives. */ export type CommandPaletteItem = { /** Secondary text after the title — a folder, a section, a host. Matched, never highlighted. */ description?: string; /** Shown under this heading when the palette lists matches. Items without one share `ungroupedLabel`. */ group?: string; /** Opens as a link: a real ``, routed through `RouterLinkProvider`. */ href?: string; /** The app's own glyph or image. Decorative; the title is the name. */ icon?: ReactNode; /** Matched as extra words and never shown: an old name, an abbreviation, a product the app hosts. */ keywords?: readonly string[]; /** Unique within the list it is in. */ key: string; /** Trailing text at the end of the row: a kind ("Bookmark") or a status. */ hint?: ReactNode; /** Runs on choice. With an `href` too, it runs as well as the navigation — a place to record a visit. */ onSelect?: () => void; /** Passed to the link. `_blank` opens a new tab on a plain Enter or click. */ target?: string; /** What is typed for and highlighted. */ title: string; /** Breaks a tie inside a match tier, higher first: an open count, say. */ weight?: number; }; /** A heading and its items, shown before anything is typed. */ export type CommandPaletteGroup = { items: readonly CommandPaletteItem[]; key: string; label: string; }; /** * A short prefix that sends the rest of the query to one target: * `{ prefix: "au", label: "Auction Site", getHref: (query) => … }` * turns `au lego` into one row that searches that site. */ export type CommandPalettePrefix = { /** The link the row opens, given what follows the prefix. */ getHref?: (query: string) => string; icon?: ReactNode; /** The target's name, in the row's title and in the footer. */ label: string; /** Runs instead of, or as well as, the link. */ onSelect?: (query: string) => void; /** What is typed before the space: `au`. Matched without case. */ prefix: string; }; export type CommandPaletteRow = { item: CommandPaletteItem; /** Where the query matched the title; empty for a suggestion. */ titleRanges: readonly TextMatchRange[]; }; export type CommandPaletteSection = { key: string; label: string; rows: readonly CommandPaletteRow[]; }; export type CommandPaletteSectionsOptions = { formatPrefixTitle: (label: string, query: string) => string; getFallbackItem?: (query: string) => CommandPaletteItem | null | undefined; items: readonly CommandPaletteItem[]; maxResultsPerGroup?: number; prefixGroupLabel: string; prefixes: readonly CommandPalettePrefix[]; query: string; suggestions: readonly CommandPaletteGroup[]; ungroupedLabel: string; }; /** * What the palette lists for a query, as headed sections in order. * * Three cases, decided in this order: * * 1. **A prefix command** (`au lego`) lists one row, for that target. * 2. **Nothing typed** lists the caller's `suggestions` — the shape * the palette exists for: something to choose the moment it opens. * 3. **Anything else** lists the word-prefix matches from `items`, * under each item's `group`, and then the caller's fallback row. * * Matched groups are ordered by their best member, so the first row * — the one Enter opens — is always the best match, whichever group * it belongs to. */ export declare const buildCommandPaletteSections: ({ formatPrefixTitle, getFallbackItem, items, maxResultsPerGroup, prefixGroupLabel, prefixes, query, suggestions, ungroupedLabel, }: CommandPaletteSectionsOptions) => CommandPaletteSection[]; //# sourceMappingURL=commandPaletteSections.d.ts.map