leenuxus/jarenui
JarenUI is a Laravel PHP package for building UI components and layouts quickly. It aims to simplify creating reusable frontend elements in your app, keeping views organized and consistent with a component-based approach.
<x-jaren::combobox> — full-featured Blade + Alpine.js combobox:
Modes:
<x-jaren::select> for more complex needsjaren-combobox-createjaren-combobox-search event with query + callback; works with any API or data sourceOption features:
grouped prop groups options under labelled headers using option['group']with-avatars shows initials with custom background colour per optionwith-badges shows a pill badge per optionwith-descriptions shows a sub-label below the option nameoption['disabled']UX:
max-selected prop)close-on-select — auto-closes on single select (default), stays open on multiSizes: xs sm md lg xl 2xl — inherits from <x-jaren::form-size> wrapper
JarenUI\Livewire\AsyncCombobox — server-side search Livewire component:
search(string $query): arraymodel, label-column, value-column, searchable-columns props without subclassingminChars — minimum characters before search fires (default 1)limit — max results (default 10)wire:model.live.debounce.300mswith-avatars, with-descriptions, with-badges display propsphp artisan jaren:make-combobox — scaffolding command:
--model=User — generates Livewire AsyncCombobox subclass with correct columns--search=name,email — comma-separated searchable columns--label=name / --value=id — column mapping--multiple — enables multi-select in generated class--async — force Livewire subclass even without --model--model: generates a Blade usage snippetEvents:
jaren-combobox-change — {value, option} — any selection/deselectionjaren-combobox-create — {value, label} — new creatable option addedjaren-combobox-search — {query, callback} — JS async search hookJarenUI\Livewire\Wizard — abstract base class for multi-step form wizards:
$steps array with id, label, and optional icon per stepdefault (numbered dots + connecting line), numbered (same), minimal (expanding dot pills)sm, md, lg — scales typography, padding, and dot dimensionsshow-progress)clickable)$stepRules array keyed by step id; runs Laravel's validate() automatically on next()onStepLeaving(), onStepEntering(), onCancel()submit() called on the final step's Continue press; call complete() to mark donecompletedData() — return array attached to jaren-wizard-completed event$complete slot to replace the default success screen; pass $cancelButton to add a cancel link in the footerrole="region", aria-current="step" on active step, role="progressbar" on progress bar, role="tabpanel" on step panelsphp artisan jaren:make-wizard — scaffolding command:
JarenUI\Livewire\Wizardresources/views/livewire/{name}/--steps= option: comma-separated step ids--variant= option: default|numbered|minimal--size= option: sm|md|lg--force to overwriteEvents dispatched:
jaren-wizard-step-changed — {step, index} — any navigationjaren-wizard-completed — {data} — on complete()jaren-wizard-cancelled — on cancel()Blade view (resources/views/components/jaren/wizard.blade.php):
toggleable prop on <x-jaren::input> — password inputs now support a show/hide toggle button in the trailing slot. Set type="password" toggleable and the eye/eye-slash icon handles the rest. Alpine manages the input type reactively; the name attribute and Livewire wire:model are unaffected.<livewire:jaren.event-calendar/> — Full-featured Livewire event calendar component:
Three views:
month — grid of days, events shown as coloured pills (max 3 per day + "+N more" overflow that drills into day view)week — 7-column time grid with timed events positioned and sized by durationday — single-day time grid with full-height events, current-time indicator (red line)Toolbar: prev/next navigation, Today button, view switcher — all wired to Livewire
Event detail panel: slides in below the calendar when an event is selected; shows title, time, description, and optional URL link
creatable mode: clicking an empty date dispatches jaren-event-created — hook into a modal or redirect
Time grid: configurable dayStartHour/dayEndHour (default 7 am – 8 pm); each hour slot is 56px; events positioned absolutely by start time and sized by duration
Current-time indicator: red dot + line in day view showing exact current time
Locale support: locale prop controls isoFormat() strings for month/day names
startDay prop: 0 = Sunday, 1 = Monday — affects week grid and month grid padding
Subclass API:
fetchEvents(Carbon $from, Carbon $to): array to load from any databaseCalendarEvent[]9 event colours: blue, green, amber, red, purple, teal, pink, coral, gray
Dispatched events: jaren-event-selected, jaren-event-created, jaren-event-moved, jaren-view-changed, jaren-date-clicked
JarenUI\CalendarEvent — value object for calendar events:
new CalendarEvent(id, title, start, end, color, description, url, allDay, meta)CalendarEvent::from($model, startKey, endKey, ...) — cast from any Eloquent model or arrayCalendarEvent::fromCollection($models, ...) — cast an entire collection at oncedate(), startTime(), endTime(), durationMinutes(), spansMultipleDays(), toArray()php artisan jaren:make-event-calendar — scaffolding command:
--model=Meeting auto-generates the fetchEvents() body with correct key mappingapp/Livewire/30 new tests in tests/Feature/EventCalendarTest.php:
CalendarEvent construction, mapping, collection casting, toArray()EventCalendar all views, navigation (month/week/day), event selection, dismissal, drill-downfetchEvents subclass override<x-jaren::calendar> — Full-featured calendar Blade component:
single (default), multiple (non-consecutive), range (start/end span)xs, sm, base, lg, xl, 2xl — controlled via CSS custom property --jaren-cellmin, max, and unavailable props (all accept Y-m-d strings; min/max accept 'today' shorthand)min-range and max-range props limit selectable span in daysmonths prop renders side-by-side panels (default 2 for range mode)locale prop or browser navigator.languagestart-day: override first day of week (0 = Sunday … 6 = Saturday)with-today: footer shortcut button to jump to and select todayselectable-header: clicking month/year name opens a month-grid picker for fast navigationfixed-weeks: always render 6 rows to prevent layout shiftweek-numbers: ISO 8601 week numbers in a left columnopen-to / force-open-to: control which month the calendar opens tostatic: display-only mode — no interaction, no cursorsnavigation: hide prev/next arrows for embedded displayjaren-calendar-change event: dispatched on every selection change with detail.valuewire:model support: full Livewire binding for all three modes[data-theme="dark"] and .dark classJarenUI\DateRange — CarbonPeriod value object for range mode:
new DateRange($start, $end) — construct from any Carbon-parseable valueDateRange::fromString('Y-m-d/Y-m-d') — parse wire:model string formatDateRange::fromArray(['start'=>'…','end'=>'…']) — parse array formatstart() / end() — Carbon accessorslength() — inclusive day countcontains($date) — boundary-inclusive checktoArray() — Carbon[] of every day in rangetoLivewire() / fromLivewire() — Livewire Wireable contractforWhereBetween() — [Carbon, Carbon] tuple for Eloquent whereBetween()CarbonPeriod — foreach ($range as $day) { … }(string) $range returns 'Y-m-d/Y-m-d'#[Session] attribute for session persistenceJarenUI\Livewire\Casts\DateRangeSynth — Livewire property synthesizer:
?DateRange propertieswire:model, wire:model.live, and #[Session]24 new tests in tests/Feature/CalendarTest.php covering:
The format follows Keep a Changelog, and this project adheres to Semantic Versioning.
50 Blade components across 8 categories:
Button — 6 variants (primary, secondary, ghost, danger, success, warning), 3 sizes, icon support, loading stateBadge — 7 colour variants, dot indicator, dismiss buttonAvatar — 5 sizes, 6 gradients, auto-colour from name, status dot, stack groupBrand — logo + name with dot icon, optional badgeHeading — semantic h1–h6 with visual size overrideText — paragraph with size/colour/weight propsSeparator — horizontal, vertical, and labelled variantsInput — with icon, prefix/suffix, clearable, copyable, error stateTextarea — resize modes, auto-resize, character counterSelect — native and searchable custom dropdown, multi-select, option groupsCheckbox — indeterminate state, card variantRadioGroup + Radio — card variant with badge and price displaySwitch — with label/description, card variant, alignmentSlider — accessible range with fill barOtpInput — configurable digit count, separator, paste supportPillbox — tag input with suggestions autocompleteField — label/hint/error wrapper for any controlAccordion + Accordion.Item — single/multiple open, animated collapseBreadcrumbs — items prop or slot, 3 separator styles, home iconDropdown + Dropdown.Item|Separator|Group — keyboard shortcuts display, danger variantNavbar + Navbar.Item — auto-active detection, badge, external linkPagination — works with Livewire paginator or manual props, page windowTabs + Tabs.Tab|Panel — line/pill/box variants, keyboard nav, badgeModal — named modals, open/close via events, danger accent, all sizesTooltip — 4 positions, configurable delay, rich HTMLPopover — 8 positions, close-on-clickToast (Livewire) — stacked, auto-dismiss progress bar, action button, HasToast traitCallout — 4 types (info/success/warning/danger), dismissibleProgress — linear (4 colours, 4 sizes) and circular SVG ring, step indicatorSkeleton — 5 variants (text, avatar, card, table, form)Card — title, description, media, footer slots, hover lift, link modeProfile — full card and compact row variants, stats, tags, verified badgeTimeline + Timeline.Item — 4 status states, animated active indicatorHeader — sticky, backdrop blur, brand/nav/search/actions slotsSidebar + Sidebar.Section|Item|User — collapsible, badge counts, user footerKanban (Livewire) — drag-and-drop (SortableJS), WIP limits, add/delete cards3 Livewire full-stack components: Toast, Table, Kanban
4 Artisan commands: jaren:install, jaren:publish, jaren:make-table, jaren:make-kanban
JarenUI facade with theme(), accent(), renderStyles()
HasToast trait with fluent builder: $this->toast()->persistent()->action('Undo','undo')->danger('Deleted')
jarenui.css — complete CSS variable token system:
prefers-color-scheme fallbackTest suite: 40+ Pest tests covering all Livewire components and Blade rendering
Auto-discovery via extra.laravel in composer.json
How can I help you explore Laravel packages today?