Zoeken...  ⌘K GitHub

FormSubscribe Forms

Abonnement aanmeldformulier.

/form-subscribe
src/components/forms/FormSubscribe.astro
---
interface Props {
  heading?: string;
  subtext?: string;
  submitLabel?: string;
  topics?: string[];
}

const {
  heading = "Abonneer je op onze updates",
  subtext = "Kies precies wat je wilt ontvangen — geen bulk, alleen wat voor jou relevant is.",
  submitLabel = "Abonnement activeren",
  topics = [
    "Performance marketing tips",
    "SEO nieuws & updates",
    "Case studies",
    "Evenementen & webinars",
    "Productnieuws van BLURR",
  ],
} = Astro.props;
---

<div class="fsb-wrap">
  <div class="fsb-header">
    {heading && <h2 class="fsb-heading">{heading}</h2>}
    {subtext && <p class="fsb-subtext">{subtext}</p>}
  </div>
  <form class="fsb-form" onsubmit="return false;" novalidate>
    <div class="fsb-row">
      <div class="fsb-field">
        <label class="fsb-label" for="fsb-name">Voornaam *</label>
        <input class="fsb-input" type="text" id="fsb-name" name="name" placeholder="Jouw naam" required autocomplete="given-name" />
      </div>
      <div class="fsb-field">
        <label class="fsb-label" for="fsb-email">E-mailadres *</label>
        <input class="fsb-input" type="email" id="fsb-email" name="email" placeholder="jij@bedrijf.nl" required autocomplete="email" />
      </div>
    </div>
    <div class="fsb-field">
      <label class="fsb-label">Ik wil ontvangen over: *</label>
      <div class="fsb-topics">
        {topics.map(topic => (
          <label class="fsb-topic-item">
            <input class="fsb-topic-check" type="checkbox" name="topics" value={topic} />
            <div class="fsb-topic-box">
              <span class="fsb-topic-name">{topic}</span>
              <span class="fsb-topic-check-icon" aria-hidden="true">✓</span>
            </div>
          </label>
        ))}
      </div>
    </div>
    <div class="fsb-field">
      <label class="fsb-label">Voorkeur frequentie</label>
      <div class="fsb-freq">
        {["Direct (live updates)", "Wekelijks digest", "Maandelijks overzicht"].map(f => (
          <label class="fsb-freq-item">
            <input class="fsb-freq-radio" type="radio" name="frequency" value={f} />
            {f}
          </label>
        ))}
      </div>
    </div>
    <button class="fsb-submit" type="submit">{submitLabel}</button>
    <p class="fsb-disclaimer">Je kunt je op elk moment afmelden. We respecteren je privacy.</p>
  </form>
</div>

<style>
  .fsb-wrap { max-width: 580px; padding: 2rem 0; }
  .fsb-header { margin-bottom: 1.75rem; }
  .fsb-heading { font-size: 1.75rem; font-weight: 800; color: var(--color-primary, #0a0a0a); margin: 0 0 0.5rem; }
  .fsb-subtext { font-size: 0.95rem; color: #666; margin: 0; }
  .fsb-form { display: flex; flex-direction: column; gap: 1.25rem; }
  .fsb-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
  @media (max-width: 480px) { .fsb-row { grid-template-columns: 1fr; } }
  .fsb-field { display: flex; flex-direction: column; gap: 0.4rem; }
  .fsb-label { font-size: 0.85rem; font-weight: 600; color: var(--color-primary, #0a0a0a); }
  .fsb-input {
    padding: 0.7rem 0.9rem; border: 1.5px solid #ddd; border-radius: 8px;
    font-size: 0.95rem; color: var(--color-primary, #0a0a0a); background: #fff;
    transition: border-color 0.2s; font-family: inherit; box-sizing: border-box; width: 100%;
  }
  .fsb-input:focus { outline: none; border-color: var(--color-accent, #6366f1); box-shadow: 0 0 0 3px rgba(99,102,241,0.12); }
  .fsb-topics { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
  @media (max-width: 400px) { .fsb-topics { grid-template-columns: 1fr; } }
  .fsb-topic-item { cursor: pointer; }
  .fsb-topic-check { display: none; }
  .fsb-topic-box {
    display: flex; justify-content: space-between; align-items: center;
    padding: 0.75rem 1rem; background: #f9f9f9; border: 1.5px solid #ebebeb;
    border-radius: 8px; font-size: 0.875rem; color: #444; transition: all 0.15s;
  }
  .fsb-topic-check-icon { color: transparent; font-weight: 700; font-size: 0.875rem; }
  .fsb-topic-check:checked + .fsb-topic-box { border-color: var(--color-accent, #6366f1); background: #eef2ff; color: var(--color-accent, #6366f1); }
  .fsb-topic-check:checked + .fsb-topic-box .fsb-topic-check-icon { color: var(--color-accent, #6366f1); }
  .fsb-freq { display: flex; flex-direction: column; gap: 0.4rem; }
  .fsb-freq-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: #444; cursor: pointer; padding: 0.55rem 1rem; background: #f9f9f9; border-radius: 8px; border: 1.5px solid transparent; }
  .fsb-freq-item:has(input:checked) { border-color: var(--color-accent, #6366f1); background: #eef2ff; color: var(--color-accent, #6366f1); }
  .fsb-freq-radio { accent-color: var(--color-accent, #6366f1); }
  .fsb-submit {
    padding: 0.9rem 2rem; background: var(--color-accent, #6366f1); color: #fff;
    border: none; border-radius: 8px; font-size: 1rem; font-weight: 600;
    cursor: pointer; transition: opacity 0.2s; align-self: flex-start;
  }
  .fsb-submit:hover { opacity: 0.88; }
  .fsb-disclaimer { font-size: 0.8rem; color: #999; margin: 0.25rem 0 0; }
</style>

Props

Prop Type Default Beschrijving
headline string Formuliertitel

* = verplicht