Layout

collapsible

An interactive panel that expands and collapses its content.

@peduarte starred 3 repositories

@radix-ui/primitives
@radix-ui/colors
@stitches/react
<x-ui.collapsible class="w-full max-w-sm space-y-2">
    <div class="flex items-center justify-between gap-4 px-1">
        <h4 class="text-sm font-semibold">
            &commat;peduarte starred 3 repositories
        </h4>
        <x-ui.collapsible.trigger
            class="inline-flex size-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
                fill="none" stroke="currentColor" stroke-width="2"
                stroke-linecap="round" stroke-linejoin="round" class="size-4">
                <path d="m7 15 5 5 5-5" />
                <path d="m7 9 5-5 5 5" />
            </svg>
            <span class="sr-only">Toggle</span>
        </x-ui.collapsible.trigger>
    </div>
    <div class="rounded-md border px-4 py-2 font-mono text-sm">
        &commat;radix-ui/primitives
    </div>
    <x-ui.collapsible.content class="space-y-2">
        <div class="rounded-md border px-4 py-2 font-mono text-sm">
            &commat;radix-ui/colors
        </div>
        <div class="rounded-md border px-4 py-2 font-mono text-sm">
            &commat;stitches/react
        </div>
    </x-ui.collapsible.content>
</x-ui.collapsible>

Installation

php artisan ui:add collapsible

1. Install dependencies

  • composer: gehrisandro/tailwind-merge-laravel
  • npm: alpinejs
  • npm: @alpinejs/collapse

2. Copy each file into resources/views/components/ui/

resources/views/components/ui/collapsible/index.blade.php

@props([
    'open' => false,
])

@php
    $classes = \TailwindMerge\Laravel\Facades\TailwindMerge::merge(
        'group/collapsible',
        $attributes->get('class'),
    );
@endphp

<div x-data="{ open: @js((bool) $open) }"
    x-bind:data-state="open ? 'open' : 'closed'"
    {{ $attributes->except('class')->merge(['class' => $classes]) }}>
    {{ $slot }}
</div>

resources/views/components/ui/collapsible/trigger.blade.php

@props([])

@php
    $classes = \TailwindMerge\Laravel\Facades\TailwindMerge::merge(
        'outline-none focus-visible:ring-ring/50 focus-visible:ring-[3px]',
        $attributes->get('class'),
    );
@endphp

<button type="button" @click="open = !open"
    x-bind:aria-expanded="open.toString()"
    {{ $attributes->except('class')->merge(['class' => $classes]) }}>
    {{ $slot }}
</button>

resources/views/components/ui/collapsible/content.blade.php

@props([])

@php
    $classes = \TailwindMerge\Laravel\Facades\TailwindMerge::merge(
        '',
        $attributes->get('class'),
    );
@endphp

<div x-show="open" x-collapse x-cloak
    {{ $attributes->except('class')->merge(['class' => $classes]) }}>
    {{ $slot }}
</div>

Usage

<x-ui.collapsible :open="false">
    <x-ui.collapsible.trigger>Toggle</x-ui.collapsible.trigger>
    <x-ui.collapsible.content>
        Hidden content revealed on toggle.
    </x-ui.collapsible.content>
</x-ui.collapsible>

Requires Alpine.js + the @alpinejs/collapse plugin (x-collapse). Compose <x-ui.collapsible>, <x-ui.collapsible.trigger>, <x-ui.collapsible.content>; pass :open to start expanded.