daisyui icon indicating copy to clipboard operation
daisyui copied to clipboard

Dropdown element close event

Open francescocretti opened this issue 3 years ago โ€ข 1 comments

Hi everyone. Thanks for this useful project.

I was wondering if there's a way to get an onClose-like event on the Dropdown Element.

I have an <input> element inside the dropdown that needs to be refreshed when the menu is closed.

I tried the onBlur event on the opener button but, rightly, it works only if the button itself is focused, that's false if the user is writing in the input fiels.

I'm using React and here's how my component looks like:

NOTE - I'm using tw- prefix to all Tailwind and Daisy UI classes

import React, { useCallback, useEffect, useRef, useState } from 'react';

const ElementsDropdown = ({ elements }) => {

  const [showInput, setShowInput] = useState(false);

  const [newElementName, setNewElementName] = useState('');

  const menuRef = useRef(null);

  const inputRef = useRef(null);

  useEffect(() => {

    if (!showInput || !inputRef.current) {
      return;
    }

    inputRef.current.focus();

  }, [showInput]);

  const handleClose = useCallback(() => {
    const { visibility } = window.getComputedStyle(menuRef.current, null);
    if (visibility === 'hidden') {
      setNewElementName('');
      setShowInput(false);
    }
  }, []);

  return (
    <div className="tw-dropdown">

      <label
        tabIndex="0"
        className="tw-btn tw-btn-sm tw-text-cp-blue tw-border-cp-blue tw-rounded hover:!tw-bg-cp-athens-gray"
        onBlur={handleClose}
      >
       OPEN
      </label>

      <ul
        ref={menuRef}
        tabIndex="0"
        className="tw-dropdown-content tw-menu tw-p-2 tw-shadow tw-bg-base-100 tw-w-52"
      >

        {/* TODO - render elements items */}

        <li className='tw-preferiti-dropdown-item'>
          <div className='tw-inline-block tw-py-[.5rem] tw-px-[.5rem] tw-border-t'>
            <button
              className='tw-w-full tw-rounded tw-btn tw-btn-sm tw-btn-primary tw-normal-case'
              onClick={() => {
                if (newElementName) {
                  // TODO - add to elements list via API
                } else { 
                  setShowInput(true)
                }
              }}
            >
              {newElementName ?
                `Create element "${newElementName}"` :
                'New Element'
              }
            </button>
          </div>
        </li>

        {showInput && (
          <li className='tw-preferiti-dropdown-item'>
            <div className='tw-w-full tw-inline-block tw-py-[.5rem] tw-px-[.5rem]'>
              <input
                ref={inputRef}
                className="tw-input tw-w-full tw-rounded tw-input-bordered tw-border-[#ced4da] tw-h-[38px] focus:tw-border-cp-light-blue-50"
                type="text"
                value={newElementName}
                onChange={e => setNewElementName(e.target.value)}
              />
            </div>
          </li>
        )}

      </ul>

    </div>
  )
}

export default PreferitiDropdown

francescocretti avatar Jun 22 '22 16:06 francescocretti

So what is the actual solution for getting an open dropdown to close again? Or is JavaScript required?

Rar9 avatar Jul 26 '22 04:07 Rar9

If you don't want the dropdown to work with focus, you can add or remove dropdown-open class.
Similar issue: https://github.com/saadeghi/daisyui/issues/157
JS Example: https://play.tailwindcss.com/4Mu9MGOmat

saadeghi avatar Nov 01 '22 15:11 saadeghi

Hi @saadeghi , thanks for the reply.

I don't think that's a solution for my case: I would like to have an event when the menu is closed, whether is done by the blur/focus or not, to refresh the content of the menu itself.

I hope I did not misunderstand your answer.

francescocretti avatar Nov 03 '22 12:11 francescocretti

@francescocretti If you want an event for when the dropdown is closed, it's simply the blur on the button:

onblur="console.log('blurred')"

https://play.tailwindcss.com/ebar5KSVd4

Let me know if that works for you.

saadeghi avatar Nov 05 '22 17:11 saadeghi

@francescocretti If you want an event for when the dropdown is closed, it's simply the blur on the button:

onblur="console.log('blurred')"

https://play.tailwindcss.com/ebar5KSVd4

Let me know if that works for you.

This event happens with the dropdown button loses focus (even if when one of the menu items is clicked and the dropdown has not gone away).

I want the event when the dropdown-content is not displayed anymore.

chrisvire avatar Feb 24 '23 15:02 chrisvire