Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Blade Elusive Icons Laravel Package

codeat3/blade-elusive-icons

Laravel Blade components for Elusive Icons that let you drop scalable SVG icons into your views with simple, familiar Blade syntax. No manual SVG copying or asset wrangling—just clean, reusable icon tags styled with CSS.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and confirm it registered.

composer require codeat3/blade-elusive-icons

There is nothing else to configure for the happy path. The service provider is auto-discovered and registers the icon set with blade-ui-kit/blade-icons, so the components exist the moment the package is in vendor/. No php artisan vendor:publish is required to start, and there is no asset build step, no CSS import, and no JS.

Where to look first, in order:

  1. vendor/codeat3/blade-elusive-icons/resources/svg/ — this directory is the icon catalogue. Filenames map 1:1 to component names (alarm.svg → <x-elusive-alarm />). Grep here before guessing a name; it is the only authoritative list.
  2. vendor/codeat3/blade-elusive-icons/config/blade-elusive-icons.php — the default prefix (elusive) and the path the set is loaded from. Read it, do not publish it yet.
  3. The blade-ui-kit/blade-icons README — 90% of the behaviour you actually care about (attribute passthrough, title, caching, currentColor) lives in the parent package, not this one.

First use case. Drop it into one Blade template and render a single icon:

<x-elusive-search class="w-5 h-5 text-gray-500" />

That is the whole adoption. The component emits an inline <svg> that inherits currentColor, so a Tailwind text-* utility is your entire colour API. If you are migrating off hand-pasted <svg> blobs, replace them one screen at a time — an internal admin page, a CRUD index, a settings view — rather than as a global sweep.

Before you write a second call site, create the wrapper described in the next section. That is the one decision with real switching cost later.

Implementation Patterns

1. Always go through a project-local wrapper. This is the single most important pattern: it decouples every call site from the vendor's component name, so swapping to a sprite sheet, Iconify, or in-house SVGs later is a one-file change instead of a find-and-replace.

{{-- resources/views/components/icon.blade.php --}}
@props(['name', 'size' => 'w-5 h-5'])

<x-dynamic-component :component="'elusive-'.$name" {{ $attributes->merge(['class' => $size]) }} />
<x-icon name="search" class="text-gray-500" />
<x-icon name="trash" size="w-4 h-4" class="text-red-600" />

Because $attributes->merge() runs the class through Blade's merge logic, a caller-supplied size overrides the default instead of fighting it. Centralising the default size here is what prevents w-5 h-5 becoming a copy-paste convention that drifts.

2. Colour and sizing belong in the template, not the package. The SVG has no hard-coded fill; it inherits currentColor. So:

<a href="/export" class="inline-flex items-center gap-2 text-sm text-blue-600 hover:text-blue-800">
    <x-icon name="download" size="w-4 h-4" />
    Export CSV
</a>

For icon-only buttons, style the button, let the icon inherit:

<button class="p-2 rounded hover:bg-gray-100 text-gray-600" aria-label="Delete">
    <x-icon name="trash" size="w-5 h-5" />
</button>

3. Decide decorative vs. semantic per call site, explicitly. This is a template-authorship decision the package will not make for you.

  • Decorative (most cases — the adjacent text already says "Delete"): leave it alone, and mark the icon aria-hidden="true" in the wrapper if your audit requires it.
  • Semantic (icon-only, or conveying meaning not present in text): pass title, which renders an accessible <title> node inside the SVG.
<x-icon name="warning" title="Account is suspended" size="w-5 h-5 text-amber-500" />

Pick one convention, put it in your wrapper's default, and write it down. Mixed conventions are how you end up with screen readers announcing "trash trash".

4. Navigation and status use <x-icon> inline, next to the label. No pattern beyond ordinary Blade — this is just template work, which is the point:

{{-- nav item --}}
<a href="{{ route('settings') }}" @class(['flex items-center gap-2 px-3 py-2 rounded', 'bg-gray-100 font-medium' => request()->routeIs('settings')])>
    <x-icon name="cog" size="w-4 h-4" />
    Settings
</a>

{{-- status indicator --}}
<x-icon name="ok-circle" size="w-4 h-4 text-green-600" title="{{ $job->status }}" />

5. Loops are fine for tens, not hundreds. Icons render inline per component instance, so a table of 50 rows × 3 icons is ~150 <svg> blocks in the HTML. Acceptable. A 500-row unpaginated table is not — paginate it, or switch to a shared sprite. If you already know you render dense icon grids, solve that before adoption rather than after.

6. Add the cache step to deploy. blade-icons registers from disk at boot; caching collapses that into one file:

composer install --no-dev --optimize-autoloader
php artisan icons:cache
php artisan view:cache

Clear it locally whenever you bump the package or add SVGs: php artisan icons:clear. Skipping the cache in production isn't broken, just slower to boot — but skipping the clear in dev after a version bump is a classic "my new icon doesn't exist" rabbit hole.

7. Test the icons you actually use. A render assertion is cheap insurance against the silent-failure gotcha:

it('renders the search icon', function () {
    $this->blade('<x-icon name="search" />')
        ->assertSee('<svg', false);
});

Better: a data-driven test enumerating every icon name in your codebase, so a typo fails CI rather than shipping a blank space.

8. Pin the version. Use "codeat3/blade-elusive-icons": "^1.6" and let the lock file record the exact resolution. Given a single maintainer and a compatibility-only 1.6.0 release, the lock file is your real safety net.

Gotchas and Tips

A misspelled icon name renders nothing — it does not throw. <x-elusive-serach /> produces an empty string and your page silently loses a glyph. This is the highest-frequency failure mode and the reason the render test above is worth writing. When an icon is "missing", check the filename in vendor/.../resources/svg/ before you debug anything else.

Prefix collisions shadow silently. If you install a second codeat3/blade-*icons package and both register a prefix, the later registration wins and you get the wrong glyph rather than an error. Before adding a sibling package, dump the registered sets and confirm elusive is unique. If it isn't, publish the config and rename the prefix — but then every call site changes, which is exactly why the <x-icon> wrapper earns its keep.

title is not aria-label, and neither is automatic. The package renders <title> when you pass it; it does nothing else. Do not assume the SVG is hidden from assistive tech by default — an unlabelled inline <svg> in an icon-only button is announced unhelpfully. Own this in the wrapper, not per-developer.

The icon set is frozen. Elusive Icons is a static upstream font. There is no upstream PR path for a new glyph — a missing icon is a permanent no, not a backlog item. If design asks for a brand logo or a glyph that isn't in the set, the answer is a one-off hand-written SVG in resources/views/components/ rather than waiting on this package. Plan that escape hatch.

Sizing via class only works because of currentColor + no intrinsic dimensions. If an icon renders at an unexpected size, you have either a conflicting width/height attribute or a parent CSS rule hitting svg broadly (common with resets like svg { display: block; }). Inspect the actual <svg> node; do not guess.

Publishing the config is usually a mistake early on. The defaults are correct for nearly everyone. Publish only when you need a custom prefix or a different SVG path — and remember that a published config is now your config, unmaintained by the package, so future default changes won't reach you.

Laravel 13 is "allowed", not "verified". The 1.6.0 release widened the illuminate/support constraint. That is a Composer constraint bump, not a proof the CI matrix exercises Laravel 13. Land it atomically with your framework upgrade, and check whether another pinned dependency is the thing capping illuminate/support below ^13.0 — that is the likelier blocker.

icons:cache and stale caches. If you edit a vendored SVG or bump the package and the old glyph persists, run php artisan icons:clear and, if you're running config:cache, php artisan optimize:clear. Symptom: "I upgraded but the icon looks identical."

Nothing here touches the database, queue, or HTTP layer. That is a feature — it means rollback is composer remove plus reverting the wrapper's x-dynamic-component line. Keep that reversibility real by never letting <x-elusive-*> appear outside the wrapper file.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle