An open API service indexing awesome lists of open source software.

https://github.com/rudrodip/asyncr

Async Select component built with React & ShadCN UI
https://github.com/rudrodip/asyncr

Last synced: 11 days ago
JSON representation

Async Select component built with React & ShadCN UI

Awesome Lists containing this project

README

        

# Async Select Component

A modern, accessible, and customizable async select component for React applications. Built with TypeScript and shadcn/ui components.

![Async Select](./public/og.png)

## Installation

The Async Select Component is built through the composition of `` and the `` components from [shadcn/ui](https://ui.shadcn.com/docs).

See installation instructions for the [Popover](https://ui.shadcn.com/docs/components/popover#installation) and the [Command](https://ui.shadcn.com/docs/components/command#installation) components.

## Basic Usage

```tsx
import { AsyncSelect } from "@/components/async-select";

function MyComponent() {
const [value, setValue] = useState("");

return (

fetcher={fetchData}
renderOption={(item) =>

{item.name}
}
getOptionValue={(item) => item.id}
getDisplayValue={(item) => item.name}
label="Select"
value={value}
onChange={setValue}
/>
);
}
```

## Props

### Required Props

| Prop | Type | Description |
|------|------|-------------|
| `fetcher` | `(query?: string) => Promise` | Async function to fetch options |
| `renderOption` | `(option: T) => React.ReactNode` | Function to render each option in the dropdown |
| `getOptionValue` | `(option: T) => string` | Function to get unique value from option |
| `getDisplayValue` | `(option: T) => React.ReactNode` | Function to render selected value |
| `value` | `string` | Currently selected value |
| `onChange` | `(value: string) => void` | Callback when selection changes |
| `label` | `string` | Label for the select field |

### Optional Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `preload` | `boolean` | `false` | Enable preloading all options |
| `filterFn` | `(option: T, query: string) => boolean` | - | Custom filter function for preload mode |
| `notFound` | `React.ReactNode` | - | Custom not found message/component |
| `loadingSkeleton` | `React.ReactNode` | - | Custom loading state component |
| `placeholder` | `string` | "Select..." | Placeholder text |
| `disabled` | `boolean` | `false` | Disable the select |
| `width` | `string \| number` | "200px" | Custom width |
| `className` | `string` | - | Custom class for popover |
| `triggerClassName` | `string` | - | Custom class for trigger button |
| `noResultsMessage` | `string` | - | Custom no results message |
| `clearable` | `boolean` | `true` | Allow clearing selection |

## Examples

### Async Mode

```tsx

fetcher={searchUsers}
renderOption={(user) => (




{user.name}

{user.role}



)}
getOptionValue={(user) => user.id}
getDisplayValue={(user) => (



{user.name}

{user.role}



)}
notFound={
No users found
}
label="User"
placeholder="Search users..."
value={selectedUser}
onChange={setSelectedUser}
width="375px"
/>
```

### Preload Mode

```tsx

fetcher={searchAllUsers}
preload
filterFn={(user, query) => user.name.toLowerCase().includes(query.toLowerCase())}
renderOption={(user) => (




{user.name}

{user.role}



)}
getOptionValue={(user) => user.id}
getDisplayValue={(user) => user.name}
label="User"
value={selectedUser}
onChange={setSelectedUser}
/>
```

## TypeScript Interface

```tsx
interface AsyncSelectProps {
fetcher: (query?: string) => Promise;
preload?: boolean;
filterFn?: (option: T, query: string) => boolean;
renderOption: (option: T) => React.ReactNode;
getOptionValue: (option: T) => string;
getDisplayValue: (option: T) => React.ReactNode;
notFound?: React.ReactNode;
loadingSkeleton?: React.ReactNode;
value: string;
onChange: (value: string) => void;
label: string;
placeholder?: string;
disabled?: boolean;
width?: string | number;
className?: string;
triggerClassName?: string;
noResultsMessage?: string;
clearable?: boolean;
}
```