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

Evo Ui Laravel Package

evolution-cms/evo-ui

Livewire + DaisyUI foundation for modern Evolution CMS manager modules. Provides a manager iframe shell, theme sync, a Livewire 4 bridge, config-driven tables and forms, and shared Blade components for buttons, modals, tabs, and more.

View on GitHub
Deep Wiki
Context7

Getting Started

evo-ui is not a module — it is the runtime your module's manager screens live inside. Treat it as a dependency you build against, not a package you configure once and forget.

Minimal bring-up:

composer require evolution-cms/evo-ui:^1.0
php artisan vendor:publish --tag=evo-ui --force

Then render your module's manager document through the owned shell:

<x-evo::layout :title="$pageTitle">
    <x-evo::module-tabs :items="$tabs" :active="$activeTab" />
    <livewire:evo-ui.module-table preset="vendor.module.items" :context="['moduleUrl' => $moduleUrl]" />
</x-evo::layout>

Where to look first, in this order:

  1. docs/module-integration.md — module shell, asset wiring, service provider registration. This is the file that answers "why is my screen blank / unstyled."
  2. docs/module-table-contract.md — the preset and provider contracts. This is the highest-leverage doc in the package; most day-to-day work is authoring presets and providers.
  3. docs/components.md — the Blade component catalogue (buttons, tabs, modals, cards, badges, choices, image fields, rich editors, table cells).

First use case to build is almost always a read-mostly list screen backed by a table preset plus a small settings form. That exercises the whole stack — layout, assets, Livewire bridge, provider, filters, pagination, session persistence — with the least bespoke code. Once that screen renders correctly under all four manager themes, you know the integration is sound and everything after it is incremental.

Implementation Patterns

Shell-first, always. Every manager screen your module exposes should be an evo-ui-owned document wrapped in x-evo::layout. The package's contract is that the iframe contains only evo-ui's local CSS/JS — no legacy Bootstrap, no jQuery, no main.js, no tabpane.js, no CDN fonts. Mixing is the single fastest way to produce flickering, double-styled, or subtly broken screens. If you have a legacy screen you cannot migrate yet, keep it fully legacy; do not half-publish a hybrid.

Config-driven tables over hand-written ones. The pattern is: declare a preset (columns, filters, sort defaults, row actions, inline vs. modal edit, reorder toggle), implement a ModuleTableProvider that returns rows for the current state, and hand it to <livewire:evo-ui.module-table preset="..." :context="[...]" />. Your provider receives filter/sort/page state and returns data; the component owns the chrome. Resist the urge to build a bespoke table the first time a column doesn't fit — extend the preset first, and only drop to custom Blade when the interaction model genuinely differs.

Pass context, not globals. The :context array is how a table learns about its environment — module URL, active tab key, parent record id. Put ownership metadata here rather than reaching into route or session state inside the provider:

<livewire:evo-ui.module-table preset="vendor.module.items" :context="['tab' => 'items']" />

The tab key matters specifically: it is what lets module-tab refresh target the right table without reloading the manager frame.

Forms are config-driven too. For settings and resource-like screens, describe fields declaratively and let the form component handle dirty-state tracking, the Save/Discard protection, and the stable save-button feedback contract. Hand-rolling a form means re-implementing all three and drifting from the rest of the ecosystem.

Register reactive components through the public boundary (1.1.0+). If you need a Livewire component beyond what ships in the package, use EvoUI::registerComponent() and extend EvoUI\Components\Component rather than calling Livewire::component() and importing Livewire\Component directly. Declarations made before runtime boot are queued and flushed; later ones activate immediately. This keeps your package decoupled from Livewire's own API churn — which is exactly the kind of thing that breaks on a minor upgrade.

Theme sync is free; don't fight it. evolight, evolightness, evodark, evodarkness are handled by the shell. Verify your screen in all four rather than assuming light is representative. Dark-mode-only contrast bugs in badges, table cells, and modal helper text are the common failure mode.

Session state is a feature, not an accident. Table filters, view mode (table vs. list), and per-page preference persist. The per-page preference is even preloaded from a cookie so the first paint is correct. Design with the assumption that a user's filter state survives navigation — and give them an explicit "clean state" path when they need it, since persisted filters that a user forgot about read as "the screen is broken."

Study the consumers. sArticles and dIssues are the working reference implementations. When a doc is ambiguous, the answer is usually in how those two assembled tabs, tables, and workspace surfaces. docs/consumers.md summarizes the adoption shape.

Gotchas and Tips

PHP 8.4 is required as of 1.1.0. The 1.0.x line ran on 8.3. If you are pinning modules to a 8.3 build image, either stay on 1.0.x or bump the image first — this is a hard composer failure, not a runtime warning.

Assets are the number-one source of "it looks broken." The classic symptoms — Unexpected token '<', EvoUI.multiFilter is not a function — are both the browser receiving HTML/404 instead of CSS/JS. Since 1.0.4 the provider auto-ensures assets/modules/evo-ui/evo-ui.css and evo-ui.js exist during boot, which covers the transitive-dependency case (evo-ui installed via a module rather than directly). Publishing prefers symlinks and falls back to copying where symlinks are unavailable. If you see stale CSS after an upgrade, you are almost certainly on a host that fell back to copy and skipped the republish: rerun php artisan vendor:publish --tag=evo-ui --force.

Route discovery is smarter than you'd expect but not magic. Since 1.0.6 the Livewire endpoint registers from EvoUIServiceProvider and handles both /evo-ui and manager-prefixed paths like /manager/evo-ui — including renamed manager directories. If you have a non-standard manager path and assets 404, check the provider boot before writing custom routes. Modules should never need consumer-specific Livewire asset routes of their own.

The module-tab refresh event was renamed. 1.0.6 documented evo-ui:module-tab.refresh; 1.1.0 replaced it with the Alpine-safe evo-ui:module-tab-refresh (dotted event names do not survive Alpine's listener parsing cleanly). Any custom Alpine handler you wrote against the old name silently stops firing. Refresh now also scopes correctly: only tables whose context tab matches the refreshed tab re-query. Tables in hidden tabs stay put, which is both correct and a debugging trap — a table "not refreshing" often means its tab context is missing or wrong.

Dirty forms intercept tab refresh. Double-clicking a module tab refreshes content, but a form in a dirty state retains the Save/Discard protection. If a QA pass reports "refresh does nothing," check whether the form was dirty.

Narrow screens switch tables to list layout automatically. Don't hand-build responsive variants; you will end up with two divergent renderings. If the list layout is wrong for your data shape, that's a preset-level fix.

Rich text fields re-initialize. 1.0.5 fixed repeated rich-text initialization, but if you embed editors in dynamically shown/hidden containers (modals, tabs), verify the editor mounts cleanly on second open rather than assuming the fix covers your case.

Run the package gates locally, not just in CI. composer test runs the smoke/contract suite (56 tests / 1500 assertions on the 1.0.3 baseline), and PHPStan level 5 plus a strict level 8 probe are clean. A PHP syntax pass (find src config lang tests -name '*.php' -print0 | xargs -0 -n1 php -l) is the documented pre-release step. These are cheap and catch the regressions this package is most exposed to — provider/service-provider wiring and asset declaration shape.

Respect the release gate's spirit. The package's own readiness criteria are explicit: all consumer modules on evo-ui-owned iframe documents, no new screen mixing evo-ui with legacy manager bundles, session persistence working for tables and workspaces, and docs/translations/assets/tests updated together. The "no new screen mixing" rule is the one developers break under deadline pressure, and it is the one that makes the eventual legacy-removal step impossible.

Maturity note. Two stars and zero listed dependents understates it — sArticles and dIssues are real production consumers, and the 1.0.x line has documented, tested fixes through 1.0.6. But it also means the community surface is thin: expect to read source for edge cases rather than find a Stack Overflow answer, and expect minor-version bumps to carry breaking-ish changes (the 1.1.0 event rename and PHP baseline are the template). Pin to a minor, read the release notes before bumping, and keep your own screen-level smoke test so an upgrade that passes composer test still gets verified against your screens.

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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels