registry:component

Multi Select

v1.0.0ga

Tag-based multi-select primitive built on command patterns.

Registry Endpoint
Open JSON

https://registry.aavya.com/r/ui-multi-select.json

npx shadcn@latest add https://registry.aavya.com/r/ui-multi-select.json

Live Preview
Usage Snippet
import MultiSelect from '@/components/ui/multi-select.tsx'

export default function Example() {
  return (
    <div className="p-6">
      <MultiSelect />
    </div>
  )
}
Source Preview
'use client'

import * as React from 'react'

import { useEffect } from 'react'

import { Command as CommandPrimitive, useCommandState } from 'cmdk'
import { XIcon } from 'lucide-react'

import { Command, CommandGroup, CommandItem, CommandList } from '@/components/ui/command'
import { cn } from '@/lib/utils'

export interface Option {
  value: string
  label: string
  disable?: boolean

  /** fixed option that can't be removed. */
  fixed?: boolean

  /** Group the options by providing key. */
  [key: string]: string | boolean | undefined
}
interface GroupOption {
  [key: string]: Option[]
}

interface MultipleSelectorProps {
  value?: Option[]
  defaultOptions?: Option[]

  /** manually controlled options */
  options?: Option[]
  placeholder?: string

  /** Loading component. */
  loadingIndicator?: React.ReactNode

  /** Empty component. */
  emptyIndicator?: React.ReactNode

  /** Debounce time for async search. Only work with `onSearch`. */
  delay?: number

  /**
   * Only work with `onSearch` prop. Trigger search when `onFocus`.
   * For example, when user click on the input, it will trigger the search to get initial options.
   **/
  triggerSearchOnFocus?: boolean

  /** async search */
  onSearch?: (value: string) => Promise<Option[]>

  /**
   * sync search. This search will not showing loadingIndicator.
   * The rest props are the same as async search.
   * i.e.: cre