src/components/forms/FormNewsletter.astro
---
/**
* FormNewsletter — nieuwsbrief-aanmelding met naam, e-mail en interesse-checkboxes.
*
* Props:
* - headline?: string
* - sub?: string
* - nameLabel?: string
* - namePlaceholder?: string
* - emailLabel?: string
* - emailPlaceholder?: string
* - interestsLabel?: string
* - interests?: string[]
* - button?: string
* - disclaimer?: string
* - privacyHref?: string
* - action?: string
*/
interface Props {
headline?: string;
sub?: string;
nameLabel?: string;
namePlaceholder?: string;
emailLabel?: string;
emailPlaceholder?: string;
interestsLabel?: string;
interests?: string[];
button?: string;
disclaimer?: string;
privacyHref?: string;
action?: string;
}
const {
headline = 'Blijf op de hoogte',
sub = 'Ontvang maandelijks onze beste marketing insights. Geen spam.',
nameLabel = 'Voornaam',
namePlaceholder = 'Jouw voornaam',
emailLabel = 'E-mailadres *',
emailPlaceholder = 'Je e-mailadres',
interestsLabel = 'Interesses (optioneel):',
interests = ['Performance marketing', 'SEO & content', 'Social media', 'Design & branding'],
button = 'Aanmelden',
disclaimer = 'Door je aan te melden ga je akkoord met onze',
privacyHref = '/privacy',
action = '#',
} = Astro.props;
---
<section class="bl-section fnl">
<div class="bl-inner bl-inner--narrow fnl-inner">
<div class="fnl-wrap">
{(headline || sub) && (
<div class="fnl-header">
{headline && <h2 class="fnl-heading">{headline}</h2>}
{sub && <p class="fnl-subtext">{sub}</p>}
</div>
)}
<form class="fnl-form" action={action} novalidate>
<div class="fnl-row">
<div class="fnl-field">
<label class="fnl-label" for="fnl-name">{nameLabel}</label>
<input class="fnl-input" type="text" id="fnl-name" name="first_name" placeholder={namePlaceholder} autocomplete="given-name" />
</div>
<div class="fnl-field">
<label class="fnl-label" for="fnl-email">{emailLabel}</label>
<input class="fnl-input" type="email" id="fnl-email" name="email" placeholder={emailPlaceholder} required autocomplete="email" />
</div>
</div>
{interests.length > 0 && (
<div class="fnl-checkgroup">
<p class="fnl-check-label-head">{interestsLabel}</p>
<div class="fnl-checks">
{interests.map((it) => (
<label class="fnl-check-item">
<input class="fnl-check" type="checkbox" name="interests" value={it} /> {it}
</label>
))}
</div>
</div>
)}
<button class="fnl-submit" type="submit">{button}</button>
{disclaimer && (
<p class="fnl-disclaimer">{disclaimer} <a href={privacyHref} class="fnl-link">privacyverklaring</a>.</p>
)}
</form>
</div>
</div>
</section>
<style>
.fnl-header{margin-bottom:1.75rem}
.fnl-heading{font-size:clamp(1.5rem,3vw,2.25rem);font-weight:800;color:var(--color-primary, #0a0a0a);letter-spacing:-.03em;margin:0 0 .5rem}
.fnl-subtext{font-size:1rem;color:#6b7280;margin:0}
.fnl-form{display:flex;flex-direction:column;gap:1.25rem}
.fnl-row{display:grid;grid-template-columns:1fr;gap:1.25rem}
.fnl-field{display:flex;flex-direction:column;gap:.4rem}
.fnl-label{font-size:1rem;font-weight:600;color:var(--color-primary, #0a0a0a)}
.fnl-input{padding:.75rem 1rem;border:1.5px solid #d1d5db;border-radius:8px;font-size:1rem;color:var(--color-primary, #0a0a0a);background:#fff;transition:border-color .2s;font-family:inherit;box-sizing:border-box;flex:1}
.fnl-input:focus{outline:none;border-color:var(--color-accent, #6366f1);box-shadow:0 0 0 3px #6366f11f}
.fnl-checkgroup{background:#f9f9f9;border-radius:8px;padding:1rem 1.25rem}
.fnl-check-label-head{font-size:1rem;font-weight:600;color:#374151;margin:0 0 .75rem}
.fnl-checks{display:flex;flex-wrap:wrap;gap:.5rem 1.25rem}
.fnl-check-item{display:flex;align-items:center;gap:.4rem;font-size:1rem;color:#374151;cursor:pointer}
.fnl-check{accent-color:var(--color-accent, #6366f1)}
.fnl-submit{padding:.875rem 1.75rem;background:var(--color-accent, #6366f1);color:#fff;border:none;border-radius:8px;font-size:1rem;font-weight:600;cursor:pointer;transition:opacity .2s;white-space:nowrap;align-self:flex-start}
.fnl-submit:hover{opacity:.88}
.fnl-disclaimer{font-size:.875rem;color:#6b7280;margin:0}
.fnl-link{color:var(--color-accent, #6366f1)}
@media(min-width:600px){.fnl-row{grid-template-columns:1fr 1fr}}
</style>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
headline | string | 'Blijf op de hoogte' | Koptekst |
sub | string | - | Ondertitel |
interests | string[] | - | Interesse-checkboxes |
button | string | 'Aanmelden' | Knoptekst |
disclaimer | string | - | Disclaimer-aanhef (link volgt automatisch) |
privacyHref | string | '/privacy' | Link privacyverklaring |
action | string | '#' | Form action URL |
* = verplicht