select-combobox-virtualized
Country
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
import * as Ariakit from "@ariakit/react";import { SelectRenderer } from "@ariakit/react-core/select/select-renderer";import type { SelectRendererItem } from "@ariakit/react-core/select/select-renderer";import deburr from "lodash-es/deburr.js";import groupBy from "lodash-es/groupBy.js";import kebabCase from "lodash-es/kebabCase.js";import { matchSorter } from "match-sorter";import { startTransition, useEffect, useState } from "react";import { countries } from "./countries.ts";import "./style.css";function getItem(country: string) {return {id: `item-${kebabCase(country)}`,value: country,children: country,};}function groupItems(items: ReturnType<typeof getItem>[]) {const groups = groupBy(items, (item) => deburr(item.value?.at(0)));return Object.entries(groups).map(([label, items]) => {return {id: `group-${label.toLowerCase()}`,label,itemSize: 40,paddingStart: 44,items,} satisfies SelectRendererItem;});}const defaultItems = countries.map(getItem);export default function Example() {const [searchValue, setSearchValue] = useState("");const [matches, setMatches] = useState(() => groupItems(defaultItems));});});useEffect(() => {startTransition(() => {const items = matchSorter(countries, searchValue);setMatches(groupItems(items.map(getItem)));});}, [searchValue]);return (<><div className="wrapper"><span className="select-value">{selectValue || "Select a country"}</span>className="popover"><div className="combobox-wrapper">placeholder="Search..."className="combobox"/></div>{({ label, ...item }) => (<SelectRendererkey={item.id}className="group"overscan={1}{...item}{label}{props.children})}>{({ value, ...item }) => (key={item.id}{...item}className="select-item"><span className="select-item-value">{value}</span>)}</SelectRenderer>)}</SelectRenderer></div></>);}import * as Ariakit from "@ariakit/react";import { SelectRenderer } from "@ariakit/react-core/select/select-renderer";import type { SelectRendererItem } from "@ariakit/react-core/select/select-renderer";import deburr from "lodash-es/deburr.js";import groupBy from "lodash-es/groupBy.js";import kebabCase from "lodash-es/kebabCase.js";import { matchSorter } from "match-sorter";import { startTransition, useEffect, useState } from "react";import { countries } from "./countries.ts";import "./style.css";function getItem(country: string) {return {id: `item-${kebabCase(country)}`,value: country,children: country,};}function groupItems(items: ReturnType<typeof getItem>[]) {const groups = groupBy(items, (item) => deburr(item.value?.at(0)));return Object.entries(groups).map(([label, items]) => {return {id: `group-${label.toLowerCase()}`,label,itemSize: 40,paddingStart: 44,items,} satisfies SelectRendererItem;});}const defaultItems = countries.map(getItem);export default function Example() {const [searchValue, setSearchValue] = useState("");const [matches, setMatches] = useState(() => groupItems(defaultItems));});});useEffect(() => {startTransition(() => {const items = matchSorter(countries, searchValue);setMatches(groupItems(items.map(getItem)));});}, [searchValue]);return (<><div className="wrapper"><span className="select-value">{selectValue || "Select a country"}</span>className="popover"><div className="combobox-wrapper">placeholder="Search..."className="combobox"/></div>{({ label, ...item }) => (<SelectRendererkey={item.id}className="group"overscan={1}{...item}{label}{props.children})}>{({ value, ...item }) => (key={item.id}{...item}className="select-item"><span className="select-item-value">{value}</span>)}</SelectRenderer>)}</SelectRenderer></div></>);}