Skip to main content

Autocomplete

Search and choose one or more options from a list.

Package@g4rcez/componentsSectionForm Controls

Examples

Basic Autocomplete

A basic autocomplete with a list of programming languages. Selecting an option updates the controlled value.

tsx
"use client";
import { useState, useEffect } from "react";
import { Autocomplete } from "@g4rcez/components";

const defaults = [
  { label: "JavaScript", value: "javascript" },
  { label: "Python", value: "python" },
  { label: "TypeScript", value: "typescript" },
  { label: "Java", value: "java" },
  { label: "Go", value: "go" },
  { label: "Rust", value: "rust" },
];

function BasicAutocomplete() {
  const [options, setOptions] = useState([]);
  const [value, setValue] = useState("");

  useEffect(() => {
    setOptions(defaults);
    setValue(defaults[0]?.value);
  }, []);

  return (
    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
      <Autocomplete
        id="basic-demo"
        required
        value={value}
        options={options}
        title="Programming Language"
        placeholder="Select a language"
        onChange={(e) => setValue(e.target.value)}
      />
      <Autocomplete
        id="basic-demo-2"
        options={options}
        title="Overflow Demo"
        placeholder="Try searching for many options"
      />
    </div>
  );
}

Create a New Option

Use dynamicOption to select a suggested language or enter a new one without an option validation error. Press Enter, select the option, or leave the field to accept the typed value.

tsx
"use client";
import { useState, type ChangeEvent } from "react";
import { Autocomplete } from "@g4rcez/components";

const initialOptions = [
  { label: "JavaScript", value: "javascript" },
  { label: "Python", value: "python" },
  { label: "TypeScript", value: "typescript" },
];

function CreatableAutocomplete() {
  const [options, setOptions] = useState(initialOptions);
  const [value, setValue] = useState("");

  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    const nextValue = event.target.value.trim();
    setValue(nextValue);
    if (!nextValue) return;

    setOptions((current) => {
      const normalizedValue = nextValue.toLowerCase();
      const exists = current.some(
        (option) =>
          option.value.toLowerCase() === normalizedValue ||
          option.label.toLowerCase() === normalizedValue,
      );

      return exists
        ? current
        : [...current, { label: nextValue, value: nextValue }];
    });
  };

  return (
    <Autocomplete
      dynamicOption
      title="Programming language"
      placeholder="Search or create a language"
      options={options}
      value={value}
      onChange={handleChange}
    />
  );
}

Empty and Disabled States

Demonstrates autocomplete in empty and disabled states.

tsx
"use client";
import { Autocomplete } from "@g4rcez/components";

function EmptyDisabledAutocomplete() {
  return (
    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
      <Autocomplete
        id="empty-demo"
        options={[]}
        title="Empty Autocomplete"
        placeholder="No options available"
        emptyMessage="No results found."
      />
      <Autocomplete
        id="disabled-demo"
        disabled
        options={[]}
        title="Disabled Autocomplete"
        placeholder="This input is disabled"
        emptyMessage="No results found."
      />
    </div>
  );
}

Autocomplete in Modal

Demonstrates how Autocomplete behaves when placed inside a Modal component.

tsx
"use client";
import { useState, Fragment } from "react";
import { Autocomplete, Button, Modal } from "@g4rcez/components";

const defaults = [
  { label: "JavaScript", value: "javascript" },
  { label: "Python", value: "python" },
  { label: "TypeScript", value: "typescript" },
  { label: "Java", value: "java" },
  { label: "Go", value: "go" },
  { label: "Rust", value: "rust" },
];

function SelectOnModal() {
  const [open, setOpen] = useState(false);
  return (
    <Fragment>
      <Modal open={open} onChange={setOpen} title="Select on modal">
        <Autocomplete
          id="select-on-modal"
          rightLabel=" "
          title="One option"
          options={defaults}
          placeholder="Choose a language"
        />
      </Modal>
      <Button onClick={() => setOpen(true)}>Open modal</Button>
    </Fragment>
  );
}

Field Sizes

Use size=normal or size=small when you need autocomplete fields to fit different densities.

tsx
import { Autocomplete } from "@g4rcez/components";

function AutocompleteSizes() {
  return (
    <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
      <Autocomplete size="normal" title="Normal autocomplete" options={defaults} placeholder="Choose a language" />
      <Autocomplete size="small" title="Small autocomplete" options={defaults} placeholder="Choose a language" />
    </div>
  );
}

When to use Autocomplete

Use when

Use Autocomplete when a user selects one or more known options from a searchable list.

Avoid when

Avoid it for a short, stable list that is faster to scan as native radio buttons or a select.

Accessibility

Keep the field labeled, announce the expanded state, and make option movement and selection available from the keyboard.

  • Keep keyboard focus visible and follow the documented key commands.
  • Provide an accessible name and connect descriptions or errors to the control.