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

bug: Dropdown does not close in an intuitive way #3382

Open
mkmoisen opened this issue Jan 14, 2025 · 4 comments
Open

bug: Dropdown does not close in an intuitive way #3382

mkmoisen opened this issue Jan 14, 2025 · 4 comments
Labels

Comments

@mkmoisen
Copy link

mkmoisen commented Jan 14, 2025

What version of daisyUI are you using?

https://play.tailwindcss.com/wWndQ9FxeZ

Which browsers are you seeing the problem on?

Chrome, Firefox

Reproduction URL

https://play.tailwindcss.com/wWndQ9FxeZ

Describe your issue

The DaisyUI dropdown method does not close in an intuitive way.

I suggest at the minimum there should be a react or svelte example on how to get it working with javascript in the documentation.

However I do wonder if making this close in an intuitive way by default would be a better fix.

The intuitive closing behavior is that the dropdown will close:

  • when the user clicks the button that opened the drop down
  • when the user clicks outside of the dropdown
  • when the user clicks an item in the dropdown

Perhaps the first two could happen automatically in the DaisyUI component while the third item would require some custom JS.

Method 1:

<details class="dropdown">
  <summary class="btn m-1">open or close</summary>
  <ul class="menu dropdown-content bg-base-100 rounded-box z-[1] w-52 p-2 shadow">
    <li><a>Item 1</a></li>
    <li><a>Item 2</a></li>
  </ul>
</details>
  • does not close when you click outside
  • does not close when you click a list item

It does however close when you click the "open or close" button.

Fixing this with javascript is relatively easy. Here it is in Svelte:

<script>
    let open = $state(false);
    
    function handleClick(event) {
        open = !open;
        event.stopPropagation();
    }

    function handleOutsideClick(event) {
        const dropdown = document.querySelector(".dropdown");
        if (!document.contains(event.target)) {
            open = false;
        }
    }
    
    onMount(() => {
        document.addEventListener("click", handleOutsideClick);
        return () => {
            docuement.removeEventListener("click", handleOutsideClick);
        }
    }
</script>

<details class="dropdown" bind:open}>
        <summary class="btn m-1">...</summary>
        <ul class="menu dropdown-content bg-base-100 rounded-box z-[1] w-52 p-2 shadow">
            <li><button onclick={handleClick}>Foo</button></li>
            <li><button onclick={handleClick}>Bar</button></li>
        </ul>
      </details>

Method 2:

<div class="dropdown">
  <div tabindex="0" role="button" class="btn m-1">Click</div>
  <ul tabindex="0" class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow">
    <li><a>Item 1</a></li>
    <li><a>Item 2</a></li>
  </ul>
</div>
  • does not close when you click a list item,
  • does it close when you click the "Click" button.

However it does close when you click outside.

Method 2 is harder to fix with javascript.

You need a handleClick and invoke a blur():

function handleClick(event) {
        const element = document.activeElement;
        if (element) {
            if (open) {
                if (element instanceof HTMLElement) {
                    element.blur();
                }
                open= false;
            } else {
                open= true;
            }
        }

        event.stopPropagation();
    }

In addition you still need a handleOutsideClick function to set open = false when the user clicks outside.

Copy link

Thank you @mkmoisen for reporting issues. It helps daisyUI a lot 💚
I'll be working on issues one by one. I will help with this one as soon as a I find a solution.
In the meantime providing more details and reproduction links would be helpful.

@saadeghi
Copy link
Owner

saadeghi commented Jan 15, 2025

Using <summary> and <details> tag, there's not much we can do about the behavior.
It is how the HTML <summary> tag works. (MDN docs) But of course you can customize the behavior using JS.

Using CSS focus, the behavior of clicking the button again to close the dropdown is fixed in daisyUI 5 (beta)
I can't change the behavior in daisyUI 4.x because it will break the websites that rely on the current behavior. It's a breaking change.

About the expectation of dropdown being closed with choosing an item:

  1. Yes it would be intuitive if we're talking about page navigation. If we're going from page A to B, you can expect the dropdown to close. But if it's not about page navigation, it's the opposite. For example consider Theme dropdown on top-right of daisyUI website. You would expect it to stay open so you can try another theme next.
  2. If it's a page navigation, it would still be intuitive with a MPA (multi page application). As we click a link the page changes so it doesn't matter what happens to the dropdown.
  3. If it's a page navigation in a SPA, it's important to understand that clicking the link is a JS click event and your framework/router is manipulating the DOM when you click a link, to give you that feeling of instant navigation. In this case, there's no way for CSS to behave according to a JS event. If your JS framework/router is changing the page content on click, you should also close the menu with JS.

Let me know if you have a question.

@saadeghi saadeghi added the v5 label Jan 15, 2025
@mkmoisen
Copy link
Author

Hi @saadeghi what you say makes sense, it is ambiguous as to what should happen when an item is clicked.

I do think it would be a good idea for DaisyUi's documentation to include javascript examples.

For example here:

https://daisyui.com/components/dropdown/#dropdown-menu-using-details-tag

Right now it shows three example tabs: preview, html, JSX.

Perhaps it could have some extra tabs for how to implement the various behaviors in javascript, react, svelte. Today you have to google "daisyui dropdown how to close".


As an aside, how stable do you think DaisyUI 5 is? If we don't mind minor breaking of backwards compatibility do you think we can give it a shot?

@saadeghi
Copy link
Owner

Agreed. I will add more details to docs.

how stable do you think DaisyUI 5 is? If we don't mind minor breaking of backwards compatibility do you think we can give it a shot?

  1. It is "safe" to use in production.
    It's not a JS library so it's not going to crash your site on client/server if there's a bug.
    It's not going to effect site's functionality for the user if something is broken.
    Worst thing can happen because of a bug in a CSS library, would be a visual displacement or misalignment of elements 😅

  2. There are no more breaking changes from now on.
    Only potential bug fixes
    So updating from beta to stable version would be seamless.

  3. Tailwind CSS 4 is still beta.
    Until now, most Tailwind CSS beta releases were about bug fixes so no further breaking changes are expected from Tailwind CSS either.

  4. Try updating on local first, check all the pages manually to make sure everything looks good visually. Then update it on production.

Release notes are here: https://v5.daisyui.com/docs/v5-beta/
Detailed changelog is here: https://v5.daisyui.com/docs/changelog/

Let me know if you have a question.

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

No branches or pull requests

2 participants