AutocompleteInput Component
** Last Built**: September 2, 2025 at 4:19 PM A powerful and accessible autocomplete input component with search functionality, keyboard navigation, and comprehensive validation support.
Overview
The AutocompleteInput component provides a modern, accessible autocomplete interface that supports:
- Real-time search and filtering of options
- Keyboard navigation (arrow keys, enter, escape)
- Custom value support for free-text input
- Loading states and error handling
- Accessibility features (ARIA, screen readers)
- Flexible styling and theming
- Multiple size and variant options
Basic Usage
import React, { useState } from 'react';
import { AutocompleteInput } from '@react-superadmin/web';
function BasicAutocompleteExample() {
const [selectedCountry, setSelectedCountry] = useState('');
const countries = [
{ value: 'us', label: 'United States' },
{ value: 'ca', label: 'Canada' },
{ value: 'uk', label: 'United Kingdom' },
{ value: 'de', label: 'Germany' },
{ value: 'fr', label: 'France' },
{ value: 'jp', label: 'Japan' },
{ value: 'au', label: 'Australia' },
{ value: 'br', label: 'Brazil' },
{ value: 'in', label: 'India' },
{ value: 'cn', label: 'China' },
];
return (
<div className='max-w-md space-y-4'>
<AutocompleteInput
label='Select Country'
value={selectedCountry}
onChange={setSelectedCountry}
options={countries}
placeholder='Type to search countries...'
helperText='Start typing to see matching countries'
/>
</div>
);
}
With Search and Filtering
import React, { useState } from 'react';
import { AutocompleteInput } from '@react-superadmin/web';
function SearchableAutocompleteExample() {
const [selectedProduct, setSelectedProduct] = useState('');
const products = [
{ value: 'laptop', label: 'Laptop Computer' },
{ value: 'desktop', label: 'Desktop Computer' },
{ value: 'tablet', label: 'Tablet Device' },
{ value: 'smartphone', label: 'Smartphone' },
{ value: 'monitor', label: 'Computer Monitor' },
{ value: 'keyboard', label: 'Computer Keyboard' },
{ value: 'mouse', label: 'Computer Mouse' },
{ value: 'headphones', label: 'Headphones' },
{ value: 'speakers', label: 'Computer Speakers' },
{ value: 'webcam', label: 'Webcam' },
];
return (
<div className='max-w-md space-y-4'>
<AutocompleteInput
label='Search Products'
value={selectedProduct}
onChange={setSelectedProduct}
options={products}
placeholder='Type to search products...'
maxSuggestions={5}
helperText='Type to filter through available products'
/>
</div>
);
}
With Custom Values
import React, { useState } from 'react';
import { AutocompleteInput } from '@react-superadmin/web';
function CustomValueAutocompleteExample() {
const [selectedValue, setSelectedValue] = useState('');
const predefinedOptions = [
{ value: 'option1', label: 'Predefined Option 1' },
{ value: 'option2', label: 'Predefined Option 2' },
{ value: 'option3', label: 'Predefined Option 3' },
];
return (
<div className='max-w-md space-y-4'>
<AutocompleteInput
label='Custom Value Input'
value={selectedValue}
onChange={setSelectedValue}
options={predefinedOptions}
placeholder='Type to search or enter custom value...'
allowCustomValue={true}
helperText='You can select from predefined options or enter your own value'
/>
</div>
);
}
With Validation and Error States
import React, { useState } from 'react';
import { AutocompleteInput } from '@react-superadmin/web';
function ValidationAutocompleteExample() {
const [selectedValue, setSelectedValue] = useState('');
const [error, setError] = useState('');
const options = [
{ value: 'valid1', label: 'Valid Option 1' },
{ value: 'valid2', label: 'Valid Option 2' },
{ value: 'valid3', label: 'Valid Option 3' },
];
const handleChange = (value: string | number) => {
setSelectedValue(value as string);
if (value === '') {
setError('This field is required');
} else {
setError('');
};
return (
<div className='max-w-md space-y-4'>
<AutocompleteInput
label='Required Field'
value={selectedValue}
onChange={handleChange}
options={options}
placeholder='Select an option...'
required={true}
error={error}
helperText='This field is required for form submission'
/>
</div>
);
}
With Loading States
import React, { useState, useEffect } from 'react';
import { AutocompleteInput } from '@react-superadmin/web';
function LoadingAutocompleteExample() {
const [selectedValue, setSelectedValue] = useState('');
const [options, setOptions] = useState([]);
const [loading, setLoading] = useState(false);
const simulateLoading = async () => {
setLoading(true);
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 2000));
setOptions([
{ value: 'loaded1', label: 'Loaded Option 1' },
{ value: 'loaded2', label: 'Loaded Option 2' },
{ value: 'loaded3', label: 'Loaded Option 3' },
{ value: 'loaded4', label: 'Loaded Option 4' },
{ value: 'loaded5', label: 'Loaded Option 5' },
]);
setLoading(false);
};
useEffect(() => {
simulateLoading();
}, []);
return (
<div className='max-w-md space-y-4'>
<AutocompleteInput
label='Loading Example'
value={selectedValue}
onChange={setSelectedValue}
options={options}
placeholder='Options are loading...'
loading={loading}
helperText='This demonstrates the loading state'
/>
</div>
);
}
With Different Sizes and Variants
import React, { useState } from 'react';
import { AutocompleteInput } from '@react-superadmin/web';
function StylingAutocompleteExample() {
const [selectedValue1, setSelectedValue1] = useState('');
const [selectedValue2, setSelectedValue2] = useState('');
const [selectedValue3, setSelectedValue3] = useState('');
const options = [
{ value: 'option1', label: 'Option 1' },
{ value: 'option2', label: 'Option 2' },
{ value: 'option3', label: 'Option 3' },
];
return (
<div className='max-w-md space-y-6'>
<AutocompleteInput
label='Small Size'
value={selectedValue1}
onChange={setSelectedValue1}
options={options}
placeholder='Small input...'
size='sm'
helperText='Small size variant'
/>
<AutocompleteInput
label='Medium Size (Default)'
value={selectedValue2}
onChange={setSelectedValue2}
options={options}
placeholder='Medium input...'
size='md'
helperText='Medium size variant (default)'
/>
<AutocompleteInput
label='Large Size'
value={selectedValue3}
onChange={setSelectedValue3}
options={options}
placeholder='Large input...'
size='lg'
helperText='Large size variant'
/>
<AutocompleteInput
label='Filled Variant'
value={selectedValue1}
onChange={setSelectedValue1}
options={options}
placeholder='Filled variant...'
variant='filled'
helperText='Filled variant with background color'
/>
</div>
);
}
With Disabled Options
import React, { useState } from 'react';
import { AutocompleteInput } from '@react-superadmin/web';
function DisabledOptionsAutocompleteExample() {
const [selectedValue, setSelectedValue] = useState('');
const options = [
{ value: 'enabled1', label: 'Enabled Option 1' },
{ value: 'enabled2', label: 'Enabled Option 2' },
{ value: 'disabled1', label: 'Disabled Option 1', disabled: true },
{ value: 'enabled3', label: 'Enabled Option 3' },
{ value: 'disabled2', label: 'Disabled Option 2', disabled: true },
];
return (
<div className='max-w-md space-y-4'>
<AutocompleteInput
label='With Disabled Options'
value={selectedValue}
onChange={setSelectedValue}
options={options}
placeholder='Select an option...'
helperText='Some options are disabled and cannot be selected'
/>
</div>
);
}
API Reference
Props
| Prop | Type | Default | Description |
| ------------------------------------- |
| label | string | - | Label text displayed above the input |
| value | string \| number | - | Current selected value |
| onChange | (value: string \| number) => void | - | Callback when value changes |
| options | AutocompleteOption[] | - | Array of available options |
| placeholder | string | "Select an option..." | Placeholder text for the input |
| disabled | boolean | false | Whether the input is disabled |
| required | boolean | false | Whether the field is required |
| error | string | - | Error message to display |
| helperText | string | - | Helper text below the input |
| className | string | - | Additional CSS classes |
| size | "sm" \| "md" \| "lg" | "md" | Size variant of the input |
| variant | "outline" \| "filled" | "outline" | Visual variant of the input |
| allowCustomValue | boolean | false | Allow custom values not in options |
| maxSuggestions | number | 10 | Maximum number of suggestions to show |
| loading | boolean | false | Show loading state |
| noOptionsMessage | string | "No options found" | Message when no options match |
| searchPlaceholder | string | "Search options..." | Placeholder for search input |
AutocompleteOption Interface
interface AutocompleteOption {
value: string | number;
label: string;
disabled?: boolean;
}
Accessibility Features
- Keyboard Navigation: Full keyboard support with arrow keys, enter, escape, and tab
- ARIA Attributes: Proper ARIA labels, descriptions, and states
- Screen Reader Support: Compatible with screen readers and assistive technologies
- Focus Management: Proper focus handling and keyboard navigation
- Clear Indicators: Visual and programmatic indicators for required fields and errors
Styling and Theming
The component uses Tailwind CSS classes and supports:
- Multiple size variants (sm, md, lg)
- Visual variants (outline, filled)
- Custom CSS classes via className prop
- Responsive design
- Dark mode compatibility (with proper CSS variables)
Best Practices
- Always provide meaningful labels for accessibility
- Use helper text to provide additional context
- Set appropriate maxSuggestions to avoid overwhelming users
- Handle loading states for async data fetching
- Provide clear error messages for validation failures
- Use disabled options sparingly and provide clear feedback
- Test keyboard navigation thoroughly for accessibility compliance
Features
Search and Filtering
The component provides real-time search functionality:
- Instant Filtering: Options are filtered as you type
- Case-Insensitive: Search is not case-sensitive
- Partial Matching: Finds options containing the search term
- Max Suggestions: Configurable limit on displayed options
Keyboard Navigation
Full keyboard support for accessibility:
- Arrow Keys: Navigate through options
- Enter: Select highlighted option or custom value
- Escape: Close dropdown
- Tab: Move to next form element
Custom Value Support
When allowCustomValue is enabled:
- Users can type values not in the options list
- Custom values are passed to
onChangecallback - Maintains flexibility for user input
Loading States
Built-in loading support:
- Shows loading message in dropdown
- Prevents option selection during loading
- Integrates with data fetching operations
Integration Examples
With Form Libraries
import { useForm, Controller } from 'react-hook-form';
import { AutocompleteInput } from '@react-superadmin/web';
function FormExample() {
const { control, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name='category'
control={control}
rules={{ required: 'Category is required' }}
render={({ field, fieldState }) => (
<AutocompleteInput
label='Category'
value={field.value}
onChange={field.onChange}
options={categoryOptions}
error={fieldState.error?.message}
required
/>
)}
/>
</form>
);
}
With Data Providers
import { useGetList } from '@react-superadmin/core';
import { AutocompleteInput } from '@react-superadmin/web';
function DataProviderExample() {
const { data: users, isLoading } = useGetList('users');
const userOptions =
users?.map(user => ({
value: user.id,
label: user.name,
})) || [];
return (
<AutocompleteInput
label='Select User'
options={userOptions}
loading={isLoading}
placeholder='Search for users...'
/>
);
}
With Async Data Fetching
import React, { useState, useEffect } from 'react';
import { AutocompleteInput } from '@react-superadmin/web';
function AsyncExample() {
const [options, setOptions] = useState([]);
const [loading, setLoading] = useState(false);
const [selectedValue, setSelectedValue] = useState('');
const fetchOptions = async searchTerm => {
setLoading(true);
try {
const response = await fetch(`/api/search?q=${searchTerm}`);
const data = await response.json();
setOptions(data);
} catch (error) {
console.error('Failed to fetch options:', error);
} finally {
setLoading(false);
};
return (
<AutocompleteInput
label='Async Search'
value={selectedValue}
onChange={setSelectedValue}
options={options}
loading={loading}
placeholder='Type to search...'
/>
);
}
Performance Considerations
- Option Filtering: Large option lists are filtered efficiently
- Max Suggestions: Limit displayed options to prevent performance issues
- Debounced Search: Consider debouncing search input for API calls
- Virtual Scrolling: For very large lists, consider virtual scrolling
Related Components
- Input - Basic text input component
- SelectInput - Dropdown selection component
- FormField - Form field wrapper with validation
- Button - Button component for form actions
- Modal - Modal component for complex forms