@reactzero/combo
v0.1.1
Published
Headless, accessible React combo & select. Attach a dropdown to anything. Zero dependencies, ARIA 1.2 compliant, <7 kB.
Maintainers
Readme
@reactzero/combo
Headless, accessible React combo & select. Zero dependencies. ARIA 1.2 compliant, < 7 kB gzipped.
Features
- Zero dependencies — Only peer depends on React 18+. No runtime surprises.
- Headless architecture — Full control over markup and styling via the
useCombohook - Pre-built component — Drop-in
<Combo>with render props for quick setup - ARIA 1.2 compliant — Keyboard navigation, screen reader support, live region announcements
- Tiny bundle — Hook: 4.8 kB, Full: 6.7 kB, CSS: 2.5 kB (all brotli)
- CSS custom properties — 40+ design tokens, built-in dark and high-contrast themes
- TypeScript first — Full generic type inference on all APIs
- Multiple variants — Combobox, select dropdown, grouped items, custom triggers
AI Reference
Feed the AI reference file to your AI coding assistant for complete API docs, examples, and patterns:
- View on GitHub: ai-reference.md
- Direct fetch URL (for AI tools):
https://raw.githubusercontent.com/motiondesignlv/ReactZero-Combo/main/ai-reference.md
Installation
npm install @reactzero/comboQuick Start — Headless Hook
import { useCombo } from "@reactzero/combo/hook";
function MyCombo() {
const items = ["Apple", "Banana", "Cherry", "Date"];
const {
isOpen,
filteredItems,
highlightedIndex,
selectedItem,
getLabelProps,
getInputProps,
getToggleButtonProps,
getClearButtonProps,
getMenuProps,
getItemProps,
getChevronProps,
hasSelection,
icons,
chevronIcon,
} = useCombo({ items });
return (
<div>
<label {...getLabelProps()}>Fruit</label>
<div>
<input {...getInputProps({ placeholder: "Search..." })} />
{hasSelection && (
<button {...getClearButtonProps()}>{icons.clear}</button>
)}
<button {...getToggleButtonProps()}>
<span {...getChevronProps()}>{chevronIcon}</span>
</button>
</div>
<ul {...getMenuProps()} style={{ display: isOpen ? "block" : "none" }}>
{isOpen &&
filteredItems.map((item, index) => (
<li
key={index}
{...getItemProps({ item, index })}
style={{
background:
highlightedIndex === index ? "#dbeafe" : "transparent",
fontWeight: selectedItem === item ? 600 : 400,
}}
>
{String(item)}
</li>
))}
</ul>
</div>
);
}Quick Start — Pre-built Component
import { Combo } from "@reactzero/combo";
import "@reactzero/combo/styles";
function App() {
return (
<Combo
items={["Apple", "Banana", "Cherry", "Date"]}
label="Favorite Fruit"
placeholder="Search fruits..."
onSelectedItemChange={(item) => console.log("Selected:", item)}
renderItem={({ item, isHighlighted, isSelected }) => (
<div style={{ fontWeight: isSelected ? 600 : 400 }}>{String(item)}</div>
)}
/>
);
}Import Paths
| Path | Size | Description |
| ------------------------------------------- | ------ | ---------------------------------- |
| @reactzero/combo/hook | 4.8 kB | Hook + types only |
| @reactzero/combo | 6.7 kB | Hook + Combo + Portal + LiveRegion |
| @reactzero/combo/styles | 2.5 kB | Base structural CSS |
| @reactzero/combo/themes/dark.css | — | Dark theme tokens |
| @reactzero/combo/themes/high-contrast.css | — | High-contrast theme tokens |
Variants
Select Dropdown
<Combo
items={["United States", "Canada", "Mexico"]}
variant="select"
placeholder="Choose a country..."
/>Grouped Items
<Combo
groups={[
{ label: "Fruits", items: ["Apple", "Banana"] },
{ label: "Vegetables", items: ["Carrot", "Broccoli"] },
]}
items={[]}
placeholder="Search..."
/>Custom Trigger
<Combo
items={items}
renderTrigger={({
getInputProps,
getToggleButtonProps,
isOpen,
chevronIcon,
}) => (
<div className="my-trigger">
<input {...getInputProps()} />
<button {...getToggleButtonProps()}>{chevronIcon}</button>
</div>
)}
/>Theming
Override CSS custom properties to customize the appearance:
.my-combobox {
--rzero-combo-input-border: 2px solid #6366f1;
--rzero-combo-input-focus-ring: 0 0 0 3px rgba(99, 102, 241, 0.3);
--rzero-combo-item-highlighted-bg: #e0e7ff;
--rzero-combo-item-selected-color: #4f46e5;
}Or use built-in themes:
<Combo items={items} theme="dark" />Documentation
- Live Demo & Examples
- AI Reference — feed to your AI coding assistant for complete API docs
