Autocomplete
An enhanced select input with search and free-text capabilities. Always in freeSolo mode, fully integrated with DashForm and Reactive V2.
Quick Start
Copy & Paste
import { Autocomplete } from '@dashforge/ui';
<Autocomplete
name="country"
label="Country"
options={['USA', 'Canada', 'Mexico']}
/>Examples
Common usage patterns and real-world examples.
Basic Static Options
Simple autocomplete with predefined choices
<Autocomplete
name="country"
label="Country"
options={countries}
value={value}
onChange={setValue}
/>FreeSolo Behavior
Custom values or selection from options
Type a custom color or select from the list. FreeSolo is always enabled.
<Autocomplete
name="favoriteColor"
label="Favorite Color"
options={colors}
value={value}
onChange={setValue}
/>Generic Options with Mappers
Type-safe object arrays with custom mappers
<Autocomplete<string, Country>
name="country"
label="Country"
options={countries}
value={value}
onChange={setValue}
getOptionValue={(option) => option.code}
getOptionLabel={(option) => option.name}
/>DashForm Integration
Form validation and error handling
<DashForm onSubmit={handleSubmit}>
<Autocomplete
name="country"
label="Country"
options={countries}
rules={{ required: 'Country is required' }}
/>
<Autocomplete
name="city"
label="City"
options={cities}
rules={{
required: 'City is required',
validate: (value) => {
if (value && value.length < 3) {
return 'City must be at least 3 characters';
}
return true;
},
}}
/>
<Button type="submit">Submit</Button>
</DashForm>Disabled Options
Prevent selection of unavailable choices
<Autocomplete<string, Product>
name="product"
label="Product"
options={products}
getOptionValue={(option) => option.id}
getOptionLabel={(option) => option.name}
getOptionDisabled={(option) => !option.inStock}
/>Layout Variants
Visual appearance options.
Autocomplete uses MUI TextField internally, which supports the standard standard variant (default). The component focuses on search and selection functionality with a clean, consistent appearance.
Default Appearance
<Autocomplete
name="country"
label="Country"
options={options}
/>Clean and minimal with underline. Always in freeSolo mode for flexible text entry.
With Helper Text
Select or type a country
<Autocomplete
name="country"
label="Country"
options={options}
helperText="Select or type a country"
/>Add helpful instructions or context below the input field.
Playground
Interactive demo with live code preview.
Live Playground
tsx
<Autocomplete
name="country"
label="Country"
options={countries}
/>Capabilities
Dashforge-specific features and integrations.
Autocomplete is designed for progressive adoption. Use it as a simple controlled component, integrate it with React Hook Form, or leverage Dashforge-native reactive capabilities. Choose the level that fits your team's workflow.
Controlled
Available Now
Autocomplete works as a standard React controlled component with familiar patterns. No proprietary lock-in required.
Standard value and onChange props
Always freeSolo mode for flexibility
Easy incremental adoption
<Autocomplete
value={country}
onChange={(e, val) => setCountry(val)}
options={countries}
label="Country"
/>React Hook Form Ready
Integration-Friendly
Designed to integrate with React Hook Form workflows through DashForm. Compatible with existing form-library patterns.
Works through DashForm bridge
Validation and error handling supported
Form Closure V1 compliant (error gating)
<DashForm>
<Autocomplete
name="country"
label="Country"
options={countries}
/>
</DashForm>Reactive Options
Available Now
Autocomplete can load options dynamically from form state or external data. Supports mapper functions for custom option shapes.
Runtime options via optionsFromFieldData
Mapper functions for custom shapes
Conditional visibility with visibleWhen
<Autocomplete
name="city"
label="City"
optionsFromFieldData="cityOptions"
getOptionValue={(opt) => opt.id}
getOptionLabel={(opt) => opt.name}
visibleWhen={(engine) =>
engine.getNode('country')?.value !== ''
}
/>Access Control (RBAC)
Control field visibility and interaction based on user permissions. Fields can be hidden, disabled, or readonly when users lack access.
Hide when unauthorized
<Autocomplete
name="assignee"
label="Assignee"
access={{
resource: 'task.assignee',
action: 'edit',
onUnauthorized: 'hide'
}}
options={[
{ value: 'alice', label: 'Alice' },
{ value: 'bob', label: 'Bob' }
]}
/>Disable when cannot edit
<Autocomplete
name="status"
label="Status"
access={{
resource: 'task.status',
action: 'update',
onUnauthorized: 'disable'
}}
options={[
{ value: 'open', label: 'Open' },
{ value: 'done', label: 'Done' }
]}
/>Readonly for view-only
<Autocomplete
name="category"
label="Category"
access={{
resource: 'product.category',
action: 'update',
onUnauthorized: 'readonly'
}}
options={[
{ value: 'electronics', label: 'Electronics' },
{ value: 'books', label: 'Books' }
]}
/>Combined with visibleWhen
<Autocomplete
name="expediteReason"
label="Expedite Reason"
visibleWhen={(e) =>
e.getValue('type') === 'expedited'
}
access={{
resource: 'order.expedite',
action: 'edit',
onUnauthorized: 'readonly'
}}
options={[
{ value: 'urgent', label: 'Urgent' }
]}
/>Note: When combining visibleWhen with RBAC, both conditions must be satisfied. The field shows only if UI logic returns true AND the user has required permissions.
Scenarios
Real-world use cases and patterns.
Common real-world scenarios showing Autocomplete in context.
Form Validation
Integrate with DashForm for validation, error handling, and form submission. Shows required fields and custom validation rules.
<DashForm onSubmit={handleSubmit}>
<Autocomplete
name="country"
label="Country"
options={countries}
rules={{ required: 'Country is required' }}
/>
<Autocomplete
name="city"
label="City"
options={cities}
rules={{
required: 'City is required',
validate: (value) => {
if (value && value.length < 3) {
return 'City must be at least 3 characters';
}
return true;
},
}}
/>
<Button type="submit">Submit</Button>
</DashForm>Runtime Dependent Options
Options that change based on another field's value. Uses optionsFromFieldData to load options from runtime state. Note: The dependent field value is NOT reset when options change (Reactive V2 policy).
<DashForm
reactions={[
{
id: 'update-subcategory-options',
watch: ['category'],
run: ({ getValue, setRuntime }) => {
const category = getValue('category');
const subcategories = getSubcategoriesForCategory(category);
setRuntime('subcategory', {
status: 'ready',
data: { options: subcategories },
});
},
},
]}
>
<Autocomplete name="category" label="Category" options={categories} />
<Autocomplete
name="subcategory"
label="Subcategory"
options={[]}
optionsFromFieldData
/>
</DashForm>API Reference
Complete props documentation.
Complete API reference for Autocomplete component props.
| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | required | Field name for form registration |
| label | React.ReactNode | - | Input label text |
| options | TOption[] | required | Array of available options |
| value | TValue | null | - | Controlled value (explicit override) |
| onChange | (value: TValue | null) => void | - | Change handler |
| getOptionValue | (option: TOption) => TValue | identity | Extract unique value from option |
| getOptionLabel | (option: TOption) => string | identity | Extract display label from option |
| getOptionDisabled | (option: TOption) => boolean | - | Determine if option is disabled |
| optionsFromFieldData | boolean | false | Load options from field runtime data (Reactive V2) |
| disabled | boolean | false | Disable entire input |
| error | boolean | - | Error state (explicit override) |
| helperText | React.ReactNode | - | Helper/error text (explicit override) |
| rules | unknown | - | Validation rules (DashForm) |
| visibleWhen | (engine: Engine) => boolean | - | Conditional visibility function |
| onBlur | (event: FocusEvent) => void | - | Additional blur handler |
Generic Type Signature
function Autocomplete< TValue extends string | number = string, TOption = AutocompleteOption >(props: AutocompleteProps<TValue, TOption>): JSX.Element
Generic Usage Example
interface Country {
code: string;
name: string;
disabled?: boolean;
}
<Autocomplete<string, Country>
name="country"
label="Country"
options={countries}
getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.code}
getOptionDisabled={(option) => option.disabled ?? false}
/>Under the hood
How Autocomplete works internally
Form integration
Automatically binds to form state inside DashForm. No Controller, no manual wiring. Works as a standard MUI Autocomplete when used standalone. Always in freeSolo mode—users can type custom values.
Behavior model
Runtime options via Reactive V2—load from APIs, filter dynamically. No automatic value reset when options change (business data responsibility). Supports generic types with getOptionValue/getOptionLabel for type-safe mapping. Display sanitizes to empty if value unmatched.
Architecture
Built on MUI Autocomplete. Fully typed with TypeScript generics. Purpose-built for searchable dropdowns, tags, and custom text entry with suggestions.