Skip to content
All components

Components

Field

A field ties a label and an optional hint to one control; on the web the control's id and name are the field's id, so a plain form post carries it, and natively Pick hands back the control with the person's edit. Control::Input { value, placeholder } is a one-line text box, Select { options, value } a list of (value, label) choices, Textarea { value, rows } a box of several lines, and Switch(bool) and Checkbox(bool) an on or off box drawn on one row with its label. The default control is an empty Input.

Text input

The label above, the help below, tied to the input.

People see this name in the queue.

Field {
    id: "f-name".into(),
    label: "Agent name".into(),
    hint: Some("People see this name in the queue.".into()),
    control: Control::Input {
        value: String::new(),
        placeholder: "Triage agent".into(),
    },
}

Select

A closed list of choices; the current one selected.

Field {
    id: "f-tone".into(),
    label: "Priority".into(),
    hint: None,
    control: Control::Select {
        options: vec![
            ("low".into(), "Low".into()),
            ("normal".into(), "Normal".into()),
            ("high".into(), "High".into()),
        ],
        value: "normal".into(),
    },
}

Textarea

Room for a few lines; rows set its height.

Plain language; the agent follows it.

Field {
    id: "f-notes".into(),
    label: "Instructions".into(),
    hint: Some("Plain language; the agent follows it.".into()),
    control: Control::Textarea { value: String::new(), rows: 4 },
}

Switch and checkbox

On and off controls put the label beside them.

Field {
    id: "f-live".into(),
    label: "Answer customers directly".into(),
    hint: None,
    control: Control::Switch(true),
}.html(out);
Field {
    id: "f-terms".into(),
    label: "Ask a person before refunds".into(),
    hint: None,
    control: Control::Checkbox(false),
}.html(out);

Required

Required is said in the label, not by a colour.

Replies go to this address.

Field {
    id: "f-email".into(),
    label: "Work email (required)".into(),
    hint: Some("Replies go to this address.".into()),
    control: Control::Input {
        value: "maya@".into(),
        placeholder: "name@company.com".into(),
    },
}

On the Mac

The same vocabulary drawn by Ocean UI's native face (egui on Metal), as the gallery's snapshot.

Field drawn by Ocean UI's native face, darkField drawn by Ocean UI's native face, light

Use it

Web

use ocean_ui_core::{Control, Field};
let control = Control::Select { options: vec![("p1".into(), "Urgent".into())], value: "p1".into() };
Field { id: "priority".into(), label: "Priority".into(), hint: Some("Urgent pages the on-call.".into()), control }

Native

use ocean_ui_native::{core::{Control, Field}, widgets::Pick};
let field = Field { id: "wrap".into(), label: "Wrap lines".into(), hint: None, control: Control::Switch(true) };
let edited: Option<Control> = field.pick(ui).value;

Cargo feature forms of ocean-ui-core, ocean-ui-web and ocean-ui-native; available since 2026-10-29.

In App UI, the form block draws it from YAML.

Props

NameTypeDefaultWhat
idString—The control's id and name, and the start of the hint's id.
labelString—What the field asks for, in sentence case.
hintOption<String>NoneOne sentence under the control, tied to it by aria-describedby.
controlControlInputInput, Select, Textarea, Switch or Checkbox, with its value.

Accessibility

  • The label is a label element whose for names the control, so clicking it focuses or toggles the control.
  • A hint is tied to the control by aria-describedby, so it is read after the label.
  • A switch is a checkbox with role="switch", announced as on or off; a checkbox is announced as checked or not.
  • Every control is a native element, so the keyboard works as the browser defines.

Related

Markdown

The same page as Markdown, for an agent or a pull request.

Search

esc

Components

Blocks

Screens built from blocks

The Ocean app

Ocean Base console