| Install | |
|---|---|
composer require matheusmarnt/tall-icon-picker |
|
| Latest Version: | v2.1.2 |
| PHP: | ^8.2 |
A highly optimized and extensible icon picker component for Laravel applications built on the TALL Stack (TailwindCSS, Alpine.js, Livewire, Laravel). Built with a focus on Clean Architecture and performance, this package delegates rendering to the Blade Icons engine and provides a modern interface powered by TallStackUI v2.
Unlike traditional pickers that load massive arrays into memory, TALL Icon Picker is designed to operate with low resource consumption through a Service Layer pattern:
| Feature | Description |
|---|---|
Optimized I/O (IconDiscoveryService) |
SVG file scanning runs in isolation, reading artifacts directly from the vendor directory only when requested. |
| Lazy Loading & Pagination | Thousands of icons are processed on demand and paginated in the backend, keeping the browser DOM and Livewire payload extremely lightweight. |
| UI Adapter | Renders exclusively through TallStackUI v2 (x-ts-* components) in v2.x. Native Alpine.js/Tailwind adapter files are preserved in the package and will be re-enabled in a future release. |
| Extensibility (OCP) | Open for extension via the config file (config/tall-icon-picker.php), allowing new icon libraries to be injected without modifying the package core. |
| Batteries-Included | Pre-configured for 15+ widely-used collections (Lucide, Phosphor, FontAwesome, Heroicons, etc.). |
| i18n | Native multi-language support. Ships with en and pt_BR — extensible by publishing the translation files. |
| Dependency | Version |
|---|---|
| PHP | ^8.2 |
| Laravel | ^11.0 or ^12.0 |
| Livewire | ^3.0 or ^4.0 |
| TallStackUI | ^2.0 (required in v2.x — native mode suspended) |
composer require matheusmarnt/tall-icon-picker
Note: Composer will automatically install
blade-ui-kit/blade-iconsand all linked icon libraries. TallStackUI v2 is required in v2.x — the package renders exclusively throughx-ts-*components. Native mode will return in a future release.
composer update matheusmarnt/tall-icon-picker
If you have previously published the config or views, re-publish them after updating to pick up any changes:
php artisan vendor:publish --tag="tall-icon-picker-config" --force
php artisan vendor:publish --tag="tall-icon-picker-views" --force
php artisan view:clear
The package works out of the box (plug-and-play). Publish the config file to customise the indexed libraries:
php artisan vendor:publish --tag="tall-icon-picker-config"
The generated config/tall-icon-picker.php exposes the libraries section:
return [
'libraries' => [
'lucide' => ['package' => 'mallardduck/blade-lucide-icons', 'path' => 'resources/svg', 'label' => 'Lucide'],
'heroicons' => ['package' => 'blade-ui-kit/blade-heroicons', 'path' => 'resources/svg', 'label' => 'Heroicons'],
// ...
],
];
v2.x note: The
'ui'adapter key andTALL_ICON_PICKER_UIenv variable have been removed. The package always renders through TallStackUI v2 — no configuration is needed for the UI adapter.
The Blade wrapper mounts the Livewire component and exposes the following props:
| Prop | Type | Default | Description |
|---|---|---|---|
wire:model |
string |
— | Livewire property to bind the selected icon value |
label |
string|null |
null |
Field label rendered above the trigger |
placeholder |
string|null |
null |
Custom empty-state text inside the trigger field |
hint |
string|null |
null |
Helper text below the field (hidden when a validation error is active) |
<x-tall::icon-picker
wire:model="system_icon"
label="Module icon"
placeholder="Select an icon..."
hint="This icon will appear in the sidebar menu."
/>
Validation errors are displayed automatically — no extra configuration needed. The wrapper reads the $errors bag using the field name from wire:model and renders the error message below the field:
// In the parent Livewire component
#[Validate('required|string')]
public string $system_icon = '';
{{-- The error for 'system_icon' is shown automatically --}}
<x-tall::icon-picker wire:model="system_icon" label="Module icon" />
{{-- Livewire v4 (dot notation) --}}
<livewire:tall.icon-picker wire:model="system_icon" />
{{-- Livewire v3 (double-colon notation) --}}
<livewire:tall::icon-picker wire:model="system_icon" />
Livewire v4 note: Use
tall.icon-picker(dot notation). Livewire v4 dropped support for::as a namespace separator in component tags. The<x-tall::icon-picker>Blade wrapper is unaffected and works with both versions.
Under the Hood: When an icon is selected, the Livewire component dispatches an
icon-pickedbrowser event. An Alpine listener on the component's root element usesLivewire.find()to locate the parent Livewire component in the DOM and call.set(property, value)directly — compatible with Livewire v3 and v4.
The value stored by the wire:model property is the full icon identifier in the format {prefix}-{name} (e.g. lucide-home, heroicon-o-user). This identifier is directly compatible with the Blade Icons ecosystem.
<x-dynamic-component> (Recommended)The most idiomatic approach — renders the full SVG via Blade:
{{-- $system_icon = 'lucide-home' --}}
<x-dynamic-component :component="$system_icon" class="w-6 h-6 text-gray-700" />
svg() HelperThe svg() helper provided by blade-ui-kit/blade-icons returns the SVG object and allows inline rendering with toHtml():
// Inside a Blade component or Livewire view
{!! svg($system_icon, 'w-6 h-6 text-indigo-500')->toHtml() !!}
@svg Blade Directive@svg($system_icon, 'w-6 h-6')
// app/Livewire/ModuleSettings.php
class ModuleSettings extends Component
{
public string $system_icon = '';
public function render(): View
{
return view('livewire.module-settings');
}
}
{{-- resources/views/livewire/module-settings.blade.php --}}
{{-- Picker --}}
<x-tall::icon-picker wire:model="system_icon" label="Module icon" />
{{-- Selected icon preview --}}
@if ($system_icon)
<div class="mt-4 flex items-center gap-2 text-sm text-gray-600">
<x-dynamic-component :component="$system_icon" class="w-5 h-5" />
<span>{{ $system_icon }}</span>
</div>
@endif
{{-- $record->icon = 'phosphor-house' --}}
<td class="flex items-center gap-2">
@if ($record->icon)
<x-dynamic-component :component="$record->icon" class="w-4 h-4 text-indigo-500" />
@endif
{{ $record->name }}
</td>
Note: Make sure the icon library matching the stored icon prefix is installed in the project that will render it. Otherwise
svg()will throw an exception. Use@if ($icon)as a guard before rendering.
Publish the views to override the picker layout or empty states:
php artisan vendor:publish --tag="tall-icon-picker-views"
Views are placed in resources/views/vendor/tall. The active view can be customised:
| File | Description |
|---|---|
livewire/icon-picker-tallstackui.blade.php |
TallStackUI (x-ts-*) view — active in v2.x |
livewire/icon-picker.blade.php |
Native Alpine.js/Tailwind view (suspended — preserved for a future release) |
The shared UI adapter components (ui/drawer, ui/button, ui/select, ui/input) wrap TallStackUI and native rendering in a single file each. Only the TallStackUI branch is reached at runtime in v2.x.
php artisan vendor:publish --tag="tall-icon-picker-translations"
Language files are placed in lang/vendor/tall-icon-picker/{locale}/icon-picker.php.
Newly installed icons do not appear
php artisan view:clear
SVG rendering at a disproportionate size
The renderer applies the classes passed via class="". Make sure your Tailwind utilities (w-5 h-5) are being compiled — add the vendor path to the content array in tailwind.config.js if needed.
x-dynamic-component throwing View not found
The Blade Icons component for that icon is not registered. Verify that the corresponding library is installed via Composer and that its ServiceProvider is being loaded.
Contributions are welcome! Before opening a Pull Request: