custom-headless-dropdown
v1.2.0
Published
Accessible dropdown with ARIA support, keyboard navigation, and removable multi-select tags
Readme
Dropdown Component
Description
The Dropdown component is a customizable, accessible dropdown component with built-in dark mode support and flexible styling options. It supports single and multiple selection, search functionality, custom value input, full keyboard navigation, and ARIA-compliant screen reader support.
Installation
To use the Dropdown component in your project, you can install it via npm (or include it as part of your component library):
npm install custom-headless-dropdown@latestUsage
Here's a simple example of how to use the Dropdown component in your application:
import React, { useState } from "react";
import Dropdown from "custom-headless-dropdown";
const App = () => {
const [value, setValue] = useState("");
const options = [
{ value: "yes", label: "Yes" },
{ value: "no", label: "No" },
{ value: "unsure", label: "Unsure" },
{ value: "na", label: "Not applicable" },
];
const handleChange = (selectedValue) => {
setValue(selectedValue);
};
return (
<div>
<Dropdown
label="Please select a value"
id="example-dropdown"
options={options}
value={value}
onChange={handleChange}
placeholder="Select an option"
allowCustom={true}
multiple={false}
hideSearch={false}
/>
</div>
);
};
export default App;Multi-Select Example
import React, { useState } from "react";
import Dropdown from "custom-headless-dropdown";
const App = () => {
const [values, setValues] = useState([]);
const options = [
{ value: "apple", label: "Apple" },
{ value: "banana", label: "Banana" },
{ value: "cherry", label: "Cherry" },
];
return (
<Dropdown
label="Pick your fruits"
id="fruit-dropdown"
options={options}
value={values}
onChange={setValues}
multiple={true}
placeholder="Select fruits..."
/>
);
};Selected items appear as removable tag chips. Click the X on any tag to remove it.
Example with Hidden Search
Here's an example of a dropdown with the search functionality disabled:
<Dropdown
label="Select a country"
id="country-dropdown"
options={countryOptions}
value={selectedCountry}
onChange={setSelectedCountry}
placeholder="Choose a country"
hideSearch={true}
/>Props
Dropdown Props
| Prop | Type | Default | Description |
| --------------------- | --------------------------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------- |
| label | React.ReactNode | - | Label to assign to the field. |
| id | string | - | Unique identifier for the dropdown. |
| options | Array<{value: string, label: string}> | - | An array of options to display in the dropdown. |
| value | string or Array<string> | - | Variable that holds the selected item(s) from the dropdown |
| onChange | function | - | A callback function that is called to save the dropdown selection |
| onBlur | function | - | Callback function called when dropdown closes (optional) |
| placeholder | string | - | Placeholder for the dropdown (optional) |
| required | boolean | - | Whether the field is required (optional) |
| icon | React.ReactNode | - | Icon to display in the dropdown button (optional) |
| className | string | - | Additional CSS classes for the dropdown button (optional) |
| allowCustom | boolean | false | Whether to allow custom value input (optional) |
| multiple | boolean | false | Whether to accept multi option selection (optional) |
| hideSearch | boolean | false | Whether to hide the search input (optional) |
| disabled | boolean | false | Whether the dropdown is disabled (optional) |
| buttonClass | string | "border-gray-200 bg-white text-black" | Custom styling for the dropdown button |
| dropdownClass | string | "bg-white border-gray-200" | Custom styling for the dropdown menu |
| optionClass | string | "text-black hover:bg-gray-100" | Custom styling for dropdown options |
| selectedOptionClass | string | "text-black hover:bg-gray-100" | Custom styling for selected options |
| tagClass | string | "bg-gray-100 text-black" | Custom styling for multi-select tags |
| searchInputClass | string | "bg-white border-gray-200 text-black placeholder-gray-400" | Custom styling for search input |
| labelClass | string | "font-bold" | Custom styling for the label |
| textColor | string | "text-black" | Custom text color |
| placeholderColor | string | "text-gray-400" | Custom placeholder text color |
| focusRingColor | string | "focus:ring-gray-300 focus:border-gray-300" | Custom focus ring styling |
| checkboxClass | string | "w-5 h-5 rounded" | Custom styling for multi-select checkboxes |
Accessibility
The dropdown is fully accessible and meets WCAG 2.1 AA standards:
Keyboard Navigation
| Key | Action |
| ------------ | --------------------------------------------------- |
| Tab | Move focus to/from the dropdown trigger |
| Enter / Space | Open dropdown or select the focused option |
| Arrow Down | Open dropdown (when closed) or move to next option |
| Arrow Up | Move to previous option |
| Escape | Close dropdown and return focus to trigger |
Screen Reader Support
- Trigger uses
role="combobox"witharia-expandedandaria-haspopup="listbox" - Options list uses
role="listbox"witharia-multiselectablefor multi-select - Each option has
role="option"witharia-selectedstate - Label is connected via
aria-labelledby - Search input has
aria-label="Search options" - Disabled state is communicated via
aria-disabled
Styling
The Dropdown component uses Tailwind CSS 4.1.11 with built-in dark mode support. The component automatically adapts to light and dark themes based on the presence of the dark class on a parent element.
Default Styling
The dropdown comes with sensible defaults that work in both light and dark modes:
- Light Mode: White background with gray borders and dark text
- Dark Mode: Dark background with subtle white borders and light text
Custom Styling
You can override any part of the dropdown's appearance by passing custom Tailwind classes:
<Dropdown
label="Custom Styled Dropdown"
options={options}
value={value}
onChange={setValue}
buttonClass="border-blue-300 bg-blue-50 text-blue-900"
dropdownClass="bg-blue-50 border-blue-300"
optionClass="text-blue-900 hover:bg-blue-100"
selectedOptionClass="bg-blue-200 text-blue-900"
tagClass="bg-blue-200 text-blue-900"
/>Dark Mode Setup
To enable dark mode, add the dark class to a parent element (typically <html> or <body>):
// Toggle dark mode
document.documentElement.classList.toggle("dark");Example CSS Setup
If you haven't set up Tailwind CSS yet, here's a basic example:
- Install Tailwind CSS:
npm install -D tailwindcss@^4.1.11 @tailwindcss/postcss@^4.1.11 postcss- Configure your postcss.config.js:
export default {
plugins: {
"@tailwindcss/postcss": {},
},
};- Include Tailwind in your CSS file:
@import "tailwindcss";Features
The dropdown component includes several advanced features:
- Single/Multiple Selection: Toggle between single and multiple selection modes
- Removable Tags: Multi-select values display as tag chips with remove buttons
- Search Functionality: Built-in search to filter options
- Custom Values: Allow users to add custom values not in the options list
- Keyboard Navigation: Full keyboard support (Arrow keys, Enter, Escape, Tab)
- Screen Reader Support: ARIA roles, states, and properties for full accessibility
- Disabled State: Disable the dropdown with the
disabledprop - Responsive Design: Works well on all screen sizes
- Dark Mode Support: Automatic theme switching
- Custom Styling: Complete control over appearance through props
