General
Collapsible code
Copy the implementation or inspect every file that belongs to this component unit.
resources/views/components/ui/collapsible.blade.php
@props([
'open' => false,
'icon' => null,
'trigger' => null,
])
@php
/*
| Collapsible — a single show/hide region (unlike the grouped accordion).
| The default trigger is a full-width row with a chevron; pass `open` to
| start expanded. A plain-text `trigger` (prop or slot) is rendered inside
| the default styled row; a trigger slot containing markup replaces the
| row entirely (bring your own padding — `toggle()` and `open` are in scope).
|
| Usage:
| <x-ui.collapsible trigger="Advanced options">
| <p>Hidden settings go here.</p>
| </x-ui.collapsible>
|
| <x-ui.collapsible :open="true" icon="gear">
| <x-slot:trigger><div class="flex items-center justify-between px-4 py-3">Custom heading</div></x-slot:trigger>
| ...
| </x-ui.collapsible>
*/
$triggerHtml = $trigger instanceof \Illuminate\View\ComponentSlot ? trim($trigger->toHtml()) : null;
$triggerIsCustomMarkup = $triggerHtml !== null && $triggerHtml !== '' && $triggerHtml !== strip_tags($triggerHtml);
$triggerLabel = is_string($trigger) ? e($trigger) : ($triggerIsCustomMarkup ? null : $triggerHtml);
@endphp
<div
x-data="{ open: @js((bool) $open), toggle() { this.open = ! this.open; } }"
{{ $attributes->merge(['class' => 'rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900']) }}
>
@if ($triggerIsCustomMarkup)
<div @click="toggle()" :aria-expanded="open" role="button" tabindex="0" @keydown.enter.prevent="toggle()" @keydown.space.prevent="toggle()" class="cursor-pointer">
{{ $trigger }}
</div>
@else
<button
type="button"
@click="toggle()"
:aria-expanded="open"
class="flex w-full items-center justify-between gap-4 px-4 py-3 text-left transition hover:bg-gray-50 dark:hover:bg-gray-800/40 cursor-pointer"
>
<span class="flex items-center gap-2.5 text-sm font-medium text-gray-900 dark:text-white">
@if ($icon)<x-ui.icon :name="$icon" size="base" class="text-gray-400 dark:text-gray-500" />@endif
{!! $triggerLabel !== null && $triggerLabel !== '' ? $triggerLabel : 'Toggle' !!}
</span>
<x-ui.icon
name="caret-down" weight="bold" size="base"
::class="open ? 'rotate-180' : ''"
class="shrink-0 text-gray-400 transition-transform duration-200"
/>
</button>
@endif
<div x-show="open" x-collapse x-cloak>
<div class="px-4 pb-4 text-sm text-gray-600 dark:text-gray-300">
{{ $slot }}
</div>
</div>
</div>