Zoeken...  ⌘K GitHub

FormSearch Forms

Zoekbalk met icoon, zoekknop en filter-pills voor categorie-keuze eronder.

/form-search
src/components/forms/FormSearch.astro
---
/**
 * FormSearch — zoekbalk met icoon, knop en filter-pills eronder.
 *
 * Props:
 * - placeholder?: string
 * - submitLabel?: string
 * - filters?: string[]
 */
interface Props {
  placeholder?: string;
  submitLabel?: string;
  filters?: string[];
}
const {
  placeholder = 'Zoek naar diensten, cases of blogs...',
  submitLabel = 'Zoeken',
  filters = ['Alles', 'Cases', 'Blogs', 'Diensten', 'Team'],
} = Astro.props;
---

<section class="bl-section fsr">
  <div class="bl-inner fsr-inner">
    <form class="fsr-form" role="search">
      <div class="fsr-input-wrap">
        <span class="fsr-icon" aria-hidden="true">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
        </span>
        <input class="fsr-input" type="search" name="q" placeholder={placeholder} aria-label="Zoekterm" autocomplete="off" />
        <button class="fsr-submit" type="submit">{submitLabel}</button>
      </div>
      <div class="fsr-filters" role="group" aria-label="Zoekfilters">
        {filters.map((f, i) => (
          <label class="fsr-filter">
            <input class="fsr-filter-input" type="radio" name="filter" value={f} checked={i === 0} />
            <span class="fsr-filter-label">{f}</span>
          </label>
        ))}
      </div>
    </form>
  </div>
</section>

<style>
.fsr-form{display:flex;flex-direction:column;gap:.875rem}
.fsr-input-wrap{display:flex;align-items:center;background:#fff;border:2px solid #ddd;border-radius:10px;overflow:hidden;transition:border-color .2s,box-shadow .2s}
.fsr-input-wrap:focus-within{border-color:var(--color-accent, #6366f1);box-shadow:0 0 0 3px #6366f11f}
.fsr-icon{padding:0 .75rem 0 1rem;color:#888;display:flex;align-items:center;flex-shrink:0}
.fsr-input{flex:1;border:none;padding:.9rem .5rem;font-size:1rem;color:var(--color-primary, #0a0a0a);background:transparent;font-family:inherit}
.fsr-input:focus{outline:none}
.fsr-input::-webkit-search-cancel-button{display:none}
.fsr-submit{padding:.75rem 1.25rem;background:var(--color-accent, #6366f1);color:#fff;border:none;font-size:1rem;font-weight:600;cursor:pointer;transition:opacity .2s;white-space:nowrap;flex-shrink:0}
.fsr-submit:hover{opacity:.88}
.fsr-filters{display:flex;gap:.4rem;flex-wrap:wrap}
.fsr-filter{cursor:pointer}
.fsr-filter-input{display:none}
.fsr-filter-label{display:block;padding:.4rem .9rem;background:#f5f5f5;color:#374151;border-radius:20px;font-size:.875rem;font-weight:500;border:1.5px solid transparent;transition:border-color .15s,background-color .15s,color .15s}
.fsr-filter-input:checked+.fsr-filter-label{background:#eef2ff;color:var(--color-accent, #6366f1);border-color:var(--color-accent, #6366f1);font-weight:600}
</style>

Props

Prop Type Default Beschrijving
placeholder string - Placeholder van het zoekveld
submitLabel string 'Zoeken' Tekst op de zoekknop
filters string[] - Filter-pills; de eerste staat standaard aan

* = verplicht