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

Mary Laravel Package

robsontenorio/mary

maryUI is a set of gorgeous Livewire UI components powered by daisyUI and Tailwind, offering ready-made building blocks for crafting polished Laravel admin panels and apps quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

Install (v2 / Tailwind 4 path):

composer require robsontenorio/mary
php artisan mary:install
npm install && npm run build   # or: npm run dev

The installer wires up daisyUI in resources/css/app.css and adds a @source glob so Tailwind scans mary's PHP components for class strings. Verify it after install — a missing @source line is the #1 cause of "components render unstyled":

@import "tailwindcss";
@plugin "daisyui";
@source "../../vendor/robsontenorio/mary/src/View/Components/**/*.php";

Icons are a separate dependency. mary does not ship an icon set; install one so icon="o-user" resolves:

composer require blade-ui-kit/blade-heroicons

Where to look first

  1. mary-ui.com — every component page has a live playground with copy-paste Blade. This beats reading source.
  2. vendor/robsontenorio/mary/src/View/Components/*.php — the authoritative prop list (public $label, $hint, $icon, etc.) when the docs are thin on a specific attribute.
  3. vendor/robsontenorio/mary/src/View/Components/Main.php + the layout docs — you almost always start by swapping your app shell for <x-mary-main>.

First use case (the ~20-minute win): rebuild one existing CRUD screen — a listing page — as a Livewire component with <x-mary-table>, a <x-mary-modal> create form, and <x-mary-toast> feedback. That single screen exercises 80% of the package's surface area (layout, table, form inputs, modal, toast, theme) and tells you immediately whether it fits your app.

Minimal shell:

{{-- resources/views/components/layouts/app.blade.php --}}
<x-mary-main with-nav full-width>
    <x-slot:sidebar drawer="main-drawer" collapsible class="bg-base-100">
        <x-mary-menu activate-by-route>
            <x-mary-menu-item title="Users" icon="o-users" link="{{ route('users') }}" />
        </x-mary-menu>
    </x-slot:sidebar>

    <x-slot:actions>
        <x-mary-theme-toggle darkTheme="dark" lightTheme="light" class="btn-ghost" />
    </x-slot:actions>

    {{ $slot }}

    <x-mary-toast />  {{-- required once, or all toasts silently vanish --}}
</x-mary-main>

Implementation Patterns

Form components as the default. <x-mary-form> wraps wire:submit, shows the loading state on its submit button, and surfaces the error bag — so you stop hand-rolling wire:loading and @error blocks. Override the actions slot when you need a "cancel" or a secondary button.

<x-mary-form wire:submit="save">
    <x-mary-input label="Name" wire:model="form.name" icon="o-user" hint="Legal name only" />
    <x-mary-input label="Price" wire:model="form.price" money prefix="R$" />
    <x-mary-select label="Role" wire:model="form.role" :options="$roles" option-value="id" option-label="name" placeholder="Pick one" />
    <x-mary-datepicker label="Starts" wire:model="form.starts_at" :config="{ dateFormat: 'Y-m-d' }" />
    <x-mary-file label="Photo" wire:model="form.photo" accept="image/*" crop-after-change />

    <x-slot:actions>
        <x-mary-button label="Cancel" link="{{ route('users') }}" />
        <x-mary-button label="Save" class="btn-primary" type="submit" spinner="save" />
    </x-slot:actions>
</x-mary-form>

Table-driven index pages. The header array is the contract: key must match your row/model attribute (or accessor), and format closures are the clean place for currency/dates/status badges.

public array $headers = [
    ['key' => 'id', 'label' => '#', 'class' => 'w-1'],
    ['key' => 'name', 'label' => 'Name', 'sortable' => true],
    ['key' => 'email', 'label' => 'E-mail'],
    ['key' => 'created_at', 'label' => 'Since', 'format' => [self::class, 'asDate']],
];

public array $sortBy = ['column' => 'name', 'direction' => 'asc'];
public string $search = '';

public function users() {
    return User::query()
        ->when($this->search, fn($q) => $q->where('name', 'like', "%{$this->search}%"))
        ->orderBy(...array_values($this->sortBy))
        ->paginate(10);
}
<x-mary-table :headers="$headers" :rows="$this->users" :sort-by="$sortBy" with-pagination per-page="10" searchable>
    @scope('cell_created_at', $row)
        <x-mary-badge :value="$row->created_at->format('M Y')" class="badge-ghost" />
    @endscope

    @scope('actions', $row)
        <x-mary-button icon="o-pencil" wire:click="edit({{ $row->id }})" spinner class="btn-ghost btn-sm" />
    @endscope
</x-mary-table>

Modal + form pairing. The modal's wire:model must point at a public boolean. Reset the backing model on close so the next open starts clean (otherwise you inherit stale state — a classic Livewire-modal bug that looks like a mary bug).

public bool $modal = false;
public array $form = [];

public function create() { $this->reset('form'); $this->modal = true; }

public function save() {
    $this->validate();
    User::create($this->form);
    $this->modal = false;
    $this->success('User created', 'They are now active.', position: 'toast-top toast-end', icon: 'o-check-circle');
}
<x-mary-modal wire:model="modal" title="New user" subtitle="Fill the basics" separator>
    {{-- form here --}}
</x-mary-modal>

Toast trait everywhere you need feedback. use Mary\Traits\Toast; and call $this->success()/warning()/error()/info(). Centralizing the position in the layout by convention (always toast-top toast-end) keeps the UI consistent.

Searchable selects: pick the right component. <x-mary-select> for static arrays; <x-mary-choices> when the option list must come from the server (implement a search(string $value) method — the component calls it as the user types); <x-mary-choices-offline> when the full list is already loaded client-side and you just need filtering. Choosing wrong is the difference between a snappy form and a 3-second keystroke delay.

Wrap, don't sprinkle. Create thin app-level components (<x-ui-input>, <x-ui-card>) with @props and $attributes forwarding so your team has one place to enforce label placement, required markers, and brand classes. This is also the escape hatch when you need to change a mary component's markup without forking it.

Testing. These are Blade components, so Livewire tests can assert on rendered text and on component state: Livewire::test(UserIndex::class)->set('search','bob')->assertSee('Bob'). No special harness required — you are testing your component, not mary's.

Gotchas and Tips

Tailwind can't see classes built in PHP. class="btn-{{ $type }}" or a header class assembled from a variable will not be generated. Use literal class strings in Blade, or safelist with Tailwind 4's @source inline("..."). This shows up as "styling works locally, broken in production build" because your dev build cached the class from somewhere else.

Missing icons are silent. No icon package → blank square, no error. If a component renders but its icon is invisible, that's almost always the cause.

Toasts require the layout component. Forget <x-mary-toast /> and every $this->success() call becomes a no-op with zero diagnostics. Add it once and never think about it again.

Focus trap vs. third-party JS. mary's modal/file/gallery components trap focus, and there are documented escape hatches (without-trap-focus). If a nested dropdown, date picker, or a JS library stops receiving keyboard events inside a modal, that's your first suspect — don't debug your own JS for an hour.

Date format mismatch. The datepicker speaks JS/moment-style formats on one side and PHP Carbon on the other. Persist as Y-m-d, format for display with a table format closure or an accessor. Same story for money inputs and live models — a couple of these were patched in 2.0.x, so pin a recent patch release.

Pin the version and read the upgrade notes. The release cadence is fast (frequent single-line patches like "Drawer: better id()", "Tabs: fix refresh"), and there were real breaking changes: v2 moved to Tailwind 4/daisyUI 5, and 2.3.0 renamed the menu enabled prop to hidden. Subscribe to releases and budget a branch for upgrades rather than floating ^2.0 and discovering a rename on a Friday.

Choices needs x-cloak/height sanity. It renders before hydration; if you see a tall unstyled select flash, check that the x-cloak CSS rule exists in your base stylesheet — several of these rough edges were fixed over time, so being on a recent patch matters.

Layout height bugs come from nesting. x-mary-main expects to be the root of your layout. Putting it inside another flex container breaks the with-nav height calculation and gives you a double scrollbar.

Editor/TinyMCE licensing. The <x-mary-editor> component wraps TinyMCE, which is GPL. The gpl-license attribute exists for a reason — if you're shipping closed-source, read the TinyMCE terms or use a different editor before you build a feature on it. Similarly, Packagist reports the license as NOASSERTION even though the repo's license.md says MIT; get a human to confirm before a compliance review.

Debugging workflow: when a prop doesn't do what the docs imply, php artisan view:clear and then open vendor/robsontenorio/mary/src/View/Components/<Component>.php. Because these are anonymous components, prop names and defaults are right there in the constructor — faster than searching the site.

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.
thomas-0816/doctrine-dbal-duckdb
moyisoft/laravel-admin
oxygen/mod-pages
oxygen/mod-import-export
oxygen/mod-media
ksoft/laravel-contentbuilderjs
ourgoldpackages/exchange
mikkimike/laravel-exchange1c
wandesnet/mercadopago-laravel
tsfcorp/email
larafony/core
laravel-enso/currencies
tartan/laravel-online-payment
gam/laravel-sat-catalogs
cloudcreativity/laravel-stripe
abdulelahragih/querybuilder
wedevbr/celcoin-laravel
surazdott/nepali-date
devsquad-cockpit/laravel
coding-socks/laravel-upload-handler