Skip to main content

Data display

Comparison Table code

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

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

@props([
    'plans' => [],
    'rows' => [],
    'featured' => null,
])

@php
    /*
    | Feature comparison matrix — features down the side, plans across the top.
    | Boolean values render a check / dash; strings render as text. Group rows
    | by inserting a row with only a `group` key. Highlight a plan column with
    | `featured`. Feature rows highlight on hover; mark a key row as permanently
    | emphasized with `'highlight' => true`.
    |
    | Pass plans as a flat list of names, and rows as:
    |   ['feature' => 'SSO & SAML', 'values' => [false, true, true]]
    |   ['feature' => 'Uptime SLA', 'values' => [false, '99.9%', '99.99%'], 'highlight' => true]
    |   ['group' => 'Security']
    |
    | Usage:
    |   <x-ui.comparison-table :plans="['Free', 'Pro', 'Enterprise']" :rows="$rows" featured="Pro" />
    */
    $planList = array_values($plans);
    $featuredIndex = null;

    if ($featured !== null) {
        $featuredIndex = is_int($featured)
            ? $featured
            : array_search($featured, $planList, true);
        $featuredIndex = $featuredIndex === false ? null : $featuredIndex;
    }
@endphp

<div {{ $attributes->merge(['class' => 'relative overflow-x-auto rounded-2xl border border-gray-200 dark:border-gray-800']) }}>
    <table class="w-full border-collapse text-sm">
        <thead>
            <tr class="border-b border-gray-200 dark:border-gray-800">
                <th scope="col" class="bg-white px-5 py-4 text-left align-bottom dark:bg-gray-900">
                    <span class="text-xs font-semibold uppercase tracking-[0.12em] text-gray-500 dark:text-gray-400">Features</span>
                </th>
                @foreach ($planList as $i => $plan)
                    <th
                        scope="col"
                        @class([
                            'px-5 py-4 text-center align-bottom',
                            'bg-brand-50/60 dark:bg-brand-950/30' => $i === $featuredIndex,
                            'bg-white dark:bg-gray-900' => $i !== $featuredIndex,
                        ])
                    >
                        <span class="block text-base font-semibold text-gray-900 dark:text-white">{{ $plan }}</span>
                        @if ($i === $featuredIndex)
                            <span class="mt-1 inline-block rounded-full bg-brand-100 px-2 py-0.5 text-[0.6875rem] font-semibold text-brand-700 dark:bg-brand-950/60 dark:text-brand-300">Recommended</span>
                        @endif
                    </th>
                @endforeach
            </tr>
        </thead>

        <tbody class="divide-y divide-gray-100 dark:divide-gray-800">
            @foreach ($rows as $row)
                @if (isset($row['group']))
                    <tr class="bg-gray-50 dark:bg-gray-800/50">
                        <th scope="colgroup" colspan="{{ count($planList) + 1 }}" class="px-5 py-2.5 text-left text-xs font-semibold uppercase tracking-[0.12em] text-gray-500 dark:text-gray-400">
                            {{ $row['group'] }}
                        </th>
                    </tr>
                @else
                    @php($highlighted = (bool) ($row['highlight'] ?? false))
                    <tr @class([
                        'group transition-colors',
                        'bg-amber-50/60 hover:bg-amber-100/60 dark:bg-amber-950/20 dark:hover:bg-amber-950/30' => $highlighted,
                        'bg-white hover:bg-gray-50 dark:bg-gray-900 dark:hover:bg-gray-800/50' => ! $highlighted,
                    ])>
                        <th scope="row" class="px-5 py-3.5 text-left font-medium text-gray-700 dark:text-gray-300">
                            {{ $row['feature'] ?? '' }}
                        </th>
                        @foreach ($planList as $i => $plan)
                            @php($value = $row['values'][$i] ?? null)
                            <td
                                @class([
                                    'px-5 py-3.5 text-center',
                                    'bg-brand-50/40 group-hover:bg-brand-100/50 dark:bg-brand-950/20 dark:group-hover:bg-brand-950/40' => $i === $featuredIndex,
                                ])
                            >
                                @if ($value === true)
                                    <x-ui.icon name="check-circle" weight="fill" size="lg" class="text-brand-500" />
                                    <span class="sr-only">Included</span>
                                @elseif ($value === false || $value === null)
                                    <x-ui.icon name="minus" weight="bold" size="base" class="text-gray-300 dark:text-gray-600" />
                                    <span class="sr-only">Not included</span>
                                @else
                                    <span class="font-medium text-gray-700 dark:text-gray-300">{{ $value }}</span>
                                @endif
                            </td>
                        @endforeach
                    </tr>
                @endif
            @endforeach
        </tbody>
    </table>
</div>