rowDecoration; $cellDecoration = $this->cellDecoration; $headers = $this->headers; // Remove closures from serialization unset($this->rowDecoration, $this->cellDecoration, $this->headers); // Serialize a unique ID for component tracking $this->uuid = "table-" . md5(serialize($this)) . $id; // Restore closures $this->rowDecoration = $rowDecoration; $this->cellDecoration = $cellDecoration; $this->headers = $headers; } // Check if header is hidden public function isHidden(mixed $header): bool { return $header['hidden'] ?? false; } // Format header contents public function format(mixed $row, mixed $field, mixed $header): mixed { $format = $header['format'] ?? null; if ( ! $format) { return $field; } if (is_callable($format)) { return $format($row, $field); } if ('currency' === $format[0]) { return ($format[2] ?? '') . number_format((float) $field, ...mb_str_split($format[1])); } if ('date' === $format[0] && $field) { return Carbon::parse($field)->translatedFormat($format[1]); } return $field; } // Check if link should be shown in cell public function hasLink(mixed $header): bool { return $this->link && empty($header['disableLink']); } // Build row link public function redirectLink(mixed $row): string { $link = $this->link; // Transform from `route()` pattern $link = Str::of($link)->replace('%5B', '{')->replace('%5D', '}'); // Extract tokens like {id}, {city.name} ... $tokens = Str::of($link)->matchAll('/\{(.*?)\}/'); // Replace tokens with actual row values $tokens->each(function (string $token) use ($row, &$link): void { $link = Str::of($link)->replace("{" . $token . "}", data_get($row, $token))->toString(); }); return $link; } public function rowClasses(mixed $row): ?string { $classes = []; foreach ($this->rowDecoration as $class => $condition) { if ($condition($row)) { $classes[] = $class; } } return Arr::join($classes, ' '); } public function cellClasses(mixed $row, array $header): ?string { $classes = Str::of($header['class'] ?? '')->explode(' ')->all(); foreach ($this->cellDecoration[$header['key']] ?? [] as $class => $condition) { if ($condition($row)) { $classes[] = $class; } } return Arr::join($classes, ' '); } public function render(): View|Closure|string { return <<<'HTML'
whereDoesntStartWith('wire:model') ->class([ 'w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400', ]) }} > $noHeaders ])> @foreach($headers as $header) @php if($isHidden($header)) continue; # Scoped slot's name like `user.city` are compiled to `user___city` through `@scope / @endscope`. # So we use current `$header` key to find that slot on context. $temp_key = str_replace('.', '___', $header['key']) @endphp @endforeach @if($actions) @endif @foreach($rows as $k => $row) $striped, 'hover:bg-gray-50' => !$noHover, 'cursor-pointer' => $attributes->has('@row-click') || $link ]) @if($attributes->has('@row-click')) @click="$dispatch('row-click', {{ json_encode($row) }});" @endif > @foreach($headers as $header) @php if($isHidden($header)) continue; $temp_key = str_replace('.', '___', $header['key']) @endphp @if(isset(${"cell_".$temp_key})) @else @endif @endforeach @if($actions) @endif @endforeach @isset ($footer) attributes->get('class') ?? '' ])> {{ $footer }} @endisset
{{ isset(${"header_".$temp_key}) ? ${"header_".$temp_key}($header) : $header['label'] }} Actions
$hasLink($header)])> @if($hasLink($header)) @endif {{ ${"cell_".$temp_key}($row) }} @if($hasLink($header)) @endif $hasLink($header)])> @if($hasLink($header)) @endif {{ $format($row, data_get($row, $header['key']), $header) }} @if($hasLink($header)) @endif {{ $actions($row) }}
@if(count($rows) === 0) @if($showEmptyText)
{{ $emptyText }}
@endif @if($empty)
{{ $empty }}
@endif @endif
@if($withPagination && method_exists($rows, 'links'))
{{ $rows->links() }}
@endif
HTML; } }