Autocomplete
more-shadcn-noair/autocompleteFreeComponent
An input component with autocomplete suggestions.
Live preview
live · rendered by the registry
Rendered by more-shadcn-noair on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://more-shadcn.noair.fun/r/autocomplete.jsonSource
1<script lang="ts" generics="T">2 import { Input } from '$lib/components/ui/input';3 import { cn } from '$UTILS$';4 import { Loader2, Search, X } from '@lucide/svelte';5 import { fly } from 'svelte/transition';6 import type { Snippet } from 'svelte';78 let {9 value = $bindable(''),10 selected = $bindable<T | null>(null),11 options = [],12 loading = false,13 placeholder = 'Search...',14 labelKey,15 class: className,16 onSelect,17 itemSnippet,18 emptySnippet,19 ...rest20 }: {21 value: string;22 selected?: T | null;23 options: T[];24 loading?: boolean;25 placeholder?: string;26 labelKey?: keyof T;27 class?: string;28 onSelect?: (item: T) => void;29 itemSnippet: Snippet<[T, boolean]>;30 emptySnippet?: Snippet;31 [key: string]: any;32 } = $props();3334 let isOpen = $state(false);35 let activeIndex = $state(-1);3637 let inputContainerRef = $state<HTMLDivElement | null>(null);38 let listRef = $state<HTMLDivElement | null>(null);3940 function open() {41 isOpen = true;42 activeIndex = -1;43 }4445 function close() {46 isOpen = false;47 activeIndex = -1;48 }4950 function handleInput(e: Event) {51 value = (e.target as HTMLInputElement).value;52 if (value.length > 0) open();53 else close();54 }5556 function handleSelect(item: T) {57 selected = item;5859 if (labelKey && item && typeof item === 'object') {60 value = String(item[labelKey]);61 } else if (typeof item === 'string') {62 value = item;63 }6465 if (onSelect) onSelect(item);66 close();67 }6869 function handleKeydown(e: KeyboardEvent) {70 if (!isOpen) {71 if (e.key === 'ArrowDown' && value.length > 0) open();72 return;73 }7475 switch (e.key) {76 case 'ArrowDown':77 e.preventDefault();78 activeIndex = (activeIndex + 1) % options.length;79 scrollToActive();80 break;81 case 'ArrowUp':82 e.preventDefault();83 activeIndex = (activeIndex - 1 + options.length) % options.length;84 scrollToActive();85 break;86 case 'Enter':87 e.preventDefault();88 if (activeIndex >= 0 && options[activeIndex]) {89 handleSelect(options[activeIndex]);90 }91 break;92 case 'Escape':93 close();94 break;95 }96 }9798 function scrollToActive() {99 if (!listRef) return;100 const activeEl = listRef.children[activeIndex] as HTMLElement;101 if (activeEl) {102 activeEl.scrollIntoView({ block: 'nearest' });103 }104 }105106 function clickOutside(node: HTMLElement) {107 const handleClick = (event: MouseEvent) => {108// … truncated
What it pulls in
Other registry items
More from more-shadcn-noair
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Audioaudio | more-shadcn-noair | Components | Free | no deps | |
| Audio Waveaudio-wave | more-shadcn-noair | Components | Free | no deps | |
| Bannerbanner | more-shadcn-noair | Components | Free | no deps | |
| Big Calendarbig-calendar | more-shadcn-noair | Components | Free | no deps | |
| Bottom Navigationbottom-nav | more-shadcn-noair | Components | Free | no deps | |
| Canvascanvas | more-shadcn-noair | Components | Free | no deps | |
| Chipchip | more-shadcn-noair | Components | Free | no deps | |
| Choiceboxchoicebox | more-shadcn-noair | Components | Free | no deps |
