src/components/forms/FormFeedback.astro
---
/**
* FormFeedback — feedbackformulier met sterren-beoordeling, naam en bericht.
*
* Props:
* - headline?: string
* - sub?: string
* - ratingLabel?: string
* - nameLabel?: string
* - messageLabel?: string
* - button?: string
* - action?: string
*/
interface Props {
headline?: string;
sub?: string;
ratingLabel?: string;
nameLabel?: string;
messageLabel?: string;
button?: string;
action?: string;
}
const {
headline = 'Hoe was jouw ervaring?',
sub = 'Jouw feedback helpt ons om onze dienstverlening te blijven verbeteren.',
ratingLabel = 'Jouw beoordeling',
nameLabel = 'Naam',
messageLabel = 'Jouw feedback',
button = 'Feedback versturen',
action = '#',
} = Astro.props;
const stars = [5, 4, 3, 2, 1];
---
<section class="bl-section ffb">
<div class="bl-inner bl-inner--narrow ffb__inner">
{headline && <h2 class="ffb__headline">{headline}</h2>}
{sub && <p class="ffb__sub">{sub}</p>}
<form class="ffb__form" action={action} novalidate>
<div class="ffb__stars-field">
<span class="ffb__label">{ratingLabel}</span>
<div class="ffb__stars" role="group" aria-label="Beoordeling in sterren">
{stars.map((n) => (
<>
<input class="ffb__star-input" type="radio" name="rating" id={`ffb-star-${n}`} value={n} />
<label class="ffb__star-label" for={`ffb-star-${n}`} title={`${n} sterren`}>★</label>
</>
))}
</div>
</div>
<div class="ffb__field">
<label class="ffb__label" for="ffb-naam">{nameLabel}</label>
<input class="ffb__input" id="ffb-naam" type="text" placeholder="Jouw naam" />
</div>
<div class="ffb__field">
<label class="ffb__label" for="ffb-bericht">{messageLabel}</label>
<textarea class="ffb__textarea" id="ffb-bericht" rows="4" placeholder="Vertel ons hoe je de samenwerking hebt ervaren…" required></textarea>
</div>
<button class="ffb__btn" type="submit">{button}</button>
</form>
</div>
</section>
<style>
.ffb{background:#fff}
.ffb__headline{font-size:clamp(1.5rem,3vw,2rem);font-weight:800;color:var(--color-primary, #0a0a0a);letter-spacing:-.03em;margin:0 0 .5rem}
.ffb__sub{color:#6b7280;font-size:1rem;margin:0 0 2rem;line-height:1.6}
.ffb__form{display:flex;flex-direction:column;gap:1.25rem}
.ffb__label{font-size:1rem;font-weight:600;color:#374151;display:block;margin-bottom:.4rem}
.ffb__stars-field{display:flex;flex-direction:column}
.ffb__stars{display:flex;flex-direction:row-reverse;justify-content:flex-end;gap:.2rem;width:fit-content}
.ffb__star-input{position:absolute;opacity:0;pointer-events:none}
.ffb__star-label{font-size:2rem;color:#d4d4d4;cursor:pointer;transition:color .15s;line-height:1}
.ffb__stars:hover .ffb__star-label,.ffb__star-label:hover~.ffb__star-label,.ffb__star-input:checked~.ffb__star-label{color:#f59e0b}
.ffb__star-input:checked+.ffb__star-label{color:#f59e0b}
.ffb__field{display:flex;flex-direction:column;gap:.4rem}
.ffb__input,.ffb__textarea{padding:.75rem 1rem;border:1.5px solid #d1d5db;border-radius:8px;font-size:1rem;color:var(--color-primary, #0a0a0a);background:#fafafa;outline:none;font-family:inherit;transition:border-color .2s;width:100%;box-sizing:border-box}
.ffb__input:focus,.ffb__textarea:focus{border-color:var(--color-accent, #6366f1);background:#fff}
.ffb__textarea{resize:vertical}
.ffb__btn{padding:.85rem 2rem;background:var(--color-accent, #6366f1);color:#fff;border:none;border-radius:8px;font-size:1rem;font-weight:600;cursor:pointer;transition:opacity .2s;align-self:flex-start}
.ffb__btn:hover{opacity:.88}
</style>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
headline | string | 'Hoe was jouw ervaring?' | Koptekst |
sub | string | - | Ondertitel |
ratingLabel | string | 'Jouw beoordeling' | Label sterrenveld |
nameLabel | string | 'Naam' | Label naamveld |
messageLabel | string | 'Jouw feedback' | Label berichtveld |
button | string | 'Feedback versturen' | Knoptekst |
action | string | '#' | Form action URL |
* = verplicht