nextui-org / nextui

🚀 Beautiful, fast and modern React UI library.
https://nextui.org
MIT License
21.89k stars 1.52k forks source link

[BUG] - Autocomplete is not focused on click #2962

Closed simPod closed 5 months ago

simPod commented 5 months ago

NextUI Version

2.3.6

Describe the bug

When I click on autocomplete, it is not focused. It requires another click. Also click-outside event closes the menu but keeps the focus.

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

  1. https://nextui.org/docs/components/autocomplete#usage
  2. click "select an animal"
  3. menu opens but you can't type
  4. click again
  5. now you can type

  1. https://nextui.org/docs/components/autocomplete#usage
  2. click "select an animal"
  3. menu opens but you can't type
  4. click outside to cancel action
  5. now you can type (???)

Expected behavior

  1. https://nextui.org/docs/components/autocomplete#usage
  2. click "select an animal"
  3. menu opens, now you can type

Screenshots or Videos

https://github.com/nextui-org/nextui/assets/327717/8c3bbac0-b08e-4e42-aa21-d3fa3395e92d

Operating System Version

macos

Browser

Chrome

linear[bot] commented 5 months ago

ENG-803 [BUG] - Autocomplete is not focused on click

jwald1 commented 5 months ago

"When the menuTrigger is set to input, the focus behavior becomes worse. Here's how the flow works:

  1. The user clicks on the input field.

  2. The user types one character.

  3. The menu opens and the focus is lost.

  4. The user needs to click on the input field again to continue typing.

This can be very confusing for users as they may continue to type without realizing that the menu has opened and the focus has been lost, resulting in the words not being typed.

shoaibarif668 commented 5 months ago

Has anyone come up with a solution for this, its still reproducing on my end. The input looses focus as soon as the menu opens up.

wingkwong commented 5 months ago

@shoaibarif668 I'll wrap up the fix by today and will be released afterwards.

GDamicoCenta commented 5 months ago

@wingkwong Hi, friend. any news on this? I have the same problem :(

Aryan-mor commented 5 months ago

@wingkwong Hi, friend. any news on this? I have the same problem :(

It's already fixed, it will merge https://github.com/nextui-org/nextui/pull/2854

kevinvincent commented 5 months ago

I am still seeing this issue using a brand new project with npx nextui-cli@latest init nextuitest

wingkwong commented 5 months ago

@kevinvincent I couldn't reproduce the issue.

autocomplete-focus-demo.webm

kevinvincent commented 5 months ago

Had to upload the video as a zip due to size: bug.mov.zip

This is from a completely new project with npx nextui-cli@latest init nextuitest using defaults. All I did was add the autocomplete. The first click opens in the dropdown, the second click focuses the input.

I also saw the same behavior in Chrome, the demo uses Safari though.

Interestingly, it works fine on https://nextui.org/docs/components/autocomplete for me!

kevinvincent commented 5 months ago

Hmm this seems to have magically fixed itself? Maybe this was some weird local next js / browser caching or something?

NikitaDen commented 5 months ago

wingkwong I couldn't reproduce the issue

Issue is still reproduceable. I have to click twice to focus input. I tried both installation types: CLI and manual.

Windows 10 Google Chrome Version 125.0.6422.141 (Official Build) (64-bit)

CLI - autocomplete version: "@nextui-org/autocomplete": "^2.1.1"

Manual - nextui version: "@nextui-org/react": "^2.4.1"

https://github.com/nextui-org/nextui/assets/47031692/57de79d6-8aab-4f36-b837-3d263a78bfa8

wingkwong commented 5 months ago

@NikitaDen please provide a minimal reproducible example.

NikitaDen commented 5 months ago

@wingkwong Basically copied example from the docs for Autocomplete component.

Project created via CLI using Vite. Autocomplete has been installed via npx nextui-cli@latest add autocomplete

App.tsx file:

import {Autocomplete, AutocompleteItem} from "@nextui-org/react";

const animals = [
  {label: "Cat", value: "cat", description: "The second most popular pet in the world"},
  {label: "Dog", value: "dog", description: "The most popular pet in the world"},
  {label: "Elephant", value: "elephant", description: "The largest land animal"},
  {label: "Lion", value: "lion", description: "The king of the jungle"},
  {label: "Tiger", value: "tiger", description: "The largest cat species"},
  {label: "Giraffe", value: "giraffe", description: "The tallest land animal"},
  {label: "Penguin", value: "penguin", description: "A group of aquatic flightless birds"},
  {label: "Zebra", value: "zebra", description: "A several species of African equids"}
];

export default function App() {
  return (
    <div className="flex w-full flex-wrap md:flex-nowrap gap-4">
      <Autocomplete
        label="Select an animal"
        className="max-w-xs"
      >
        {animals.map((animal) => (
          <AutocompleteItem key={animal.value} value={animal.value}>
            {animal.label}
          </AutocompleteItem>
        ))}
      </Autocomplete>
      <Autocomplete
        label="Favorite Animal"
        placeholder="Search an animal"
        className="max-w-xs"
        defaultItems={animals}
      >
        {(item) => <AutocompleteItem key={item.value}>{item.label}</AutocompleteItem>}
      </Autocomplete>
    </div>
  );
}

main.tsx file:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import {NextUIProvider} from '@nextui-org/react'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <NextUIProvider>
      <App />
    </NextUIProvider>
  </React.StrictMode>,
)
halesyy commented 4 months ago

This is a great component, and I can't wait until it's improved with the above fix in production. I'm unfortunately still getting this issue when intermixing dynamic data with the menu. If I could, I'd just set the menu to always be open - so I am now considering using a Input + Listbox since this is odd behaviour.

I'm still getting this bug on "@nextui-org/react": "^2.3.6", using NextJS 14.0.3. Using a similar approach with rendering items, and mine is stuck behind a modal which could be contributing.

Switching to "manual" works on first click to get focus. "Focus" exhibits the same properties. "Input" with custom input causes the ability to only type 1 letter at a time.

Using allowsCustomValue**

halesyy commented 4 months ago

I've just had a go modifying my code a few ways around, and it seems to remove this behaviour when I stop using dynamic data, and place in [] into items, or and render using the anonymous function method. When adding items, this behaviour shows up.

Removing allowsCustomValue does not fix this issue on my side when using items.

Removing managed input value does not help either.

Just wanted to add.

alarv commented 4 months ago

Same for me keeps happening with dynamic items, you have to click the input twice to get it to focus

BW-Blake commented 4 months ago

I'm using this as a temporary hack until the next release.

  useEffect(() => {
    const autocompleteElements = document.querySelectorAll('[aria-autocomplete]');
    autocompleteElements.forEach(element => {
      element.closest('[data-slot="base"]').addEventListener('click', e => {
        (e.currentTarget as Element).querySelector('input').focus();
      });
    });
  }, []);
computerd36 commented 4 months ago

I have the same problem, nothing fixed it exept the temporary hack of BW-Blake.

In typescript it has to look like this:

// WORKAROUND UNTIL NEXTUI UPDATE
    React.useEffect(() => {
        const autocompleteElements = document.querySelectorAll('[aria-autocomplete]');
        autocompleteElements.forEach(element => {
            element.closest('[data-slot="base"]')?.addEventListener('click', e => {
                (e.currentTarget as Element).querySelector('input')?.focus();
            });
        });
    }, []);
b-owl commented 2 months ago

I had the same problem.

I fixed it using this snippet:

 const handleClose = () => {
    if (document.activeElement instanceof HTMLElement) {
      document.activeElement.blur();
    }
  };
  <Autocomplete
            aria-label="test-type"
            inputValue={newFilterSearch?.testtype}
            value={newFilterSearch?.testtype}
            onSelectionChange={(e) => {
              setNewFilterSearch({
                ...newFilterSearch,
                testtype: (e as any) || "All",
              });
              handleClose();
            }}
            onClose={handleClose}
            size="lg"
            fullWidth
            allowsCustomValue
            isClearable={false}
            placeholder={t("SEARCHBAR.PLACEHOLDER")}
            items={types}
            radius="none"
          >
            {(item: any) => (
              <AutocompleteItem key={item.value}>{item.label}</AutocompleteItem>
            )}
          </Autocomplete>