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>