zikula/jquery-minicolors-bundle
A Symfony bundle that packages the jQuery MiniColors color picker, making it easy to include its assets and add a lightweight, customizable color selector to forms and UI with minimal setup.
This is not a Laravel package. zikula/jquery-minicolors-bundle is a Zikula 3 bundle: its composer.json requires zikula/core, and its job is to register the jQuery MiniColors assets with Zikula's asset helper and expose a form type / Twig integration. Running composer require zikula/jquery-minicolors-bundle in a Laravel app will either fail on dependency resolution or drag Zikula's kernel into your vendor/ for no benefit. With 0 stars and 0 dependents there is also no community signal to lean on.
Treat it as an asset source and a reference implementation, not a dependency.
Resources/public/js/jquery.minicolors.min.js — the actual plugin (upstream: @claviska/jquery-minicolors, MIT).Resources/public/css/jquery.minicolors.css — required, the widget is unusable without it.npm install @claviska/jquery-minicolors jquery
Fall back to copying the two files into resources/js/vendor/ only if you're pinned to an old version or offline.resources/js/app.js:
import $ from 'jquery';
window.$ = window.jQuery = $; // plugin expects a global
import 'jquery-minicolors';
import 'jquery-minicolors/jquery.minicolors.css';
<input type="text" name="brand_color" id="brand_color"
value="{{ old('brand_color', $settings->brand_color) }}"
data-minicolors>
$('[data-minicolors]').minicolors({ format: 'hex', theme: 'bootstrap' });
That's the whole "installation" — there is no service provider, no config file, no facade to publish.
Reusable Blade component. The bundle's value is the pattern, not the code; reproduce it as a component so every color field is consistent:
{{-- resources/views/components/color-input.blade.php --}}
@props(['name', 'value' => null, 'swatches' => []])
<input type="text"
name="{{ $name }}"
id="{{ $id = $attributes->get('id', $name) }}"
value="{{ old($name, $value) }}"
data-minicolors
data-swatches="{{ implode('|', $swatches) }}"
{{ $attributes->merge(['class' => 'form-input']) }}>
@error($name) <p class="text-red-600">{{ $message }}</p> @enderror
Central initializer, not per-page scripts. One bootstrap function that scans for [data-minicolors] and reads options off data attributes keeps page templates clean and makes turbolinks-style navigation safe:
function initColorPickers(root = document) {
$(root).find('[data-minicolors]').each(function () {
if ($(this).data('minicolors-initialized')) return;
$(this).minicolors({
format: 'hex',
theme: 'bootstrap',
swatches: ($(this).data('swatches') || '').split('|').filter(Boolean),
change: function (hex) { this.dispatchEvent(new Event('input', { bubbles: true })); },
}).data('minicolors-initialized', true);
});
}
document.addEventListener('DOMContentLoaded', () => initColorPickers());
Livewire. Wrap the input in wire:ignore so morphing doesn't rip the plugin's DOM out from under it, then re-init after navigation:
<div wire:ignore>
<x-color-input name="brand_color" :value="$brand_color" wire:model.defer="brand_color" />
</div>
document.addEventListener('livewire:navigated', () => initColorPickers());
Alpine / Inertia / Vue. Don't fight the framework — own the lifecycle. In Vue/React init in mounted/useEffect and call $(el).minicolors('destroy') on unmount so you don't leak the dropdown panel into body.
Validation is server-side. The widget is a convenience; never trust it. Normalize and validate in a Form Request:
'brand_color' => ['required', 'string', 'regex:/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/'],
Then in your service/action, expand 3-digit to 6-digit before persisting so your DB doesn't hold two shapes of the same color.
Config-driven palette. Put allowed swatches in config/branding.php and pass them into the component — this is the Laravel equivalent of the bundle's Twig-side option injection, and it lets ops change the palette without a deploy of JS.
zikula/core in a Laravel composer.json is an immediate conflict with laravel/framework's Symfony/PSR constraints. Vendor the JS/CSS or use npm.window.$ = window.jQuery = $ goes above the import 'jquery-minicolors' line. ES module imports are hoisted, so an assignment in a later file is too late.jquery.minicolors.css the panel renders unstyled and invisible at the bottom of the page — the single most common "it's broken" report.wire:ignore is mandatory; re-init on livewire:navigated and after any partial that contains a picker.change doesn't always fire a native input event. Livewire/Alpine won't see the update. Use the change callback to dispatch a bubbling input event, as in the snippet above.opacity: true, format: 'rgb', or 'rgba', the value written back is not #rrggbb. If your validator only allows hex, lock the options (format: 'hex', no opacity) rather than trying to accept everything.zIndex or position: 'top left' and check overflow-hidden on ancestors.<label for="..."> still points at the hidden input, which is fine, but verify keyboard focus reaches the swatch button and that the hidden input is not aria-hidden-only.app.js and have Tailwind's preflight in app.css, the preflight can win on input styling. Import MiniColors' CSS after your base layer.$(el).minicolors('destroy') stacks panels in <body>. The data-minicolors-initialized guard above prevents this for the simple case.@claviska/jquery-minicolors, not here — check the upstream changelog before patching the vendored file.initColorPickers() helper are the extension points — keep them in resources/js/utils/ so other fields (e.g. a chart series color repeater) can reuse them.How can I help you explore Laravel packages today?