Documentation

Documentation

FormBlock

Inline input-and-button row that swaps to a success message after submission.

The <dsgn-form-block> component lays out a single-field form: an input, a submit button beside it, and an optional note underneath. When success flips to true, the form row fades out and the success slot fades in.

It is the signup row used in a hero or a section CTA — it does not own the submission itself. Wire your own <form>, or handle the button click, then tell the block it succeeded.

Usage

<dsgn-form-block alignment="center">
  <dsgn-input
    slot="input"
    type="email"
    name="email"
    aria-label="Email"
    placeholder="you@example.com"
  ></dsgn-input>
  <dsgn-button slot="button" type="submit">Request access</dsgn-button>
  <dsgn-text slot="note" size="sm" color="secondary"
    >No spam. Unsubscribe anytime.</dsgn-text
  >
  <dsgn-text slot="success">You're on the list.</dsgn-text>
</dsgn-form-block>

Import the component module in your application entrypoint:

import '@ds-gn/ui/form-block';

Props

Prop Type Default Description
alignment 'start' | 'center' 'start' Horizontal alignment of the form row, note, and success content.
success boolean false Success state. Setting it hides the form row and reveals the success slot. Reflected.
surface 'light' | 'dark' 'light' Semantic token surface to use.

Slots

Slot Description
input Form input control.
button Submission control.
note Supporting note below the row. The region is omitted when empty.
success Content shown after a successful submission.

There is no default slot — every child needs a slot attribute.

Success state

Two ways to flip it:

// Set the property directly
document.querySelector('dsgn-form-block').success = true;
// Or dispatch dsgn-form-success on the block (or from inside it)
block.dispatchEvent(new CustomEvent('dsgn-form-success', { bubbles: true }));

dsgn-form-success is an event the block listens for, not one it fires — it exists so a submission handler deeper in your markup can report success without holding a reference to the block.

Setting success back to false restores the form row immediately, which makes it easy to reset after an error or a second submission.

If nothing is slotted into success, the form row still disappears — always supply the success content.

Examples

In a hero

<dsgn-hero layout="centered" content-align="center">
  <dsgn-heading-block slot="content" alignment="center">
    <dsgn-heading slot="heading" heading-size="hero" surface="dark"
      >Join the beta</dsgn-heading
    >
  </dsgn-heading-block>
  <dsgn-form-block slot="form" surface="dark">
    <dsgn-input
      slot="input"
      type="email"
      name="email"
      aria-label="Email"
    ></dsgn-input>
    <dsgn-button slot="button" type="submit">Request access</dsgn-button>
    <dsgn-text slot="success" surface="dark">You're on the list.</dsgn-text>
  </dsgn-form-block>
</dsgn-hero>

With a real form submission

<form id="signup">
  <dsgn-form-block id="block">
    <dsgn-input
      slot="input"
      type="email"
      name="email"
      aria-label="Email"
      required
    ></dsgn-input>
    <dsgn-button slot="button" type="submit">Subscribe</dsgn-button>
    <dsgn-text slot="success">Check your inbox to confirm.</dsgn-text>
  </dsgn-form-block>
</form>
signup.addEventListener('submit', async (event) => {
  event.preventDefault();
  await fetch('/api/signup', { method: 'POST', body: new FormData(signup) });
  block.success = true;
});

Accessibility

  • The success message replaces the form in the DOM. Move focus to it, or render it in a live region, so the change is announced rather than only seen.
  • Give the slotted input a visible label or an aria-label; a placeholder is not an accessible name.
  • Keep the note slot for supporting copy, not for error messages — errors belong on the input itself, through <dsgn-input>’s error prop.
Esc