Introduction
Accordion
Badge
Button
Card
Checkbox
Counter
Dialog
Dropdown
Input
Select
Switch
Tabs
Toast
Tooltip
Controlled Input
Field Arrays
Submit
Validation

Dropdown

A select-like dropdown menu for choosing from a list of options.

Apple
Banana
Cherry
Grape
1<Dropdown><DropdownTrigger>...</DropdownTrigger><DropdownContent>...</DropdownContent></Dropdown>

#Installation

1bunx barefoot add dropdown

#Usage

1import { createSignal } from '@barefootjs/dom'2import {3  Dropdown,4  DropdownTrigger,5  DropdownContent,6  DropdownItem,7  DropdownLabel,8} from '@/components/ui/dropdown'910export default function Page() {11  const [open, setOpen] = createSignal(false)12  const [value, setValue] = createSignal('')1314  const options = [15    { value: 'apple', label: 'Apple' },16    { value: 'banana', label: 'Banana' },17    { value: 'cherry', label: 'Cherry' },18  ]1920  const selectedLabel = () => {21    const selected = options.find(opt => opt.value === value())22    return selected ? selected.label : ''23  }2425  const handleSelect = (optionValue: string) => {26    setValue(optionValue)27    setOpen(false)28  }2930  return (31    <Dropdown>32      <DropdownTrigger open={open()} onClick={() => setOpen(!open())}>33        {value() ? selectedLabel() : <DropdownLabel>Select...</DropdownLabel>}34      </DropdownTrigger>35      <DropdownContent open={open()} onClose={() => setOpen(false)}>36        {options.map(option => (37          <DropdownItem38            value={option.value}39            selected={value() === option.value}40            onClick={() => handleSelect(option.value)}41          >42            {option.label}43          </DropdownItem>44        ))}45      </DropdownContent>46    </Dropdown>47  )48}

#Features

  • Props-based state - Parent controls open/selected state with signals
  • ESC key to close - Press Escape to close the dropdown
  • Click to select - Click an item to select it
  • Accessibility - role="combobox", role="listbox", role="option", aria-expanded, aria-selected
  • Visual feedback - Selected item shows checkmark

#Examples

#Basic Dropdown

Apple
Banana
Cherry
Grape
1const [open, setOpen] = createSignal(false)2const [value, setValue] = createSignal('')34const options = [5  { value: 'apple', label: 'Apple' },6  { value: 'banana', label: 'Banana' },7  { value: 'cherry', label: 'Cherry' },8  { value: 'grape', label: 'Grape' },9]1011<Dropdown>12  <DropdownTrigger open={open()} onClick={() => setOpen(!open())}>13    {value() ? selectedLabel() : <DropdownLabel>Select a fruit</DropdownLabel>}14  </DropdownTrigger>15  <DropdownContent open={open()} onClose={() => setOpen(false)}>16    {options.map(option => (17      <DropdownItem18        value={option.value}19        selected={value() === option.value}20        onClick={() => handleSelect(option.value)}21      >22        {option.label}23      </DropdownItem>24    ))}25  </DropdownContent>26</Dropdown>

#With Default Value

Small
Medium
Large
Extra Large
1const [open, setOpen] = createSignal(false)2const [value, setValue] = createSignal('medium') // Default value34const options = [5  { value: 'small', label: 'Small' },6  { value: 'medium', label: 'Medium' },7  { value: 'large', label: 'Large' },8  { value: 'xlarge', label: 'Extra Large' },9]1011<Dropdown>12  <DropdownTrigger open={open()} onClick={() => setOpen(!open())}>13    {selectedLabel()}14  </DropdownTrigger>15  <DropdownContent open={open()} onClose={() => setOpen(false)}>16    {options.map(option => (17      <DropdownItem18        value={option.value}19        selected={value() === option.value}20        onClick={() => handleSelect(option.value)}21      >22        {option.label}23      </DropdownItem>24    ))}25  </DropdownContent>26</Dropdown>

#Disabled

Option 1
1<Dropdown>2  <DropdownTrigger open={open()} onClick={() => setOpen(!open())} disabled>3    <DropdownLabel>Disabled</DropdownLabel>4  </DropdownTrigger>5  <DropdownContent open={open()} onClose={() => setOpen(false)}>6    <DropdownItem value="option1" onClick={() => {}}>7      Option 18    </DropdownItem>9  </DropdownContent>10</Dropdown>

#With CSS Transform

Dropdown inside a scaled container:

Option 1
Option 2
Option 3

Dropdown inside a rotated container:

Option 1
Option 2
Option 3

Dropdown inside a translated container:

Option 1
Option 2
Option 3
1// Dropdown works correctly inside CSS transformed containers2<div class="transform scale-100 translate-x-0">3  <Dropdown>4    <DropdownTrigger open={open()} onClick={() => setOpen(!open())}>5      {selectedLabel() || <DropdownLabel>Select option</DropdownLabel>}6    </DropdownTrigger>7    <DropdownContent open={open()} onClose={() => setOpen(false)}>8      <DropdownItem value="option1">Option 1</DropdownItem>9      <DropdownItem value="option2">Option 2</DropdownItem>10    </DropdownContent>11  </Dropdown>12</div>

#Accessibility

  • Keyboard Navigation - Arrow Up/Down to navigate, Home/End to jump, Enter/Space to select
  • Focus Return - Focus returns to trigger after selection
  • ESC to Close - Press Escape to close the dropdown
  • ARIA - role="combobox" on trigger, role="listbox" on content, role="option" on items
  • State Attributes - aria-expanded, aria-haspopup, aria-selected, aria-disabled

#API Reference

DropdownTrigger

PropTypeDefaultDescription
openbooleanfalseWhether the dropdown is open.
disabledbooleanfalseWhether the trigger is disabled.
onClick() => void-Event handler called when the trigger is clicked.

DropdownContent

PropTypeDefaultDescription
openbooleanfalseWhether the dropdown content is visible.
onClose() => void-Event handler called when the dropdown should close (ESC key).

DropdownItem

PropTypeDefaultDescription
valuestring-The value of the item.
selectedbooleanfalseWhether the item is selected.
disabledbooleanfalseWhether the item is disabled.
onClick() => void-Event handler called when the item is clicked.

DropdownLabel

PropTypeDefaultDescription
childrenChild-The placeholder text to display.