Skip to content
lab components / Actions and controls

Base picker

Provides structure for creating a picker, using the Popover.

This is a Lab component!

That means it doesn't satisfy our definition of done and may be changed or even deleted. For an exact status, please reach out to the Fancy team through the dev_fancy or ux_fancy channels.

import { BasePicker } from "@siteimprove/fancylab";
import { BaseTablePicker } from "@siteimprove/fancylab";

#Examples

The base picker is built upon the Popover component and shares the same props.

It serves as the base component for other picker components, such as the Site picker and the Period picker.

The main difference between the base picker and the popover component is that the base picker provides picker-related styling.

Theme: agentic-ai-2025
return ( <BasePicker buttonContent="Click me" popoverContent={(id, firstFocusableRef, { setIsOpen }) => ( <div id={id} ref={firstFocusableRef}> <EmptyState type="reassure" heading="Nothing available" /> <Popover.Footer> <ActionBar primary={{ children: "Confirm", onClick: () => { setIsOpen(false); }, }} cancel={{ children: "Cancel", onClick: () => { setIsOpen(false); }, }} /> </Popover.Footer> </div> )} /> );

#BaseTablePicker usage

The base table picker is a variant of the base picker, intended for selecting items from a table.

It is built upon the base picker, but it does not inherit the same props. The props of the base table picker are tailored specifically for the table implementation.

Theme: agentic-ai-2025
const [items, setItems] = React.useState(defaultItems); const [selectedItem, setSelectedItem] = React.useState<{ id: number; name: string }>(); const [query, setQuery] = React.useState(""); const [paged, setPaged] = React.useState(1); const take = 5; const filteredItems = items.filter((item) => item.name.toLowerCase().includes(query.toLowerCase()) ); const pagedItems = filteredItems.slice(0, take * paged); return ( <BaseTablePicker itemsCount={pagedItems.length} totalItems={filteredItems.length} selectedItem={selectedItem} selectedItemStringify={(site) => site.name} search={{ query, onSearch: setQuery }} onLoadMore={() => setPaged((prev) => prev + 1)} take={take} loading={false} buttonIcon={<IconFunnel />} texts={{ buttonContentNoItemSelected: "Select an item", showingXOfYItems: (showing, total) => `Showing ${showing} of ${total} items`, }} toolbarActions={ <Button variant="primary" href="https://fancy.siteimprove.com/"> Edit items </Button> } contentItems={(firstFocusableRef, close, tableClassName, selectButtonClassName) => ( <Table items={pagedItems} columns={[ { header: [{ content: "Favorite", property: "favorite" }], render: (item) => ( <Starred isStarred={item.favorite} onChange={(starred) => setItems((prev) => prev.map((i) => (i.id === item.id ? { ...i, favorite: starred } : i)) ) } aria-label={`Mark ${item.name} as favorite`} /> ), }, { header: [{ content: "Name", property: "name" }], render: (item, cellPosition) => ( <Button variant="borderless" className={selectButtonClassName} onClick={() => { setSelectedItem(item); close(); }} ref={cellPosition.rowNum === 0 ? firstFocusableRef : undefined} > {item.name} </Button> ), }, ]} loading={false} sort={{ property: "name", direction: "asc" }} setSort={() => {}} highlightRow={(item) => item.name === selectedItem?.name} className={tableClassName} /> )} /> );

#Properties

#BasePicker

Theme: agentic-ai-2025
PropertyDescriptionDefinedValue
popoverContentRequired
functioncontent for popover element over dropdown
buttonIconOptional
element
buttonContentOptional
elementText and other content for dropdown menu
buttonPropsOptional
objectProps to affect the styling of the dropdown button
labelledByPopoverOptional
booleanIf set to true, popover label may be set to the id, if isOpen is also true
placementOptional
"auto" | "auto-end" | "auto-start" | "bottom" | "bottom-end" | "bottom-start" | "left" | "left-end" | "left-start" | "right" | "right-end" | "right-start" | "top" | "top-end" | "top-start"Preferred placement for the popover
allowedAutoPlacementsOptional
literal-union[]Allowed placements for the popover when using an "auto" value for the "placement" prop
strategyOptional
"absolute" | "fixed"Position popover using fixed or absolute
buttonRefOptional
objectreference sent to basePopover element
startOpenOptional
booleanIf set to true the dropdown will open automatically
invalidOptional
booleanIs the dropdown in an invalid state
containerClassNameOptional
stringClassname for container of both dropdown and popover
hideChevronOptional
booleanIf set to true, chevron icon will be hidden
noMinWidthOptional
booleanIf true, the default minimum width won't be set
noMaxWidthOptional
booleanIf true, the default maximum width won't be set
disabledOptional
booleanMakes the component non-interactive
aria-labelOptional
stringDescribe what happens if the button is clicked (for icon only buttons)
aria-haspopupOptional
"dialog" | "listbox" | "menu"What type of content is expanded. Should only be set if the content has the corrosponding 'role'
onCloseOptional
functionCallback for onClose events
onClearOptional
functionCallback for clearing the dropdown (displays clear button when provided)
tooltipOptional
| string | number | elementTooltip text
tooltipPlacementOptional
"bottom" | "bottom-end" | "bottom-start" | "left" | "left-end" | "left-start" | "right" | "right-end" | "right-start" | "top" | "top-end" | "top-start"Tooltip placement
updateKeysOptional
unknown[]Key to control updates to the placement of the popover. Provide a different value when an update is desired
data-componentOptional
stringName of the component. Should only be set by components since it needs to stable. Used to track component usage
data-observe-keyOptional
stringUnique string, used by external script e.g. for event tracking
classNameOptional
stringCustom className that's applied to the outermost element (only intended for special cases)
styleOptional
objectStyle object to apply custom inline styles (only intended for special cases)
tabIndexOptional
numberTab index of the outermost HTML element of the component
onKeyDownOptional
functionCallback for onKeyDown event
onMouseDownOptional
functionCallback for onMouseDown event
onMouseEnterOptional
functionCallback for onMouseEnter event
onMouseLeaveOptional
functionCallback for onMouseLeave event
onFocusOptional
functionCallback for onFocus event
onBlurOptional
functionCallback for onBlur event

#BaseTablePicker

Theme: agentic-ai-2025
PropertyDescriptionDefinedValue
contentItemsRequired
functionFunction to render the content and items of the picker.
itemsCountRequired
numberItems count of the current loaded items.
totalItemsRequired
numberTotal items count.
selectedItemStringifyRequired
functionFunction to stringify the selected item in the button.
textsRequired
objectTranslations.
objectSearch options to filter picker items.
onLoadMoreOptional
functionLoad more callback.
buttonIconOptional
elementButton icon.
selectedItemOptional
unknownSelected item.
toolbarActionsOptional
elementToolbar actions.
loadingOptional
booleanIf the picker is loading.
takeOptional
numberAmount of items to take on Load more.
buttonPropsOptional
objectProps to affect the styling of the dropdown button
data-observe-keyOptional
stringUnique string, used by external script e.g. for event tracking

#Guidelines

#Best practices

  • ...
  • ...

#Do not use when

  • ...
  • ...

#Accessibility

  • ...
  • ...

Explore detailed guidelines for this component: Accessibility Specifications

#Writing

  • ...
  • ...