ralphjsmit/tall-interactive
ralphjsmit/tall-interactive provides reusable interactive UI components for Laravel TALL stack apps—modals, slide-overs, dropdowns, tooltips, and more—built with Livewire, Alpine.js, and Tailwind CSS for fast, polished interfaces.
Prerequisites. Confirm you are actually on the TALL stack: Laravel + Livewire 3 + Tailwind + Alpine (Livewire 3 bundles Alpine — load it exactly once). This package has no value outside that combination.
Install (pinned). The repo is archived, so never use a floating constraint:
composer require ralphjsmit/tall-interactive:"0.11.0"
Commit composer.json and composer.lock. Treat the version as frozen until you deliberately bump it and re-test.
Wire up Tailwind first — this is the step people skip. The package ships Blade views with utility classes. If they are not in your tailwind.config.js content globs, the markup renders unstyled and you will waste an afternoon "debugging" a config problem:
content: [
'./resources/**/*.blade.php',
'./vendor/ralphjsmit/tall-interactive/resources/views/**/*.blade.php',
]
Where to look first. Read the source, not the docs (docs are frozen upstream). The real API surface lives in:
vendor/ralphjsmit/tall-interactive/resources/views/ — the Blade component markup and slot namesvendor/ralphjsmit/tall-interactive/src/ — component classes and config defaultsconfig/tall-interactive.php (publish with php artisan vendor:publish --tag="tall-interactive-config" if present)Reading these three locations takes under an hour and tells you more than any stale README.
First use case: a create/edit slide-over. The canonical day-one win is a back-office CRUD slide-over: a table row "Edit" button opens a slide-over containing a Livewire form component that validates, saves, and closes. Build this one flow end-to-end before adopting the package anywhere else — it exercises triggers, form binding, validation error display, submit state, and close behavior in a single representative workflow.
Overlay wraps a Livewire component, not raw form markup. Keep the Livewire form as its own component and let the slide-over/modal be the shell around it. This keeps validation, dirty state, and submit handling in a testable place and lets you reuse the same form in a full page and in an overlay.
<x-tall-interactive::slide-over wire:model="showEdit">
<livewire:users.edit-form :user="$user" />
</x-tall-interactive::slide-over>
(Adjust component names to the exact tags in your vendor views — the pattern, not the literal tag, is the point.)
Drive open/close from Livewire state. Use a public boolean ($showEdit) plus wire:model on the overlay rather than sprinkling Alpine x-data toggles across views. One source of truth means Livewire tests can assert visibility, and $this->dispatch('close') or flipping the property from an action is a one-liner.
Close on save, not from inside the form. After a successful save(), flip the property or dispatch an event upward. Do not call overlay-close JavaScript through $wire from deep inside a child component; route it through the parent that owns the boolean.
Confirmation modals for destructive actions. A second, smaller modal for "Delete user?" is the cheapest reliability win: confirm → dispatch action → close. Keep the confirm component generic and pass the action/message as props.
Dropdowns in tables and toolbars. Use the dropdown component for per-row actions instead of custom Alpine menus. Because it is Tailwind-styled, you can override with your own classes by passing class (check the slot/attribute contract in the vendor view).
Compose, don't rebuild. If you need a styled button that triggers the modal, build your own wrapper Blade component that emits the trigger attributes the package expects. Overriding the vendor component's <x-slot>s is a lower-friction extension point than copying its markup.
Test at the Livewire level where possible. Livewire::test(EditForm::class)->set(...)->call('save')->assertDispatched(...) covers validation and side effects. Overlay open/close, focus, and escape need a real browser (Dusk or Playwright) — write those tests once on the pilot and reuse.
Archived means you own it. Pin the exact version, add a recurring quarterly compatibility review, and consider forking into your own namespace with a documented diff. Vendor-and-own beats composer update surprises.
Tailwind purge is the #1 "it's broken" report. Vendor views must be in content globs. If classes disappear in production but look fine in dev, this is almost always the cause.
Alpine duplication. Livewire 3 ships Alpine. If you also load Alpine from a CDN or your own bundle, overlay behavior doubles up or fails silently. Load Alpine once, from Livewire.
Accessibility is inherited unverified. Focus trapping, screen-reader announcements, nested overlays, scroll locking, and back-button behavior have not been audited by an active maintainer. Do a manual keyboard/screen-reader pass on the pilot and write regression tests for escape and focus return.
Lost form state after validation. Test the round trip explicitly: submit invalid data, confirm errors render inside the still-open overlay and previously entered values survive. If they don't, the overlay is remounting the Livewire component — keep the component mounted and toggle visibility rather than conditionally rendering it.
Nested overlays conflict on z-index and escape handling. Prefer closing the parent or using a dedicated confirm component rather than stacking arbitrary overlays. Document the approved nesting rule.
Back-button and deep-linking. Modals do not push history by default. If users expect the back button to close a slide-over, that is your code to write — plan it before shipping customer-facing surfaces.
Debug by reading the vendor source. There is no upstream issue tracker activity to lean on and little community knowledge (115 stars, zero dependents). When something misbehaves, open the Blade view and the component class; it is small enough to trace in minutes.
Extension points, in order of preference: pass Tailwind classes/props → override slots → publish and edit views → fork into your namespace. Editing directly inside vendor/ is not an extension strategy; use a fork so the change is governed.
Keep overlays lightweight. Each Livewire-driven overlay is a server round trip. Avoid wrapping whole page sections in one overlay component; scope it to the form, keep heavy state server-side, and watch for repeated hydration on modal-heavy screens.
Exit plan is cheap — keep it that way. Because the surface area is small, a native <dialog> + Alpine fallback is a day or two of work. Maintain a documented rollback path and avoid coupling the rest of the app to package-specific markup so that exit stays cheap.
How can I help you explore Laravel packages today?