@props([ /** The document's line items (already eager-loaded — this never queries). */ 'items' => null, /** 'row' for the desktop table cell, 'card' for the mobile list. */ 'variant' => 'row', /** Fallback wording when the document has no lines at all. */ 'empty' => null, ]) @php // A hint of what the document is actually for, so nobody has to open the // PDF to find out. The lines are already loaded by the list query; this // component only formats them. $lines = collect($items ?? []); $label = function ($item): string { $name = trim((string) ($item->name ?? '')) ?: __('Item'); $count = (float) ($item->qty ?? 0); if ($count <= 0 || abs($count - 1.0) < 0.001) { return $name; } return rtrim(rtrim(number_format($count, 2, '.', ','), '0'), '.').'× '.$name; }; $first = $lines->first(); $rest = $lines->slice(1); // Native tooltip: the full list, one line each, so a hover reveals // everything without a popover that the table's own scroll would clip. $tooltip = $lines->map(fn ($item) => '• '.$label($item))->implode("\n"); // Second line: the description when there is only one item (that is where // the detail lives on a one-line quote), otherwise the other item names. $detail = $rest->isEmpty() ? trim((string) ($first->description ?? '')) : $rest->map(fn ($item) => $label($item))->implode(' · '); @endphp @if ($lines->isEmpty()) {{ $empty ?? __('No items') }} @elseif ($variant === 'card')
{{ $detail }}
@endif