Files
livewire-material/resources/views/components/card.blade.php
T
Andreas Reinhold / reiniandClaude Opus 5 fef20a9178
tests / lint (push) Failing after 2m6s
tests / feature (8.4) (push) Successful in 1m3s
tests / feature (8.5) (push) Successful in 1m7s
tests / browser (safari, webkit) (push) Successful in 3m14s
tests / browser (chrome, chromium) (push) Successful in 2m9s
tests / browser (firefox, firefox) (push) Successful in 2m29s
Add cards, lists, dialogs, sheets and the rest of M3's containment
<x-card> (filled, elevated, outlined), <x-list> and <x-list-item>
(plain or M3 Expressive's segmented list), <x-divider>, <x-collapse> on
<details>, <x-modal> on the native <dialog>, <x-drawer> as a side sheet or
list-detail pane, and <x-bottom-sheet> with drag to dismiss. Dialogs and
sheets bind to a Livewire flag or id and write back false or null on close,
or use the surrounding Alpine scope. Rows open from anywhere on them through
data-list-row and data-list-open. DesignGuard now also reports Blade
directives written inside a component tag, where they do not compile.

Browser test helpers wait for a complete document with Alpine and Livewire
running: in Firefox, networkidle alone could return before a repeated visit
had loaded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
2026-09-13 07:28:05 +02:00

77 lines
3.0 KiB
PHP

{{-- An M3 card: content and actions about one subject.
`variant` is M3's three (FilledCardTokens, ElevatedCardTokens, OutlinedCardTokens, androidx
Compose Material 3, Apache-2.0): `filled` (surface-container-highest, the default),
`elevated` (surface-container-low at elevation 1) and `outlined` (surface, an outline-variant
edge); all with a medium corner. maryUI's props keep their meaning: `title`, `subtitle`,
`separator` (a divider under the header), and the `menu` (top-end, beside the title),
`figure` (full-bleed media on top) and `actions` (end-aligned, under the content) slots.
A card that opens something is a row: give it `data-list-row` and one `data-list-open`
control inside (the title link or a button), and a press anywhere on it reaches that control
while its other buttons keep their own (resources/js/list-rows.js). It answers with a state
layer and its corner opening a step. Never a stretched link, and never a whole-card `<a>`
around buttons.
Do not pass a `bg-*` class to change its fill it races the card's own in Tailwind's emit
order; use `variant`, or colour a wrapper inside. --}}
@props([
'title' => null,
'subtitle' => null,
'variant' => 'filled',
'separator' => false,
])
@php
$variant = in_array($variant, ['filled', 'elevated', 'outlined'], true) ? $variant : 'filled';
@endphp
<div
data-card
{{ $attributes->class([
'relative flex flex-col overflow-hidden rounded-corner-md text-on-surface',
'bg-surface-container-highest' => $variant === 'filled',
'bg-surface-container-low shadow-elevation-1' => $variant === 'elevated',
'border border-outline-variant bg-surface' => $variant === 'outlined',
]) }}
>
@isset($figure)
<div class="shrink-0 overflow-hidden [&>img]:w-full [&>img]:object-cover">{{ $figure }}</div>
@endisset
<div class="flex flex-1 flex-col gap-4 p-4">
@if ($title || $subtitle || isset($menu))
<div>
<div class="flex items-start gap-2">
<div class="min-w-0 flex-1">
@if ($title)
<h3 class="type-title-md">{{ $title }}</h3>
@endif
@if ($subtitle)
<p class="mt-0.5 type-body-md text-on-surface-variant">{{ $subtitle }}</p>
@endif
</div>
@isset($menu)
<div class="-me-2 -mt-2 flex shrink-0 items-center gap-1">{{ $menu }}</div>
@endisset
</div>
@if ($separator)
<x-divider class="mt-4" />
@endif
</div>
@endif
@if ($slot->isNotEmpty())
<div class="flex-1 type-body-md">{{ $slot }}</div>
@endif
@isset($actions)
<div class="flex flex-wrap items-center justify-end gap-2">{{ $actions }}</div>
@endisset
</div>
</div>