0

I am creating a nested sortable list in react using the dnd package. Each item inside the draggable contains input fields wrapped inside the Disclosure component from @headlessui. I am updating the item value with onChange on each input field.

The item field is updating on every input but the problem is disclosure panel closes immediately on keystroke. The issue is probably due to rerendering the list I simply tried making a list of the Disclosure panels without dnd and it doesn't close the Disclosure panel on input.

I have reproduced the issue in repl.it sample and I think it's too long to post code here.

export default function App() {
  const [items, setItems] = useState([
    {id: 1, title: 'My Item 1'},
    {id: 2, title: 'My Item 2'},
    {id: 3, title: 'My Item 3'},
    {id: 4, title: 'My Item 4'},
  ]);

  const handleInputChange = (e, item) => {
    const {name, value} = event.target;
    setItems(prev => 
      [
        ...prev.map((elm) => {
          if (elm.id === item.id) {
            elm[name] = value;
          }
          return elm;
        })
      ]
    )
  }
  return (
    <main>
      <SortableTree
                  items={items}
                  onItemsChanged={setItems}
                  
                  TreeItemComponent={forwardRef((props, ref) => {
                    return (
                      <SimpleTreeItemWrapper
                        {...props}
                        showDragHandle={false}
                        disableCollapseOnItemClick={true}
                        hideCollapseButton={true}
                        indentationWidth={20}
                        ref={ref}
                        className={"w-[400px]"}
                      >
                        <Disclosure as="div" className={"w-full mb-2"}>
                          {({ open }) => (
                            <>
                              <Disclosure.Button
                                open={true}
                                className="flex items-center w-full justify-between bg-[#F6F7F7] border border-gray-200 px-3 py-2 text-left text-xs font-medium text-gray-600 shadow-sm hover:border-gray-400 focus:outline-none focus-visible:ring focus-visible:ring-purple-500 focus-visible:ring-opacity-75"
                              >
                                <span>{props.item.title}</span>
                                <ChevronUpIcon
                                  className={`${
                                    open ? "rotate-180 transform" : ""
                                  } h-5 w-5 text-gray-500`}
                                />
                              </Disclosure.Button>
                              <Disclosure.Panel className="px-4 pt-4 pb-2 text-sm text-gray-500">
                                
                                <div className="flex flex-col mb-2">
                                  <label
                                    htmlFor="nav_label"
                                    className="text-xs mb-1"
                                  >
                                    Navigation Label
                                  </label>
                                  <input
                                    onChange={(e) => handleInputChange(e, props.item)}
                                    name='title'
                                    type={"text"}
                                    className="px-2 py-1 border border-gray-400"
                                    value={props.item.title}
                                  />
                                </div>
                                
                                <div className="">
                                  <button
                                    
                                    className="text-red-500 text-xs"
                                  >
                                    Remove
                                  </button>
                                </div>
                              </Disclosure.Panel>
                            </>
                          )}
                        </Disclosure>
                      </SimpleTreeItemWrapper>
                    );
                  })}
                />
    </main>
  )
}

0 Answers0