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

    <script setup lang="ts">
    import {
    FieldDescription,
    FieldGroup,
    FieldLegend,
    FieldSet,
    Form,
    } from "opui-css/vue"
    </script>
    <template>
    <Form>
    <FieldSet>
    <FieldLegend><!-- --></FieldLegend>
    <FieldDescription><!-- --></FieldDescription>
    <FieldGroup>
    <!-- -->
    </FieldGroup>
    <FieldGroup>
    <!-- -->
    </FieldGroup>
    </FieldSet>
    </Form>
    </template>

    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.

    <script setup lang="ts">
    import { FieldDescription, FieldLegend, FieldSet, Form } from "opui-css/vue"
    </script>
    <template>
    <Form as="div">
    <FieldSet as="div">
    <FieldLegend as="p">Using as prop</FieldLegend>
    <FieldDescription> Renders as div and p elements. </FieldDescription>
    </FieldSet>
    </Form>
    </template>

    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.

    <script setup lang="ts">
    import {
    FieldDescription,
    FieldGroup,
    FieldLegend,
    FieldSet,
    Radio,
    } from "opui-css/vue"
    </script>
    <template>
    <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>
    </template>
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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 type="radio" value="dog" aria-describedby="s0-0" /><span
    class="ui-label"
    ><!--[-->Dog<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input type="radio" value="cat" aria-describedby="s0-1" /><span
    class="ui-label"
    ><!--[-->Cat<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input type="radio" value="hamster" aria-describedby="s0-2" /><span
    class="ui-label"
    ><!--[-->Hamster<!--]--></span
    ><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>

    Required

    Pet info

    We must know your pet's information.

    <script setup lang="ts">
    import {
    FieldDescription,
    FieldGroup,
    FieldLegend,
    FieldSet,
    Textarea,
    TextField,
    } from "opui-css/vue"
    </script>
    <template>
    <FieldSet>
    <FieldLegend>Pet info</FieldLegend>
    <FieldDescription>We must know your pet's information.</FieldDescription>
    <FieldGroup name="bio">
    <TextField label="Name" />
    <Textarea required label="Life story" />
    </FieldGroup>
    </FieldSet>
    </template>
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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 id="s1-0" type="text" /><!----><!----><!----><!----></span
    ><!----><!--[--><!--]--></label
    ><label class="ui-textarea"
    ><span class="ui-label"><!--[-->Life story<!--]--></span><!----><span
    class="ui-field"
    >
    <textarea id="s1-1" required></textarea
    ><!----><!----><!----><!----></span
    ><!----><!--[--><!--]--></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>

    Disabled

    Turns out you can disable an entire fieldset.

    Pet dating

    You can't change these settings

    <script setup lang="ts">
    import {
    Checkbox,
    FieldDescription,
    FieldGroup,
    FieldLegend,
    FieldSet,
    } from "opui-css/vue"
    </script>
    <template>
    <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>
    </template>
    <fieldset class="ui-fieldset" disabled>
    <!--[-->
    <legend class=""><!--[-->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 type="checkbox" value="horse-tinder" /><span class="ui-label"
    ><!--[-->Horse Tinder<!--]--></span
    ><!----></label
    ><label class="ui-checkbox"
    ><input type="checkbox" value="onlyhorsefans" /><span class="ui-label"
    ><!--[-->OnlyHorseFans<!--]--></span
    ><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>

    Field Legend

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

    Legend
    <script setup lang="ts">
    import { FieldLegend, FieldSet } from "opui-css/vue"
    </script>
    <template>
    <FieldSet>
    <FieldLegend>Legend</FieldLegend>
    </FieldSet>
    </template>
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->Legend<!--]--></legend>
    <!--]-->
    </fieldset>

    Field Description

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

    Legend

    This is a field description.

    <script setup lang="ts">
    import { FieldDescription, FieldLegend, FieldSet } from "opui-css/vue"
    </script>
    <template>
    <FieldSet>
    <FieldLegend>Legend</FieldLegend>
    <FieldDescription>This is a field description.</FieldDescription>
    </FieldSet>
    </template>
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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.

    <script setup lang="ts">
    import {
    Checkbox,
    FieldDescription,
    FieldGroup,
    FieldLegend,
    FieldSet,
    Form,
    Radio,
    } from "opui-css/vue"
    </script>
    <template>
    <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
    <template #end-text
    >Thom Yorke, Jonny Greenwood, Tom Skinner</template
    >
    </Checkbox>
    <Checkbox value="atoms-for-peace">
    Atoms for Peace
    <template #end-text>Thom Yorke, Flea, Nigel Godrich</template>
    </Checkbox>
    <Checkbox value="eob">
    EOB
    <template #end-text>Ed O'Brien solo</template>
    </Checkbox>
    <Checkbox value="jonny-scores">
    Film Scores
    <template #end-text>Film compositions by Jonny Greenwood</template>
    </Checkbox>
    <Checkbox value="selway-solo">
    Philip Selway
    <template #end-text>Philip Selway solo albums</template>
    </Checkbox>
    </FieldGroup>
    </FieldSet>
    </Form>
    </template>
    <form class="ui-form">
    <!--[-->
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class="">
    <!--[-->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 type="radio" value="ok-computer" aria-describedby="s5-0" /><span
    class="ui-label"
    ><!--[-->OK Computer<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input type="radio" value="kid-a" aria-describedby="s5-1" /><span
    class="ui-label"
    ><!--[-->Kid A<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input type="radio" value="in-rainbows" aria-describedby="s5-2" /><span
    class="ui-label"
    ><!--[-->In Rainbows<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input
    type="radio"
    value="king-of-limbs"
    aria-describedby="s5-3"
    /><span class="ui-label"><!--[-->The King of Limbs<!--]--></span
    ><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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
    type="checkbox"
    value="the-smile"
    aria-describedby="s5-4"
    /><span class="ui-label"
    ><!--[-->
    The Smile
    <!--]--></span
    ><span id="s5-4" class="ui-end-text"
    ><!--[-->Thom Yorke, Jonny Greenwood, Tom Skinner<!--]--></span
    ></label
    ><label class="ui-checkbox"
    ><input
    type="checkbox"
    value="atoms-for-peace"
    aria-describedby="s5-5"
    /><span class="ui-label"
    ><!--[-->
    Atoms for Peace
    <!--]--></span
    ><span id="s5-5" class="ui-end-text"
    ><!--[-->Thom Yorke, Flea, Nigel Godrich<!--]--></span
    ></label
    ><label class="ui-checkbox"
    ><input type="checkbox" value="eob" aria-describedby="s5-6" /><span
    class="ui-label"
    ><!--[-->
    EOB
    <!--]--></span
    ><span id="s5-6" class="ui-end-text"
    ><!--[-->Ed O'Brien solo<!--]--></span
    ></label
    ><label class="ui-checkbox"
    ><input
    type="checkbox"
    value="jonny-scores"
    aria-describedby="s5-7"
    /><span class="ui-label"
    ><!--[-->
    Film Scores
    <!--]--></span
    ><span id="s5-7" class="ui-end-text"
    ><!--[-->Film compositions by Jonny Greenwood<!--]--></span
    ></label
    ><label class="ui-checkbox"
    ><input
    type="checkbox"
    value="selway-solo"
    aria-describedby="s5-8"
    /><span class="ui-label"
    ><!--[-->
    Philip Selway
    <!--]--></span
    ><span id="s5-8" 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
    <script setup lang="ts">
    import { Checkbox, FieldGroup, FieldLegend, FieldSet, Form } from "opui-css/vue"
    </script>
    <template>
    <Form>
    <FieldSet>
    <FieldLegend>Options</FieldLegend>
    <FieldGroup direction="row">
    <Checkbox>Option 1</Checkbox>
    <Checkbox>Option 2</Checkbox>
    <Checkbox>Option 3</Checkbox>
    </FieldGroup>
    </FieldSet>
    </Form>
    </template>
    <form class="ui-form">
    <!--[-->
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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

    <script setup lang="ts">
    import {
    Button,
    Divider,
    FieldGroup,
    FieldLegend,
    FieldSet,
    Form,
    TextField,
    } from "opui-css/vue"
    </script>
    <template>
    <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>
    </template>
    <form class="ui-form">
    <!--[-->
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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
    id="s7-0"
    type="text"
    placeholder="My new post"
    /><!----><!----><!----><!----></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

    <script setup lang="ts">
    import {
    Button,
    Checkbox,
    Divider,
    FieldDescription,
    FieldGroup,
    FieldLegend,
    FieldSet,
    Form,
    Radio,
    Range,
    Select,
    Switch,
    TextField,
    Textarea,
    } from "opui-css/vue"
    import { ref } from "vue"
    const roleItems = [
    { text: "Developer", value: "dev" },
    { text: "Designer", value: "design" },
    { text: "Manager", value: "manager" },
    ]
    const emailNotifs = ref(true)
    const smsNotifs = ref(false)
    const theme = ref("light")
    const experience = ref(5)
    </script>
    <template>
    <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="roleItems" />
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Notifications</FieldLegend>
    <FieldDescription>
    Configure how you want to receive updates.
    </FieldDescription>
    <FieldGroup name="notifications">
    <Switch v-model="emailNotifs" name="email_notifs"
    >Email Notifications</Switch
    >
    <Switch v-model="smsNotifs" 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 v-model="theme" value="light">Light Theme</Radio>
    <Radio v-model="theme" value="dark">Dark Theme</Radio>
    <Radio v-model="theme" 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"
    v-model="experience"
    start-text="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
    <template #end-text>Support this text</template>
    </Checkbox>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldGroup>
    <Button variant="filled" type="submit">Send</Button>
    <Button>Cancel</Button>
    </FieldGroup>
    </Form>
    </template>
    <form class="ui-form" id="kitchen-sink-example">
    <!--[-->
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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
    id="s8-0"
    type="text"
    placeholder="Jane Doe"
    required
    /><!----><!----><!----><!----></span
    ><!----><!--[--><!--]--></label
    ><label class="ui-text-field"
    ><span class="ui-label"><!--[-->Email Address<!--]--></span><!----><span
    class="ui-field"
    ><input
    id="s8-1"
    type="email"
    placeholder="jane@example.com"
    required
    /><!----><!----><!----><!----></span
    ><!----><!--[--><!--]--></label
    ><label class="ui-select"
    ><span class="ui-label" id="s8-3"><!--[-->Role<!--]--></span
    ><!----><span class="ui-field"
    ><select aria-labelledby="s8-3" id="s8-2">
    <button><selectedcontent></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 class=""><!--[-->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"
    aria-describedby="s8-5"
    checked
    /><span class="ui-label"><!--[-->Email Notifications<!--]--></span
    ><!----></label
    ><label class="ui-switch"
    ><!----><!----><input
    type="checkbox"
    role="switch"
    name="sms_notifs"
    aria-describedby="s8-6"
    /><span class="ui-label"><!--[-->SMS Notifications<!--]--></span
    ><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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
    type="radio"
    value="light"
    aria-describedby="s8-7"
    checked
    /><span class="ui-label"><!--[-->Light Theme<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input type="radio" value="dark" aria-describedby="s8-8" /><span
    class="ui-label"
    ><!--[-->Dark Theme<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input type="radio" value="system" aria-describedby="s8-9" /><span
    class="ui-label"
    ><!--[-->System Default<!--]--></span
    ><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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="s8-11"
    ><!--[-->Professional Experience<!--]--></span
    ><!----><span class="ui-start-text" id="s8-12"
    ><!--[-->Drag the slider to match your total tenure.<!--]--></span
    ><input
    aria-describedby="s8-12"
    aria-labelledby="s8-11"
    id="s8-10"
    type="range"
    min="0"
    max="20"
    step="1"
    value="5"
    /><!----><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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
    id="s8-14"
    placeholder="Tell us about yourself..."
    rows="4"
    ></textarea
    ><!----><!----><!----><!----></span
    ><!----><!--[--><!--]--></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->Legal<!--]--></legend>
    <div class="ui-field-group" role="group">
    <!--[--><label class="ui-checkbox"
    ><input
    type="checkbox"
    name="terms"
    required
    aria-describedby="s8-15"
    /><span class="ui-label"
    ><!--[-->
    I agree to the terms and conditions
    <!--]--></span
    ><span id="s8-15" class="ui-end-text"
    ><!--[-->Support this text<!--]--></span
    ></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <div class="ui-field-group" role="group">
    <!--[--><button class="ui-button ui-filled" type="submit">
    <!--[-->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

    <script setup lang="ts">
    import {
    Button,
    Checkbox,
    Divider,
    FieldDescription,
    FieldGroup,
    FieldLegend,
    FieldSet,
    Form,
    Radio,
    Range,
    Select,
    Switch,
    TextField,
    Textarea,
    } from "opui-css/vue"
    import { ref } from "vue"
    const roleItems = [
    { text: "Developer", value: "dev" },
    { text: "Designer", value: "design" },
    { text: "Manager", value: "manager" },
    ]
    const emailNotifs = ref(true)
    const smsNotifs = ref(false)
    const theme = ref("light")
    const experience = ref(5)
    </script>
    <template>
    <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>
    <template #label>Full Name</template>
    </TextField>
    <TextField type="email" placeholder="jane@example.com" required spread>
    <template #label>Email Address</template>
    </TextField>
    <Select :items="roleItems" spread>
    <template #label>Role</template>
    </Select>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Notifications</FieldLegend>
    <FieldDescription>
    Configure how you want to receive updates.
    </FieldDescription>
    <FieldGroup name="notifications">
    <Switch v-model="emailNotifs" name="email_notifs" spread
    >Email Notifications</Switch
    >
    <Switch v-model="smsNotifs" 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 v-model="theme" value="light">Light Theme</Radio>
    <Radio v-model="theme" value="dark">Dark Theme</Radio>
    <Radio v-model="theme" 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" v-model="experience" spread>
    Professional Experience
    <template #start-text
    >Drag the slider to match your total tenure.</template
    >
    </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>
    <template #label>Biography</template>
    </Textarea>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldSet>
    <FieldLegend>Legal</FieldLegend>
    <FieldGroup name="legal">
    <Checkbox name="terms" required spread>
    I agree to the terms and conditions
    <template #end-text>Support this text</template>
    </Checkbox>
    </FieldGroup>
    </FieldSet>
    <Divider />
    <FieldGroup>
    <Button variant="filled" type="submit">Send</Button>
    <Button>Cancel</Button>
    </FieldGroup>
    </Form>
    </template>
    <form class="ui-form" id="kitchen-sink-example-row">
    <!--[-->
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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
    id="s9-0"
    type="text"
    placeholder="Jane Doe"
    required
    /><!----><!----><!----><!----></span
    ><!----><!--[--><!--]--></label
    ><label class="ui-text-field ui-spread"
    ><span class="ui-label"><!--[-->Email Address<!--]--></span><!----><span
    class="ui-field"
    ><input
    id="s9-1"
    type="email"
    placeholder="jane@example.com"
    required
    /><!----><!----><!----><!----></span
    ><!----><!--[--><!--]--></label
    ><label class="ui-select ui-spread"
    ><span class="ui-label" id="s9-3"><!--[-->Role<!--]--></span
    ><!----><span class="ui-field"
    ><select id="s9-2">
    <button><selectedcontent></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 class=""><!--[-->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"
    aria-describedby="s9-5"
    checked
    /><span class="ui-label"><!--[-->Email Notifications<!--]--></span
    ><!----></label
    ><label class="ui-switch ui-spread"
    ><!----><!----><input
    type="checkbox"
    role="switch"
    name="sms_notifs"
    aria-describedby="s9-6"
    /><span class="ui-label"><!--[-->SMS Notifications<!--]--></span
    ><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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
    type="radio"
    value="light"
    aria-describedby="s9-7"
    checked
    /><span class="ui-label"><!--[-->Light Theme<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input type="radio" value="dark" aria-describedby="s9-8" /><span
    class="ui-label"
    ><!--[-->Dark Theme<!--]--></span
    ><!----></label
    ><label class="ui-radio"
    ><input type="radio" value="system" aria-describedby="s9-9" /><span
    class="ui-label"
    ><!--[-->System Default<!--]--></span
    ><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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="s9-11"
    ><!--[-->
    Professional Experience
    <!--]--></span
    ><!----><span class="ui-start-text" id="s9-12"
    ><!--[-->Drag the slider to match your total tenure.<!--]--></span
    ><input
    aria-describedby="s9-12"
    aria-labelledby="s9-11"
    id="s9-10"
    type="range"
    min="0"
    max="20"
    step="1"
    value="5"
    /><!----><!----></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->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
    id="s9-14"
    placeholder="Tell us about yourself..."
    rows="4"
    ></textarea
    ><!----><!----><!----><!----></span
    ><!----><!--[--><!--]--></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <fieldset class="ui-fieldset">
    <!--[-->
    <legend class=""><!--[-->Legal<!--]--></legend>
    <div class="ui-field-group" role="group">
    <!--[--><label class="ui-checkbox ui-spread"
    ><input
    type="checkbox"
    name="terms"
    required
    aria-describedby="s9-15"
    /><span class="ui-label"
    ><!--[-->
    I agree to the terms and conditions
    <!--]--></span
    ><span id="s9-15" class="ui-end-text"
    ><!--[-->Support this text<!--]--></span
    ></label
    ><!--]-->
    </div>
    <!--]-->
    </fieldset>
    <hr class="ui-divider" />
    <div class="ui-field-group" role="group">
    <!--[--><button class="ui-button ui-filled" type="submit">
    <!--[-->Send<!--]--></button
    ><button class="ui-button"><!--[-->Cancel<!--]--></button><!--]-->
    </div>
    <!--]-->
    </form>

    API

    Form

    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);
    }
    }
    }
    }