pripanggalih/mary-ui-optimized
An optimized fork of Mary UI providing ready-to-use Laravel Blade components styled with Tailwind CSS and daisyUI. A drop-in toolkit for building admin panels, forms, and dashboards fast, with streamlined component output for lighter pages.
This is a performance-optimized fork of Mary UI, so treat it as a drop-in component library for Laravel + Blade + Livewire with DaisyUI/Tailwind styling.
composer require the package, then run the install command (php artisan mary:install) to wire up Tailwind/DaisyUI and publish the config.tailwind.config.js and layout <head> as instructed by the published config.<x-mary-button label="Save" />, <x-mary-card>…</x-mary-card>, <x-mary-input wire:model="name" />.Where to look first:
$uuid is consumed via id/for/aria-*.First real use case: a Livewire form panel — inputs, a submit button, and a modal for confirmation. That exercises UUID generation, wire:model binding, and the Alpine-backed components in one screen.
Standard Blade usage. Components are anonymous/class-backed Blade components under the mary namespace. Prefer the documented attribute API (label, icon, variant, hint) over injecting raw classes; the fork's perf gains come from streamed initialization, so overriding internals is where you'll lose them.
Livewire forms. Bind with wire:model directly on x-mary-input, x-mary-select, x-mary-datetime. Use x-mary-form for error-bag wiring and x-mary-errors for display. Keep validation rules server-side; the components do not validate.
Modals and drawers. Use the Livewire-driven pattern (wire:model="showModal" plus x-mary-modal) rather than hand-rolled Alpine state — these components depend on the generated $uuid for their x-data/x-ref wiring, and fighting that is not worth it.
Tables and charts. x-mary-table with :headers and a @scope-style slot, or use the built-in header/row API for simple cases. Charts take a :dataset array and render client-side — don't expect them to update without a Livewire round trip plus wire:key.
Wrapping components. When you build your own component around a Mary one, extend the package's base class (or reuse its UUID trait) so nested components keep distinct ids rather than inheriting a parent's.
Theming. Do it through CSS variables / the published theme config, not by publishing and editing component views — overridden views won't receive future perf fixes.
The UUID change is the real breaking change. v1.0.0 replaces md5(serialize($this)) with a per-request incrementing counter (btn-1, btn-2, …). Consequences:
data-*, name, or role instead.@cache blocks will replay the same btn-1 on every request, producing invalid duplicate ids on pages that also render live components. Don't cache component markup that relies on $uuid.wire:key. Without it, Alpine state (open dropdowns, modal scroll) can attach to the wrong node after a morph.assertSee('btn-1') are now order-dependent: reordering components in a view changes the numbers.Debugging. dump($this->uuid) inside a component view is the fastest check. If ids look wrong, confirm you're not extending an older base class or overriding a component view that was copied before the upgrade.
Config quirks. Publishing views/config pins you to that snapshot; re-publish after upgrading to pick up the counter-based internals. Check the prefix setting before writing selectors — a custom prefix changes the id pattern entirely.
Upgrade checklist. Search the codebase for #[id^=, md5(, hardcoded numeric ids, and any test asserting on generated ids. Run the e2e suite against a page that renders many components to confirm nothing depended on the old deterministic hashes.
Extension point. If you need stable, content-derived ids for a specific component, override the UUID method on that one class rather than reverting the base — you keep the ~70% initialization win everywhere else.
How can I help you explore Laravel packages today?