@iazadur/hierarchical-select
Version:
A modern React component for hierarchical/dependent dropdowns with Ant Design and Shadcn UI support
241 lines (195 loc) • 9.37 kB
Markdown
# Hierarchical Select
<p align="center">
<a href="https://iazadur.github.io/Hierarchical-Select/" target="_blank">
<img src="https://raw.githubusercontent.com/iazadur/Hierarchical-Select/main/public/logo.svg" height="120" alt="Hierarchical Select Logo" />
</a>
</p>
<p align="center">
<a href="https://www.npmjs.com/package/@iazadur/hierarchical-select" target="_blank">
<img src="https://img.shields.io/npm/v/@iazadur/hierarchical-select.svg?style=flat-square" alt="npm version" />
</a>
<a href="https://github.com/iazadur/Hierarchical-Select/blob/main/LICENSE" target="_blank">
<img src="https://img.shields.io/github/license/iazadur/Hierarchical-Select?style=flat-square" alt="license" />
</a>
<a href="https://github.com/iazadur/Hierarchical-Select" target="_blank">
<img src="https://img.shields.io/github/stars/iazadur/Hierarchical-Select?style=flat-square" alt="GitHub stars" />
</a>
<a href="https://iazadur.github.io/Hierarchical-Select/" target="_blank">
<img src="https://img.shields.io/badge/documentation-storybook-7026b9?style=flat-square" alt="documentation" />
</a>
</p>
<p align="center">
A production-ready React component for hierarchical (dependent) dropdowns, designed for both Ant Design and Shadcn UI.
</p>
## 📖 Live Documentation & Demos
Check out our **[interactive component documentation](https://iazadur.github.io/Hierarchical-Select/)** to see live examples and explore all features.
## ✨ Features
- **Hierarchical Dependency**: Support for up to 5 select fields with parent-child relationships
- **Single and Multiple Select**: Configure fields for single or multiple selection
- **Dynamic Loading**: Load options statically or fetch dynamically from APIs
- **Design System Integration**: Seamless integration with both Ant Design and Shadcn UI
- **Fully Customizable**: Customize labels, placeholders, error messages, and styling
- **TypeScript Support**: Fully typed with comprehensive type definitions
- **Accessibility**: WAI-ARIA compliant with keyboard navigation support
- **Performance Optimized**: Memoization, lazy loading, and response caching
## 🚀 Installation
```bash
npm install @iazadur/hierarchical-select
# Peer dependencies
npm install react react-dom
```
### With Ant Design
```bash
npm install antd
```
### With Shadcn UI
```bash
npm install @radix-ui/react-select
```
## 💻 Basic Usage
```jsx
import React from "react";
import HierarchicalSelect from "@iazadur/hierarchical-select";
const App = () => {
const fields = [
{
index: 0,
options: [
{ value: "us", label: "United States" },
{ value: "ca", label: "Canada" },
{ value: "uk", label: "United Kingdom" },
],
placeholder: "Select Country",
label: "Country",
},
{
index: 1,
options: [],
placeholder: "Select Region",
label: "Region",
fetchOptions: async (parentValue) => {
// Fetch regions based on selected country
// Simulated API call with static data
await new Promise((resolve) => setTimeout(resolve, 500));
const regions = {
us: [
{ value: "ca", label: "California" },
{ value: "ny", label: "New York" },
],
ca: [
{ value: "on", label: "Ontario" },
{ value: "qc", label: "Quebec" },
],
uk: [
{ value: "eng", label: "England" },
{ value: "sct", label: "Scotland" },
],
};
return regions[parentValue] || [];
},
},
{
index: 2,
options: [],
placeholder: "Select City",
label: "City",
multiple: true, // Allow multiple selections
fetchOptions: async (parentValue) => {
// Fetch cities based on selected region
await new Promise((resolve) => setTimeout(resolve, 500));
const cities = {
ca: [
{ value: "sf", label: "San Francisco" },
{ value: "la", label: "Los Angeles" },
],
ny: [
{ value: "nyc", label: "New York City" },
{ value: "buf", label: "Buffalo" },
],
// ... more cities
};
return cities[parentValue] || [];
},
},
];
return (
<HierarchicalSelect
fields={fields}
designSystem="shadcn" // or "antd"
onChange={(values) => console.log("Selected:", values)}
onError={(error) => console.error("Error:", error)}
/>
);
};
export default App;
```
## 🎨 Custom Styling
The component supports custom styling to match your application design. You can add custom styles to each field:
```jsx
<HierarchicalSelect
fields={[
{
index: 0,
options: [...],
// Custom styling
className: 'my-custom-field',
customStyle: {
background: '#f8fafc',
padding: '12px',
borderRadius: '8px'
},
// Style just the select element
selectClassName: 'my-custom-select',
selectStyle: { borderWidth: '2px' }
},
// ...more fields
]}
designSystem="shadcn"
/>
```
## 📝 API Reference
### HierarchicalSelect Props
| Property | Type | Default | Description |
| ------------ | --------------------------------------------------------------- | -------- | -------------------------------------- |
| fields | FieldConfig[] | required | Array of field configurations |
| designSystem | 'antd' \| 'shadcn' | 'antd' | The design system to use |
| onChange | (values: (string \| number \| (string \| number)[])[] ) => void | - | Callback when any value changes |
| onError | (error: Error) => void | - | Callback for handling errors |
| className | string | '' | Additional CSS class for the container |
| disabled | boolean | false | Disables all fields |
### FieldConfig Interface
| Property | Type | Default | Description |
| --------------- | ----------------------------------------------------------- | -------------------- | ---------------------------------------- |
| index | number | required | The position of the field (0-based) |
| options | { value: string \| number; label: string }[] | required | Static options for the field |
| multiple | boolean | false | Whether multiple selections are allowed |
| placeholder | string | 'Select an option' | Placeholder text |
| label | string | `Level ${index + 1}` | Label for the field |
| fetchOptions | (parentValue: any) => Promise<OptionType[]> \| OptionType[] | - | Function to fetch dependent options |
| disabled | boolean | false | Disables the specific field |
| errorMessage | string | - | Custom error message |
| className | string | - | Custom CSS class for the field container |
| customStyle | React.CSSProperties | - | Custom styles for the field container |
| selectClassName | string | - | Custom CSS class for the select element |
| selectStyle | React.CSSProperties | - | Custom styles for the select element |
## 👍 Design System Support
### Ant Design
The component integrates seamlessly with Ant Design, using the official `Select` component with proper styling and error states.
### Shadcn UI
For Shadcn UI, we've built a custom implementation based on Radix UI's primitives that follows Shadcn's design principles, with:
- Clean, minimal styling
- Proper focus and hover states
- Accessible keyboard navigation
- Elegant tags for multiple selection
- Error and loading states
## 🧩 Browser Support
- Chrome (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Edge (latest 2 versions)
## 🛠️ Troubleshooting
If you encounter any issues with the component, please check our [GitHub issues](https://github.com/iazadur/Hierarchical-Select/issues) or submit a new one.
## 📚 Documentation
For more examples and detailed documentation, visit our [Storybook site](https://iazadur.github.io/Hierarchical-Select/).
## 📄 License
MIT © [iazadur](https://github.com/iazadur)