Label & Messages
The label, description and error slots every field composes.
use herogpui::components::field::{Description, ErrorMessage, FieldError, Label};Description on docs.rsSource at v0.14.0
Usage
Showing Usage, live: HeroGPUI compiled to WebAssembly. The canvas has no accessibility tree; each example's description and code below carry the same information.
An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Label::new("Email").into_any_element(),
Description::new("We will never share your address.").into_any_element(),
ErrorMessage::new("Enter a valid email address.").into_any_element(),
])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label};
Label::new("Email")
.is_required(true)An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label};
Label::new("Email")
.is_disabled(true)An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label};
Label::new("Email")
.is_invalid(true)Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{Description, ErrorMessage, FieldError, InputType, Label, TextField};
TextField::new(self.demo_text(
"fs-with-field",
"",
cx,
))
.label("Email")
.placeholder("Enter your email")
.input_type(InputType::Email)
.description("We will never share your email")A `TextField` composes all three parts itself: the label above, the input, and the description or the error message below. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label, TextField};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.w(px(256.))
.flex()
.flex_col()
.child(TextField::new(self.demo_text("fs-integration", "", cx))
.label("Email")
.placeholder("Enter your email")
.description("We will never share your email"))Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{Description, ErrorMessage, FieldError, InputType, Label, TextField};
TextField::new(self.demo_text(
"fs-validate",
"",
cx,
))
.label("Password")
.placeholder("••••••••")
.input_type(InputType::Password)
.is_required(true)
.validate(|value| {
(value.chars().count() < 8).then(|| "Use at least 8 characters".into())
})`FieldError` takes a render closure and joins the validation error list. `validationErrors` here is a list, and the field shows them in order. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label, TextField};
TextField::new(self.demo_text("fs-dynamic", "abc", cx))
.label("Password")
.is_invalid(true)
.validation_errors(["Use at least 8 characters", "Include a digit"])Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label, TextField};
TextField::new(self.demo_text("fs-custom", "", cx))
.label("Username")
.description("Letters, digits and dashes only")
.validate(|value| {
(!value.is_empty()
&& !value.chars().all(|c| c.is_ascii_alphanumeric() || c == '-'))
.then(|| "Letters, digits and dashes only".into())
})Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label, TextField};
TextField::new(self.demo_text("fs-multi", "", cx))
.label("Password")
.is_invalid(true)
.validation_errors([
"Use at least 8 characters",
"Include an uppercase letter",
"Include a digit",
])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Label::new("Email").into_any_element(),
Label::new("Email").is_required(true).into_any_element(),
Label::new("Email").is_invalid(true).into_any_element(),
Label::new("Email").is_disabled(true).into_any_element(),
])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
Description::new("We will never share your address.").into_any_element(),
ErrorMessage::new("Enter a valid email address.").into_any_element(),
])A FieldError with no message renders nothing. An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Description, ErrorMessage, FieldError, Label};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
FieldError::new()
.id("label-messages-error-demo")
.message("This field is required.")
.into_any_element(),
FieldError::new().into_any_element(),
])Anatomy
Rust types
Label & Messages is assembled from these builders. The API reference lists each one.
API reference
Against HeroUI v3.2.6: 10 entries ported, 6 partial, 4 not ported. Partial rows are marked in the tables; entries not ported are listed under each table with the reason.
Builders
| Builder | Values | Default | Description |
|---|---|---|---|
label_for(Partial | string | — | The id of the element the label is associated with. GPUI has no element id graph, so the association is the field's focus handle — the one visible effect, clicking the label focusing the field — instead of an id reference. |
is_required( | true | | false | Whether to display a required indicator: the danger-coloured asterisk after the text. |
is_disabled( | true | | false | Whether the label is in a disabled state (the status-disabled dimming). |
is_invalid( | true | | false | Whether the label is in an invalid state (`text-danger`). |
Label::Partial | AnyElement | — | The content of the label. Takes the text. |
Description::Partial | AnyElement | — | The content of the description. Takes the text. |
ErrorMessage::Partial | AnyElement | — | The error message content. Always rendered when present; takes the text. |
FieldError::Partial | AnyElement | | — | Error message content or a render function of the validation result. The render-function form is not portable — the port's `FieldError` takes the message and manages visibility from the field's validation state, rendering nothing unless the field is invalid and a message is present. |
FieldError:: | ElementId | — | GPUI extension: stable identity used to retain the last message and animate the height/opacity transition across validation updates. |
Not ported4 HeroUI entries not ported
| HeroUI v3 | Why it is not ported |
|---|---|
Label.className | |
Description.className | |
ErrorMessage.className | |
FieldError.className |
Parts
| Part | Description |
|---|---|
Label | `text-sm font-medium text-foreground` label on the `.label` BEM class; lays it out as a 2px flex row so the required asterisk can follow the text. |
DescriptionPartial | `text-xs text-wrap wrap-break-word text-muted` helper copy (`slot="description"`). The soft-wrapping utilities have no GPUI analogue. |
ErrorMessage | `text-xs wrap-break-word text-danger` on the `.error-message` BEM class; shared field wrappers retain its body and animate the visibility transition. |
FieldError | `.field-error` adds `px-1` and the collapsible `h-0 opacity-0 data-visible:h-auto` behaviour to the error text. Keeps the 4px horizontal padding, retains the last message during exit, and drives the height and opacity timelines when a stable id is available. |
States
| State | Builder | Description |
|---|---|---|
Required | is_required | Appends the danger-coloured asterisk after the label text. |
Disabled | is_disabled | Status-disabled dimming of the label text. |
Invalid | is_invalid | Repaints the label text in the danger colour. |