# components/palette/PalettePanel (zidane-ui)

Import: `import { … } from 'zidane-ui'`. Source: [ui/src/components/palette/PalettePanel.tsx](https://github.com/Tahul/zidane/blob/main/ui/src/components/palette/PalettePanel.tsx).

## Components

### `PalettePanel`

Component.

Renders the Cmd+K surface: the query as the header, the ranked sections, a footer that says
what Enter does, and an optional notice. It is controlled: the caller owns the query, the
cursor and what running a row means. The input takes focus on mount and handles the arrows,
Home, End, Enter, Escape and Backspace on an empty nested query. It brings no scrim or focus
trap, so mount it in a layer such as `Overlay`.

```ts
function PalettePanel<T extends PaletteEntry>(props: PalettePanelProps<T>): Element
```

**Type parameters**

- `T` (`extends PaletteEntry`)

**Parameters**

- `props` (`PalettePanelProps<T>`): [`PalettePanelProps`](https://zidane.si/docs/reference/ui-components-palette-palette-panel.md#PalettePanelProps).

**Returns** `Element`

**Props**

- `cursor` (`number`): Flat index of the marked row, across sections.
- `groups` (`readonly PaletteSection<T>[]`): The ranked sections to show.
- `inputRef?` (`Ref<HTMLInputElement>`): Ref to the query input.
- `loading?` (`boolean`): The rows are not known yet.
- `nested?` (`boolean`): A nested level: a back button, and Backspace on an empty query calls it.
- `notice?` (`PaletteNotice | null`): A status line shown under the footer.
- `onBack?` (`() => void`): Called by the back button, and by Backspace on an empty query, to leave a nested level.
- `onClose` (`() => void`): Escape in the input.
- `onCursorChange` (`(index: number) => void`): Called with a new flat row index when the arrows, Home, End or the pointer move the cursor.
- `onQueryChange` (`(query: string) => void`): Called with the new text when the query changes. The cursor resets to the first row.
- `onRun` (`(row: PaletteRowData<T>) => void`): Called with the marked row on Enter, or with a clicked row.
- `onScopeClear?` (`() => void`): Backspace on an empty query at the root while scoped: search every section again.
- `onScopeNext?` (`() => void`): Shift+Tab at the root: scope the search to the next section (after the last, back to every section).
- `placeholder?` (`string`): Defaults to the labels' `paletteFilter`.
- `query` (`string`): The query in the input.
- `renderIcon?` (`(row: PaletteRowData<T>) => ReactNode`): Draws the default row's icon. A dot shows when omitted.
- `renderKeys?` (`PaletteKeys`, default `defaultPaletteKeys`): Draws a keybinding spec as keycaps.
- `renderRow?` (`(props: PaletteRowProps<T>) => ReactNode`): Draws a row. Return `undefined` for the default row. Keep it stable, since rows are memoized.
- `running?` (`boolean`): A row is running: a spinner in the header.
- `scope?` (`string`): The section the root search is scoped to, as a chip before the query.
- `settled?` (`boolean`): False while the rows are still for an earlier query: Enter waits for them. Default true.
- `title?` (`string`): The level's name, as a chip before the query.
- `verb?` (`(row: PaletteRowData<T>, nested: boolean) => string | undefined`): The footer's word for Enter on the marked row; `undefined` falls back to `paletteVerb`.

Source: [ui/src/components/palette/PalettePanel.tsx:142](https://github.com/Tahul/zidane/blob/main/ui/src/components/palette/PalettePanel.tsx#L142)

## Functions

### `paletteVerb`

Function.

What Enter does to a row by its kind; an app names its own kinds first (`verb`).

```ts
function paletteVerb(
  row: PaletteRowData<PaletteEntry> | undefined,
  nested: boolean,
  labels: { addDiagnosticToChat: (message: string) => string; address: string; addressPlaceholder: string; addToChat: string; back: string; cancel: string; close: string; closeTab: (name: string) => string; code: string; completionSuggestions: string; confirm: string; continue: string; copied: string; copy: string; copyCode: string; copyImage: string; copyImageBase64: string; copyImageDataUrl: string; current: string; diagnosticsCheckedBy: (source: string) => string; diagnosticsChecking: string; diagnosticsNone: string; editorConflict: string; editorConflictDetail: string; editorEmpty: string; editorOverwrite: string; editorReadFailed: (message: string) => string; editorReload: string; errorFailed: (region: string) => string; errorStack: string; errorTryAgain: string; filePath: (path: string) => string; fileReadOnly: (path: string) => string; fileTree: string; fileUnsaved: string; fileUnsavedTitle: (path: string) => string; findClose: string; findCloseHint: string; findInFile: string; findMatchCase: string; findNext: string; findNextHint: string; findNoResults: string; findPrevious: string; findPreviousHint: string; findReferences: string; goToDefinition: string; goToStep: (step: string) => string; loading: string; modalBack: string; modalFailed: string; next: string; noReferences: string; of: (index: number, count: number) => string; openFiles: string; openInNewTab: string; paletteBack: string; paletteBackHint: string; paletteChoose: string; paletteEmpty: string; paletteFilter: string; paletteLabel: string; paletteLoading: string; paletteNoMatch: (query: string) => string; paletteOpen: string; paletteRun: string; paletteScopeHint: string; paletteTurnOff: string; paletteTurnOn: string; previous: string; reload: string; rename: string; retry: string; screenBack: (screen: string) => string; screenBackKey: string; signInCopyCode: string; signInDone: (account?: string) => string; signInEnterCode: (host: string) => string; signInFailed: string; signInInBrowser: (service: string) => string; signInNotOpened: string; signInOpenPage: string; signInPaste: string; signInStarting: string; signInSubmit: string; skip: string; stepOf: (index: number, count: number) => string; steps: string; terminal: string; terminalExited: (code: number) => string; terminalLoadFailed: (message: string) => string; working: string; wrapLines: string; zoomFit: string; zoomPercent: (percent: number) => string },
): string
```

**Parameters**

- `row` (`PaletteRowData<PaletteEntry> | undefined`): The marked row. When `undefined`, the run label is used.
- `nested` (`boolean`): Whether the palette is at a nested picker level, where a `toggle` row is chosen
  instead of switched.
- `labels` (`{ addDiagnosticToChat: (message: string) => string; address: string; addressPlaceholder: string; addToChat: string; back: string; cancel: string; close: string; closeTab: (name: string) => string; code: string; completionSuggestions: string; confirm: string; continue: string; copied: string; copy: string; copyCode: string; copyImage: string; copyImageBase64: string; copyImageDataUrl: string; current: string; diagnosticsCheckedBy: (source: string) => string; diagnosticsChecking: string; diagnosticsNone: string; editorConflict: string; editorConflictDetail: string; editorEmpty: string; editorOverwrite: string; editorReadFailed: (message: string) => string; editorReload: string; errorFailed: (region: string) => string; errorStack: string; errorTryAgain: string; filePath: (path: string) => string; fileReadOnly: (path: string) => string; fileTree: string; fileUnsaved: string; fileUnsavedTitle: (path: string) => string; findClose: string; findCloseHint: string; findInFile: string; findMatchCase: string; findNext: string; findNextHint: string; findNoResults: string; findPrevious: string; findPreviousHint: string; findReferences: string; goToDefinition: string; goToStep: (step: string) => string; loading: string; modalBack: string; modalFailed: string; next: string; noReferences: string; of: (index: number, count: number) => string; openFiles: string; openInNewTab: string; paletteBack: string; paletteBackHint: string; paletteChoose: string; paletteEmpty: string; paletteFilter: string; paletteLabel: string; paletteLoading: string; paletteNoMatch: (query: string) => string; paletteOpen: string; paletteRun: string; paletteScopeHint: string; paletteTurnOff: string; paletteTurnOn: string; previous: string; reload: string; rename: string; retry: string; screenBack: (screen: string) => string; screenBackKey: string; signInCopyCode: string; signInDone: (account?: string) => string; signInEnterCode: (host: string) => string; signInFailed: string; signInInBrowser: (service: string) => string; signInNotOpened: string; signInOpenPage: string; signInPaste: string; signInStarting: string; signInSubmit: string; skip: string; stepOf: (index: number, count: number) => string; steps: string; terminal: string; terminalExited: (code: number) => string; terminalLoadFailed: (message: string) => string; working: string; wrapLines: string; zoomFit: string; zoomPercent: (percent: number) => string }`): The label set to take the verb from.

**Returns** `string`: The word for what Enter does: choose, turn on, turn off, open or run.

Source: [ui/src/components/palette/PalettePanel.tsx:65](https://github.com/Tahul/zidane/blob/main/ui/src/components/palette/PalettePanel.tsx#L65)

## Interfaces

### `PaletteNotice`

Interface.

A line of status text under the palette's footer.

```ts
interface PaletteNotice
```

**Properties**

- `text` (`string`): The message.
- `tone?` (`'error' | 'warn' | 'info'`, default `'info'`): Colour of the message: muted for `info`, warning for `warn`, danger for `error`.

Source: [ui/src/components/palette/PalettePanel.tsx:46](https://github.com/Tahul/zidane/blob/main/ui/src/components/palette/PalettePanel.tsx#L46)

## Types

### `PalettePanelProps`

Type.

Props of [`PalettePanel`](https://zidane.si/docs/reference/ui-components-palette-palette-panel.md#PalettePanel): the controlled palette state and callbacks, plus the attributes of
the panel's `div`.

```ts
type PalettePanelProps<T extends PaletteEntry = PaletteEntry> = PanelElementProps & { cursor: number; groups: readonly PaletteSection<T>[]; inputRef?: Ref<HTMLInputElement>; loading?: boolean; nested?: boolean; notice?: PaletteNotice | null; onBack?: () => void; onClose: () => void; onCursorChange: (index: number) => void; onQueryChange: (query: string) => void; onRun: (row: PaletteRowData<T>) => void; onScopeClear?: () => void; onScopeNext?: () => void; placeholder?: string; query: string; renderIcon?: (row: PaletteRowData<T>) => ReactNode; renderKeys?: PaletteKeys; renderRow?: (props: PaletteRowProps<T>) => ReactNode; running?: boolean; scope?: string; settled?: boolean; title?: string; verb?: (row: PaletteRowData<T>, nested: boolean) => string | undefined }
```

**Type parameters**

- `T` (`extends PaletteEntry`, default `PaletteEntry`)

Source: [ui/src/components/palette/PalettePanel.tsx:81](https://github.com/Tahul/zidane/blob/main/ui/src/components/palette/PalettePanel.tsx#L81)
