Skip to main content

Navigation

Accordion code

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

resources/views/components/ui/accordion.blade.php

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

@php
    /*
    | Accordion container. Use one or more <x-ui.accordion.item> inside. Set
    | `multiple` to allow more than one item open at a time.
    |
    | Usage:
    |   <x-ui.accordion>
    |       <x-ui.accordion.item question="Can I cancel?">Yes, anytime.</x-ui.accordion.item>
    |   </x-ui.accordion>
    */
@endphp

<div
    x-data="{
        items: [],
        multiple: @js($multiple),
        toggle(id) {
            if (this.items.includes(id)) {
                this.items = this.items.filter(i => i !== id);
            } else {
                this.items = this.multiple ? [...this.items, id] : [id];
            }
        },
        isOpen(id) { return this.items.includes(id); }
    }"
    {{ $attributes->merge(['class' => 'divide-y divide-gray-200 dark:divide-gray-800 rounded-2xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900']) }}
>
    {{ $slot }}
</div>

resources/views/components/ui/accordion/item.blade.php

@props([
    'question',
])

@php
    /* A single accordion row. Place inside <x-ui.accordion>. */
    $id = 'acc_'.\Illuminate\Support\Str::random(8);
@endphp

<div x-data="{ id: '{{ $id }}' }">
    <button
        type="button"
        @click="toggle(id)"
        :aria-expanded="isOpen(id)"
        class="flex w-full items-center justify-between gap-4 px-6 py-4 text-left transition hover:bg-gray-50 dark:hover:bg-gray-800/40 cursor-pointer"
    >
        <span class="text-sm font-medium text-gray-900 dark:text-white">{{ $question }}</span>
        <x-ui.icon
            name="caret-down" weight="bold" size="base"
            ::class="isOpen(id) ? 'rotate-180' : ''"
            class="shrink-0 text-gray-400 transition-transform duration-200"
        />
    </button>

    <div x-show="isOpen(id)" x-collapse x-cloak>
        <div class="px-6 pb-5 text-sm text-gray-600 dark:text-gray-300">
            {{ $slot }}
        </div>
    </div>
</div>