rhf-autocomplete-field
shuip/rhf-autocomplete-fieldFreeComponent
shuip publishes no description for this item.
Install it
npx shadcn@latest add https://shuip.plvo.dev/r/rhf-autocomplete-field.jsonSource
1'use client';23import type { Lens } from '@hookform/lenses';4import { Loader2 } from 'lucide-react';5import * as React from 'react';6import { useController } from 'react-hook-form';7import { Command, CommandEmpty, CommandGroup, CommandItem, CommandList } from '@/components/ui/command';8import { Field, FieldDescription, FieldError, FieldLabel } from '@/components/ui/field';9import { Input } from '@/components/ui/input';10import { Popover, PopoverAnchor, PopoverContent } from '@/components/ui/popover';11import { cn } from '@/lib/utils';1213const DEBOUNCE_TIME = 300;1415function defaultFilter(suggestion: string, query: string) {16 return suggestion.toLowerCase().includes(query.toLowerCase());17}1819export interface AutocompleteFieldProps extends Omit<React.ComponentProps<typeof Input>, 'value' | 'onChange'> {20 lens: Lens<string>;21 label?: string;22 description?: string;23 placeholder?: string;24 suggestions?: string[];25 onSearch?: (query: string) => Promise<string[]>;26 emptyText?: string;27 debounceMs?: number;28 filter?: (suggestion: string, query: string) => boolean;29}3031export function AutocompleteField({32 lens,33 label,34 description,35 placeholder,36 suggestions,37 onSearch,38 emptyText = 'No results',39 debounceMs = DEBOUNCE_TIME,40 filter = defaultFilter,41 ...props42}: AutocompleteFieldProps) {43 const { field, fieldState } = useController(lens.interop());4445 const [open, setOpen] = React.useState(false);46 const [selectedIndex, setSelectedIndex] = React.useState(-1);47 const [results, setResults] = React.useState<string[]>([]);48 const [isPending, startTransition] = React.useTransition();49 const debounceTimerRef = React.useRef<NodeJS.Timeout | null>(null);50 const requestIdRef = React.useRef(0);51 const popoverRef = React.useRef<HTMLDivElement>(null);5253 const query = field.value ?? '';5455 const items = React.useMemo(() => {56 if (onSearch) return results;57 if (!suggestions) return [];58 if (!query) return suggestions;59 return suggestions.filter((suggestion) => filter(suggestion, query));60 }, [onSearch, results, suggestions, query, filter]);6162 React.useEffect(() => {63 if (!onSearch || !open) return;6465 if (debounceTimerRef.current) {66 clearTimeout(debounceTimerRef.current);67 }6869 if (!query) {70 requestIdRef.current++;71 setResults([]);72 return;73 }7475 debounceTimerRef.current = setTimeout(() => {76 const requestId = ++requestIdRef.current;77 startTransition(async () => {78 try {79// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from shuip
All 52 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| confirmation-dialogconfirmation-dialog | shuip | Components | Free | 1 dep | |
| copy-buttoncopy-button | shuip | Components | Free | 3 deps | |
| hover-revealhover-reveal | shuip | Components | Free | 1 dep | |
| rhf-address-fieldrhf-address-field | shuip | Components | Free | 5 deps · 2 files | |
| rhf-checkbox-fieldrhf-checkbox-field | shuip | Components | Free | 3 deps | |
| rhf-combobox-fieldrhf-combobox-field | shuip | Components | Free | 5 deps | |
| rhf-date-fieldrhf-date-field | shuip | Components | Free | 6 deps | |
| rhf-date-range-fieldrhf-date-range-field | shuip | Components | Free | 6 deps |
