Skip to main content

Data display

Plain Table code

Copy the implementation or inspect every file that belongs to this component unit.

resources/views/components/ui/plain-table.blade.php

@props([
    'caption' => null,
    'captionClass' => 'sr-only',
    'striped' => false,
    'bordered' => true,
    'density' => 'comfortable',
    'background' => null,
    'headerBackground' => null,
    'rowBackground' => null,
    'stripeBackground' => null,
    'columnBackgrounds' => [],
])

@php
    /*
    | Plain table primitive. It keeps native table geometry visible and avoids
    | the rounded card chrome used by x-ui.table / x-ui.data-table.
    */
    $normalizeCssValue = function (mixed $value): ?string {
        if (! is_scalar($value)) {
            return null;
        }

        $value = trim((string) $value);

        return $value === '' ? null : $value;
    };

    $cssVariables = [
        'background' => $normalizeCssValue($background),
        'header-background' => $normalizeCssValue($headerBackground),
        'row-background' => $normalizeCssValue($rowBackground),
        'stripe-background' => $normalizeCssValue($stripeBackground),
    ];

    $style = collect($cssVariables)
        ->filter()
        ->map(fn (string $value, string $name): string => "--plain-table-{$name}: {$value};")
        ->implode(' ');

    $densityClass = [
        'compact' => '[&_th]:px-3 [&_th]:py-2 [&_td]:px-3 [&_td]:py-2',
        'comfortable' => '[&_th]:px-4 [&_th]:py-3 [&_td]:px-4 [&_td]:py-3',
        'spacious' => '[&_th]:px-5 [&_th]:py-4 [&_td]:px-5 [&_td]:py-4',
    ][$density] ?? '[&_th]:px-4 [&_th]:py-3 [&_td]:px-4 [&_td]:py-3';

    $backgroundClass = $cssVariables['background']
        ? 'bg-[var(--plain-table-background)]'
        : 'bg-white dark:bg-gray-950';

    $headerBackgroundClass = $cssVariables['header-background']
        ? '[&_thead]:bg-[var(--plain-table-header-background)]'
        : '[&_thead]:bg-gray-100 dark:[&_thead]:bg-gray-900';

    $rowBackgroundClass = $cssVariables['row-background']
        ? '[&_tbody_tr]:bg-[var(--plain-table-row-background)]'
        : '';

    $stripeClass = $striped
        ? ($cssVariables['stripe-background']
            ? '[&_tbody_tr:nth-child(odd)]:bg-[var(--plain-table-stripe-background)]'
            : '[&_tbody_tr:nth-child(odd)]:bg-gray-50 dark:[&_tbody_tr:nth-child(odd)]:bg-gray-900/70')
        : '';

    $borderClass = $bordered
        ? 'border border-gray-300 dark:border-gray-700 [&_td]:border [&_td]:border-gray-300 dark:[&_td]:border-gray-700 [&_th]:border [&_th]:border-gray-300 dark:[&_th]:border-gray-700'
        : '';

    $columnBackgrounds = is_array($columnBackgrounds) ? $columnBackgrounds : [];
    $normalizedColumnBackgrounds = [];

    if (array_is_list($columnBackgrounds)) {
        foreach ($columnBackgrounds as $index => $columnBackground) {
            $columnBackground = $normalizeCssValue($columnBackground);

            if ($columnBackground) {
                $normalizedColumnBackgrounds[$index + 1] = $columnBackground;
            }
        }
    } else {
        foreach ($columnBackgrounds as $column => $columnBackground) {
            $column = (int) $column;
            $columnBackground = $normalizeCssValue($columnBackground);

            if ($column > 0 && $columnBackground) {
                $normalizedColumnBackgrounds[$column] = $columnBackground;
            }
        }
    }

    $columnCount = count($normalizedColumnBackgrounds) > 0 ? max(array_keys($normalizedColumnBackgrounds)) : 0;
@endphp

<div
    @if ($style !== '') style="{{ $style }}" @endif
    {{ $attributes->merge(['class' => 'overflow-x-auto']) }}
>
    <table class="min-w-full border-collapse text-left text-sm text-gray-700 dark:text-gray-200 {{ $backgroundClass }} {{ $headerBackgroundClass }} {{ $rowBackgroundClass }} {{ $stripeClass }} {{ $borderClass }} {{ $densityClass }}">
        @if ($caption)
            <caption class="{{ $captionClass }}">{{ $caption }}</caption>
        @endif

        @if ($columnCount > 0)
            <colgroup>
                @for ($column = 1; $column <= $columnCount; $column++)
                    <col @if (isset($normalizedColumnBackgrounds[$column])) style="background-color: {{ $normalizedColumnBackgrounds[$column] }};" @endif>
                @endfor
            </colgroup>
        @endif

        @isset($head)
            <thead>
                <tr>{{ $head }}</tr>
            </thead>
        @endisset

        <tbody>
            {{ $slot }}
        </tbody>
    </table>
</div>

resources/views/components/ui/plain-table/cell.blade.php

@props([
    'align' => 'left',
    'background' => null,
    'muted' => false,
    'numeric' => false,
    'width' => null,
])

@php
    $alignClass = ['left' => 'text-left', 'center' => 'text-center', 'right' => 'text-right'][$align] ?? 'text-left';
    $colorClass = $muted ? 'text-gray-500 dark:text-gray-400' : 'text-gray-700 dark:text-gray-200';
    $numericClass = $numeric ? 'tabular-nums' : '';
    $styles = [];

    if (is_scalar($background) && trim((string) $background) !== '') {
        $styles[] = 'background-color: '.trim((string) $background);
    }

    if (is_scalar($width) && trim((string) $width) !== '') {
        $styles[] = 'width: '.trim((string) $width);
    }

    $style = count($styles) > 0 ? implode('; ', $styles).';' : null;
@endphp

<td
    @if ($style) style="{{ $style }}" @endif
    {{ $attributes->merge(['class' => "align-top {$alignClass} {$colorClass} {$numericClass}"]) }}
>
    {{ $slot }}
</td>

resources/views/components/ui/plain-table/heading.blade.php

@props([
    'align' => 'left',
    'background' => null,
    'scope' => 'col',
    'width' => null,
])

@php
    $alignClass = ['left' => 'text-left', 'center' => 'text-center', 'right' => 'text-right'][$align] ?? 'text-left';
    $styles = [];

    if (is_scalar($background) && trim((string) $background) !== '') {
        $styles[] = 'background-color: '.trim((string) $background);
    }

    if (is_scalar($width) && trim((string) $width) !== '') {
        $styles[] = 'width: '.trim((string) $width);
    }

    $style = count($styles) > 0 ? implode('; ', $styles).';' : null;
@endphp

<th
    @if ($scope) scope="{{ $scope }}" @endif
    @if ($style) style="{{ $style }}" @endif
    {{ $attributes->merge(['class' => "align-bottom text-xs font-semibold uppercase tracking-wider text-gray-600 dark:text-gray-300 {$alignClass}"]) }}
>
    {{ $slot }}
</th>

resources/views/components/ui/plain-table/row.blade.php

@props([
    'background' => null,
    'hover' => false,
])

@php
    $background = is_scalar($background) ? trim((string) $background) : '';
    $style = $background === '' ? null : "background-color: {$background};";
    $hoverClass = $hover ? 'transition-colors hover:bg-gray-50 dark:hover:bg-gray-900/70' : '';
@endphp

<tr
    @if ($style) style="{{ $style }}" @endif
    {{ $attributes->merge(['class' => $hoverClass]) }}
>
    {{ $slot }}
</tr>