- FormStylePanel: ContactForm field editor (add/remove/reorder via
ArrayPropEditor + manual move up/down) covering label/name/placeholder/
type (full sanitizeInputType allowlist + textarea/select)/required/
options.
- SubscribeForm.toHtml: was a dead `<form method="POST">` with no action at
all -- wired through the same relayFormWiring contract as ContactForm/
FormContainer so a recipientEmail makes it actually submit (marker +
placeholder action + honeypot), falling back to action="#" otherwise.
- SearchBar: was purely decorative (no action/method/input name) -- now a
real GET form (configurable target, default "/") with input name="q",
safeUrl-guarded against javascript:/vbscript: breakout.
- Box-model (margin/padding per-side, border, shadow, opacity), entrance
animation, and hide-on-device controls added to FormStylePanel and
rolled out (blank/false craft.props defaults) across ContactForm,
FormContainer, InputField, TextareaField, FormButton, SubscribeForm,
SearchBar. No toHtml changes needed for animation/visibility --
html-export.ts's buildDataAttrs() already emits data-animation/
data-hide-* generically from these prop names.
- Extended toHtml tests for all 7 components: field-type rendering
(incl. textarea/select), type-attribute XSS sanitization, relay/GET
functional wiring, box-model style passthrough, craft.props defaults.
npx vitest run: 689/689 passed. npm run build: green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>