Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't use button element as accordion heading #1030

Open
3 tasks done
ruskiyos opened this issue Jan 24, 2025 · 1 comment
Open
3 tasks done

Don't use button element as accordion heading #1030

ruskiyos opened this issue Jan 24, 2025 · 1 comment

Comments

@ruskiyos
Copy link

ruskiyos commented Jan 24, 2025

Flux (pro) version

v1.1.2

Livewire version

v3.5.18

What is the problem?

The accordion uses a <button> element for the heading of the accordion item.
That becomes a problem if I want to add a button into the accordion header.

My use case is that I'm displaying a list of items. To save space, I use the accordion to display the name and some actions in the header. If the user wants more details, they can expand the accordion item to see/modify the contents.
I would like it add a delete button into the header to allow the user to remove an item from the list. However, as soon as I add a button, it breaks the HTML as it is invalid to have a <button> element inside a <button> element.

Note: I'm not sure if using a table would be more suitable for this, but flux table doesn't have collapsible rows.

// Before adding button
Image

// After adding button
Image

Code snippets

// flux code

<flux:accordion.heading>
    <div class="flex justify-between items-center">
        <div>{{$item['import_data']['name'] ?? '(no name)'}}</div>
        <div>
            <flux:switch
                wire:model="form.items.{{ $loop->index }}.is_approved"
                label="Is Approved"
                type="switch"
            />
            <!-- any button breaks the html
            <button></button>
            -->
        </div>
    </div>
</flux:accordion.heading>

// rendered code (without button)

<ui-disclosure
        class="block pt-4 first:pt-0 pb-4 last:pb-0 border-b last:border-b-0 border-zinc-800/10 dark:border-white/10"
        wire:key="item-0" x-data="{ open: false }" x-model.self="open" data-flux-accordion-item="">
    <button type="button"
            class="group/accordion-heading flex items-center w-full text-left text-sm font-medium justify-between [&amp;>svg]:ml-6 text-zinc-800 dark:text-white cursor-pointer"
            data-flux-accordion-heading="" aria-controls="lofi-disclosure-b81d3fe28c223" aria-expanded="false">
        <span class="flex-1">
            <div class="flex justify-between items-center">
                <div>Treutel-Hammes</div>
                <div>
                    <ui-field
                        class="min-w-0 [&amp;:not(:has([data-flux-field])):has([data-flux-control][disabled])>[data-flux-label]]:opacity-50 [&amp;:has(>[data-flux-radio-group][disabled])>[data-flux-label]]:opacity-50 [&amp;:has(>[data-flux-checkbox-group][disabled])>[data-flux-label]]:opacity-50 grid gap-x-3 gap-y-1.5 has-[[data-flux-label]~[data-flux-control]]:grid-cols-[1fr_auto] has-[[data-flux-control]~[data-flux-label]]:grid-cols-[auto_1fr] [&amp;>[data-flux-control]~[data-flux-description]]:row-start-2 [&amp;>[data-flux-control]~[data-flux-description]]:col-start-2 [&amp;>[data-flux-control]~[data-flux-error]]:col-span-2 [&amp;>[data-flux-control]~[data-flux-error]]:mt-1 [&amp;>[data-flux-label]~[data-flux-control]]:row-start-1 [&amp;>[data-flux-label]~[data-flux-control]]:col-start-2"
                        data-flux-field="">
                        <ui-label class="text-sm font-medium select-none text-zinc-800 dark:text-white" data-flux-label=""
                            id="lofi-label-e86e9c226a72c" aria-hidden="true">Is Approved</ui-label>
                        <ui-switch
                                class="group h-5 w-8 relative inline-flex items-center outline-offset-2 rounded-full transition bg-zinc-800/15 [&amp;[disabled]]:opacity-50 dark:bg-transparent dark:border dark:border-white/20 dark:[&amp;[disabled]]:border-white/10 [print-color-adjust:exact] data-[checked]:bg-[var(--color-accent)] data-[checked]:border-0"
                                wire:model="form.items.0.is_approved" label="Is Approved" type="switch" wire:click.stop="doNothing"
                                data-flux-control="" data-flux-switch="" aria-checked="false" role="switch" tabindex="0"
                                aria-labelledby="lofi-label-e86e9c226a72c">
                            <span class="size-3.5 rounded-full transition translate-x-[3px] dark:translate-x-[2px] bg-white group-data-[checked]:translate-x-[15px] group-data-[checked]:bg-[var(--color-accent-foreground)]"></span>
                        </ui-switch>
                        <div aria-live="assertive" class="mt-3 text-sm font-medium text-red-500 dark:text-red-400 hidden"
                             data-flux-error=""></div>
                    </ui-field>
                </div>
            </div>
        </span>
        <svg class="shrink-0 [:where(&amp;)]:size-5 text-zinc-300 dark:text-zinc-400 group-hover/accordion-heading:text-zinc-800 dark:group-hover/accordion-heading:text-white hidden group-data-[open]/accordion-heading:block !text-zinc-800 dark:!text-white"
             aria-hidden="true" data-flux-icon="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"
             fill="currentColor" data-slot="icon">
            <path fill-rule="evenodd"
                  d="M9.47 6.47a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 1 1-1.06 1.06L10 8.06l-3.72 3.72a.75.75 0 0 1-1.06-1.06l4.25-4.25Z"
                  clip-rule="evenodd"></path>
        </svg>
        <svg class="shrink-0 [:where(&amp;)]:size-5 text-zinc-300 dark:text-zinc-400 group-hover/accordion-heading:text-zinc-800 dark:group-hover/accordion-heading:text-white block group-data-[open]/accordion-heading:hidden"
             aria-hidden="true" data-flux-icon="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"
             fill="currentColor" data-slot="icon">
            <path fill-rule="evenodd"
                  d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z"
                  clip-rule="evenodd"></path>
        </svg>
    </button>
    <div x-show="open" data-flux-accordion-content="" id="lofi-disclosure-b81d3fe28c223" style="display: none;">
        <div class="pt-2 text-sm text-zinc-500 dark:text-zinc-300">
            <!-- content -->
        </div>
    </div>
</ui-disclosure>

How do you expect it to work?

I expect to be able to add any component/element into the accordion heading, or to have collapsible rows in tables.
I figured the accordion would be an easier fix than adding extra functionality to tables.

Please confirm (incomplete submissions will not be addressed)

  • I have provided easy and step-by-step instructions to reproduce the bug.
  • I have provided code samples as text and NOT images.
  • I understand my bug report will be closed if I haven't met the criteria above.
@ruskiyos
Copy link
Author

ruskiyos commented Jan 24, 2025

Note: I was able to get around the button limitation for now by using the flux icon directly, but it still feels like this should be changed to not use a button as the header item

<flux:accordion.heading>
    <div class="flex justify-between items-center">
        <div>{{$item['import_data']['name'] ?? '(no name)'}}</div>
        <div class="flex">
            <flux:switch
                    wire:model="form.items.{{ $loop->index }}.is_approved"
                    label="Is Approved"
                    type="switch"
            />
            <flux:icon.trash class="size-5 ml-2"
                     wire:click.stop="removeItem({{ $loop->index }})"
            />
        </div>
    </div>
</flux:accordion.heading>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant