Component 22 of 60
Fieldset
Groups related form controls with a legend.
Starting the preview. GPUI compiles to WebAssembly, so the first load takes a few seconds. This browser has neither WebGPU nor WebGL 2, so the live preview cannot run. The code on this page still works. The preview did not start.
fn fieldset_preview(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let name = demo_input("shipping.name", "", "Ada Lovelace", window, cx);
let city = demo_input("shipping.city", "", "London", window, cx);
fieldset("shipping", cx)
.w(px(300.))
.aria_label("Shipping address")
.child(fieldset_legend(FieldsetLegendVariant::Legend, cx).child("Shipping address"))
.child(Field::new("shipping-name", &name).label("Full name"))
.child(Field::new("shipping-city", &city).label("City"))
}
Installation
After the one-time setup, run the command from your app root. The CLI
writes the modules and keeps src/ui/mod.rs in step.
gpuicn add fieldset field
If you prefer to copy the files by hand, declare them yourself:
// src/ui/mod.rs
pub mod theme;
pub mod fieldset;
pub mod input;
pub mod field;
// src/main.rs
mod ui;
Usage
Put this in a view module and return example(name, cx) from its render method.
use crate::ui::field::Field;
use crate::ui::fieldset::*;
use crate::ui::input::InputState;
use gpui_kit::Entity;
use gpui_kit::{App, IntoElement, ParentElement, StatefulInteractiveElement};
fn example(name: &Entity<InputState>, cx: &App) -> impl IntoElement {
fieldset("shipping", cx)
.aria_label("Shipping address")
.child(fieldset_legend(FieldsetLegendVariant::Legend, cx).child("Shipping address"))
.child(Field::new("name", name).label("Full name"))
}
API reference
pub fn fieldset(id: impl Into<ElementId>, cx: &App) -> Stateful<Div>
Creates a semantic group; give it an accessible label matching its legend.
pub fn fieldset_legend(variant: FieldsetLegendVariant, cx: &App) -> Div
Creates the group heading.
Installed source, 45 lines
//! Nova field groups and headings. Pass disabled state to their controls explicitly.
use super::theme::UiTheme;
use gpui_kit::{
App, Div, ElementId, FontWeight, InteractiveElement as _, Role, Stateful,
StatefulInteractiveElement as _, Styled, div,
};
/// The two visual treatments for a group legend.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum FieldsetLegendVariant {
/// A section heading.
#[default]
Legend,
/// A compact field label.
Label,
}
/// Creates a semantic group; give it an accessible label matching its legend.
pub fn fieldset(id: impl Into<ElementId>, cx: &App) -> Stateful<Div> {
let t = UiTheme::read(cx);
div()
.id(id)
.role(Role::Group)
.flex()
.flex_col()
.w_full()
.gap(t.space(6.))
.font_family(t.fonts.body.clone())
.text_color(t.colors.foreground)
}
/// Creates the group heading.
pub fn fieldset_legend(variant: FieldsetLegendVariant, cx: &App) -> Div {
let t = UiTheme::read(cx);
div()
.font_family(t.fonts.body.clone())
.font_weight(FontWeight::MEDIUM)
.text_size(t.text(if variant == FieldsetLegendVariant::Legend {
16.
} else {
14.
}))
.line_height(t.text(20.))
.text_color(t.colors.foreground)
}
Platform notes
Visual reference: shadcn/ui 4.19.0, Neutral Nova. Implementation:
crates/ui/registry/fieldset/fieldset.rs, using GPUI Kit 0.6.4.
A named fieldset groups application-owned fields with a visible legend and description. gpuicn supplies layout and Nova typography; the application owns each field and its validation.
The Rust source and Usage example define the supported API. Browser DOM/CSS behavior, exact exit animations and cross-platform screen-reader parity are not implied by the native component. See migration qualification for the checks completed on this revision.