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

Bootstrap Colorpicker Bundle Laravel Package

jimigrunge/bootstrap-colorpicker-bundle

A Symfony bundle that integrates bootstrap-colorpicker into your Twig templates, giving you a simple reusable form component for adding Bootstrap-styled color pickers to your application's forms.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to understand is that this is not a Laravel package. jimigrunge/bootstrap-colorpicker-bundle is a Symfony2 bundle (circa 2014–2016) that wraps the mjolnic/bootstrap-colorpicker jQuery plugin. It registers assets through Assetic and (typically) exposes a Twig form type. With 2 stars, 0 dependents, a NOASSERTION license, and a hard dependency on Symfony2's now-removed Assetic pipeline, you cannot composer require it into a Laravel app and expect anything to happen. Treat the repo as documentation for a pattern, not a dependency.

What you actually want is the underlying plugin, which is what does 100% of the work anyway:

npm install bootstrap-colorpicker@^3.4.0
# jQuery is a peer dependency
npm install jquery

Where to look first:

  1. The upstream plugin docs at github.com/mjolnic/bootstrap-colorpicker (the bundle adds nothing you can't read there).
  2. resources/js/bootstrap.js in your Laravel app — this is where jQuery and plugin registration belong.
  3. The bundle's Resources/views/ and Resources/public/ folders if you're curious about the Twig form-type pattern, which maps cleanly onto a Blade component.

Minimal first use case — a hex color field in a settings form:

// resources/js/bootstrap.js
import $ from 'jquery';
window.$ = window.jQuery = $;
import 'bootstrap-colorpicker';
import 'bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css';
{{-- resources/views/components/color-input.blade.php --}}
@props(['name', 'value' => '#563d7c'])
<input
    type="text"
    name="{{ $name }}"
    id="{{ $name }}"
    value="{{ old($name, $value) }}"
    {{ $attributes->merge(['class' => 'form-control']) }}
    data-colorpicker
/>
document.querySelectorAll('[data-colorpicker]').forEach((el) => {
    $(el).colorpicker({ format: 'hex' });
});

That's the whole "bundle" in about fifteen lines.

Implementation Patterns

Bundle the CSS through Vite, not a CDN. The plugin ships a Sprite-based PNG for the saturation/picker dials; if you load only the JS you'll get an invisible picker with a working input. Import the CSS in your entrypoint so Vite rewrites the asset URLs.

Blade component + @push for one-time init. If you render a picker inside a partial that can appear many times, initialize once at the page level rather than per-component:

@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', () => {
    $('[data-colorpicker]').colorpicker({
        format: 'hex',
        color: undefined,          // let the input's value win
        popover: { container: 'body' },
    });
});
</script>
@endpush

popover.container: 'body' is the single most useful option — it solves the "picker clipped by overflow: hidden" problem inside cards, tables, and modals.

Livewire integration. jQuery mutates the input's value but does not fire a native input event, so wire:model won't pick it up. Bind the plugin's event explicitly:

<input
    type="text"
    wire:model.defer="accent_color"
    x-data
    x-init="$($el).colorpicker({ format: 'hex' })
        .on('changeColor', (e) => $el.value = e.color.toString('hex'))"
/>

Two caveats: x-init requires Alpine, and after a Livewire re-render (wire:model updating elsewhere) the DOM node may be replaced and the picker destroyed. Use wire:ignore on the input wrapper if the value is only touched by the user.

Alpine wrapper component. Cleaner than scattered jQuery:

Alpine.data('colorPicker', (initial = '#000000') => ({
    value: initial,
    init() {
        const picker = $(this.$el.querySelector('input'))
            .colorpicker({ format: 'hex' })
            .on('changeColor', (e) => {
                this.value = e.color.toString('hex');
                this.$dispatch('color-changed', { value: this.value });
            });
        this.$watch('value', (v) => picker.colorpicker('setValue', v));
    },
}));

Note the re-entrancy risk: setValue fires changeColor, which sets this.value, which triggers $watch. Guard with a flag or compare-before-set if you see an infinite loop.

Dynamic rows. Any picker added after page load needs its own init. If you're using Alpine x-for this is automatic (each iteration runs x-init); if you're using jQuery .append() you must call .colorpicker() on the new element manually.

Server-side validation is mandatory. Everything the plugin produces is a string the user could have typed by hand — the picker is a UI convenience, not a validator.

$request->validate([
    'accent_color' => ['required', 'string', 'regex:/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/'],
]);

Normalize before persisting (strtolower, expand 3-digit hex, or store rgb()/HSL as your schema dictates) so that #FFF, #ffffff, and rgb(255,255,255) don't become three different DB values.

Storage. Hex strings in a char(7) column are the pragmatic default. If you need alpha, store #rrggbbaa and be explicit about it — the plugin's format: 'rgba' output is not what most people expect in a "color" column.

Gotchas and Tips

  • Do not attempt to install the bundle. composer require jimigrunge/bootstrap-colorpicker-bundle will fail or drag in Symfony2/Assetic-era constraints that conflict with any modern Laravel app. There is no Laravel service provider, no facade, no config publish — the "integration" simply doesn't exist.
  • Assetic is dead. The bundle's asset registration relies on Symfony's Assetic bundle, removed in Symfony 3. Laravel's Vite/Mix pipeline has no equivalent and no reason to emulate it.
  • Namespace umlaut. The vendor namespace is JimiGrünge\… (with ü). This has historically caused PSR-4 autoloading and filesystem-encoding problems on Windows and in some CI images — another reason not to vendor the PHP side.
  • License is NOASSERTION. GitHub could not detect a license file. That means the bundle is legally "all rights reserved" by default even though the underlying plugin is MIT (or Apache-2.0 depending on version). If your legal team cares, depend on mjolnic/bootstrap-colorpicker directly and cite its license; do not copy code out of the bundle.
  • jQuery requirement. bootstrap-colorpicker v3 requires jQuery; there is no vanilla-JS build and no maintained React/Vue/Alpine port from the original author. For a modern Laravel app that has otherwise removed jQuery, this is a real cost — weigh it against a small native <input type="color"> or a lightweight vanilla picker.
  • Bootstrap version coupling. v2.x targets Bootstrap 3, v3.x targets Bootstrap 4. On Bootstrap 5 the picker renders but the popover styling can be off. Test visually; the CSS is not designed for BS5's variable system.
  • changeColor vs colorpicker-change. Event names differ across versions. If your handler silently never fires, log $(el).data('colorpicker') and check the installed version's docs rather than guessing.
  • Format round-tripping. .colorpicker('setValue', '#abc') may normalize to #aabbcc, and getValue/color.toString() differ from the raw input value. Always read from the plugin API, not el.value, if you've set a non-hex format.
  • Debugging checklist when the picker "doesn't appear": (1) is the CSS imported, (2) did jQuery load before the plugin, (3) is the element in the DOM at init time (not inside a hidden modal), (4) is it clipped by overflow: hidden (→ popover.container: 'body'), (5) are there two copies of jQuery on the page.
  • Extension points are your own code. There is nothing to "extend" on the Laravel side — no service container binding, no macro. If you want reuse, publish a small Blade component plus an Alpine plugin and treat that as your internal package; it's ~50 lines and you own the license and the upgrade path.
  • Bottom line: use this repo as a reminder that "Symfony bundle" ≠ "Laravel package," then implement the fifteen-line integration against the upstream npm package. That is the entire day-to-day leverage available here.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager