combobox-group

PreviousNext
Docs
reuicomponent

Preview

Loading previewโ€ฆ
registry/default/components/combobox/group.tsx
'use client';

import * as React from 'react';
import { cn } from '@/registry/default/lib/utils';
import { Button, ButtonArrow } from '@/registry/default/ui/button';
import {
  Command,
  CommandCheck,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/registry/default/ui/command';
import { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover';
import { ScrollArea, ScrollBar } from '@/registry/default/ui/scroll-area';

const groupedCountries = [
  {
    group: 'Europe',
    countries: [
      { value: 'netherlands', label: 'Netherlands', flag: '๐Ÿ‡ณ๐Ÿ‡ฑ' },
      { value: 'united_kingdom', label: 'United Kingdom', flag: '๐Ÿ‡ฌ๐Ÿ‡ง' },
      { value: 'france', label: 'France', flag: '๐Ÿ‡ซ๐Ÿ‡ท' },
      { value: 'germany', label: 'Germany', flag: '๐Ÿ‡ฉ๐Ÿ‡ช' },
      { value: 'italy', label: 'Italy', flag: '๐Ÿ‡ฎ๐Ÿ‡น' },
    ],
  },
  {
    group: 'Asia',
    countries: [
      { value: 'japan', label: 'Japan', flag: '๐Ÿ‡ฏ๐Ÿ‡ต' },
      { value: 'china', label: 'China', flag: '๐Ÿ‡จ๐Ÿ‡ณ' },
      { value: 'india', label: 'India', flag: '๐Ÿ‡ฎ๐Ÿ‡ณ' },
      { value: 'uae', label: 'United Arab Emirates', flag: '๐Ÿ‡ฆ๐Ÿ‡ช' },
      { value: 'south_korea', label: 'South Korea', flag: '๐Ÿ‡ฐ๐Ÿ‡ท' },
    ],
  },
  {
    group: 'Africa',
    countries: [
      { value: 'south_africa', label: 'South Africa', flag: '๐Ÿ‡ฟ๐Ÿ‡ฆ' },
      { value: 'nigeria', label: 'Nigeria', flag: '๐Ÿ‡ณ๐Ÿ‡ฌ' },
      { value: 'egypt', label: 'Egypt', flag: '๐Ÿ‡ช๐Ÿ‡ฌ' },
      { value: 'kenya', label: 'Kenya', flag: '๐Ÿ‡ฐ๐Ÿ‡ช' },
      { value: 'morocco', label: 'Morocco', flag: '๐Ÿ‡ฒ๐Ÿ‡ฆ' },
    ],
  },
  {
    group: 'North America',
    countries: [
      { value: 'united_states', label: 'United States', flag: '๐Ÿ‡บ๐Ÿ‡ธ' },
      { value: 'canada', label: 'Canada', flag: '๐Ÿ‡จ๐Ÿ‡ฆ' },
      { value: 'mexico', label: 'Mexico', flag: '๐Ÿ‡ฒ๐Ÿ‡ฝ' },
      { value: 'cuba', label: 'Cuba', flag: '๐Ÿ‡จ๐Ÿ‡บ' },
      { value: 'jamaica', label: 'Jamaica', flag: '๐Ÿ‡ฏ๐Ÿ‡ฒ' },
    ],
  },
  {
    group: 'South America',
    countries: [
      { value: 'brazil', label: 'Brazil', flag: '๐Ÿ‡ง๐Ÿ‡ท' },
      { value: 'argentina', label: 'Argentina', flag: '๐Ÿ‡ฆ๐Ÿ‡ท' },
      { value: 'colombia', label: 'Colombia', flag: '๐Ÿ‡จ๐Ÿ‡ด' },
      { value: 'chile', label: 'Chile', flag: '๐Ÿ‡จ๐Ÿ‡ฑ' },
      { value: 'peru', label: 'Peru', flag: '๐Ÿ‡ต๐Ÿ‡ช' },
    ],
  },
  {
    group: 'Oceania',
    countries: [
      { value: 'australia', label: 'Australia', flag: '๐Ÿ‡ฆ๐Ÿ‡บ' },
      { value: 'new_zealand', label: 'New Zealand', flag: '๐Ÿ‡ณ๐Ÿ‡ฟ' },
      { value: 'fiji', label: 'Fiji', flag: '๐Ÿ‡ซ๐Ÿ‡ฏ' },
      { value: 'papua_new_guinea', label: 'Papua New Guinea', flag: '๐Ÿ‡ต๐Ÿ‡ฌ' },
      { value: 'samoa', label: 'Samoa', flag: '๐Ÿ‡ผ๐Ÿ‡ธ' },
    ],
  },
];

export default function ComboboxDemo() {
  const [open, setOpen] = React.useState(false);
  const [value, setValue] = React.useState('');

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          mode="input"
          placeholder={!value}
          aria-expanded={open}
          className="w-[250px]"
        >
          <span className={cn('truncate')}>
            {value
              ? groupedCountries.flatMap((group) => group.countries).find((country) => country.value === value)?.label
              : 'Select country...'}
          </span>
          <ButtonArrow />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-(--radix-popper-anchor-width) p-0">
        <Command>
          <CommandInput placeholder="Search country..." />
          <CommandList>
            <ScrollArea viewportClassName="max-h-[300px]">
              <CommandEmpty>No country found.</CommandEmpty>
              {groupedCountries.map((group) => (
                <CommandGroup key={group.group} heading={group.group}>
                  {group.countries.map((country) => (
                    <CommandItem
                      key={country.value}
                      value={country.value}
                      onSelect={(currentValue) => {
                        setValue(currentValue === value ? '' : currentValue);
                        setOpen(false);
                      }}
                    >
                      <span className="flex items-center gap-2">
                        <span className="text-sm">{country.flag}</span>
                        {country.label}
                      </span>
                      {value === country.value && <CommandCheck />}
                    </CommandItem>
                  ))}
                </CommandGroup>
              ))}
              <ScrollBar />
            </ScrollArea>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}

Installation

npx shadcn@latest add @reui/combobox-group

Usage

import { ComboboxGroup } from "@/components/combobox-group"
<ComboboxGroup />