Zoeken...  ⌘K GitHub

FormFilter Forms

Filterformulier met dropdowns en checkboxen.

/form-filter
src/components/forms/FormFilter.astro
---
/**
 * FormFilter
 * Filter-/zoekformulier met dropdowns en checkboxen
 */
interface Props {
  headline?: string;
  filters?: { label: string; options: string[] }[];
}
const {
  headline = 'Verfijn je zoekopdracht',
  filters = [
    { label: 'Dienst', options: ['SEO', 'Google Ads', 'Social Media', 'Webdesign', 'Branding'] },
    { label: 'Budget', options: ['< € 500 / mnd', '€ 500–1.000', '€ 1.000–2.500', '> € 2.500'] },
    { label: 'Branche', options: ['E-commerce', 'B2B', 'Horeca', 'Zorg', 'Technologie'] },
  ],
} = Astro.props;
---

<section class="ffl">
  <div class="ffl__inner">
    {headline && <h2 class="ffl__headline">{headline}</h2>}
    <form class="ffl__form" novalidate>
      <div class="ffl__search-wrap">
        <input class="ffl__search" type="search" placeholder="Zoek op trefwoord…" />
        <button class="ffl__search-btn" type="submit" aria-label="Zoeken">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.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>
        </button>
      </div>
      <div class="ffl__filters">
        {filters.map((filter, fi) => (
          <div class="ffl__group">
            <span class="ffl__group-label">{filter.label}</span>
            <div class="ffl__checkboxes">
              {filter.options.map((opt, oi) => (
                <label class="ffl__checkbox">
                  <input type="checkbox" name={`filter-${fi}`} value={opt} />
                  <span>{opt}</span>
                </label>
              ))}
            </div>
          </div>
        ))}
      </div>
      <div class="ffl__actions">
        <button class="ffl__btn" type="submit">Resultaten tonen</button>
        <button class="ffl__reset" type="reset">Filters wissen</button>
      </div>
    </form>
  </div>
</section>

<style>
  .ffl {
    background: #f9f9fb;
    padding: 3rem 1.5rem;
  }
  .ffl__inner {
    max-width: 860px;
    margin: 0 auto;
  }
  .ffl__headline {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--color-primary, #0a0a0a);
    margin: 0 0 1.5rem;
  }
  .ffl__form {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
  }
  .ffl__search-wrap {
    position: relative;
    max-width: 520px;
  }
  .ffl__search {
    width: 100%;
    box-sizing: border-box;
    padding: 0.75rem 3rem 0.75rem 1rem;
    border: 1.5px solid #e0e0e0;
    border-radius: 8px;
    font-size: 0.95rem;
    background: #fff;
    outline: none;
    font-family: inherit;
    transition: border-color 0.2s;
  }
  .ffl__search:focus { border-color: var(--color-accent, #6366f1); }
  .ffl__search-btn {
    position: absolute;
    right: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    cursor: pointer;
    color: #888;
    display: flex;
    align-items: center;
  }
  .ffl__filters {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
  }
  .ffl__group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 160px;
  }
  .ffl__group-label {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: #555;
  }
  .ffl__checkboxes {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }
  .ffl__checkbox {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9rem;
    color: var(--color-primary, #0a0a0a);
    cursor: pointer;
  }
  .ffl__checkbox input[type="checkbox"] {
    accent-color: var(--color-accent, #6366f1);
    width: 15px;
    height: 15px;
    cursor: pointer;
  }
  .ffl__actions {
    display: flex;
    gap: 1rem;
    align-items: center;
  }
  .ffl__btn {
    padding: 0.8rem 1.75rem;
    background: var(--color-accent, #6366f1);
    color: #fff;
    border: none;
    border-radius: 8px;
    font-size: 0.93rem;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.2s;
  }
  .ffl__btn:hover { opacity: 0.88; }
  .ffl__reset {
    background: none;
    border: none;
    font-size: 0.88rem;
    color: #888;
    cursor: pointer;
    text-decoration: underline;
    font-family: inherit;
  }
  .ffl__reset:hover { color: #333; }
</style>

Props

Prop Type Default Beschrijving
headline string Formuliertitel

* = verplicht