Zoeken...  ⌘K GitHub

FormSearch Forms

Zoekformulier met filters.

/form-search
src/components/forms/FormSearch.astro
---
interface Props {
  placeholder?: string;
  submitLabel?: string;
  filters?: string[];
  size?: "sm" | "md" | "lg";
}

const {
  placeholder = "Zoek in onze cases, artikelen en diensten...",
  submitLabel = "Zoeken",
  filters = ["Alles", "Cases", "Blogs", "Diensten", "Team"],
  size = "md",
} = Astro.props;
---

<div class={`fsr-wrap fsr-wrap--${size}`}>
  <form class="fsr-form" onsubmit="return false;" 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"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></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>
    {filters && filters.length > 0 && (
      <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>

<style>
  .fsr-wrap { width: 100%; max-width: 700px; }
  .fsr-form { display: flex; flex-direction: column; gap: 0.875rem; }
  .fsr-input-wrap {
    display: flex; align-items: center;
    background: #fff; border: 2px solid #ddd; border-radius: 10px;
    overflow: hidden; transition: border-color 0.2s, box-shadow 0.2s;
  }
  .fsr-input-wrap:focus-within {
    border-color: var(--color-accent, #6366f1);
    box-shadow: 0 0 0 3px rgba(99,102,241,0.12);
  }
  .fsr-icon {
    padding: 0 0.75rem 0 1rem; color: #aaa; display: flex; align-items: center; flex-shrink: 0;
  }
  .fsr-input {
    flex: 1; border: none; padding: 0.85rem 0.5rem; font-size: 0.975rem;
    color: var(--color-primary, #0a0a0a); background: transparent; font-family: inherit;
  }
  .fsr-wrap--lg .fsr-input { padding: 1.1rem 0.5rem; font-size: 1.1rem; }
  .fsr-wrap--sm .fsr-input { padding: 0.6rem 0.5rem; font-size: 0.875rem; }
  .fsr-input:focus { outline: none; }
  .fsr-input::-webkit-search-cancel-button { display: none; }
  .fsr-submit {
    padding: 0.75rem 1.25rem; background: var(--color-accent, #6366f1); color: #fff;
    border: none; font-size: 0.9rem; font-weight: 600; cursor: pointer;
    transition: opacity 0.2s; white-space: nowrap; flex-shrink: 0;
  }
  .fsr-submit:hover { opacity: 0.88; }
  .fsr-filters { display: flex; gap: 0.4rem; flex-wrap: wrap; }
  .fsr-filter { cursor: pointer; }
  .fsr-filter-input { display: none; }
  .fsr-filter-label {
    display: block; padding: 0.35rem 0.85rem; background: #f5f5f5; color: #555;
    border-radius: 20px; font-size: 0.8rem; font-weight: 500;
    border: 1.5px solid transparent; transition: all 0.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 tekst

* = verplicht