### Development Setup
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Install dependencies and build the JavaScript assets for development. Run the test suite using Pest.
```bash
composer install
npm install
npm run build # rebuild dist/components/autocomplete.js after editing resources/js
vendor/bin/pest # run the test suite
```
--------------------------------
### Install Dependencies and Run Tests
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/README.md
Installs project dependencies using Composer and npm, builds frontend assets, and executes the test suite.
```bash
composer install
npm install
npm run build # rebuild dist/ assets after editing resources/js or resources/css
vendor/bin/pest # run the test suite
```
--------------------------------
### Install Filament TextInput Autocomplete
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/README.md
Install the package using Composer. This command adds the plugin to your project dependencies.
```bash
composer require giacomomasseron/filament-textinput-autocomplete
```
--------------------------------
### Install Package and Publish Assets
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/AGENTS.md
Install the package using Composer and publish Filament assets. Re-run `php artisan filament:assets` if suggestions are unstyled or the dropdown does not open.
```bash
composer require giacomomasseron/filament-textinput-autocomplete
php artisan filament:assets # required — publishes the Alpine component + CSS. Re-run on deploy.
```
--------------------------------
### Publish Filament Assets
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/README.md
After installation, publish Filament's assets to ensure the plugin's stylesheet is served correctly. This command should be run on each deployment.
```bash
php artisan filament:assets
```
--------------------------------
### Test Case Setup
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Extends Orchestra's TestCase and defines the package providers necessary for testing the Filament v5 components and the custom service provider.
```php
toBeInstanceOf(AutocompleteInput::class)
->and($field->getName())->toBe('country');
});
```
--------------------------------
### Blade View for Autocomplete Component
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/specs/2026-06-12-filament-textinput-autocomplete-design.md
Example of how to load and initialize the autocomplete component in a Blade view using Alpine.js directives. The component's source is dynamically fetched.
```blade
```
--------------------------------
### Call Validation in search Method
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
This snippet demonstrates calling validateConfiguration() at the start of the search() method to enforce valid configuration before executing search logic.
```php
public function search(string $search):
{
$this->validateConfiguration();
if ($this->getSearchResultsUsing === null) {
// ...unchanged...
```
--------------------------------
### Test Static Options Preparation
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
These tests verify that the `getOptionsForJs` method correctly handles static options, ensuring they are mapped to the expected format including value, label, HTML, and searchable keys.
```php
getOptionsForJs())->toBe([]);
});
it('maps options to value, label, html and searchable keys', function () {
$field = AutocompleteInput::make('q')
->options([
['value' => 1, 'label' => 'Spain', 'description' => 'Country'],
])
->searchKeys(['label', 'description'])
->itemView(fn (array $item) => "{$item['label']}");
expect($field->getOptionsForJs())->toBe([
[
'value' => 1,
'label' => 'Spain',
'html' => 'Spain',
'keys' => ['spain', 'country'],
],
]);
});
```
--------------------------------
### Import AutocompleteInput Component
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/AGENTS.md
Import the AutocompleteInput component from the correct namespace. Ensure the namespace matches the package's structure.
```php
use GiacomoMasseroni\TextInputAutocomplete\Forms\Components\AutocompleteInput;
```
--------------------------------
### Implement Server Search Method
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Implement the Livewire-exposed `search` method in the AutocompleteInput component, including error handling and result mapping.
```php
#[ExposedLivewireMethod]
#[Renderless]
public function search(string $search): array
{
if ($this->getSearchResultsUsing === null) {
return ['results' => [], 'error' => null];
}
try {
$raw = $this->evaluate($this->getSearchResultsUsing, ['search' => $search]) ?? [];
} catch (\Throwable $e) {
return ['results' => [], 'error' => $e->getMessage()];
}
$results = array_map(
fn (array $item) => $this->mapItem($item),
array_slice(array_values($raw), 0, $this->getMaxResults()),
);
return ['results' => $results, 'error' => null];
}
```
--------------------------------
### Service Provider Implementation
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
A minimal service provider for the package, extending Spatie's PackageServiceProvider and configuring the package name and views.
```php
name('filament-textinput-autocomplete')
->hasViews('filament-textinput-autocomplete');
}
}
```
--------------------------------
### Configure AutocompleteInput with Server-Side Search
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/AGENTS.md
Use `getSearchResultsUsing()` for server-side search over Livewire. Configure minimum characters to trigger search with `minChars()` and debounce time with `searchDebounce()`.
```php
use Illuminate\Support\Facades\Http;
AutocompleteInput::make('repo')
->getSearchResultsUsing(function (string $search) {
$items = Http::get('https://api.github.com/search/repositories', ['q' => $search])
->json('items', []);
return collect($items)
->map(fn (array $r) => ['value' => $r['id'], 'label' => $r['full_name']])
->all();
})
->minChars(2)
->searchDebounce(300);
```
--------------------------------
### Implement Static Option Mapping
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Implement the `getOptionsForJs` and `mapItem` methods in `AutocompleteInput.php` to prepare static options for the Alpine.js component. This involves mapping each item to its value, label, HTML representation, and searchable keys.
```php
public function getOptionsForJs(): array
{
$options = $this->getOptions() ?? [];
return array_map(fn (array $item) => $this->mapItem($item), $options);
}
protected function mapItem(array $item): array
{
$searchable = array_map(
fn (string $key) => mb_strtolower((string) ($item[$key] ?? '')),
$this->getSearchKeys(),
);
return [
'value' => $item[$this->getOptionValue()] ?? null,
'label' => (string) ($item[$this->getOptionLabel()] ?? ''),
'html' => $this->renderItem($item),
'keys' => array_values($searchable),
];
}
```
--------------------------------
### Git commit for build tooling
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Stages and commits package.json, the build script, and the compiled asset after setting up esbuild.
```bash
git add package.json bin/build.js dist/components/autocomplete.js
git commit -m "build: add esbuild tooling and compiled Alpine asset"
```
--------------------------------
### Commit Documentation Changes
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Stage and commit the updated README.md file.
```bash
git add README.md
git commit -m "docs: add README with installation and usage"
```
--------------------------------
### Add Livewire Exposed Imports
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Add necessary imports for Livewire 3 attributes to expose the search method.
```php
use Filament\Support\Components\Attributes\ExposedLivewireMethod;
use Livewire\Attributes\Renderless;
```
--------------------------------
### esbuild build script
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Uses esbuild to bundle, minify, and format the autocomplete JavaScript entry point into an ESM module for the browser.
```javascript
import * as esbuild from 'esbuild';
await esbuild.build({
entryPoints: ['resources/js/autocomplete.js'],
outfile: 'dist/components/autocomplete.js',
bundle: true,
minify: true,
format: 'esm',
platform: 'browser',
});
console.log('Built dist/components/autocomplete.js');
```
--------------------------------
### Smoke Test for Package Bootstrapping
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
A simple Pest test to verify that the package's service provider class exists and can be loaded.
```php
toBeTrue();
});
```
--------------------------------
### Usage: Server Search with Livewire
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Configure the AutocompleteInput to fetch search results from a server endpoint using Livewire. Specify the minimum characters required to trigger a search (`minChars`) and the debounce time in milliseconds (`searchDebounce`). The `itemView` can reference a Blade view for rendering suggestions.
```php
use Illuminate\Support\Facades\Http;
AutocompleteInput::make('repo')
->getSearchResultsUsing(function (string $search) {
return Http::get('https://api.github.com/search/repositories', ['q' => $search])
->json('items', [])
? collect(Http::get('https://api.github.com/search/repositories', ['q' => $search])->json('items'))
->map(fn ($r) => ['value' => $r['id'], 'label' => $r['full_name']])
->all()
: [];
})
->itemView('filament.autocomplete.repo') // a Blade view receiving $item
->minChars(2)
->searchDebounce(300);
```
--------------------------------
### Git commit for service provider and tests
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Stages and commits changes to the service provider, render test, and Livewire test fixture.
```bash
git add src/TextInputAutocompleteServiceProvider.php tests/Feature/RendersFieldTest.php tests/Fixtures/AutocompleteTestComponent.php
git commit -m "feat: register Alpine asset and verify field rendering"
```
--------------------------------
### Git Commit Command
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Command to stage and commit the initial package scaffolding files.
```bash
git add composer.json phpunit.xml tests/ src/TextInputAutocompleteServiceProvider.php
git commit -m "chore: scaffold package, test harness, and service provider"
```
--------------------------------
### Autocomplete Input with Static Options
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/README.md
Configure an AutocompleteInput component with a predefined list of options. These options are filtered client-side. The `searchKeys` method specifies which fields to search within, and `itemView` customizes how each item is displayed.
```php
use GiacomoMasseroni\TextInputAutocomplete\Forms\Components\AutocompleteInput;
AutocompleteInput::make('country')
->options([
['value' => 'es', 'label' => 'Spain', 'description' => 'Country'],
['value' => 'fr', 'label' => 'France', 'description' => 'Country'],
])
->searchKeys(['label', 'description'])
->itemView(fn (array $item) => "{$item['label']} — {$item['description']}");
```
--------------------------------
### Commit AutocompleteInput Skeleton
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Shows the Git commands to stage and commit the initial AutocompleteInput class and its test file.
```bash
git add src/Forms/Components/AutocompleteInput.php tests/Unit/AutocompleteInputTest.php
git commit -m "feat: add AutocompleteInput field class skeleton"
```
--------------------------------
### Commit Changes
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Command to stage and commit the implemented `renderItem` method, associated tests, and configuration changes.
```bash
git add src/Forms/Components/AutocompleteInput.php tests/Unit/RenderItemTest.php tests/views/item.blade.php tests/TestCase.php
git commit -m "feat: resolve itemView to HTML (closure, view, template, default)"
```
--------------------------------
### Test Search Keys Configuration
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Checks the functionality for setting and retrieving search keys, including the default value and custom configurations. This ensures the field can be configured to search specific properties.
```php
it('stores search keys with a sensible default', function () {
$field = AutocompleteInput::make('country');
expect($field->getSearchKeys())->toBe(['label']);
$field->searchKeys(['label', 'description']);
expect($field->getSearchKeys())->toBe(['label', 'description']);
});
```
--------------------------------
### package.json for esbuild build
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Defines project name, private status, module type, build script, and esbuild as a dev dependency.
```json
{
"name": "filament-textinput-autocomplete",
"private": true,
"type": "module",
"scripts": {
"build": "node bin/build.js"
},
"devDependencies": {
"esbuild": "^0.23.0"
}
}
```
--------------------------------
### Test Server Search Configuration
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Checks the boolean flag that indicates whether server-side search is configured for the AutocompleteInput. This is crucial for performance with large datasets.
```php
it('reports whether server search is configured', function () {
$field = AutocompleteInput::make('country');
expect($field->hasServerSearch())->toBeFalse();
$field->getSearchResultsUsing(fn (string $search) => []);
expect($field->hasServerSearch())->toBeTrue();
});
```
--------------------------------
### Test Option Label and Value Key Configuration
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Ensures that the component correctly handles custom keys for option labels and values, overriding the default 'label' and 'value'. This allows flexibility in data structure.
```php
it('stores option label and value keys with defaults', function () {
$field = AutocompleteInput::make('country');
expect($field->getOptionLabel())->toBe('label')
->and($field->getOptionValue())->toBe('value');
$field->optionLabel('name')->optionValue('id');
expect($field->getOptionLabel())->toBe('name')
->and($field->getOptionValue())->toBe('id');
});
```
--------------------------------
### Package Layout Structure
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/specs/2026-06-12-filament-textinput-autocomplete-design.md
Overview of the directory structure for the Filament TextInput Autocomplete package, including source files, resources, build outputs, and tests.
```plaintext
composer.json
src/
TextInputAutocompleteServiceProvider.php
Forms/Components/AutocompleteInput.php
resources/
views/forms/components/autocomplete-input.blade.php
js/autocomplete.js
dist/components/autocomplete.js # esbuild output (committed for composer installs)
package.json
bin/build.js # esbuild config
tests/
TestCase.php
Unit/AutocompleteInputTest.php
docs/superpowers/specs/2026-06-12-filament-textinput-autocomplete-design.md
```
--------------------------------
### Test: Item Rendering with Template String
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Tests rendering an item using a template string. Tokens like {label} and {type} within the string should be replaced with corresponding item attributes.
```php
it('renders a template string by replacing tokens', function () {
$field = AutocompleteInput::make('q')
->itemView('
');
});
```
--------------------------------
### Implement Configuration Validation Method
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
This method, validateConfiguration(), checks for invalid combinations of options and search callbacks, and ensures maxResults is at least 1. It should be added to the AutocompleteInput class.
```php
protected function validateConfiguration(): void
{
if ($this->options !== null && $this->getSearchResultsUsing !== null) {
throw new \InvalidArgumentException(
'AutocompleteInput cannot use both static options() and getSearchResultsUsing(); choose one source.',
);
}
if ($this->getMaxResults() < 1) {
throw new \InvalidArgumentException('AutocompleteInput maxResults() must be at least 1.');
}
}
```
--------------------------------
### Composer Package Configuration
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Defines the package name, description, dependencies, autoloading, and extra Laravel configuration for the Filament TextInput Autocomplete package.
```json
{
"name": "giacomo/filament-textinput-autocomplete",
"description": "A Filament v5 TextInput field with autocomplete (static + server search).",
"type": "library",
"license": "MIT",
"require": {
"php": "^8.2",
"filament/filament": "^5.0",
"spatie/laravel-package-tools": "^1.16"
},
"require-dev": {
"orchestra/testbench": "^10.0",
"pestphp/pest": "^3.0",
"pestphp/pest-plugin-laravel": "^3.0"
},
"autoload": {
"psr-4": {
"Giacomo\TextInputAutocomplete\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Giacomo\TextInputAutocomplete\Tests\": "tests/"
}
},
"extra": {
"laravel": {
"providers": [
"Giacomo\TextInputAutocomplete\TextInputAutocompleteServiceProvider"
]
}
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true,
"php-http/discovery": true
},
"sort-packages": true
},
"minimum-stability": "stable",
"prefer-stable": true
}
```
--------------------------------
### Autocomplete Input with Server Search
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/README.md
Implement server-side search for AutocompleteInput using Livewire. The `getSearchResultsUsing` method defines a callback that fetches data, potentially from an external API like GitHub. `minChars` sets the minimum input length to trigger a search, and `searchDebounce` controls the delay before the search request is sent.
```php
use GiacomoMasseroni\TextInputAutocomplete\Forms\Components\AutocompleteInput;
use Illuminate\Support\Facades\Http;
AutocompleteInput::make('repo')
->getSearchResultsUsing(function (string $search) {
$items = Http::get('https://api.github.com/search/repositories', [
'q' => $search,
])->json('items', []);
return collect($items)
->map(fn (array $repo) => [
'value' => $repo['id'],
'label' => $repo['full_name'],
])
->all();
})
->itemView('filament.autocomplete.repo') // a Blade view that receives $item
->minChars(2)
->searchDebounce(300);
```
--------------------------------
### Test Server Search Method
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Write failing tests for the server search method, covering mapped results, error handling, and the absence of a configured search.
```php
maxResults(2)
->itemView(fn (array $item) => "{$item['label']}")
->getSearchResultsUsing(fn (string $search) => [
['value' => 1, 'label' => $search . '-a'],
['value' => 2, 'label' => $search . '-b'],
['value' => 3, 'label' => $search . '-c'],
]);
$out = $field->search('x');
expect($out['error'])->toBeNull()
->and($out['results'])->toHaveCount(2)
->and($out['results'][0])->toMatchArray([
'value' => 1,
'label' => 'x-a',
'html' => 'x-a',
]);
});
it('returns an error and empty results when the closure throws', function () {
$field = AutocompleteInput::make('q')
->getSearchResultsUsing(function (string $search) {
throw new RuntimeException('boom');
});
$out = $field->search('x');
expect($out['results'])->toBe([])
->and($out['error'])->toBe('boom');
});
it('returns empty results without server search configured', function () {
$out = AutocompleteInput::make('q')->search('x');
expect($out['results'])->toBe([])->and($out['error'])->toBeNull();
});
```
--------------------------------
### Call Validation in getOptionsForJs
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
This snippet shows how to call the validateConfiguration() method at the beginning of the getOptionsForJs() method to ensure configuration is valid before proceeding.
```php
public function getOptionsForJs(): array
{
$this->validateConfiguration();
$options = $this->getOptions() ?? [];
// ...unchanged...
```
--------------------------------
### PHPUnit Configuration
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
XML configuration for PHPUnit, specifying the bootstrap file, test suite directory, and source inclusion for code coverage.
```xml
testssrc
```
--------------------------------
### Commit Changes
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Commit the implemented server search method and passing tests.
```bash
git add src/Forms/Components/AutocompleteInput.php tests/Unit/SearchMethodTest.php
git commit -m "feat: add Livewire-exposed server search method"
```
--------------------------------
### Registering Autocomplete Component Asset
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/specs/2026-06-12-filament-textinput-autocomplete-design.md
Register the JavaScript component for the autocomplete input using FilamentAsset. This should be done within the package's boot method.
```php
FilamentAsset::register([
AlpineComponent::make('autocomplete', __DIR__ . '/../dist/components/autocomplete.js'),
], package: 'giacomo/filament-textinput-autocomplete');
```
--------------------------------
### Basic AutocompleteInput Class Skeleton
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Provides the minimal PHP class structure for the AutocompleteInput component, extending Filament's base Field class. This is necessary for the component to be recognized.
```php
getMinChars())->toBe(1)
->and($field->getSearchDebounce())->toBe(300)
->and($field->getMaxResults())->toBe(10);
$field->minChars(3)->searchDebounce(500)->maxResults(5);
expect($field->getMinChars())->toBe(3)
->and($field->getSearchDebounce())->toBe(500)
->and($field->getMaxResults())->toBe(5);
});
```
--------------------------------
### Registering Alpine Component Asset in Service Provider
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Registers the 'autocomplete' Alpine component using FilamentAsset in the service provider's packageBooted method.
```php
name('filament-textinput-autocomplete')
->hasViews('filament-textinput-autocomplete');
}
public function packageBooted(): void
{
FilamentAsset::register([
AlpineComponent::make('autocomplete', __DIR__ . '/../dist/components/autocomplete.js'),
], package: static::$assetPackageName);
}
}
```
--------------------------------
### AutocompleteInput API
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/specs/2026-06-12-filament-textinput-autocomplete-design.md
This snippet outlines the available methods for configuring the AutocompleteInput field, including setting data sources, search parameters, and display options.
```APIDOC
## AutocompleteInput API
This section details the configuration options for the `AutocompleteInput` component.
### Methods
- **`make(string $name)`**: Creates a new instance of the AutocompleteInput.
- **`options(array | Closure $options)`**: Sets the data source for static client-side mode. Accepts an array of options or a Closure that returns an array.
- **`searchKeys(array $keys)`**: Specifies the item keys to be matched against the search query in static mode.
- **`getSearchResultsUsing(Closure $callback)`**: Configures server mode. The provided Closure receives a string `$search` and should return search results.
- **`itemView(string | Closure $view)`**: Defines how individual items are rendered. Accepts a string representing a Blade view name, a Closure that returns raw HTML, or a template string.
- **`optionLabel(string $key)`**: Specifies the item key whose value will be displayed in the input field after an item is selected.
- **`optionValue(string $key)`**: Specifies the item key whose value will be stored as the form state.
- **`minChars(int $min)`**: Sets the minimum number of characters a user must type before a search is triggered.
- **`searchDebounce(int $milliseconds)`**: Sets the delay in milliseconds before triggering a search after the user stops typing.
- **`maxResults(int $max)`**: Limits the maximum number of results displayed.
- **`placeholder(string $placeholder)`**: Sets the placeholder text for the input field.
- **`noResultsMessage(string $message)`**: Sets the message to display when no search results are found.
- **`loadingMessage(string $message)`**: Sets the message to display while search results are being loaded.
- **`afterSelected(Closure $callback)`**: An optional callback that is executed after an item is selected. It receives the selected item as an argument.
### `itemView` Resolution
- **`Closure`**: The Closure is called with the item (`$item`), and its return value is treated as raw HTML.
- **`string` matching a Blade view**: If the string matches an existing Blade view (`view()->exists($value)`), it will be rendered with `['item' => $item]` passed to the view.
- **Other `string`**: Treated as a template string. `{key}` tokens are replaced with item attributes, and the remaining markup is passed through as HTML.
**Default `itemView`**: Renders the `optionLabel` as escaped text.
### Mode Resolution
- **Server Mode**: Activated if `getSearchResultsUsing` is set.
- **Static Mode**: Activated if `options` is set and `getSearchResultsUsing` is not.
- **Configuration Error**: Setting both `getSearchResultsUsing` and `options` will result in an error.
```
--------------------------------
### Test Message Configuration for AutocompleteInput
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Verifies the ability to customize messages displayed by the AutocompleteInput, such as 'No results found' and 'Loading...'. This allows for localized or branded messaging.
```php
it('stores messages with defaults', function () {
$field = AutocompleteInput::make('country');
expect($field->getNoResultsMessage())->toBe('No results found')
->and($field->getLoadingMessage())->toBe('Loading...');
$field->noResultsMessage('Nothing')->loadingMessage('Wait');
expect($field->getNoResultsMessage())->toBe('Nothing')
->and($field->getLoadingMessage())->toBe('Wait');
});
```
--------------------------------
### Test: Item Rendering with Closure
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Tests rendering an item using a closure provided to `itemView`. The closure is expected to return raw HTML, which should not be escaped.
```php
it('renders a closure as raw html', function () {
$field = AutocompleteInput::make('q')
->itemView(fn (array $item) => "{$item['label']}");
expect(callRenderItem($field, ['label' => 'Spain']))->toBe('Spain');
});
```
--------------------------------
### Commit Git Changes
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Stage and commit the new AutocompleteInput component and its tests. This command adds the modified files to the Git staging area and then commits them with a descriptive message.
```bash
git add src/Forms/Components/AutocompleteInput.php tests/Unit/AutocompleteInputTest.php
git commit -m "feat: add AutocompleteInput configuration API"
```
--------------------------------
### Test: Item Rendering with Blade View
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Tests rendering an item using a registered Blade view. The view should receive the item data and render it, including specific HTML attributes.
```php
it('renders a matching blade view with the item', function () {
$field = AutocompleteInput::make('q')->itemView('test-fixtures::item');
$html = callRenderItem($field, ['label' => 'Spain']);
expect(trim($html))->toContain('class="fixture"')->toContain('Spain');
});
```
--------------------------------
### Implement `renderItem` Method
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
The core implementation of the `renderItem` method in `AutocompleteInput.php`. It handles resolution logic for closures, Blade views, template strings, and default rendering, including HTML escaping.
```php
protected function renderItem(array $item): string
{
$itemView = $this->itemView;
if ($itemView instanceof \Closure) {
return (string) $this->evaluate($itemView, ['item' => $item]);
}
if (is_string($itemView)) {
if (view()->exists($itemView)) {
return view($itemView, ['item' => $item])->render();
}
return preg_replace_callback(
'/\{(\w+)\}/',
fn (array $m) => e($item[$m[1]] ?? ''),
$itemView,
);
}
return e($item[$this->getOptionLabel()] ?? '');
}
```
--------------------------------
### Test Static Options for AutocompleteInput
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Verifies that the AutocompleteInput field can correctly store and retrieve a static array of options. This test ensures the basic functionality of setting options.
```php
it('stores static options', function () {
$options = [['value' => 1, 'label' => 'Spain']];
$field = AutocompleteInput::make('country')->options($options);
expect($field->getOptions())->toBe($options);
});
```
--------------------------------
### Commit Git Changes
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Stage and commit the newly added Alpine.js autocomplete component source file to your Git repository.
```bash
git add resources/js/autocomplete.js
git commit -m "feat: add Alpine autocomplete component source"
```
--------------------------------
### Livewire Test Fixture for Filament Forms
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
A Livewire component fixture used for testing Filament form components, implementing HasForms and InteractsWithForms traits.
```php
field = $field;
$this->form->fill();
}
public function form(Schema $schema): Schema
{
return $schema
->components([$this->field])
->statePath('data');
}
public function render()
{
return <<<'BLADE'
{{ $this->form }}
BLADE;
}
}
```
--------------------------------
### Commit Changes
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Commit the implemented code and tests for preparing static options for the AutocompleteInput component.
```bash
git add src/Forms/Components/AutocompleteInput.php tests/Unit/PrepareOptionsTest.php
git commit -m "feat: prepare static options for the Alpine component"
```
--------------------------------
### Test Invalid Configuration: Both Sources Set
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
This test verifies that an InvalidArgumentException is thrown when both static options and a server-side search callback are provided to the AutocompleteInput.
```php
options([['value' => 1, 'label' => 'A']])
->getSearchResultsUsing(fn (string $s) => []);
$field->getOptionsForJs();
})->throws(InvalidArgumentException::class, 'both');
```
--------------------------------
### Commit Changes
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
This bash command stages and commits the modified AutocompleteInput.php and ValidationTest.php files with a descriptive commit message.
```bash
git add src/Forms/Components/AutocompleteInput.php tests/Unit/ValidationTest.php
git commit -m "feat: validate AutocompleteInput configuration"
```
--------------------------------
### AutocompleteInput Field API Configuration
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/specs/2026-06-12-filament-textinput-autocomplete-design.md
Configure the AutocompleteInput component by setting options, search keys, custom search logic, item views, and display/value keys. It also allows for controlling search behavior like minimum characters, debounce time, and maximum results.
```php
AutocompleteInput::make('field')
->options(array | Closure) // static client-side source
->searchKeys(['label', 'description']) // item keys matched in static mode
->getSearchResultsUsing(Closure) // server mode; receives string $search
->itemView(string | Closure) // view name | raw-HTML closure | string template
->optionLabel('label') // item key shown in the input on select
->optionValue('value') // item key stored as form state
->minChars(1)
->searchDebounce(300)
->maxResults(10)
->placeholder('...')
->noResultsMessage('No results found')
->loadingMessage('Loading...')
->afterSelected(Closure);
```
--------------------------------
### Pest Test Bootstrap
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Configures Pest to use the custom TestCase for all tests within the tests directory.
```php
in(__DIR__);
```
--------------------------------
### Register Fixture View Directory in TestCase
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Adds a custom namespace for fixture views to the Laravel application environment. This is necessary for Filament to locate and render custom Blade views for item rendering.
```php
protected function defineEnvironment($app): void
{
$app['view']->addNamespace('test-fixtures', __DIR__ . '/views');
}
```
--------------------------------
### Filament Form Component Render Test
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Tests that the AutocompleteInput component renders correctly within a Filament Livewire schema, asserting the presence of a specific CSS class.
```php
AutocompleteInput::make('country')
->options([['value' => 1, 'label' => 'Spain']]),
])
->assertOk()
->assertSee('fi-ac-wrapper', escape: false);
});
```
--------------------------------
### Test: Default Item Rendering (Escaped Label)
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Tests the default behavior of `renderItem` where it escapes the 'label' attribute of the item. This ensures basic security against XSS attacks.
```php
it('renders the escaped label by default', function () {
$field = AutocompleteInput::make('q');
$html = callRenderItem($field, ['label' => 'A & B']);
expect($html)->toBe('A & B');
});
```
--------------------------------
### Commit Autocomplete View Changes
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Stages and commits the newly created Blade view file for the autocomplete input component to the Git repository.
```bash
git add resources/views/forms/components/autocomplete-input.blade.php
git commit -m "feat: add autocomplete field blade view"
```
--------------------------------
### AutocompleteInput Component Class
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
Defines the AutocompleteInput component for Filament, including properties for options, search keys, and various display messages. Use this class to extend Filament's form capabilities with autocomplete functionality.
```php
options = $options;
return $this;
}
public function searchKeys(array | Closure $keys): static
{
$this->searchKeys = $keys;
return $this;
}
public function getSearchResultsUsing(Closure $callback): static
{
$this->getSearchResultsUsing = $callback;
return $this;
}
public function itemView(string | Closure $view): static
{
$this->itemView = $view;
return $this;
}
public function optionLabel(string | Closure $key): static
{
$this->optionLabel = $key;
return $this;
}
public function optionValue(string | Closure $key): static
{
$this->optionValue = $key;
return $this;
}
public function minChars(int | Closure $count): static
{
$this->minChars = $count;
return $this;
}
public function searchDebounce(int | Closure $ms): static
{
$this->searchDebounce = $ms;
return $this;
}
public function maxResults(int | Closure $count): static
{
$this->maxResults = $count;
return $this;
}
public function noResultsMessage(string | Closure $message): static
{
$this->noResultsMessage = $message;
return $this;
}
public function loadingMessage(string | Closure $message): static
{
$this->loadingMessage = $message;
return $this;
}
public function afterSelected(Closure $callback): static
{
$this->afterSelected = $callback;
return $this;
}
public function getOptions(): ?array
{
return $this->evaluate($this->options);
}
public function getSearchKeys(): array
{
return $this->evaluate($this->searchKeys);
}
public function hasServerSearch(): bool
{
return $this->getSearchResultsUsing !== null;
}
public function getOptionLabel(): string
{
return $this->evaluate($this->optionLabel);
}
public function getOptionValue(): string
{
return $this->evaluate($this->optionValue);
}
public function getMinChars(): int
{
return $this->evaluate($this->minChars);
}
public function getSearchDebounce(): int
{
return $this->evaluate($this->searchDebounce);
}
public function getMaxResults(): int
{
return $this->evaluate($this->maxResults);
}
public function getNoResultsMessage(): string
{
return $this->evaluate($this->noResultsMessage);
}
public function getLoadingMessage(): string
{
return $this->evaluate($this->loadingMessage);
}
}
```
--------------------------------
### Helper Function for Reflection
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
A helper function to access the protected `renderItem` method of the AutocompleteInput component using PHP Reflection. This is used in tests to invoke the method.
```php
setAccessible(true);
return $method->invoke($field, $item);
}
```
--------------------------------
### Fixture Blade View for Item Rendering
Source: https://github.com/giacomomasseron/filament-textinput-autocomplete/blob/main/docs/superpowers/plans/2026-06-12-filament-textinput-autocomplete.md
A simple Blade view used as a fixture to test custom item rendering. It displays the 'label' attribute of the item within a span with a specific class.
```blade
{{ $item['label'] }}
```