src/components/forms/FormMultiStep.astro
---
interface Props {
heading?: string;
steps?: string[];
}
const {
heading = "Stap voor stap naar jouw marketingplan",
steps = ["Jouw bedrijf", "Doelstellingen", "Budget & planning"],
} = Astro.props;
---
<div class="fms-wrap">
{heading && <h2 class="fms-heading">{heading}</h2>}
<div class="fms-stepper" aria-label="Voortgang">
{steps.map((step, i) => (
<div class={`fms-step${i === 0 ? " fms-step--active" : ""}`}>
<div class="fms-step-circle">{i + 1}</div>
<span class="fms-step-label">{step}</span>
</div>
))}
<div class="fms-step-track" aria-hidden="true"></div>
</div>
<form class="fms-form" onsubmit="return false;" novalidate>
<!-- Step 1 -->
<div class="fms-panel fms-panel--active" data-step="1">
<h3 class="fms-panel-title">Vertel ons over jouw bedrijf</h3>
<div class="fms-row">
<div class="fms-field">
<label class="fms-label" for="fms-company">Bedrijfsnaam *</label>
<input class="fms-input" type="text" id="fms-company" name="company" placeholder="Jouw bedrijf BV" required />
</div>
<div class="fms-field">
<label class="fms-label" for="fms-sector">Branche *</label>
<select class="fms-select" id="fms-sector" name="sector" required>
<option value="">Selecteer branche</option>
<option>E-commerce</option>
<option>B2B dienstverlening</option>
<option>SaaS / Tech</option>
<option>Zorg & welzijn</option>
<option>Retail</option>
<option>Horeca & toerisme</option>
<option>Anders</option>
</select>
</div>
</div>
<div class="fms-field">
<label class="fms-label" for="fms-website">Website URL</label>
<input class="fms-input" type="url" id="fms-website" name="website" placeholder="https://jouwbedrijf.nl" />
</div>
<div class="fms-field">
<label class="fms-label" for="fms-employees">Aantal medewerkers</label>
<select class="fms-select" id="fms-employees" name="employees">
<option value="">Selecteer</option>
<option>1–5</option>
<option>6–25</option>
<option>26–100</option>
<option>100+</option>
</select>
</div>
<div class="fms-actions">
<button class="fms-btn fms-btn--next" type="button">Volgende stap →</button>
</div>
</div>
<!-- Step 2 -->
<div class="fms-panel" data-step="2">
<h3 class="fms-panel-title">Wat zijn jouw marketingdoelen?</h3>
<div class="fms-field">
<label class="fms-label">Primaire doelstelling *</label>
<div class="fms-radio-group">
{["Meer leads genereren", "Omzet verhogen", "Naamsbekendheid opbouwen", "Bestaande klanten activeren"].map(g => (
<label class="fms-radio-item">
<input class="fms-radio" type="radio" name="goal" value={g} required />
{g}
</label>
))}
</div>
</div>
<div class="fms-field">
<label class="fms-label" for="fms-channels">Huidige kanalen</label>
<div class="fms-checks">
{["Google Ads", "SEO", "Social Ads", "E-mail", "Geen"].map(c => (
<label class="fms-check-item">
<input class="fms-check" type="checkbox" name="current_channels" value={c} />
{c}
</label>
))}
</div>
</div>
<div class="fms-field">
<label class="fms-label" for="fms-challenge">Grootste uitdaging</label>
<textarea class="fms-textarea" id="fms-challenge" name="challenge" rows="3" placeholder="Beschrijf je belangrijkste marketinguitdaging..."></textarea>
</div>
<div class="fms-actions fms-actions--between">
<button class="fms-btn fms-btn--back" type="button">← Terug</button>
<button class="fms-btn fms-btn--next" type="button">Volgende stap →</button>
</div>
</div>
<!-- Step 3 -->
<div class="fms-panel" data-step="3">
<h3 class="fms-panel-title">Budget en planning</h3>
<div class="fms-field">
<label class="fms-label" for="fms-budget">Maandelijks marketingbudget *</label>
<select class="fms-select" id="fms-budget" name="budget" required>
<option value="">Selecteer budget</option>
<option>Minder dan €1.000</option>
<option>€1.000 – €2.500</option>
<option>€2.500 – €5.000</option>
<option>€5.000 – €10.000</option>
<option>Meer dan €10.000</option>
</select>
</div>
<div class="fms-row">
<div class="fms-field">
<label class="fms-label" for="fms-name">Jouw naam *</label>
<input class="fms-input" type="text" id="fms-name" name="name" placeholder="Voornaam achternaam" required autocomplete="name" />
</div>
<div class="fms-field">
<label class="fms-label" for="fms-email">E-mailadres *</label>
<input class="fms-input" type="email" id="fms-email" name="email" placeholder="jij@bedrijf.nl" required autocomplete="email" />
</div>
</div>
<div class="fms-field">
<label class="fms-label" for="fms-start">Gewenste startdatum</label>
<input class="fms-input" type="date" id="fms-start" name="start_date" />
</div>
<div class="fms-actions fms-actions--between">
<button class="fms-btn fms-btn--back" type="button">← Terug</button>
<button class="fms-btn fms-btn--submit" type="submit">Plan versturen ✓</button>
</div>
</div>
</form>
</div>
<style>
.fms-wrap { max-width: 640px; padding: 2rem 0; }
.fms-heading { font-size: 1.75rem; font-weight: 800; color: var(--color-primary, #0a0a0a); margin: 0 0 2rem; }
.fms-stepper {
display: flex; position: relative; margin-bottom: 2.5rem;
justify-content: space-between;
}
.fms-step { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; flex: 1; position: relative; z-index: 1; }
.fms-step-circle {
width: 36px; height: 36px; border-radius: 50%; background: #e5e5e5;
color: #999; display: flex; align-items: center; justify-content: center;
font-weight: 700; font-size: 0.9rem; transition: all 0.2s;
}
.fms-step--active .fms-step-circle { background: var(--color-accent, #6366f1); color: #fff; }
.fms-step-label { font-size: 0.75rem; color: #999; text-align: center; font-weight: 500; }
.fms-step--active .fms-step-label { color: var(--color-accent, #6366f1); font-weight: 700; }
.fms-step-track {
position: absolute; top: 18px; left: 10%; right: 10%; height: 2px;
background: #e5e5e5; z-index: 0;
}
.fms-panel { display: none; flex-direction: column; gap: 1.25rem; }
.fms-panel--active { display: flex; }
.fms-panel-title { font-size: 1.1rem; font-weight: 700; color: var(--color-primary, #0a0a0a); margin: 0; }
.fms-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
@media (max-width: 480px) { .fms-row { grid-template-columns: 1fr; } }
.fms-field { display: flex; flex-direction: column; gap: 0.4rem; }
.fms-label { font-size: 0.85rem; font-weight: 600; color: var(--color-primary, #0a0a0a); }
.fms-input, .fms-select, .fms-textarea {
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%;
}
.fms-input:focus, .fms-select:focus, .fms-textarea:focus { outline: none; border-color: var(--color-accent, #6366f1); box-shadow: 0 0 0 3px rgba(99,102,241,0.12); }
.fms-textarea { resize: vertical; min-height: 90px; }
.fms-radio-group { display: flex; flex-direction: column; gap: 0.5rem; }
.fms-radio-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; color: #333; cursor: pointer; padding: 0.6rem 1rem; background: #f9f9f9; border-radius: 8px; border: 1.5px solid transparent; }
.fms-radio-item:has(input:checked) { border-color: var(--color-accent, #6366f1); background: #eef2ff; }
.fms-radio { accent-color: var(--color-accent, #6366f1); }
.fms-checks { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.fms-check-item { display: flex; align-items: center; gap: 0.4rem; padding: 0.35rem 0.8rem; background: #f5f5f5; border-radius: 20px; font-size: 0.83rem; cursor: pointer; border: 1.5px solid transparent; }
.fms-check-item:has(input:checked) { border-color: var(--color-accent, #6366f1); background: #eef2ff; color: var(--color-accent, #6366f1); }
.fms-check { display: none; }
.fms-actions { display: flex; justify-content: flex-end; padding-top: 0.5rem; }
.fms-actions--between { justify-content: space-between; }
.fms-btn { padding: 0.8rem 1.5rem; border-radius: 8px; font-size: 0.9rem; font-weight: 600; cursor: pointer; border: none; transition: opacity 0.2s; }
.fms-btn--back { background: #f5f5f5; color: #555; }
.fms-btn--next { background: var(--color-accent, #6366f1); color: #fff; }
.fms-btn--submit { background: #22c55e; color: #fff; }
.fms-btn:hover { opacity: 0.85; }
</style>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
headline | string | — | Formuliertitel |
steps | string[] | — | Stap labels |
* = verplicht