4.5.1






Typeahead

Default

user



Use the above input to search for users on Github, and see the results as you type.
When you make a selection, you will see it apear in the list below

Close
<%= pb_rails("typeahead", props: { label: "user", name: :foo, data: { typeahead_example: true } }) %>

<br><br><br>

<%= pb_rails("card", props: { padding: "xl", data: { typeahead_example_selected_option: true } }) do %>
  <%= pb_rails("body") do %>
    Use the above input to search for users on Github, and see the results as you type.
  <% end %>

  <%= pb_rails("body") do %>
    When you make a selection, you will see it apear in the list below
  <% end %>

  <div data-selected-option></div>
<% end %>

<template data-typeahead-example-result-option>
  <%= pb_rails("user", props: {
    name: tag(:slot, name: "name"),
    orientation: "horizontal",
    align: "left",
    avatar_url: "placeholder"
    }) %>
</template>

<%= javascript_tag defer: "defer" do %>
  document.addEventListener("pb-typeahead-kit-search", function(event) {
    if (!event.target.dataset.typeaheadExample) return;

    fetch(`https://api.github.com/search/users?q=${encodeURIComponent(event.detail.searchingFor)}`)
      .then(response => response.json())
      .then((result) => {
        const resultOptionTemplate = document.querySelector("[data-typeahead-example-result-option]")

        event.detail.setResults((result.items || []).map((user) => {
          const wrapper = resultOptionTemplate.content.cloneNode(true)
          wrapper.querySelector('slot[name="name"]').replaceWith(user.login)
          wrapper.querySelector('img').setAttribute("src", user.avatar_url)
          return wrapper
        }))
      })
  })


  document.addEventListener("pb-typeahead-kit-result-option-selected", function(event) {
    if (!event.target.dataset.typeaheadExample) return;

    document.querySelector("[data-typeahead-example-selected-option] [data-selected-option]").innerHTML = ""
    document.querySelector("[data-typeahead-example-selected-option] [data-selected-option]").appendChild(event.detail.selected)
  })
<% end %>
With Context

Crayola Crayons




Close
<%= pb_rails("select", props: {
  label: "Colors",
  name: "foo",
  data: { context_select: true },
  options: [
    { value: "red", value_text: "Red" },
    { value: "orange", value_text: "Orange" },
    { value: "yellow", value_text: "Yellow" },
    { value: "green", value_text: "Green" },
    { value: "blue", value_text: "Blue" },
    { value: "purple", value_text: "Purple" },
  ]
  }) %>
<%= pb_rails("typeahead", props: { label: "Crayola Crayons", name: :foo, data: { typeahead_example2: true, search_context_value_selector: "[data-context-select] select" } }) %>

<br><br><br>


<%= javascript_tag defer: "defer" do %>
  document.addEventListener("pb-typeahead-kit-search", function(event) {
    if (!event.target.dataset.typeaheadExample2) return;

    const fuzzyMatch = function(string, term) {
      const ratio = 0.5;
      string = string.toLowerCase();
      const compare = term.toLowerCase();
      let matches = 0;

      if (string.indexOf(compare) > -1) return true;

      for (let index = 0; index < compare.length; index++) {
        if (string.indexOf(compare[index]) > -1) {
          matches += 1
        } else {
          matches -=1;
        }
      }

      return (matches / string.length >= ratio || term == "")
    };

    const colors = { red: ["Red", "Scarlet", "Chestnut", "Mahogany"],
                     orange: ["Orange", "Apricot", "Peach", "Melon", "Burnt Sienna", "Macaroni and Cheese"],
                     yellow: ["Yellow", "Gold", "Goldenrod", "Canary", "Laser Lemon"],
                     green: ["Green", "Olive Green", "Granny Smith Apple", "Spring Green", "Sea Green"],
                     blue: ["Blue", "Cerulean", "Bluetiful", "Sky Blue", "Cadet Blue", "Cornflower"],
                     purple: ["Violet", "Indigo", "Wisteria", "Purple Mountain Majesty", "Lavender"] };

    event.detail.setResults(colors[event.detail.searchingContext].filter((color) => fuzzyMatch(color, event.detail.searchingFor)).map((color) => document.createTextNode(color)));
  })
<% end %>

Available Props
id
data
classname
aria
children
label
name
value
placeholder
search_term_minimum_length
search_debounce_timeout