Active Foundation · Example
A settings form with sections and actions
A settings form with sections and actionsSimulationA server imitated in your browser: shows the interaction, not a working server integration.
Full source examples/ui/form-section.tsx
// apps/docs/examples/ui/form-section.tsx'use client';
import {useState} from 'react';
import {SubmitButton} from '@workspace/active-ui/components/composed/buttons';import {FormActions} from '@workspace/active-ui/components/composed/form-actions';import {FormCancelButton} from '@workspace/active-ui/components/composed/form-cancel-button';import {FormSection} from '@workspace/active-ui/components/composed/form-section';import {FormSuccess} from '@workspace/active-ui/components/composed/form-success';import {Button} from '@workspace/active-ui/components/primitives/button';import { Field, FieldLabel,} from '@workspace/active-ui/components/primitives/field';import {Input} from '@workspace/active-ui/components/primitives/input';
const SAVED = {name: 'Northwind pension fund', email: 'office@example.com'};
/** * A settings form in two sections with the form's action row. Change a * field to make the form dirty: Cancel then asks before it discards. Saving * is simulated with a short wait; nothing is sent. */export default function FormSectionExample() { const [saved, setSaved] = useState(SAVED); const [values, setValues] = useState(SAVED); const [isPending, setIsPending] = useState(false); const [message, setMessage] = useState(''); const isDirty = values.name !== saved.name || values.email !== saved.email;
const save = (event: React.FormEvent) => { event.preventDefault(); setIsPending(true); setMessage(''); window.setTimeout(() => { setSaved(values); setIsPending(false); setMessage('Your changes are saved.'); }, 1200); };
return ( <form className="grid w-full max-w-xl gap-6" onSubmit={save}> <FormSection title="Organisation" description="How the organisation appears on statements." > <Field> <FieldLabel htmlFor="org-name">Name</FieldLabel> <Input id="org-name" value={values.name} onChange={(event) => setValues({...values, name: event.target.value}) } /> </Field> </FormSection> <FormSection title="Contact" actions={ <Button type="button" variant="outline" size="sm"> Add a contact </Button> } footer={ <p className="text-muted-foreground text-sm"> Last changed: 16 May 2026 </p> } variant="compact" > <Field> <FieldLabel htmlFor="org-email">Email</FieldLabel> <Input id="org-email" type="email" value={values.email} onChange={(event) => setValues({...values, email: event.target.value}) } /> </Field> </FormSection> <FormActions> <FormCancelButton label="Cancel" isDirty={isDirty} disabled={isPending} onConfirm={() => { setValues(saved); setMessage(''); }} dialog={{ title: 'Unsaved changes', description: 'You have unsaved changes. Discard them?', confirmLabel: 'Discard changes', cancelLabel: 'Keep editing', }} /> <SubmitButton isPending={isPending} normalLabel="Save" disabled={!isDirty} /> </FormActions> <FormSuccess message={message} /> </form> );}