Faceted Search

Search with multiple category facets.

128 results

Availability
Brand
Colour

html

<section class="facets" style="--accent:#A8E6C1;">
  <form role="search" class="facets__search">
    <label class="facets__search-label" for="fq">Search results</label>
    <input class="facets__search-input" id="fq" type="search" name="q" placeholder="Search...">
  </form>
  <p class="facets__status" role="status">128 results</p>
  <div class="facets__groups facets__groups--list">
    <fieldset class="facets__group">
      <legend class="facets__legend">Availability</legend>
      <label class="facets__option">
        <input type="checkbox" name="availability" value="in-stock" checked>
        In stock
      </label>
      <label class="facets__option">
        <input type="checkbox" name="availability" value="pre-order">
        Pre-order
      </label>
    </fieldset>
    <fieldset class="facets__group">
      <legend class="facets__legend">Brand</legend>
      <label class="facets__option">
        <input type="checkbox" name="brand" value="acme">
        Acme
      </label>
      <label class="facets__option">
        <input type="checkbox" name="brand" value="orbit">
        Orbit
      </label>
    </fieldset>
    <fieldset class="facets__group">
      <legend class="facets__legend">Colour</legend>
      <label class="facets__option">
        <input type="checkbox" name="colour" value="mint">
        Mint
      </label>
      <label class="facets__option">
        <input type="checkbox" name="colour" value="blush">
        Blush
      </label>
    </fieldset>
  </div>
</section>
<style>
.facets { font: 14px system-ui, sans-serif; color: #241430; max-width: 340px; }
.facets__search { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.facets__search-label { font-weight: 600; }
.facets__search-input { flex: 1; box-sizing: border-box; padding: 8px 10px; font: inherit; border: 1.5px solid #24143040; background: #FAF7F2; }
.facets__search-input:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
.facets__status { margin: 0 0 12px; font-size: 12px; color: #24143099; }
.facets__groups--list { display: grid; gap: 14px; }
.facets__groups--grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.facets__group { border: none; padding: 0; margin: 0; }
.facets__legend { padding: 0; font-weight: 600; font-size: 13px; margin-bottom: 6px; }
.facets__option { display: flex; align-items: center; gap: 8px; padding: 3px 0; cursor: pointer; }
.facets__option input { accent-color: var(--accent); width: 16px; height: 16px; }
</style>

tailwind

<section class="font-sans text-sm text-[#241430] max-w-[340px]" style="--accent:#A8E6C1;">
  <form role="search" class="flex items-center gap-2 mb-2.5">
    <label for="fq-tw" class="font-semibold">Search results</label>
    <input id="fq-tw" type="search" name="q" placeholder="Search..." class="flex-1 box-border px-2.5 py-2 border-[1.5px] border-[#24143040] bg-[#FAF7F2] focus-visible:outline-none focus-visible:border-[var(--accent)]">
  </form>
  <p role="status" class="m-0 mb-3 text-xs text-[#24143099]">128 results</p>
  <div class="facets-groups-tw facets-groups-tw--list grid gap-3.5">
    <fieldset class="border-0 p-0 m-0">
      <legend class="p-0 font-semibold text-[13px] mb-1.5">Availability</legend>
      <label class="flex items-center gap-2 py-0.5 cursor-pointer">
        <input type="checkbox" name="availability" value="in-stock" checked class="w-4 h-4 accent-[var(--accent)]">
        In stock
      </label>
      <label class="flex items-center gap-2 py-0.5 cursor-pointer">
        <input type="checkbox" name="availability" value="pre-order" class="w-4 h-4 accent-[var(--accent)]">
        Pre-order
      </label>
    </fieldset>
    <fieldset class="border-0 p-0 m-0">
      <legend class="p-0 font-semibold text-[13px] mb-1.5">Brand</legend>
      <label class="flex items-center gap-2 py-0.5 cursor-pointer">
        <input type="checkbox" name="brand" value="acme" class="w-4 h-4 accent-[var(--accent)]">
        Acme
      </label>
      <label class="flex items-center gap-2 py-0.5 cursor-pointer">
        <input type="checkbox" name="brand" value="orbit" class="w-4 h-4 accent-[var(--accent)]">
        Orbit
      </label>
    </fieldset>
    <fieldset class="border-0 p-0 m-0">
      <legend class="p-0 font-semibold text-[13px] mb-1.5">Colour</legend>
      <label class="flex items-center gap-2 py-0.5 cursor-pointer">
        <input type="checkbox" name="colour" value="mint" class="w-4 h-4 accent-[var(--accent)]">
        Mint
      </label>
      <label class="flex items-center gap-2 py-0.5 cursor-pointer">
        <input type="checkbox" name="colour" value="blush" class="w-4 h-4 accent-[var(--accent)]">
        Blush
      </label>
    </fieldset>
  </div>
</section>
<style>
.facets-groups-tw--grid { grid-template-columns: 1fr 1fr; }
</style>

react

export function FacetedSearch({
  label = "Search results",
  count = 128,
  availableChecked = true,
  layout = "list",
  accent = "#A8E6C1",
}) {
  const groupsStyle = layout === "grid"
    ? { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }
    : { display: "grid", gap: 14 };
  return (
    <section style={{ fontFamily: "system-ui, sans-serif", fontSize: 14, color: "#241430", maxWidth: 340, "--accent": accent }}>
      <form role="search" style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
        <label htmlFor="fq-r" style={{ fontWeight: 600 }}>{label}</label>
        <input id="fq-r" type="search" name="q" placeholder="Search..." style={{ flex: 1, boxSizing: "border-box", padding: "8px 10px", border: "1.5px solid #24143040", background: "#FAF7F2" }} />
      </form>
      <p role="status" style={{ margin: "0 0 12px", fontSize: 12, color: "#24143099" }}>{count} results</p>
      <div style={groupsStyle}>
        <fieldset style={{ border: "none", padding: 0, margin: 0 }}>
          <legend style={{ padding: 0, fontWeight: 600, fontSize: 13, marginBottom: 6 }}>Availability</legend>
          <label style={{ display: "flex", alignItems: "center", gap: 8, padding: "3px 0", cursor: "pointer" }}>
            <input type="checkbox" name="availability" value="in-stock" defaultChecked={availableChecked} style={{ width: 16, height: 16, accentColor: accent }} />
            In stock
          </label>
          <label style={{ display: "flex", alignItems: "center", gap: 8, padding: "3px 0", cursor: "pointer" }}>
            <input type="checkbox" name="availability" value="pre-order" style={{ width: 16, height: 16, accentColor: accent }} />
            Pre-order
          </label>
        </fieldset>
        <fieldset style={{ border: "none", padding: 0, margin: 0 }}>
          <legend style={{ padding: 0, fontWeight: 600, fontSize: 13, marginBottom: 6 }}>Brand</legend>
          <label style={{ display: "flex", alignItems: "center", gap: 8, padding: "3px 0", cursor: "pointer" }}>
            <input type="checkbox" name="brand" value="acme" style={{ width: 16, height: 16, accentColor: accent }} />
            Acme
          </label>
          <label style={{ display: "flex", alignItems: "center", gap: 8, padding: "3px 0", cursor: "pointer" }}>
            <input type="checkbox" name="brand" value="orbit" style={{ width: 16, height: 16, accentColor: accent }} />
            Orbit
          </label>
        </fieldset>
        <fieldset style={{ border: "none", padding: 0, margin: 0 }}>
          <legend style={{ padding: 0, fontWeight: 600, fontSize: 13, marginBottom: 6 }}>Colour</legend>
          <label style={{ display: "flex", alignItems: "center", gap: 8, padding: "3px 0", cursor: "pointer" }}>
            <input type="checkbox" name="colour" value="mint" style={{ width: 16, height: 16, accentColor: accent }} />
            Mint
          </label>
          <label style={{ display: "flex", alignItems: "center", gap: 8, padding: "3px 0", cursor: "pointer" }}>
            <input type="checkbox" name="colour" value="blush" style={{ width: 16, height: 16, accentColor: accent }} />
            Blush
          </label>
        </fieldset>
      </div>
    </section>
  );
}