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

Combobox v2 issue with dynamic fetched options in nextjs #3184

Closed
lasseklovstad opened this issue May 8, 2024 · 3 comments · Fixed by #3259
Closed

Combobox v2 issue with dynamic fetched options in nextjs #3184

lasseklovstad opened this issue May 8, 2024 · 3 comments · Fixed by #3259
Assignees

Comments

@lasseklovstad
Copy link

lasseklovstad commented May 8, 2024

What package within Headless UI are you using?

@headlessui/react

What version of that package are you using?

v2.0.3

What browser are you using?

Chrome

Reproduction URL

Reproduction CodeSandbox

Describe your issue
combox-issue

After selecting an option and changing the input value the Input value resets back to the selected option. This is not how it was in the latest v1. This issue also seems only to occure in Nextjs. I could not reproduce it with the vite issue template.

  1. Type the letter "T" in inputfield and select the "Tailwind" option
  2. After selecting we want to search for something new, so we backspace 4 letters.
  3. This will trigger react query to run again and the input is reset to the selected value.

The excpected behavior is to not change the displayValue when changing the inputValue.

@juliancoleman
Copy link

Here to say I'm experiencing the same thing

@juliancoleman
Copy link

@lasseklovstad Following up here: I can temporarily get around this by setting the Combobox value to null if the input value has changed. This obviously isn't great and impacts the UX negatively (e.g. blurring the field will not reset to the previously selected value by default), which means more code will need to be written by you to restore the ideal UX.

Here's some (simplified) code I'm using that's running in production now using @headlessui/react ^2.0.3

type Place = {
  code: string; // can be empty string
  type: string; // can be empty string
};

export type LocationPickerProps = {
  /**
   * Available options to populate the menu
   */
  options: LocationResponse;
  /**
   * The selected value
   */
  value: Place | null;
  /**
   * Callback whenever a new selection is made
   */
  onChange(value: Place | null): void;
  /**
   * Callback whenever the search input value changes
   */
  onSearch(search: string): void;
};

export function LocationPicker(props: LocationPickerProps) {
  const {
    onChange,
    onSearch,
    options,
    value,
  } = props;

  const handleSearch = useMemo(
    () => debounce((input: string) => onSearch(input)),
    [onSearch],
  );

return (
    <Combobox
      value={value}
      onChange={(value) => onChange(value)}
      as="div"
      className="w-full"
      by="code"
      immediate
    >
      <Label className="flex w-full items-center gap-2.5 rounded-lg border border-grey-200 bg-grey-50 px-3 py-2.5 transition-all focus-within:border-grey-300 hover:border-grey-400">
        <ComboboxInput
          autoComplete="off"
          placeholder="Choose location"
          onChange={({ target }) => {
            onChange(null); // <-- this fixes the bug in question
            handleSearch(target.value);
          }}
          displayValue={(location: Place | null) => {
            if (
              location == null ||
              (location.type === "" && location.code === "")
            ) {
              return "";
            }

            const found = options.find(
              (o) =>
                o.code === location.code &&
                o.granularLocationType === location.type,
            );

            return found?.title ?? "";
          }}
          className="flex-1 bg-transparent text-sm outline-none"
        />
      </Label>

      {/* ... */}

    </Combobox>
  );
}

@RobinMalfait
Copy link
Collaborator

This should be fixed by #3259, and will be available in the next release.

You can already try it using:

  • npm install @headlessui/react@insiders.

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

Successfully merging a pull request may close this issue.

3 participants