@inline-one/livewire-ui-pack
v0.1.4
Published
JS runtime and Tailwind 4 preset for inline-one/livewire-ui-pack Livewire components.
Readme
livewire-ui-pack
Livewire-friendly Blade components that fill the gap left by daisyUI + MaryUI — a date picker, a date-range picker, and a Cmd/Ctrl+K command palette — plus a shared Tailwind 4 design-token preset.
shadcn-style "you own the source" model applied to Livewire: components live in a repo you control, AI can read and edit them directly, no black-box library.
What this package is (and isn't)
Is: A narrow set of Livewire-friendly Blade components that need vendored JS, plus a shared Tailwind 4 token set. One repo, two packages — Composer (PHP + Blade) and npm (JS + CSS) — versioned together.
Is not: A Livewire framework. A Laravel starter kit. A replacement for daisyUI/MaryUI. A home for buttons/modals/basic inputs — use the upstream libraries for those.
Features
| Component | Description |
|---|---|
| <x-livewire-ui-pack::date-picker> | Flatpickr-backed single date picker. EN + TH locales. model, minDate, maxDate, locale, buddhist props. Emits Gregorian YYYY-MM-DD to $wire. |
| <x-livewire-ui-pack::date-range-picker> | Flatpickr range-mode picker. Same props as date-picker. Wire value is null or [startYYYY-MM-DD, endYYYY-MM-DD]. |
| <x-livewire-ui-pack::command-palette> | Cmd/Ctrl+K operator quick-actions. Homegrown Alpine (~150 LOC, no third-party JS). Each command has url (navigates) or method (calls $wire.call). |
| resources/css/preset.css | Tailwind 4 @theme token set — colors, radii, shadows, fonts. |
Buddhist-calendar display for the date picker is opt-in via the buddhist prop. The prop is accepted but currently a no-op; the wire-value contract (Gregorian ISO) holds regardless.
Install
composer require inline-one/livewire-ui-pack
npm install @inline-one/livewire-ui-packTailwind 4 setup (mandatory)
In your resources/css/app.css:
@import "tailwindcss";
/* Tailwind 4 ignores node_modules by default. Without this line the package's
* Blade views render unstyled in production. Path is relative to this file. */
@source "../../vendor/inline-one/livewire-ui-pack/resources/views/**/*.blade.php";
@import "@inline-one/livewire-ui-pack/preset.css";
@plugin "daisyui";JS bootstrap
Per-component imports only — there is no root export, and a wildcard import hard-errors at resolve time:
// resources/js/app.js
import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';
import uiDatePicker from '@inline-one/livewire-ui-pack/date-picker';
import uiDateRangePicker from '@inline-one/livewire-ui-pack/date-range-picker';
import uiCommandPalette from '@inline-one/livewire-ui-pack/command-palette';
import '@inline-one/livewire-ui-pack/date-picker.css';
import '@inline-one/livewire-ui-pack/date-range-picker.css';
// no command-palette.css — the palette uses daisyUI / Tailwind classes only
Alpine.plugin(uiDatePicker);
Alpine.plugin(uiDateRangePicker);
Alpine.plugin(uiCommandPalette);
Livewire.start();Each subpath bundle is self-contained (Flatpickr is inlined into the date-picker and date-range-picker bundles separately), so unused components add zero bytes to your build.
Use
Date picker
<x-livewire-ui-pack::date-picker
model="dueDate"
locale="th"
:min-date="now()->toDateString()"
:max-date="now()->addYear()->toDateString()"
/>model is the parent Livewire component's property name (string). The widget reads it once on mount via $wire.get($model), writes back on selection via $wire.set($model, value, false), and subscribes to server-side mutations via $wire.watch($model, …). No @entangle — that's deprecated in Livewire 4.
Date range picker
<x-livewire-ui-pack::date-range-picker model="filterRange" />Wire value is null (no range yet) or [startYYYY-MM-DD, endYYYY-MM-DD]. Selecting only the start keeps the wire value null until the end is chosen. Setting the parent property to null clears the picker.
Command palette
<x-livewire-ui-pack::command-palette :commands="[
['id' => 'new-order', 'label' => 'Create Order', 'group' => 'Orders', 'url' => '/orders/new'],
['id' => 'export-csv', 'label' => 'Export CSV', 'group' => 'Data', 'method' => 'exportCsv'],
]" />Cmd+K (Mac) / Ctrl+K (everywhere else) opens the palette. Each command has either a url (navigates) or a method name (calls $wire.call(method) on the parent). Shortcut customisable via the shortcut prop (mod+k by default).
Compatibility
| Layer | Version |
|---|---|
| PHP | ^8.3 |
| Laravel | 11 / 12 / 13 |
| Livewire | ^4.0 |
| Tailwind | 4 (CSS-first @theme config) |
| Node | >=20.19 |
| Flatpickr | ^4.6 (bundled into date-picker / date-range-picker) |
Develop
composer install
composer test # Pest
npm install # also runs the build via the `prepare` script
npm run dev # rebuild on save
npm test # Vitest
npm run demo # open http://localhost:5173/demo/ — live preview, no Livewire requiredCI runs the full Laravel 11 / 12 / 13 Pest matrix plus Vitest + build verification on every push and PR to main. See .github/workflows/test.yml.
Every JS-owned widget follows the same lifecycle pattern:
- Outer
wire:ignoreon the JS-owned element - PHP→Alpine data via
@js(...), never string interpolation - Idempotent Alpine
init(), cleandestroy() - Two-way binding via
$wire.get(model)/$wire.set(model, value, false)+$wire.watch(model, …)— never@entangle - Dates emit Gregorian
YYYY-MM-DDviaflatpickr.formatDate(d, 'Y-m-d')— nevertoISOString()(that does UTC math and shifts the day in non-UTC timezones) - Idempotency, destroy, morph survival, and both sync directions are covered by Vitest
License
MIT.
