Components
Loading preview...
Here is Autocomplete component
@prebuiltui
npx shadcn@latest add https://21st.dev/r/prebuiltui/autocompleteimport * as React from 'react';
import { Autocomplete } from '@base-ui-components/react/autocomplete';
import { matchSorter } from 'match-sorter';
export default function ExampleFuzzyMatchingAutocomplete() {
return (
<Autocomplete.Root
items={fuzzyItems}
filter={fuzzyFilter}
itemToStringValue={(item) => item.title}
>
<label className="flex flex-col gap-1 text-sm leading-5 font-medium text-gray-900">
Fuzzy search documentation
<Autocomplete.Input
placeholder="e.g. React"
className="bg-[canvas] h-10 w-[16rem] md:w-[20rem] font-normal rounded-md border border-gray-200 pl-3.5 text-base text-gray-900 focus:outline focus:outline-2 focus:-outline-offset-1 focus:outline-blue-800"
/>
</label>
<Autocomplete.Portal>
<Autocomplete.Positioner className="outline-none" sideOffset={4}>
<Autocomplete.Popup className="w-[var(--anchor-width)] max-h-[min(var(--available-height),28rem)] max-w-[var(--available-width)] overflow-y-auto scroll-pt-2 scroll-pb-2 overscroll-contain rounded-md bg-[canvas] py-2 text-gray-900 shadow-lg shadow-gray-200 outline-1 outline-gray-200 dark:shadow-none dark:-outline-offset-1 dark:outline-gray-300">
<Autocomplete.Empty className="px-4 py-2 text-[0.925rem] leading-4 text-gray-600 empty:m-0 empty:p-0">
No results found for "{<Autocomplete.Value />}"
</Autocomplete.Empty>
<Autocomplete.List className="flex flex-col">
{(item: FuzzyItem) => (
<Autocomplete.Item
key={item.title}
value={item}
className="flex cursor-default py-2 pr-8 pl-4 text-base leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-2 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded data-[highlighted]:before:bg-gray-200"
>
<Autocomplete.Value>
{(value) => (
<div className="flex w-full flex-col gap-1">
<div className="flex items-center justify-between gap-3">
<div className="flex-1 font-medium leading-5">
{highlightText(item.title, value)}
</div>
</div>
<div className="text-sm leading-5 text-gray-600">
{highlightText(item.description, value)}
</div>
</div>
)}
</Autocomplete.Value>
</Autocomplete.Item>
)}
</Autocomplete.List>
</Autocomplete.Popup>
</Autocomplete.Positioner>
</Autocomplete.Portal>
</Autocomplete.Root>
);
}
function highlightText(text: string, query: string): React.ReactNode {
const trimmed = query.trim();
if (!trimmed) {
return text;
}
const limited = trimmed.slice(0, 100);
const escaped = limited.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(`(${escaped})`, 'gi');
return text.split(regex).map((part, idx) =>
regex.test(part) ? (
<mark key={idx} className="text-blue-800 bg-transparent font-bold">
{part}
</mark>
) : (
part
),
);
}
function fuzzyFilter(item: FuzzyItem, query: string): boolean {
if (!query) {
return true;
}
const results = matchSorter([item], query, {
keys: [
'title',
'description',
'category',
{ key: 'title', threshold: matchSorter.rankings.CONTAINS },
{ key: 'description', threshold: matchSorter.rankings.WORD_STARTS_WITH },
],
});
return results.length > 0;
}
interface FuzzyItem {
title: string;
description: string;
category: string;
}
const fuzzyItems: FuzzyItem[] = [
{
title: 'React Hooks Guide',
description: 'Learn how to use React Hooks like useState, useEffect, and custom hooks',
category: 'React',
},
{
title: 'JavaScript Array Methods',
description: 'Master array methods like map, filter, reduce, and forEach in JavaScript',
category: 'JavaScript',
},
{
title: 'CSS Flexbox Layout',
description: 'Complete guide to CSS Flexbox for responsive web design',
category: 'CSS',
},
{
title: 'TypeScript Interfaces',
description: 'Understanding TypeScript interfaces and type definitions',
category: 'TypeScript',
},
{
title: 'React Performance Optimization',
description: 'Tips and techniques for optimizing React application performance',
category: 'React',
},
{
title: 'HTML Semantic Elements',
description: 'Using semantic HTML elements for better accessibility and SEO',
category: 'HTML',
},
{
title: 'Node.js Express Server',
description: 'Building RESTful APIs with Node.js and Express framework',
category: 'Node.js',
},
{
title: 'Vue Composition API',
description: 'Modern Vue.js development using the Composition API',
category: 'Vue.js',
},
{
title: 'Angular Components',
description: 'Creating reusable Angular components with TypeScript',
category: 'Angular',
},
{
title: 'Python Django Framework',
description: 'Web development with Python Django framework',
category: 'Python',
},
{
title: 'CSS Grid Layout',
description: 'Advanced CSS Grid techniques for complex layouts',
category: 'CSS',
},
{
title: 'React Testing Library',
description: 'Testing React components with React Testing Library',
category: 'React',
},
{
title: 'MongoDB Queries',
description: 'Advanced MongoDB queries and aggregation pipelines',
category: 'Database',
},
{
title: 'Webpack Configuration',
description: 'Optimizing Webpack configuration for production builds',
category: 'Build Tools',
},
{
title: 'SASS/SCSS Guide',
description: 'Writing maintainable CSS with SASS and SCSS',
category: 'CSS',
},
];