The dropdown surface a Select renders, with an optional header, categories rail, detail pane and footer.

SelectPalette is what a Select renders inside its dropdown. You don't render it yourself — you turn its regions on through Select props. With none of them set, a Select's dropdown looks exactly as it always has.

Regions

  • HeaderpaletteTitle, paletteHeaderMetaComponent, withPaletteCloseButton, and the Select's own isSearchable
  • Categories railpaletteCategories
  • Results — always present; the Select's options list, unchanged
  • Detail panepaletteDetailComponent
  • FooterpaletteFooterComponent
Loading editor

Importing

import { Select } from '@customerio/pluma-components/react';
// The parts, for assembling a custom region:
import {
	SelectPaletteCategory,
	SelectPaletteFooter,
	SelectPaletteHeaderSearch,
	SelectPaletteHeaderTitle,
} from '@customerio/pluma-components/react';

Categories

The rail reports which category is active — it never filters. Pass options that already match, as the example above does.

When you narrow options, set value to the selected option object rather than its value string, so the trigger keeps showing the selection while it's filtered out.

Control the selection with activePaletteCategoryId and onPaletteCategoryChange, or leave it uncontrolled with defaultActivePaletteCategoryId. An uncontrolled category resets when the dropdown closes.

Groups and tooltips

A rail entry is either a category or a group of them: a label, its own categories, and optionally isCollapsible and defaultIsCollapsed. Categories take tooltip and tooltipPlacement — the place to say why one is disabled.

Loading editor

Detail pane

paletteDetailComponent renders inside the pane, so it needs no styling of its own. It receives the highlighted option, that option's index in the full list, whether the option is also selected, the active category and the current search value.

See the first example for a detail pane in place.

Icons

Alongside icon, every icon slot — a category row, an option, a group header — takes iconSrc for an image URL, plus iconColor and iconSize. iconSrc wins if both are set, and iconColor applies only to icon.

Select's iconComponent takes icon names only, so an option using iconSrc renders through the built-in image slot instead.

Loading editor

Replacing a region

paletteHeaderComponent, paletteCategoriesComponent, paletteDetailComponent and paletteFooterComponent each replace their region's contents and render inside it, so they need no styling of their own.

A custom header receives a searchComponent — render it where the search input belongs.

Loading editor

paletteFooterComponent receives the result count, the active category and the search value, and renders bare — wrap your content in SelectPaletteFooter for the standard band. It takes precedence over the Select's footerComponent.

From a button

SelectPrimitive takes the same palette props and lets you supply your own trigger.

Loading editor

API

Which category is active. Use this for controlled mode.

The currently highlighted value.

How long the enter/exit animation runs for.

The component to render between the header and the body, at full width.

The component to render above the header, outside its padding.

The categories to render in the rail. Absent or empty means no rail, unless categoriesComponent is set.

The component to render as the rail's contents, replacing the default category rows. Receives SelectPaletteCategoriesContext. Renders inside the rail, so it doesn't need to reproduce its padding, background or border.

Which category starts out active, for uncontrolled mode.

The component to render in the detail pane, which follows the highlighted option. Absent means no detail pane. Receives SelectPaletteDetailContext. Renders inside the pane, so it doesn't need to reproduce its padding or border.

The detail pane's context, resolved by whoever owns the option list. The palette fills in activeCategoryId itself, since it owns that state.

The component to render as the footer. Receives SelectPaletteFooterContext. Renders bare — wrap your content in SelectPaletteFooter for the standard footer styling.

The component to render as the header's contents, replacing the title, meta slot, close button and search input. Receives SelectPaletteHeaderContext, which carries a ready-to-render search input. Renders inside the header's padding, so it doesn't need to reproduce it.

The component to render in the header's trailing slot, after the title and before the close button. For content like a total item count.

Whether more options are currently being loaded.

Whether to render the search input in the header.

Called when a category is selected. The palette does not filter the results list — supply options that already match.

Called when the close button is pressed.

Callback for when the end of the results list is reached and more options should be loaded.

An array of options to render in the results list.

The id of the palette's owner, used to build the ids the search input's aria-controls points at.

How many results the list holds, reported to the footer component. Supplied by the owner of the option list, which can count them accurately even when a search is filtering the list.

Accessible label for the search input.

Placeholder text for the search input.

The current search value.

The currently selected value.

Whether onLoadMore should be called when the end of the list is reached.

A title to render in the header, before the meta slot and the close button. Absent means no title — a searchable palette with no title renders just the search input, which is the plain searchable Select.

Whether to render a close button in the header.