Skip to main content

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

  1. Always provide meaningful labels for accessibility
  2. Use helper text to provide additional context
  3. Set appropriate maxSuggestions to avoid overwhelming users
  4. Handle loading states for async data fetching
  5. Provide clear error messages for validation failures
  6. Use disabled options sparingly and provide clear feedback
  7. 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 onChange callback
  • 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
  • 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