Skip to main content

Theme config

Theme mode

Color palette

Grays

Border radii/radiuses/radiopedes/you know
Border radius
Field border radius
Button border radius
All
Components
Guides
API
Recent

    Components

    Form

    A way to build structured forms.

    Full supportSupported since v105.Full supportSupported since v121.Full supportSupported since v15.4.

    Usage

    ---
    import { Form } from "@opui/astro"
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldGroup } from "@opui/astro"
    import { FieldDescription } from "@opui/astro"
    ---
    <Form>
    <FieldSet>
    <FieldLegend><!-- --></FieldLegend>
    <FieldDescription><!-- --></FieldDescription>
    <FieldGroup>
    <!-- -->
    </FieldGroup>
    <FieldGroup>
    <!-- -->
    </FieldGroup>
    </FieldSet>
    </Form>
    <!-- or -->
    <Form as="div">
    <FieldSet as="div">
    <FieldLegend as="p"><!-- --></FieldLegend>
    <FieldDescription><!-- --></FieldDescription>
    <FieldGroup>
    <!-- -->
    </FieldGroup>
    <FieldGroup>
    <!-- -->
    </FieldGroup>
    </FieldSet>
    </Form>

    Non-semantic elements

    Sometimes you can't use semantic form elements like <fieldset> and <legend>. Use the as prop on FieldSet and FieldLegend to render non-semantic alternatives.

    ---
    import { FieldDescription, FieldLegend, FieldSet, Form } from "@opui/astro"
    ---
    <Form as="div">
    <FieldSet as="div">
    <FieldLegend as="p">Using as prop</FieldLegend>
    <FieldDescription> Renders as div and p elements. </FieldDescription>
    </FieldSet>
    </Form>

    Fieldset

    Used to show a relationship between form elements.

    FieldLegend

    to describe what it's about.
    FieldDescription(optional)

    to give extra context about the fieldset.
    FieldGroup

    groups related fields.
    Favorite Pet

    Please select your favorite type of pet.

    ---
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldDescription } from "@opui/astro"
    import { FieldGroup } from "@opui/astro"
    import { Radio } from "@opui/astro"
    ---
    <FieldSet>
    <FieldLegend>Favorite Pet</FieldLegend>
    <FieldDescription>Please select your favorite type of pet.</FieldDescription>
    <FieldGroup name="pet">
    <Radio value="dog">Dog</Radio>
    <Radio value="cat">Cat</Radio>
    <Radio value="hamster">Hamster</Radio>
    </FieldGroup>
    </FieldSet>
    <fieldset class="ui-fieldset">
    <legend>Favorite Pet</legend>
    <p class="ui-field-description">Please select your favorite type of pet.</p>
    <div class="ui-field-group" role="group">
    <label class="ui-radio"
    ><input name="pet" type="radio" value="dog" /><span class="ui-label"
    >Dog</span
    ></label
    ><label class="ui-radio"
    ><input name="pet" type="radio" value="cat" /><span class="ui-label"
    >Cat</span
    ></label
    ><label class="ui-radio"
    ><input name="pet" type="radio" value="hamster" /><span class="ui-label"
    >Hamster</span
    ></label
    >
    </div>
    </fieldset>

    Required

    Pet info

    We must know your pet's information.

    ---
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldDescription } from "@opui/astro"
    import { FieldGroup } from "@opui/astro"
    import { Textarea } from "@opui/astro"
    import { TextField } from "@opui/astro"
    ---
    <FieldSet>
    <FieldLegend>Pet info</FieldLegend>
    <FieldDescription>We must know your pet's information.</FieldDescription>
    <FieldGroup name="bio">
    <TextField label="Name" name="name" />
    <Textarea required label="Life story" />
    </FieldGroup>
    </FieldSet>
    <fieldset class="ui-fieldset">
    <legend>Pet info</legend>
    <p class="ui-field-description">We must know your pet's information.</p>
    <div class="ui-field-group" role="group">
    <label class="ui-text-field"
    ><span class="ui-label">Name</span
    ><span class="ui-field"><input name="name" type="text" /></span></label
    ><label class="ui-textarea"
    ><span class="ui-label">Life story</span
    ><span class="ui-field"><textarea name="bio" required></textarea></span
    ></label>
    </div>
    </fieldset>

    Disabled

    Turns out you can disable an entire fieldset.

    Pet dating

    You can't change these settings

    ---
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldDescription } from "@opui/astro"
    import { FieldGroup } from "@opui/astro"
    import { Checkbox } from "@opui/astro"
    ---
    <FieldSet disabled>
    <FieldLegend>Pet dating</FieldLegend>
    <FieldDescription>You can't change these settings</FieldDescription>
    <FieldGroup name="notifications">
    <Checkbox value="horse-tinder" checked>Horse Tinder</Checkbox>
    <Checkbox value="onlyhorsefans" checked>OnlyHorseFans</Checkbox>
    </FieldGroup>
    </FieldSet>
    <fieldset disabled class="ui-fieldset">
    <legend>Pet dating</legend>
    <p class="ui-field-description">You can't change these settings</p>
    <div class="ui-field-group" role="group">
    <label class="ui-checkbox"
    ><input
    name="notifications"
    type="checkbox"
    value="horse-tinder"
    checked
    />
    <script type="module">
    function e(e = document) {
    e.querySelectorAll(
    `input[type="checkbox"][data-indeterminate]`,
    ).forEach((e) => {
    e.indeterminate = !0;
    });
    }
    function t() {
    (e(), document.addEventListener(`astro:after-swap`, () => e()));
    }
    t();
    </script>
    <span class="ui-label">Horse Tinder</span></label
    ><label class="ui-checkbox"
    ><input
    name="notifications"
    type="checkbox"
    value="onlyhorsefans"
    checked
    /><span class="ui-label">OnlyHorseFans</span></label
    >
    </div>
    </fieldset>

    Field Legend

    Use FieldLegend (or <legend>) to describe the fieldset.

    Legend
    ---
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    ---
    <FieldSet>
    <FieldLegend>Legend</FieldLegend>
    </FieldSet>
    <fieldset class="ui-fieldset"><legend>Legend</legend></fieldset>

    Field Description

    Use FieldDescription (or .ui-field-description) to give extra context about the fieldset.

    Legend

    This is a field description.

    ---
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldDescription } from "@opui/astro"
    ---
    <FieldSet>
    <FieldLegend>Legend</FieldLegend>
    <FieldDescription>This is a field description.</FieldDescription>
    </FieldSet>
    <fieldset class="ui-fieldset">
    <legend>Legend</legend>
    <p class="ui-field-description">This is a field description.</p>
    </fieldset>

    Field Group

    Use FieldGroup to wrap related fields. It provides a sharedname to all nested inputs.

    Choose your favorite Radiohead album

    There are no wrong answers.

    Which side projects do you follow?

    Some are better than others.

    ---
    import { Checkbox } from "@opui/astro"
    import { FieldDescription } from "@opui/astro"
    import { FieldGroup } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldSet } from "@opui/astro"
    import { Form } from "@opui/astro"
    import { Radio } from "@opui/astro"
    ---
    <Form>
    <FieldSet>
    <FieldLegend>Choose your favorite Radiohead album</FieldLegend>
    <FieldDescription>There are no wrong answers.</FieldDescription>
    <FieldGroup name="albums">
    <Radio value="ok-computer">OK Computer</Radio>
    <Radio value="kid-a">Kid A</Radio>
    <Radio value="in-rainbows">In Rainbows</Radio>
    <Radio value="king-of-limbs">The King of Limbs</Radio>
    </FieldGroup>
    </FieldSet>
    <FieldSet>
    <FieldLegend>Which side projects do you follow?</FieldLegend>
    <FieldDescription>Some are better than others.</FieldDescription>
    <FieldGroup name="projects">
    <Checkbox value="the-smile">
    The Smile
    <Fragment slot="end-text"
    >Thom Yorke, Jonny Greenwood, Tom Skinner</Fragment
    >
    </Checkbox>
    <Checkbox value="atoms-for-peace">
    Atoms for Peace
    <Fragment slot="end-text">Thom Yorke, Flea, Nigel Godrich</Fragment>
    </Checkbox>
    <Checkbox value="eob">
    EOB
    <Fragment slot="end-text">Ed O'Brien solo</Fragment>
    </Checkbox>
    <Checkbox value="jonny-scores">
    Film Scores
    <Fragment slot="end-text">Film compositions by Jonny Greenwood</Fragment
    >
    </Checkbox>
    <Checkbox value="selway-solo">
    Philip Selway
    <Fragment slot="end-text">Philip Selway solo albums</Fragment>
    </Checkbox>
    </FieldGroup>
    </FieldSet>
    </Form>
    <form class="ui-form">
    <fieldset class="ui-fieldset">
    <legend>Choose your favorite Radiohead album</legend>
    <p class="ui-field-description">There are no wrong answers.</p>
    <div class="ui-field-group" role="group">
    <label class="ui-radio"
    ><input name="albums" type="radio" value="ok-computer" /><span
    class="ui-label"
    >OK Computer</span
    ></label
    ><label class="ui-radio"
    ><input name="albums" type="radio" value="kid-a" /><span
    class="ui-label"
    >Kid A</span
    ></label
    ><label class="ui-radio"
    ><input name="albums" type="radio" value="in-rainbows" /><span
    class="ui-label"
    >In Rainbows</span
    ></label
    ><label class="ui-radio"
    ><input name="albums" type="radio" value="king-of-limbs" /><span
    class="ui-label"
    >The King of Limbs</span
    ></label
    >
    </div>
    </fieldset>
    <fieldset class="ui-fieldset">
    <legend>Which side projects do you follow?</legend>
    <p class="ui-field-description">Some are better than others.</p>
    <div class="ui-field-group" role="group">
    <label class="ui-checkbox"
    ><input
    name="projects"
    type="checkbox"
    aria-describedby="end-text-1"
    value="the-smile"
    /><span class="ui-label">The Smile</span
    ><span id="end-text-1" class="ui-end-text"
    >Thom Yorke, Jonny Greenwood, Tom Skinner</span
    ></label
    ><label class="ui-checkbox"
    ><input
    name="projects"
    type="checkbox"
    aria-describedby="end-text-2"
    value="atoms-for-peace"
    /><span class="ui-label">Atoms for Peace</span
    ><span id="end-text-2" class="ui-end-text"
    >Thom Yorke, Flea, Nigel Godrich</span
    ></label
    ><label class="ui-checkbox"
    ><input
    name="projects"
    type="checkbox"
    aria-describedby="end-text-3"
    value="eob"
    /><span class="ui-label">EOB</span
    ><span id="end-text-3" class="ui-end-text">Ed O'Brien solo</span></label
    ><label class="ui-checkbox"
    ><input
    name="projects"
    type="checkbox"
    aria-describedby="end-text-4"
    value="jonny-scores"
    /><span class="ui-label">Film Scores</span
    ><span id="end-text-4" class="ui-end-text"
    >Film compositions by Jonny Greenwood</span
    ></label
    ><label class="ui-checkbox"
    ><input
    name="projects"
    type="checkbox"
    aria-describedby="end-text-5"
    value="selway-solo"
    /><span class="ui-label">Philip Selway</span
    ><span id="end-text-5" class="ui-end-text"
    >Philip Selway solo albums</span
    ></label
    >
    </div>
    </fieldset>
    </form>

    Row

    Use the direction="row" prop to lay out fields horizontally.

    Options
    ---
    import { Form } from "@opui/astro"
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldGroup } from "@opui/astro"
    import { Checkbox } from "@opui/astro"
    ---
    <Form>
    <FieldSet>
    <FieldLegend>Options</FieldLegend>
    <FieldGroup direction="row">
    <Checkbox>Option 1</Checkbox>
    <Checkbox>Option 2</Checkbox>
    <Checkbox>Option 3</Checkbox>
    </FieldGroup>
    </FieldSet>
    </Form>
    <form class="ui-form">
    <fieldset class="ui-fieldset">
    <legend>Options</legend>
    <div class="ui-field-group ui-row" role="group">
    <label class="ui-checkbox"
    ><input type="checkbox" /><span class="ui-label">Option 1</span></label
    ><label class="ui-checkbox"
    ><input type="checkbox" /><span class="ui-label">Option 2</span></label
    ><label class="ui-checkbox"
    ><input type="checkbox" /><span class="ui-label">Option 3</span></label
    >
    </div>
    </fieldset>
    </form>

    Divider

    Use the Divider component to create a visual break between sections of your form.

    Post Content

    ---
    import { Form } from "@opui/astro"
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldGroup } from "@opui/astro"
    import { TextField } from "@opui/astro"
    import { Button } from "@opui/astro"
    import { Divider } from "@opui/astro"
    ---
    <Form>
    <FieldSet>
    <FieldLegend>Post Content</FieldLegend>
    <FieldGroup>
    <TextField label="Title" placeholder="My new post" />
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldGroup>
    <Button variant="filled">Publish</Button>
    </FieldGroup>
    </Form>
    <form class="ui-form">
    <fieldset class="ui-fieldset">
    <legend>Post Content</legend>
    <div class="ui-field-group" role="group">
    <label class="ui-text-field"
    ><span class="ui-label">Title</span
    ><span class="ui-field"
    ><input placeholder="My new post" type="text" /></span
    ></label>
    </div>
    </fieldset>
    <hr class="ui-divider" />
    <div class="ui-field-group" role="group">
    <button class="ui-button ui-filled">Publish</button>
    </div>
    </form>

    Kitchen Sink

    Everything all at once.

    User Profile

    Please provide your basic contact details.


    Notifications

    Configure how you want to receive updates.


    Theme Preference

    Select your preferred visual style.


    Experience Level

    How many years of experience do you have?


    Additional Info

    Anything else we should know?


    Legal

    ---
    import { Form } from "@opui/astro"
    import { FieldSet } from "@opui/astro"
    import { FieldLegend } from "@opui/astro"
    import { FieldDescription } from "@opui/astro"
    import { FieldGroup } from "@opui/astro"
    import { TextField } from "@opui/astro"
    import { Select } from "@opui/astro"
    import { Switch } from "@opui/astro"
    import { Radio } from "@opui/astro"
    import { Textarea } from "@opui/astro"
    import { Checkbox } from "@opui/astro"
    import { Range } from "@opui/astro"
    import { Button } from "@opui/astro"
    import { Divider } from "@opui/astro"
    ---
    <Form id="kitchen-sink-example">
    <FieldSet>
    <FieldLegend>User Profile</FieldLegend>
    <FieldDescription>
    Please provide your basic contact details.
    </FieldDescription>
    <FieldGroup>
    <TextField label="Full Name" placeholder="Jane Doe" required />
    <TextField
    label="Email Address"
    type="email"
    placeholder="jane@example.com"
    required
    />
    <Select
    label="Role"
    items={[
    { text: "Developer", value: "dev" },
    { text: "Designer", value: "design" },
    { text: "Manager", value: "manager" },
    ]}
    />
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Notifications</FieldLegend>
    <FieldDescription>
    Configure how you want to receive updates.
    </FieldDescription>
    <FieldGroup name="notifications">
    <Switch name="email_notifs" checked>Email Notifications</Switch>
    <Switch name="sms_notifs">SMS Notifications</Switch>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Theme Preference</FieldLegend>
    <FieldDescription>Select your preferred visual style.</FieldDescription>
    <FieldGroup name="theme">
    <Radio value="light" checked>Light Theme</Radio>
    <Radio value="dark">Dark Theme</Radio>
    <Radio value="system">System Default</Radio>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Experience Level</FieldLegend>
    <FieldDescription
    >How many years of experience do you have?</FieldDescription
    >
    <FieldGroup>
    <Range
    label="Professional Experience"
    min="0"
    max="20"
    step="1"
    value="5"
    startText="Drag the slider to match your total tenure."
    />
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Additional Info</FieldLegend>
    <FieldDescription>Anything else we should know?</FieldDescription>
    <FieldGroup name="details">
    <Textarea
    label="Biography"
    placeholder="Tell us about yourself..."
    rows={4}
    />
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Legal</FieldLegend>
    <FieldGroup name="legal">
    <Checkbox name="terms" required>
    I agree to the terms and conditions
    <Fragment slot="end-text">Support this text</Fragment>
    </Checkbox>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldGroup>
    <Button variant="filled" type="submit">Send</Button>
    <Button>Cancel</Button>
    </FieldGroup>
    </Form>
    <form id="kitchen-sink-example" class="ui-form"><fieldset class="ui-fieldset"><legend>User Profile</legend><p class="ui-field-description">Please provide your basic contact details.</p><div class="ui-field-group" role="group"><label class="ui-text-field"><span class="ui-label">Full Name</span><span class="ui-field"><input placeholder="Jane Doe" required type="text"></span></label><label class="ui-text-field"><span class="ui-label">Email Address</span><span class="ui-field"><input placeholder="jane@example.com" required type="email"></span></label><label class="ui-select"><span class="ui-label" id="select-label-3">Role</span><span class="ui-field"><select aria-labelledby="select-label-3"><button><selectedcontent></button><div class="ui-list"><option value="dev">Developer</option><option value="design">Designer</option><option value="manager">Manager</option></div></select></span></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Notifications</legend><p class="ui-field-description">Configure how you want to receive updates.</p><div class="ui-field-group" role="group"><label class="ui-switch"><input type="checkbox" role="switch" name="email_notifs" checked><span class="ui-label">Email Notifications</span></label><label class="ui-switch"><input type="checkbox" role="switch" name="sms_notifs"><span class="ui-label">SMS Notifications</span></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Theme Preference</legend><p class="ui-field-description">Select your preferred visual style.</p><div class="ui-field-group" role="group"><label class="ui-radio"><input name="theme" type="radio" value="light" checked><span class="ui-label">Light Theme</span></label><label class="ui-radio"><input name="theme" type="radio" value="dark"><span class="ui-label">Dark Theme</span></label><label class="ui-radio"><input name="theme" type="radio" value="system"><span class="ui-label">System Default</span></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Experience Level</legend><p class="ui-field-description">How many years of experience do you have?</p><div class="ui-field-group" role="group"><label class="ui-range"><span class="ui-label" id="range-label-6">Professional Experience</span><span class="ui-start-text" id="range-start-1">Drag the slider to match your total tenure.</span><input aria-describedby="range-start-1" aria-labelledby="range-label-6" max="20" min="0" step="1" type="range" value="5"></label><script type="module">for(let e of document.querySelectorAll(`.ui-range`)){let t=e.querySelector(`input[type="range"]`),n=e.querySelector(`:scope > output.ui-value`);if(!t||!n)continue;let r=n.dataset.suffix??``,i=()=>{n.textContent=`${t.value}${r}`};t.addEventListener(`input`,i),i()}</script></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Additional Info</legend><p class="ui-field-description">Anything else we should know?</p><div class="ui-field-group" role="group"><label class="ui-textarea"><span class="ui-label">Biography</span><span class="ui-field"><textarea name="details" placeholder="Tell us about yourself..." rows="4"></textarea></span></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Legal</legend><div class="ui-field-group" role="group"><label class="ui-checkbox"><input type="checkbox" aria-describedby="end-text-6" name="terms" required><span class="ui-label">I agree to the terms and conditions</span><span id="end-text-6" class="ui-end-text">Support this text</span></label></div></fieldset><hr class="ui-divider"><div class="ui-field-group" role="group"><button type="submit" class="ui-button ui-filled">Send</button><button class="ui-button">Cancel</button></div></form>

    Row

    Everything all at once, but horizontally.

    User Profile

    Please provide your basic contact details.


    Notifications

    Configure how you want to receive updates.


    Theme Preference

    Select your preferred visual style.


    Experience Level

    How many years of experience do you have?


    Additional Info

    Anything else we should know?


    Legal

    ---
    import {
    Button,
    Checkbox,
    Divider,
    FieldDescription,
    FieldGroup,
    FieldLegend,
    FieldSet,
    Form,
    Radio,
    Range,
    Select,
    Switch,
    TextField,
    Textarea,
    } from "@opui/astro"
    ---
    <Form id="kitchen-sink-example-row">
    <FieldSet>
    <FieldLegend>User Profile</FieldLegend>
    <FieldDescription>
    Please provide your basic contact details.
    </FieldDescription>
    <FieldGroup>
    <TextField placeholder="Jane Doe" required spread>
    <Fragment slot="label">Full Name</Fragment>
    </TextField>
    <TextField type="email" placeholder="jane@example.com" required spread>
    <Fragment slot="label">Email Address</Fragment>
    </TextField>
    <Select
    items={[
    { text: "Developer", value: "dev" },
    { text: "Designer", value: "design" },
    { text: "Manager", value: "manager" },
    ]}
    spread
    >
    <Fragment slot="label">Role</Fragment>
    </Select>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Notifications</FieldLegend>
    <FieldDescription>
    Configure how you want to receive updates.
    </FieldDescription>
    <FieldGroup name="notifications">
    <Switch name="email_notifs" checked spread>Email Notifications</Switch>
    <Switch name="sms_notifs" spread>SMS Notifications</Switch>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Theme Preference</FieldLegend>
    <FieldDescription>Select your preferred visual style.</FieldDescription>
    <FieldGroup direction="row" name="theme">
    <Radio value="light" checked>Light Theme</Radio>
    <Radio value="dark">Dark Theme</Radio>
    <Radio value="system">System Default</Radio>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Experience Level</FieldLegend>
    <FieldDescription
    >How many years of experience do you have?</FieldDescription
    >
    <FieldGroup>
    <Range min="0" max="20" step="1" value="5" spread>
    Professional Experience
    <Fragment slot="start-text"
    >Drag the slider to match your total tenure.</Fragment
    >
    </Range>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Additional Info</FieldLegend>
    <FieldDescription>Anything else we should know?</FieldDescription>
    <FieldGroup name="details">
    <Textarea placeholder="Tell us about yourself..." rows={4} spread>
    <Fragment slot="label">Biography</Fragment>
    </Textarea>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Legal</FieldLegend>
    <FieldGroup name="legal">
    <Checkbox name="terms" required spread>
    I agree to the terms and conditions
    <Fragment slot="end-text">Support this text</Fragment>
    </Checkbox>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldGroup>
    <Button variant="filled" type="submit">Send</Button>
    <Button>Cancel</Button>
    </FieldGroup>
    </Form>
    <form id="kitchen-sink-example-row" class="ui-form"><fieldset class="ui-fieldset"><legend>User Profile</legend><p class="ui-field-description">Please provide your basic contact details.</p><div class="ui-field-group" role="group"><label class="ui-text-field ui-spread"><span class="ui-label">Full Name</span><span class="ui-field"><input placeholder="Jane Doe" required type="text"></span></label><label class="ui-text-field ui-spread"><span class="ui-label">Email Address</span><span class="ui-field"><input placeholder="jane@example.com" required type="email"></span></label><label class="ui-select ui-spread"><span class="ui-label" id="select-label-4">Role</span><span class="ui-field"><select aria-labelledby="select-label-4"><button><selectedcontent></button><div class="ui-list"><option value="dev">Developer</option><option value="design">Designer</option><option value="manager">Manager</option></div></select></span></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Notifications</legend><p class="ui-field-description">Configure how you want to receive updates.</p><div class="ui-field-group" role="group"><label class="ui-switch ui-spread"><input type="checkbox" role="switch" name="email_notifs" checked><span class="ui-label">Email Notifications</span></label><label class="ui-switch ui-spread"><input type="checkbox" role="switch" name="sms_notifs"><span class="ui-label">SMS Notifications</span></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Theme Preference</legend><p class="ui-field-description">Select your preferred visual style.</p><div class="ui-field-group ui-row" role="group"><label class="ui-radio"><input name="theme" type="radio" value="light" checked><span class="ui-label">Light Theme</span></label><label class="ui-radio"><input name="theme" type="radio" value="dark"><span class="ui-label">Dark Theme</span></label><label class="ui-radio"><input name="theme" type="radio" value="system"><span class="ui-label">System Default</span></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Experience Level</legend><p class="ui-field-description">How many years of experience do you have?</p><div class="ui-field-group" role="group"><label class="ui-range ui-spread"><span class="ui-label" id="range-label-7">Professional Experience</span><span class="ui-start-text" id="range-start-2">Drag the slider to match your total tenure.</span><input aria-describedby="range-start-2" aria-labelledby="range-label-7" max="20" min="0" step="1" type="range" value="5"></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Additional Info</legend><p class="ui-field-description">Anything else we should know?</p><div class="ui-field-group" role="group"><label class="ui-textarea ui-spread"><span class="ui-label">Biography</span><span class="ui-field"><textarea name="details" placeholder="Tell us about yourself..." rows="4"></textarea></span></label></div></fieldset><hr class="ui-divider"><fieldset class="ui-fieldset"><legend>Legal</legend><div class="ui-field-group" role="group"><label class="ui-checkbox ui-spread"><input type="checkbox" aria-describedby="end-text-7" name="terms" required><span class="ui-label">I agree to the terms and conditions</span><span id="end-text-7" class="ui-end-text">Support this text</span></label></div></fieldset><hr class="ui-divider"><div class="ui-field-group" role="group"><button type="submit" class="ui-button ui-filled">Send</button><button class="ui-button">Cancel</button></div></form>

    API

    Form API

    PropTypeDefaultDescription
    as"div", "form""form"The element to render.

    Slots

    SlotDescription
    defaultThe fieldsets and fields.

    Field set API

    PropTypeDefaultDescription
    as"div", "fieldset""fieldset"The element to render.
    disabledbooleanfalseDisables every field inside.

    Slots

    SlotDescription
    defaultThe legend, description and fields.

    Field legend API

    PropTypeDefaultDescription
    as"p", "legend""legend"The element to render. Adds .ui-legend when not "legend".

    Slots

    SlotDescription
    defaultThe label.

    Field description API

    Slots

    SlotDescription
    defaultThe text.

    Field group API

    PropTypeDefaultDescription
    direction"row", "column"-The orientation of the element.
    namestring-Sets name on every input, select and textarea inside.

    Slots

    SlotDescription
    defaultThe fields, such as checkboxes, radios or switches.

    Browser support

    Full supportSupported since v105.Full supportSupported since v121.Full supportSupported since v15.4.

    See also the full browser support guide.

    Installation

    This doesn't include all the styles for all form elements, just the scaffolding around them.

    See also

    @layer components.extended {
    /* Form */
    :where(.ui-form) {
    display: grid;
    gap: var(--size-8);
    hr {
    margin-block: 0;
    }
    }
    /* Fieldset */
    :where(.ui-fieldset) {
    all: unset;
    border: 0;
    border-radius: 0;
    display: grid;
    gap: var(--size-1);
    margin: 0;
    min-inline-size: 0;
    padding: 0;
    /* Legend */
    :where(legend, .ui-legend) {
    all: unset;
    color: var(--text-primary);
    font-weight: 600;
    margin-block-end: var(--size-3);
    padding: 0;
    &:has(+ :where(.ui-field-description)) {
    margin-block-end: 0;
    }
    }
    /* Field description / supporting text */
    :where(.ui-field-description) {
    color: var(--text-muted);
    font-size: var(--font-size-05);
    line-height: var(--font-lineheight-3);
    &:has(+ *) {
    margin-block-end: var(--size-3);
    }
    }
    /* End text */
    :where(.ui-end-text) {
    color: var(--text-muted);
    font-size: var(--font-size-0);
    line-height: var(--font-lineheight-3);
    }
    &:has(.ui-text-field.ui-row) {
    row-gap: var(--size-7);
    }
    /* Disabled */
    &[disabled] {
    opacity: 0.64;
    user-select: none;
    input,
    label,
    .ui-label {
    cursor: not-allowed;
    }
    }
    /* Error / validation */
    &[data-invalid] {
    :where(.ui-end-text) {
    color: var(--critical);
    }
    :where(.ui-checkbox, .ui-radio, .ui-switch) {
    --primary: var(--critical);
    :where(.ui-end-text) {
    color: var(--critical);
    }
    }
    :where(.ui-switch) {
    input {
    border-radius: var(--radius-round);
    outline: 2px solid var(--critical);
    }
    }
    }
    /* Required */
    &:has(:invalid) {
    :where(legend, .ui-legend) {
    padding-inline-end: 1ex;
    position: relative;
    &::after {
    color: var(--red);
    content: "*";
    inset: 0 -0.25ex auto auto;
    position: absolute;
    }
    }
    }
    }
    /* Field group */
    :where(.ui-field-group) {
    display: flex;
    flex-direction: column;
    gap: var(--size-4);
    /* If it only has checkboxes, radios, or switches */
    &:has(> :where(.ui-checkbox, .ui-radio, .ui-switch)):not(
    :has(> :not(.ui-checkbox, .ui-radio, .ui-switch))
    ) {
    gap: var(--size-2);
    }
    /* If it only has buttons */
    &:has(.ui-button):not(:has(*:not(.ui-button))) {
    align-items: center;
    flex-direction: row;
    gap: var(--size-2);
    /* If it's not preceded by an hr */
    &:not(hr + &) {
    margin-block-start: var(--size-4);
    }
    }
    & + & {
    margin-block-start: var(--size-5);
    }
    /* Directions */
    &.ui-row {
    flex-direction: row;
    flex-wrap: wrap;
    &:has(> :where(.ui-checkbox, .ui-radio, .ui-switch)) {
    gap: var(--size-4);
    }
    }
    }
    }