Skip to component content
Input052 / 155

SearchField

Provide a native search field with local suggestions.

Example
Enter
Search by component name.

Suggestions are native datalist options.

Source
SearchField.tsxtsx
import { useState } from "react";
import { MagnifyingGlassIcon } from "@phosphor-icons/react";
import { Button, Form, HStack, Picker, SearchField, Text, VStack } from "@/ohmygui";

type FieldMode = "normal" | "required" | "error" | "readOnly" | "disabled";
const modes: { value: FieldMode; label: string }[] = [
  { value: "normal", label: "Normal" }, { value: "required", label: "Required" },
  { value: "error", label: "Error" }, { value: "readOnly", label: "Read only" },
  { value: "disabled", label: "Disabled" },
];

export default function Example() {
  const [query, setQuery] = useState("");
  const [mode, setMode] = useState<FieldMode>("normal");
  const [message, setMessage] = useState("Suggestions are native datalist options.");

  return (
    <VStack gap="sm" align="stretch">
      <Picker label="Field state" value={mode} onChange={(event) => setMode(event.currentTarget.value as FieldMode)} items={modes} />
      <Form onSubmit={(event) => { event.preventDefault(); setMessage(query ? `Submitted search: ${query}` : "Enter a search term."); }}>
        <HStack gap="sm" align="end" wrap>
          <SearchField label="Search the library" name="query" value={query} onChange={(event) => setQuery(event.currentTarget.value)} placeholder="Try Badge…" suggestions={["Badge", "Button", "Banner"]} helperText={mode === "error" ? undefined : "Search by component name."} error={mode === "error" ? "That search could not be completed." : undefined} startContent={<MagnifyingGlassIcon aria-hidden="true" />} endContent={<Text as="small" color="muted">Enter</Text>} required={mode === "required"} readOnly={mode === "readOnly"} disabled={mode === "disabled"} autoComplete="off" maxLength={40} />
          <Button type="submit" disabled={mode === "disabled"}>Search</Button>
        </HStack>
      </Form>
      <Text as="p" role="status" aria-live="polite">{message}</Text>
    </VStack>
  );
}