Auto Complete

Component

Interactive examples and API documentation

Basic Usage
Provide an options array to suggest items as users type.
Burns Bay Road
Downing Street
Wall Street
Oxford Street
Bourke Street
Code
<%= render Hakumi::Autocomplete::Component.new(
  name: :basic_autocomplete,
  placeholder: "Search address",
  options: [
    "Burns Bay Road",
    "Downing Street",
    "Wall Street",
    "Oxford Street",
    "Bourke Street"
  ]
) %>
Customized Labels
Display labels that differ from the submitted values.
Burns Bay Road — Sydney
Downing Street — London
Wall Street — New York
Queen Street — Auckland
Code
<%= render Hakumi::Autocomplete::Component.new(
  name: :custom_label_autocomplete,
  placeholder: "Search location",
  options: [
    { label: "Burns Bay Road — Sydney", value: "burns" },
    { label: "Downing Street — London", value: "downing" },
    { label: "Wall Street — New York", value: "wall" },
    { label: "Queen Street — Auckland", value: "queen" }
  ]
) %>
Customize Input Component
Use input_renderer to wrap the input with a custom layout.
Apple
Apricot
Avocado
Banana
Blueberry
Cherry
Code
<% custom_renderer = ->(attrs) do
     tag.div(class: "playground-custom-input") do
       tag.input(**attrs.merge(class: [attrs[:class], "playground-custom-input-field"].compact.join(" ")))
     end
   end %>

<%= render Hakumi::Autocomplete::Component.new(
  name: :custom_input_autocomplete,
  placeholder: "Type a keyword",
  input_renderer: custom_renderer,
  options: ["Apple", "Apricot", "Avocado", "Banana", "Blueberry", "Cherry"]
) %>
Non-case-sensitive
Disable case-sensitivity to match queries regardless of casing.
USA
Australia
Austria
Germany
United Kingdom
Uruguay
Code
<%= render Hakumi::Autocomplete::Component.new(
  name: :case_insensitive_autocomplete,
  placeholder: "Try typing 'us' or 'US'",
  case_sensitive: false,
  options: [
    "USA",
    "Australia",
    "Austria",
    "Germany",
    "United Kingdom",
    "Uruguay"
  ]
) %>
Lookup Patterns - Certain Category
Group suggestions into categories with static headings.
Libraries
Burns Bay Road
Downing Street
Wall Street
Results
Sydney
London
New York
Code
<%= render Hakumi::Autocomplete::Component.new(
  name: :lookup_certain_category,
  placeholder: "Search library",
  options: [
    {
      label: "Libraries",
      options: [
        "Burns Bay Road",
        "Downing Street",
        "Wall Street"
      ]
    },
    {
      label: "Results",
      options: [
        "Sydney",
        "London",
        "New York"
      ]
    }
  ]
) %>
Lookup Patterns - Uncertain Category
Use starts_with filtering for an "uncertain" pattern experience.
Libraries
Burns Bay Road
Oxford Street
Queen Street
Results
Sydney
London
Wellington
Auckland
Code
<%= render Hakumi::Autocomplete::Component.new(
  name: :lookup_uncertain_category,
  placeholder: "Search categories",
  filter_mode: :starts_with,
  options: [
    {
      label: "Libraries",
      options: [
        "Burns Bay Road",
        "Oxford Street",
        "Queen Street"
      ]
    },
    {
      label: "Results",
      options: [
        "Sydney",
        "London",
        "Wellington",
        "Auckland"
      ]
    }
  ]
) %>
Status
Show error or warning states via the status prop.
Apple
Banana
Cherry
Alpha
Beta
Gamma
Code
<%= render Hakumi::Autocomplete::Component.new(
  name: :status_error_autocomplete,
  placeholder: "Status: error",
  status: :error,
  options: [
    "Apple",
    "Banana",
    "Cherry"
  ]
) %>

<%= render Hakumi::Autocomplete::Component.new(
  name: :status_warning_autocomplete,
  placeholder: "Status: warning",
  status: :warning,
  options: [
    "Alpha",
    "Beta",
    "Gamma"
  ]
) %>
Variants
Outlined, filled, borderless, and underlined variants.
Red
Orange
Yellow
Green
Blue
One
Two
Three
Four
Alpha
Beta
Gamma
North
East
South
West
Code
<%= render Hakumi::Space::Component.new(direction: :vertical, size: 16) do %>
  <%= render Hakumi::Autocomplete::Component.new(
    name: :variant_outlined,
    placeholder: "Outlined",
    variant: :outlined,
    options: ["Red", "Orange", "Yellow", "Green", "Blue"]
  ) %>

  <%= render Hakumi::Autocomplete::Component.new(
    name: :variant_filled,
    placeholder: "Filled",
    variant: :filled,
    options: ["One", "Two", "Three", "Four"]
  ) %>

  <%= render Hakumi::Autocomplete::Component.new(
    name: :variant_borderless,
    placeholder: "Borderless",
    variant: :borderless,
    options: ["Alpha", "Beta", "Gamma"]
  ) %>

  <%= render Hakumi::Autocomplete::Component.new(
    name: :variant_underlined,
    placeholder: "Underlined",
    variant: :underlined,
    options: ["North", "East", "South", "West"]
  ) %>
<% end %>
Customize Clear Button
Enable allow_clear and pick a custom icon.
Apple
Apricot
Avocado
Banana
Blueberry
Cherry
Code
<%= render Hakumi::Autocomplete::Component.new(
  name: :custom_clear_autocomplete,
  placeholder: "Search to clear",
  allow_clear: true,
  clear_icon: :close,
  options: [
    "Apple",
    "Apricot",
    "Avocado",
    "Banana",
    "Blueberry",
    "Cherry"
  ]
) %>
Load Options Dynamically
Inject remote results via the JS API after opening the dropdown.
No options
Code
<%= render Hakumi::Autocomplete::Component.new(
  id: "dynamic-autocomplete",
  name: :dynamic_autocomplete,
  placeholder: "Type to load cities",
  options: []
) %>

<script>
  (() => {
    const element = document.getElementById("dynamic-autocomplete")
    if (!element) return

    const remoteData = [
      { label: "Sydney", value: "sydney" },
      { label: "Melbourne", value: "melbourne" },
      { label: "Brisbane", value: "brisbane" },
      { label: "Perth", value: "perth" }
    ]

    const wire = () => {
      if (element.dataset.dynamicBound === "true") return true
      if (!element.hakumiComponent?.api) return false

      element.dataset.dynamicBound = "true"
      element.addEventListener(
        "hakumi--autocomplete:open",
        () => {
          if (element.dataset.optionsLoaded === "true") return
          element.dataset.optionsLoaded = "true"
          element.hakumiComponent.api.setOptions(remoteData)
        },
        { once: true }
      )
      return true
    }

    if (wire()) return

    const onRegister = ({ detail }) => {
      if (detail.id !== element.id) return
      if (wire()) window.removeEventListener("hakumi-component:registered", onRegister)
    }

    window.addEventListener("hakumi-component:registered", onRegister)
  })()
</script>

:auto_complete API

Prop Type Default Description
name String or Symbol required Input name/id used for submitted value.
options Array [] Data source. Accepts strings, [label, value] pairs, hashes { label:, value: }, or grouped { label:, options: [...] }.
value String nil Initial value shown in the input.
placeholder String nil Placeholder text.
size :small | :middle or :large :middle Input height and padding.
variant :outlined | :filled | :borderless or :underlined :outlined Visual presentation of the control.
status :error or :warning nil Display feedback color for validation state.
disabled Boolean false Disable interactions.
allow_clear Boolean false Show a clear button that resets the value.
clear_icon Symbol :close_circle Icon name used for the clear button when allow_clear is true.
input_renderer Proc nil Lambda that receives the computed input attributes and must return custom markup.
case_sensitive Boolean false Match queries using exact case when true.
filter_mode :contains or :starts_with :contains Filtering algorithm applied to labels.
not_found_content String "No options" Message shown when no options match.
**html_options Keyword args - Extra attributes merged into the wrapper (e.g., class, id, data).

JavaScript API (element.hakumi:auto_complete)

Prop Type Default Description
getValue() Function - Returns the current value.
setValue(value) Function - Sets the value and filters suggestions.
setOptions(options, config) Function - Replace or append options. Config supports { append: false }.
open() Function - Opens the dropdown.
close() Function - Closes the dropdown.
clear() Function - Clears the input and hides the dropdown.
filter(query) Function - Applies filtering without altering the input value.
focus() Function - Focuses the input.
blur() Function - Removes focus from the input.

Events

Prop Type Default Description
hakumi--:auto_complete:select CustomEvent - Triggered after a suggestion is selected. Detail: { value, label }.
hakumi--:auto_complete:clear CustomEvent - Triggered when the clear button or API clears the value. Detail: { value: "", label: "" }.