UNPKG

@papernote/ui

Version:

A modern React component library with a paper notebook aesthetic - minimal, professional, and expressive

83 lines 3.16 kB
import { ReactNode } from 'react'; export interface SearchableListItem<T = unknown> { key: string; data: T; } export interface SearchableListProps<T = unknown> { /** Array of items to display */ items: SearchableListItem<T>[]; /** Search input placeholder */ searchPlaceholder?: string; /** Controlled search value */ searchValue?: string; /** Callback when search changes */ onSearchChange?: (value: string) => void; /** Custom filter function */ filterFn?: (item: SearchableListItem<T>, searchTerm: string) => boolean; /** Debounce delay for search in ms */ debounceMs?: number; /** Render function for each item */ renderItem: (item: SearchableListItem<T>, index: number, isSelected: boolean, isHighlighted: boolean) => ReactNode; /** Currently selected item key */ selectedKey?: string; /** Callback when item is selected */ onSelect?: (item: SearchableListItem<T>) => void; /** Maximum height with overflow scroll */ maxHeight?: string | number; /** Show result count */ showResultCount?: boolean; /** Result count format function */ formatResultCount?: (count: number, total: number) => string; /** Message when no items available */ emptyMessage?: string | ReactNode; /** Message when search has no results */ noResultsMessage?: string | ReactNode; /** Loading state */ loading?: boolean; /** Loading message */ loadingMessage?: string | ReactNode; /** Size variant */ size?: 'sm' | 'md' | 'lg'; /** Visual variant */ variant?: 'default' | 'bordered' | 'card'; /** Additional CSS classes */ className?: string; /** Enable keyboard navigation (arrow keys, enter) */ enableKeyboardNavigation?: boolean; /** Auto-focus search input */ autoFocus?: boolean; } /** * SearchableList - List component with integrated search/filter functionality * * @example Basic usage * ```tsx * <SearchableList * items={users.map(u => ({ key: u.id, data: u }))} * renderItem={(item) => <div>{item.data.name}</div>} * onSelect={(item) => setSelectedUser(item.data)} * searchable * searchPlaceholder="Search users..." * /> * ``` * * @example With custom filter and loading * ```tsx * <SearchableList * items={products} * renderItem={(item, index, isSelected) => ( * <div className={isSelected ? 'bg-accent-50' : ''}> * {item.data.name} - ${item.data.price} * </div> * )} * filterFn={(item, term) => * item.data.name.toLowerCase().includes(term.toLowerCase()) * } * loading={isLoading} * loadingMessage="Fetching products..." * maxHeight="400px" * /> * ``` */ export default function SearchableList<T = unknown>({ items, searchPlaceholder, searchValue: controlledSearchValue, onSearchChange, filterFn, debounceMs, renderItem, selectedKey, onSelect, maxHeight, showResultCount, formatResultCount, emptyMessage, noResultsMessage, loading, loadingMessage, size, variant, className, enableKeyboardNavigation, autoFocus, }: SearchableListProps<T>): import("react/jsx-runtime").JSX.Element; //# sourceMappingURL=SearchableList.d.ts.map