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