# Component reference

The docs build generates this page from the source of `crates/nd-components` every time, so it
lists exactly what the crate exports. To see what each component looks like on each OS, open the
[Gallery](https://native.formalsnake.dev/examples.md#gallery) example.

Generated from `crates/nd-components/src` by `nd-docs`: 130 element constructors in 39 modules. Each lists the builder methods of the element it returns.

## `accessory`

### `bottom_accessory`

```rust
pub fn bottom_accessory(id : impl Into<SharedString>) -> BottomAccessory
```

| `BottomAccessory` method | Does |
| --- | --- |
| `.content(content : impl IntoElement)` |  |
| `.bar(bar : impl IntoElement)` | The bar; none shows the content alone. |

## `controls`

### `icon_button`

```rust
pub fn icon_button(id : impl Into<SharedString>, icon : Icon) -> Button
```

A button showing only `icon`; the platform's toolbar or borderless style.

### `menu_button`

```rust
pub fn menu_button(id : impl Into<SharedString>, icon : Icon, build : impl Fn(crate::menu::ContextMenu, &mut Window, &mut App) -> crate::menu::ContextMenu + 'static) -> Button
```

An icon button that opens a menu under itself: a header bar's primary menu, a row's
"More" button. `build` runs each time it opens.

### `separator`

```rust
pub fn separator() -> Separator
```

| `Separator` method | Does |
| --- | --- |
| `.vertical()` |  |

## `form`

### `form`

```rust
pub fn form() -> Form
```

A grouped form. Children are [`form_section`]s.

| `Form` method | Does |
| --- | --- |
| `.title(title : impl Into<SharedString>)` | A page title above the sections, scrolling with them unless [`Form::pin_title`]. |
| `.pin_title()` | Keeps the title in place while the rows scroll under it. |

### `form_section`

```rust
pub fn form_section() -> FormSection
```

A group of rows under an optional title.

| `FormSection` method | Does |
| --- | --- |
| `.title(title : impl Into<SharedString>)` |  |
| `.footer(footer : impl Into<SharedString>)` |  |

### `form_row`

```rust
pub fn form_row(label : impl Into<SharedString>) -> FormRow
```

One row: `label` on the leading side, its single child control on the trailing side.

| `FormRow` method | Does |
| --- | --- |
| `.help(help : impl Into<SharedString>)` |  |
| `.id(id : impl Into<SharedString>)` |  |

## `forms/choice`

### `option_index`

```rust
pub fn option_index(options : &[SharedString], value : &str) -> Option<usize>
```

The index `value` names among `options`: the option's title (exact, then ignoring case),
or its index.

### `select`

```rust
pub fn select(id : impl Into<SharedString>, options : impl IntoIterator<Item = impl Into<SharedString>>) -> Select
```

| `Select` method | Does |
| --- | --- |
| `.selected(index : usize)` |  |
| `.native(mapping : Mapping)` |  |
| `.horizontal()` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.icons(icons : impl IntoIterator<Item = crate::Icon>)` | Icons for a segmented control's segments, in option order: each segment shows its icon in place of its title, which stays the segment's accessible name and tooltip. |
| `.on_change(f : impl Fn(&SelectChanged, &mut Window, &mut App) + 'static)` |  |

### `segmented`

```rust
pub fn segmented(id : impl Into<SharedString>, options : impl IntoIterator<Item = impl Into<SharedString>>) -> Select
```

A segmented control: the options side by side, one selected.

| `Select` method | Does |
| --- | --- |
| `.selected(index : usize)` |  |
| `.native(mapping : Mapping)` |  |
| `.horizontal()` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.icons(icons : impl IntoIterator<Item = crate::Icon>)` | Icons for a segmented control's segments, in option order: each segment shows its icon in place of its title, which stays the segment's accessible name and tooltip. |
| `.on_change(f : impl Fn(&SelectChanged, &mut Window, &mut App) + 'static)` |  |

### `radio_group`

```rust
pub fn radio_group(id : impl Into<SharedString>, options : impl IntoIterator<Item = impl Into<SharedString>>) -> Select
```

Radio buttons, one per option, stacked unless `.horizontal()`.

| `Select` method | Does |
| --- | --- |
| `.selected(index : usize)` |  |
| `.native(mapping : Mapping)` |  |
| `.horizontal()` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.icons(icons : impl IntoIterator<Item = crate::Icon>)` | Icons for a segmented control's segments, in option order: each segment shows its icon in place of its title, which stays the segment's accessible name and tooltip. |
| `.on_change(f : impl Fn(&SelectChanged, &mut Window, &mut App) + 'static)` |  |

## `forms/date`

### `date_picker`

```rust
pub fn date_picker(id : impl Into<SharedString>, value : CivilDateTime) -> DatePicker
```

| `DatePicker` method | Does |
| --- | --- |
| `.mode(mode : DatePickerMode)` |  |
| `.presentation(presentation : DatePickerStyle)` |  |
| `.min(min : CivilDateTime)` |  |
| `.max(max : CivilDateTime)` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.on_change(f : impl Fn(&DateChanged, &mut Window, &mut App) + 'static)` |  |

### `color_well`

```rust
pub fn color_well(id : impl Into<SharedString>, color : Hsla) -> ColorWell
```

| `ColorWell` method | Does |
| --- | --- |
| `.alpha(alpha : bool)` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.on_change(f : impl Fn(&ColorChanged, &mut Window, &mut App) + 'static)` |  |

## `forms/display`

### `label`

```rust
pub fn label(text : impl Into<SharedString>) -> Label
```

Text in one of the system's text styles. `text()` is the plain run; a label is the control
a form or window uses for titles and supporting text.

| `Label` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |
| `.text_style(style : TextStyle)` |  |
| `.secondary()` |  |
| `.tone(tone : LabelTone)` |  |
| `.selectable()` |  |
| `.wraps()` |  |
| `.lines(lines : u16)` | Wraps onto at most `lines` lines, ending the last in an ellipsis when the text is cut: a two-line message preview. |
| `.rich(rich : RichText)` | Replaces the text with runs of their own style, in the label's text style. |
| `.on_link(handler : impl Fn(&LinkClicked, &mut Window, &mut App) + 'static)` | Handles a click on a link run; the system no longer opens it. |

### `link`

```rust
pub fn link(id : impl Into<SharedString>, title : impl Into<SharedString>) -> Link
```

A text link. With a `url` it opens in the default browser; `on_click` sees every activation.

| `Link` method | Does |
| --- | --- |
| `.url(url : impl Into<SharedString>)` |  |
| `.keep_internal()` | Fires [`LinkActivated`] only; the app opens what it wants. |
| `.on_click(f : impl Fn(&LinkActivated, &mut Window, &mut App) + 'static)` |  |

### `progress`

```rust
pub fn progress(value : Option<f32>) -> Progress
```

A progress bar at `value` (0 to 1); `None` shows an indeterminate bar.

| `Progress` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |
| `.circular()` |  |
| `.label(label : impl Into<SharedString>)` |  |

### `spinner`

```rust
pub fn spinner() -> Progress
```

The spinning activity indicator.

| `Progress` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |
| `.circular()` |  |
| `.label(label : impl Into<SharedString>)` |  |

## `forms/rows`

### `settings_group`

```rust
pub fn settings_group(title : impl Into<SharedString>) -> FormSection
```

A titled group of rows; `form_section` under its libadwaita name.

| `FormSection` method | Does |
| --- | --- |
| `.title(title : impl Into<SharedString>)` |  |
| `.footer(footer : impl Into<SharedString>)` |  |

### `row`

```rust
pub fn row(title : impl Into<SharedString>) -> FormRow
```

A row with a title and optional subtitle, holding one trailing control (`.child(..)`).

| `FormRow` method | Does |
| --- | --- |
| `.help(help : impl Into<SharedString>)` |  |
| `.id(id : impl Into<SharedString>)` |  |

### `switch_row`

```rust
pub fn switch_row(id : impl Into<SharedString>, title : impl Into<SharedString>) -> SwitchRow
```

A titled row with a switch, controlled like [`switch`].

| `SwitchRow` method | Does |
| --- | --- |
| `.subtitle(subtitle : impl Into<SharedString>)` |  |
| `.checked(checked : bool)` |  |
| `.disabled(disabled : bool)` |  |
| `.on_toggle(f : impl Fn(&Toggled, &mut Window, &mut App) + 'static)` |  |

### `navigation_row`

```rust
pub fn navigation_row(id : impl Into<SharedString>, title : impl Into<SharedString>, on_activate : impl Fn(&RowActivated, &mut Window, &mut App) + 'static) -> FormRow
```

A row that navigates somewhere: a disclosure chevron as its control, firing
[`RowActivated`].

| `FormRow` method | Does |
| --- | --- |
| `.help(help : impl Into<SharedString>)` |  |
| `.id(id : impl Into<SharedString>)` |  |

### `clamp`

```rust
pub fn clamp() -> Clamp
```

| `Clamp` method | Does |
| --- | --- |
| `.maximum(maximum : Pixels)` |  |

### `form_field`

```rust
pub fn form_field(label : impl Into<SharedString>) -> FormField
```

| `FormField` method | Does |
| --- | --- |
| `.help(help : impl Into<SharedString>)` |  |
| `.error(error : Option<impl Into<SharedString>>)` | Shown in place of the help text while set. |
| `.control(control : impl IntoElement)` |  |

### `button_group`

```rust
pub fn button_group() -> ButtonGroup
```

### `sheet_layout`

```rust
pub fn sheet_layout(title : impl Into<SharedString>) -> SheetLayout
```

| `SheetLayout` method | Does |
| --- | --- |
| `.footer(button : impl IntoElement)` | Adds a footer button; add the default action last. |

## `forms/settings`

### `settings_form`

```rust
pub fn settings_form<T : Settings>() -> AnyElement
```

The settings form for `T`. Without a provided handle it shows the defaults, read-only.

## `forms/text`

### `text_field`

```rust
pub fn text_field(id : impl Into<SharedString>) -> TextField
```

A single-line text field.

| `TextField` method | Does |
| --- | --- |
| `.secure()` |  |
| `.search()` |  |
| `.large()` | The platform's largest field size: extra large (36 pt) on macOS 26, large before it. |
| `.leading_icon(icon : Icon, label : impl Into<SharedString>)` | An icon at the field's leading edge; clicks fire [`FieldIconClicked`]. |
| `.trailing_icon(icon : Icon, label : impl Into<SharedString>)` | An icon at the field's trailing edge (a reveal or clear button). |
| `.on_icon_click(f : impl Fn(&FieldIconClicked, &mut Window, &mut App) + 'static)` |  |
| `.select_on_focus(range : std::ops::Range<usize>)` | Selects the characters in `range` (counted in chars) each time the field takes focus, as Finder selects a name without its extension. Focus it with `window.focus_id(cx, id)`. |
| `.on_end_editing(f : impl Fn(&TextEditingEnded, &mut Window, &mut App) + 'static)` | Return, or focus leaving the field, with its text: where an inline rename commits. |
| `.on_cancel(f : impl Fn(&TextCancelled, &mut Window, &mut App) + 'static)` | Escape: the edit is abandoned, and editing ends without [`TextEditingEnded`]. |

### `secure_field`

```rust
pub fn secure_field(id : impl Into<SharedString>) -> TextField
```

A password field: characters hidden, value never exposed to automation reads.

| `TextField` method | Does |
| --- | --- |
| `.secure()` |  |
| `.search()` |  |
| `.large()` | The platform's largest field size: extra large (36 pt) on macOS 26, large before it. |
| `.leading_icon(icon : Icon, label : impl Into<SharedString>)` | An icon at the field's leading edge; clicks fire [`FieldIconClicked`]. |
| `.trailing_icon(icon : Icon, label : impl Into<SharedString>)` | An icon at the field's trailing edge (a reveal or clear button). |
| `.on_icon_click(f : impl Fn(&FieldIconClicked, &mut Window, &mut App) + 'static)` |  |
| `.select_on_focus(range : std::ops::Range<usize>)` | Selects the characters in `range` (counted in chars) each time the field takes focus, as Finder selects a name without its extension. Focus it with `window.focus_id(cx, id)`. |
| `.on_end_editing(f : impl Fn(&TextEditingEnded, &mut Window, &mut App) + 'static)` | Return, or focus leaving the field, with its text: where an inline rename commits. |
| `.on_cancel(f : impl Fn(&TextCancelled, &mut Window, &mut App) + 'static)` | Escape: the edit is abandoned, and editing ends without [`TextEditingEnded`]. |

### `search_field`

```rust
pub fn search_field(id : impl Into<SharedString>, state : &Entity<TextFieldState>) -> TextField
```

The platform's search field, bound to `state`.

| `TextField` method | Does |
| --- | --- |
| `.secure()` |  |
| `.search()` |  |
| `.large()` | The platform's largest field size: extra large (36 pt) on macOS 26, large before it. |
| `.leading_icon(icon : Icon, label : impl Into<SharedString>)` | An icon at the field's leading edge; clicks fire [`FieldIconClicked`]. |
| `.trailing_icon(icon : Icon, label : impl Into<SharedString>)` | An icon at the field's trailing edge (a reveal or clear button). |
| `.on_icon_click(f : impl Fn(&FieldIconClicked, &mut Window, &mut App) + 'static)` |  |
| `.select_on_focus(range : std::ops::Range<usize>)` | Selects the characters in `range` (counted in chars) each time the field takes focus, as Finder selects a name without its extension. Focus it with `window.focus_id(cx, id)`. |
| `.on_end_editing(f : impl Fn(&TextEditingEnded, &mut Window, &mut App) + 'static)` | Return, or focus leaving the field, with its text: where an inline rename commits. |
| `.on_cancel(f : impl Fn(&TextCancelled, &mut Window, &mut App) + 'static)` | Escape: the edit is abandoned, and editing ends without [`TextEditingEnded`]. |

### `text_area`

```rust
pub fn text_area(id : impl Into<SharedString>) -> TextArea
```

Multi-line text, scrolling inside its frame.

| `TextArea` method | Does |
| --- | --- |
| `.min_lines(lines : u16)` |  |
| `.max_lines(lines : u16)` | Grows with its text up to `lines`, then scrolls. |
| `.submit_on_return()` | Return submits ([`TextInput::on_submit`]); Shift-Return inserts a line break. |
| `.accepts_media()` | Takes pasted and dropped images and files as events instead of text. |
| `.trailing_room(points : f32)` | Keeps `points` clear at the trailing edge, inside the outline, for a button the app lays over the field there; the text wraps before it. |
| `.emoji_picker(request : u64)` | Opens the emoji picker at the caret whenever `request` changes (the platform's, or nd's own where it has none); pass a counter the app bumps. The chosen emoji goes in at the caret. |
| `.on_images(f : impl Fn(&ImagesPasted, &mut Window, &mut App) + 'static)` |  |
| `.on_files(f : impl Fn(&FilesDropped, &mut Window, &mut App) + 'static)` |  |

### `combo_box`

```rust
pub fn combo_box(id : impl Into<SharedString>, options : impl IntoIterator<Item = impl Into<SharedString>>) -> ComboBox
```

A text field with suggestions.

| `ComboBox` method | Does |
| --- | --- |
| `.completes(completes : bool)` |  |
| `.on_select(f : impl Fn(&super::SelectChanged, &mut Window, &mut App) + 'static)` | The user picked a suggestion; its text arrives as a [`TextChanged`] too. |

## `forms/toggle`

### `checkbox`

```rust
pub fn checkbox(id : impl Into<SharedString>, label : impl Into<SharedString>) -> Checkbox
```

A checkbox with its title beside it.

| `Checkbox` method | Does |
| --- | --- |
| `.checked(checked : bool)` |  |
| `.mixed(mixed : bool)` |  |
| `.on_toggle(f : impl Fn(&Toggled, &mut Window, &mut App) + 'static)` |  |

### `switch`

```rust
pub fn switch(id : impl Into<SharedString>) -> Switch
```

An on/off switch. Give it a `.label(..)` when no row title names it.

| `Switch` method | Does |
| --- | --- |
| `.checked(checked : bool)` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.on_toggle(f : impl Fn(&Toggled, &mut Window, &mut App) + 'static)` |  |

## `forms/value`

### `number_text`

```rust
pub fn number_text(value : f64, digits : Option<u8>) -> String
```

Formats a number without trailing zeros (`0.5`, `3`), the form automation reads back.

### `slider`

```rust
pub fn slider(id : impl Into<SharedString>, value : f32) -> Slider
```

| `Slider` method | Does |
| --- | --- |
| `.range(range : RangeInclusive<f32>)` |  |
| `.step(step : f32)` |  |
| `.ticks(ticks : usize)` |  |
| `.vertical()` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.drawn()` | The framework-drawn slider on every OS instead of the native control: it takes every style override (height, radius, colours) the native one cannot express. |
| `.on_change(f : impl Fn(&SliderChanged, &mut Window, &mut App) + 'static)` |  |

### `stepper`

```rust
pub fn stepper(id : impl Into<SharedString>, value : f64) -> Stepper
```

Up and down arrows changing `value` by a step.

| `Stepper` method | Does |
| --- | --- |
| `.range(range : RangeInclusive<f64>)` |  |
| `.step(step : f64)` |  |
| `.wraps(wraps : bool)` |  |
| `.with_field(digits : u8)` | The value in an editable field beside the arrows, with `digits` decimals. |
| `.label(label : impl Into<SharedString>)` |  |
| `.on_change(f : impl Fn(&StepperChanged, &mut Window, &mut App) + 'static)` |  |

## `glass`

### `glass`

```rust
pub fn glass() -> Glass
```

A glass surface. Lays its children out like a `div`.

| `Glass` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |
| `.variant(variant : GlassVariant)` |  |
| `.tint(tint : impl Into<Hsla>)` |  |
| `.interactive()` |  |

### `glass_group`

```rust
pub fn glass_group() -> GlassGroup
```

| `GlassGroup` method | Does |
| --- | --- |
| `.spacing(spacing : Pixels)` |  |

## `icon`

### `icon`

```rust
pub fn icon(icon : Icon, size : f32) -> IconView
```

`icon` on its own in a `size` point square: an SF Symbol on macOS, the Lucide shape
elsewhere, tinted with the element's text colour.

| `IconView` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |
| `.label(label : impl Into<SharedString>)` | Names the icon for screen readers and automation. |

## `media/chat`

### `chat_bubble`

```rust
pub fn chat_bubble(text : impl Into<SharedString>, side : BubbleSide) -> ChatBubble
```

A message bubble. Its width follows the text up to `BUBBLE.max_width`.

| `ChatBubble` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |
| `.position(position : RunPosition)` |  |
| `.reactions(reactions : impl IntoIterator<Item = Reaction>)` |  |
| `.time(time : impl Into<SharedString>)` | The time, shown on hover. |
| `.rich(rich : RichText)` | Replaces the text with runs of their own style. A link run reports [`LinkClicked`] (`.on_link`); text that is all emoji still draws large without a bubble. |
| `.role(role : FillRole)` | Fills the bubble by meaning instead of by side: `FillRole::Success` is an SMS message's green. Fill and ink come from the theme. |
| `.on_link(handler : impl Fn(&LinkClicked, &mut Window, &mut App) + 'static)` | Handles a click on a link run; the system no longer opens it. |

### `initials`

```rust
pub fn initials(name : &str) -> String
```

The monogram for `name`: the first letters of its first and last words, uppercased, or
`#` for a name that is empty or a phone number (drawn as a person glyph).

### `group_layout`

```rust
pub fn group_layout(count : usize, size : f32) -> Vec<nd_core::Rect>
```

Where each person of a group sits inside a `size` circle: up to four mini avatars
[`AVATAR_GROUP_SCALE`] of it, one row for two, one over two for three, two by two for four.

### `avatar`

```rust
pub fn avatar(person : Person, size : f32) -> Avatar
```

A person's photo, or their initials, in a circle `size` points across.

| `Avatar` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |

### `avatar_group`

```rust
pub fn avatar_group(people : impl IntoIterator<Item = Person>, size : f32) -> Avatar
```

A group's avatar: its first four people clustered in one circle.

| `Avatar` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |

### `chat_row`

```rust
pub fn chat_row(id : impl Into<SharedString>, message : ChatMessage) -> AnyElement
```

A message laid out as a thread row: aligned to its side, spaced by its run, the sender's
avatar and name in a group, a receipt under it. `id` keys the row's bubble.

## `media/composer`

### `composer`

```rust
pub fn composer(id : impl Into<SharedString>, draft : &Draft) -> Composer
```

The message field over `draft`.

| `Composer` method | Does |
| --- | --- |
| `.placeholder(placeholder : impl Into<SharedString>)` |  |
| `.disabled(disabled : bool)` |  |
| `.without_attach()` | No attach button; pasted and dropped files still stage. |
| `.send_icon(icon : Icon, tooltip : impl Into<SharedString>)` | The send button's icon and tooltip, for a send that is not a new message: a check while editing one. |
| `.send_fill(color : Hsla)` | Fills the send button with `color` instead of the accent: an SMS conversation's green, read from the app's theme (`theme.fill(FillRole::Success)`). |
| `.on_event(f : impl Fn(&ComposerEvent, &mut Window, &mut App) + 'static)` |  |

## `media/equalizer`

### `bar_frames`

```rust
pub fn bar_frames(side : f32, heights : impl Fn(usize) -> f32) -> Vec<(f32, f32, f32, f32)>
```

The bars' frames in a `side` point square, bottom aligned and centred, at `heights`.

### `equalizer`

```rust
pub fn equalizer(size : f32, playing : bool) -> Equalizer
```

The now-playing bars in a `size` point square, moving while `playing`.

| `Equalizer` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |

## `media/hover`

### `artwork_actions`

```rust
pub fn artwork_actions(id : impl Into<SharedString>, group : impl Into<SharedString>) -> ArtworkActions
```

Play and More over artwork, shown while the pointer is over the ancestor `.group(group)`.
Put it in a `relative()`, `overflow_hidden()` box with the artwork, rounded as the artwork
is; it fills the box.

| `ArtworkActions` method | Does |
| --- | --- |
| `.on_play(f : impl Fn(&mut Window, &mut App) + 'static)` |  |
| `.menu(build : impl Fn(ContextMenu, &mut Window, &mut App) -> ContextMenu + 'static)` |  |
| `.compact()` | A row's artwork: the Play glyph alone in the middle, More left to the row. Without `on_play` the glyph only shows, and a click goes to the row (a list row plays on select). |
| `.now_playing(playing : Option<bool>)` | Marks the artwork as the track that is playing (`Some(true)`) or paused on (`Some(false)`): it stays dimmed under the now-playing bars, which give way to the buttons under the pointer, and a row's glyph becomes Pause while it plays. |

### `hover_menu_button`

```rust
pub fn hover_menu_button(id : impl Into<SharedString>, group : impl Into<SharedString>, build : impl Fn(ContextMenu, &mut Window, &mut App) -> ContextMenu + 'static) -> Div
```

A More button revealed while the pointer is over the ancestor `.group(group)`: the end of a
song row in Music.

## `media/image`

### `image`

```rust
pub fn image(source : impl Into<ImageSource>) -> Image
```

A picture from a path, URL or bytes. Size it with the style; a side left open follows the
image's aspect.

| `Image` method | Does |
| --- | --- |
| `.bubble_tail(side : BubbleSide)` | Cuts the picture into a message bubble whose tail leaves the bottom corner on `side`'s outer edge, the picture running into the tail, as Messages draws a photo that ends a run. The tail takes `BUBBLE.tail_drop` of the element's height at its bottom; the corner radius is the style's. GPUI backends draw the rounded picture without the tail. |
| `.id(id : impl Into<SharedString>)` |  |
| `.fit(fit : ImageFit)` |  |
| `.blur(radius : Pixels)` | Softens the picture to washes of its colours about `radius` across, for a backdrop. |
| `.tint(color : impl Into<Hsla>)` | Draws the picture in `color` (a theme token), keeping each pixel's alpha. |
| `.contain()` | Letterboxes instead of cropping. |
| `.size_hint(width : u32, height : u32)` |  |
| `.alt(alt : impl Into<SharedString>)` |  |
| `.still()` | Shows the first frame of an animation only. |
| `.on_load(f : impl Fn(&ImageLoaded, &mut Window, &mut App) + 'static)` |  |
| `.on_error(f : impl Fn(&ImageFailed, &mut Window, &mut App) + 'static)` |  |

### `image_placeholder`

```rust
pub fn image_placeholder() -> Image
```

An image node with no picture yet: the placeholder alone, at the size the style gives.

| `Image` method | Does |
| --- | --- |
| `.bubble_tail(side : BubbleSide)` | Cuts the picture into a message bubble whose tail leaves the bottom corner on `side`'s outer edge, the picture running into the tail, as Messages draws a photo that ends a run. The tail takes `BUBBLE.tail_drop` of the element's height at its bottom; the corner radius is the style's. GPUI backends draw the rounded picture without the tail. |
| `.id(id : impl Into<SharedString>)` |  |
| `.fit(fit : ImageFit)` |  |
| `.blur(radius : Pixels)` | Softens the picture to washes of its colours about `radius` across, for a backdrop. |
| `.tint(color : impl Into<Hsla>)` | Draws the picture in `color` (a theme token), keeping each pixel's alpha. |
| `.contain()` | Letterboxes instead of cropping. |
| `.size_hint(width : u32, height : u32)` |  |
| `.alt(alt : impl Into<SharedString>)` |  |
| `.still()` | Shows the first frame of an animation only. |
| `.on_load(f : impl Fn(&ImageLoaded, &mut Window, &mut App) + 'static)` |  |
| `.on_error(f : impl Fn(&ImageFailed, &mut Window, &mut App) + 'static)` |  |

## `media/lyrics`

### `rows`

```rust
pub fn rows(lyrics : &Lyrics) -> Vec<Row>
```

The rows for `lyrics`: lines with text in time order, interludes in the long gaps, and word
fills for every synced line.

### `lit_at`

```rust
pub fn lit_at(rows : &[Row], t : f64, previous : usize) -> Lit
```

The lit rows at `t`. `previous` is the anchor last time, kept through gaps.

### `lyrics_view`

```rust
pub fn lyrics_view(id : impl Into<SharedString>, lyrics : impl Into<Arc<Lyrics>>, clock : PlaybackClock) -> LyricsView
```

Lyrics following `clock`. Size it with the style; it fills what it is given.

| `LyricsView` method | Does |
| --- | --- |
| `.duration(duration : Option<Duration>)` |  |
| `.resync_after(after : Duration)` |  |
| `.empty_text(text : impl Into<SharedString>)` |  |
| `.on_line_click(f : impl Fn(&LyricClicked, &mut Window, &mut App) + 'static)` |  |
| `.on_follow_change(f : impl Fn(&LyricsFollowChanged, &mut Window, &mut App) + 'static)` |  |

## `media/player_layout`

### `player_layout`

```rust
pub fn player_layout(id : impl Into<SharedString>, state : &PlayerLayoutState) -> PlayerLayout
```

The expanded player's layout, adapting to the room it is given.

| `PlayerLayout` method | Does |
| --- | --- |
| `.artwork(build : impl FnOnce(f32) -> E + 'static)` | The artwork at `side` points square. |
| `.details(details : impl IntoElement)` | The song's details: under the artwork when wide, beside it when narrow. |
| `.panel(panel : impl IntoElement)` | Lyrics, the queue: right of the artwork when wide, under the header when narrow. |

## `media/shelf`

### `shelf`

```rust
pub fn shelf(id : impl Into<SharedString>, handle : &ShelfHandle) -> Shelf
```

A sideways-scrolling row of cards. `handle` keeps its position across renders.

| `Shelf` method | Does |
| --- | --- |
| `.arrows(arrows : ShelfArrows)` |  |
| `.free_scrolling()` | Stops wherever the scroll ends instead of on a card's edge. |
| `.label(label : impl Into<SharedString>)` |  |
| `.bleed(points : f32)` | Runs the shelf `points` past its box on both sides, out over the page's margins, with its cards inset by as much: at rest the first card lines up with the page's headings, and scrolled, cards pass to the content's edges instead of being cut at the margin, as Music's and the App Store's shelves do. The paging arrows sit in the margins. The shelf takes its width from its parent, so the parent lays it out as a block or a column. |
| `.on_scroll(f : impl Fn(&ShelfScrolled, &mut Window, &mut App) + 'static)` |  |

## `media/transport`

### `seek_bar`

```rust
pub fn seek_bar(id : impl Into<SharedString>, clock : PlaybackClock) -> SeekBar
```

A playback scrubber over `clock`. Give it the track's `duration`; it fires [`Seeked`].

| `SeekBar` method | Does |
| --- | --- |
| `.duration(duration : Option<Duration>)` |  |
| `.buffered(buffered : Option<Duration>)` |  |
| `.show_times()` |  |
| `.times_beside()` | Elapsed time before the track and the length after it, on one row. |
| `.line()` |  |
| `.step(step : Duration)` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.on_seek(f : impl Fn(&Seeked, &mut Window, &mut App) + 'static)` |  |

### `player_bar`

```rust
pub fn player_bar(id : impl Into<SharedString>, now : NowPlaying) -> PlayerBar
```

| `PlayerBar` method | Does |
| --- | --- |
| `.layout(layout : TransportLayout)` |  |
| `.compact()` |  |
| `.on_command(f : impl Fn(&TransportCommand, &mut Window, &mut App) + 'static)` |  |
| `.on_open(f : impl Fn(&mut Window, &mut App) + 'static)` | A tap on the artwork and titles opens the app's now-playing view (the expanded player). |
| `.accessory(element : impl IntoElement)` | A control after the titles that acts on the playing item: rating, its menu. The pill puts it at the end of the title row, over the progress line, where Music keeps More. |
| `.trailing(element : impl IntoElement)` | A control after the volume: repeat, shuffle, the queue. Full and pill layouts. |
| `.open_button(element : impl IntoElement)` | The button that opens the now-playing view, after the trailing controls. Unlike them it stays at every width: a narrow bar keeps a way into the expanded player. Full and pill layouts. |
| `.before_transport(element : impl IntoElement)` | A control before previous, where Music keeps shuffle. Full and pill layouts. |
| `.after_transport(element : impl IntoElement)` | A control after next, where Music keeps repeat. Full and pill layouts. |
| `.without_song()` | Leaves the artwork and titles out and keeps the seek bar: a bar over a view showing the song. |

### `volume_icon`

```rust
pub fn volume_icon(volume : f32, muted : bool) -> Icon
```

The volume icon for a level, as the system's own volume menu picks it.

## `media/video`

### `video`

```rust
pub fn video(source : impl Into<SharedString>) -> Video
```

A video from a path or URL, paused until [`Video::playing`] is set.

| `Video` method | Does |
| --- | --- |
| `.id(id : impl Into<SharedString>)` |  |
| `.playing(playing : bool)` |  |
| `.muted(muted : bool)` |  |
| `.looping(looping : bool)` |  |
| `.seek(request : u64, seconds : f64)` | Moves playback to `seconds`. `request` names the seek: a new number seeks, the same one again is the seek already done. |
| `.cover()` | Crops the picture to fill the box instead of letterboxing it. |
| `.alt(alt : impl Into<SharedString>)` |  |
| `.on_ready(f : impl Fn(&VideoReady, &mut Window, &mut App) + 'static)` |  |
| `.on_progress(f : impl Fn(&VideoProgress, &mut Window, &mut App) + 'static)` |  |
| `.on_end(f : impl Fn(&VideoEnded, &mut Window, &mut App) + 'static)` |  |
| `.on_error(f : impl Fn(&VideoFailed, &mut Window, &mut App) + 'static)` |  |

## `menu`

### `primary_menu_items`

```rust
pub fn primary_menu_items() -> Vec<MenuItem>
```

The app's menu bar folded into one primary menu, for platforms without a menu bar: the
app menu's items first, then each menu as a submenu under its title, then Help's items.
System roles (Edit, Window, Quit) are left out; the window and its controls cover them.

## `palette`

### `palette_item`

```rust
pub fn palette_item(id : impl Into<SharedString>, title : impl Into<SharedString>) -> PaletteItem
```

| `PaletteItem` method | Does |
| --- | --- |
| `.subtitle(subtitle : impl Into<SharedString>)` |  |
| `.icon(icon : Icon)` |  |
| `.icon_bytes(bytes : impl Into<Arc<[u8]>>)` |  |
| `.hint(hint : impl Into<SharedString>)` |  |
| `.completion(completion : impl Into<SharedString>)` |  |

### `command_palette`

```rust
pub fn command_palette(id : impl Into<SharedString>) -> CommandPalette
```

A palette over the active window. The element takes no space where it sits; place it anywhere
in the window's tree (`scaffold().overlay(..)` reads best).

| `CommandPalette` method | Does |
| --- | --- |
| `.open(open : bool)` |  |
| `.placeholder(placeholder : impl Into<SharedString>)` |  |
| `.query(query : impl Into<SharedString>)` | The text a present starts from. Feeding back what [`PaletteQueryChanged`] reported changes nothing on screen. |
| `.items(items : impl IntoIterator<Item = PaletteItem>)` | The rows, already filtered and ordered. |
| `.on_query_change(f : impl Fn(&PaletteQueryChanged, &mut Window, &mut App) + 'static)` |  |
| `.on_activate(f : impl Fn(&PaletteActivated, &mut Window, &mut App) + 'static)` |  |
| `.on_submit(f : impl Fn(&PaletteSubmitted, &mut Window, &mut App) + 'static)` |  |
| `.on_cancel(f : impl Fn(&PaletteCancelled, &mut Window, &mut App) + 'static)` |  |

## `panes/dock`

### `empty_dock`

```rust
pub fn empty_dock<T>() -> DockModel<T>
```

### `dock_panel_of`

```rust
pub fn dock_panel_of<T>(tabs : Vec<DockTab<T>>, active_tab_id : Option<&str>) -> DockPanel<T>
```

A panel over `tabs`, active tab defaulting to the first. An empty tab list is not a legal
panel ([`close_tab`] collapses the panel instead).

### `seed_dock`

```rust
pub fn seed_dock<T>(groups : Vec<Vec<DockTab<T>>>) -> DockModel<T>
```

Balanced horizontal dock over one panel per tab group, panel ids `"1"` to `"n"`. Groups with
no tabs are dropped, so every leaf starts with at least one tab.

### `seed_dock_with`

```rust
pub fn seed_dock_with<T>(groups : Vec<Vec<DockTab<T>>>, id : impl Fn(&DockPanel<T>, usize) -> String) -> DockModel<T>
```

### `dock_panels`

```rust
pub fn dock_panels<T>(m : &DockModel<T>) -> Vec<(&PaneId, &DockPanel<T>)>
```

Panels in layout order, as `(panel id, panel)`.

### `find_dock_panel`

```rust
pub fn find_dock_panel<'a, T>(m : &'a DockModel<T>, panel_id : &str) -> Option<&'a DockPanel<T>>
```

### `find_dock_tab`

```rust
pub fn find_dock_tab<'a, T>(m : &'a DockModel<T>, tab_id : &str) -> Option<DockTabLocation<'a, T>>
```

### `active_dock_tab`

```rust
pub fn active_dock_tab<T>(panel : &DockPanel<T>) -> Option<&DockTab<T>>
```

### `add_tab`

```rust
pub fn add_tab<T : Clone>(m : &DockModel<T>, panel_id : &str, tab : DockTab<T>, index : Option<usize>) -> DockModel<T>
```

Adds a tab to an existing panel and activates it. A tab id already used anywhere in the dock
is rejected (same tree), since every op here addresses tabs by id.

### `close_tab`

```rust
pub fn close_tab<T : Clone>(m : &DockModel<T>, tab_id : &str) -> DockModel<T>
```

Closes a tab; the last tab in a panel closes the panel, which collapses the split and gives
the space back to the sibling.

### `activate_tab`

```rust
pub fn activate_tab<T : Clone>(m : &DockModel<T>, tab_id : &str) -> DockModel<T>
```

Selects a tab inside its own panel. Focus is a separate op (`focus_pane`): activating a tab
in a background panel should not steal the focus ring.

### `move_tab`

```rust
pub fn move_tab<T : Clone>(m : &DockModel<T>, tab_id : &str, target_panel_id : &str, index : Option<usize>) -> DockModel<T>
```

Moves a tab to `index` of `target_panel_id`. Within one panel this is a reorder and leaves
the active tab alone; across panels the tab is activated in its new home, which takes the
focus with it, and a source panel left empty collapses.

### `undock_tab`

```rust
pub fn undock_tab<T : Clone>(m : &DockModel<T>, tab_id : &str, zone : DockEdgeZone) -> DockModel<T>
```

Pulls a tab out of its panel into a new panel beside it. A panel holding one tab has nothing
to undock, so that is a same-tree no-op.

### `dock_panel`

```rust
pub fn dock_panel<T : Clone>(m : &DockModel<T>, panel_id : &str, target_panel_id : &str, zone : DockZone) -> DockModel<T>
```

Relocates a whole panel against another one. `Center` merges its tabs into the target's
stack; the four edges split the target and take that side. [`apply_dock_drop`] routes a
drop here.

### `hit_test_dock_zone`

```rust
pub fn hit_test_dock_zone(rect : DockRect, px : f32, py : f32, edge : Option<f32>) -> DockZone
```

Which zone a pointer at (`px`, `py`) lands in over `rect`. Pure geometry: the outer `edge`
fraction (default 0.25, clamped to [0.01, 0.5]) of each side is that side's zone, the middle
is `Center`. A point past an edge still names that edge; a degenerate rect is all `Center`.

### `dock_drag_payload`

```rust
pub fn dock_drag_payload(kind : DockDragKind, id : &str) -> String
```

The drag payload a dock drag source carries. Namespaced because the drop side also receives
plain text dragged in from other applications, which must not be read as a tab id.

### `parse_dock_drag`

```rust
pub fn parse_dock_drag(payload : &str) -> Option<DockDrag>
```

The inverse and the guard: anything not minted by [`dock_drag_payload`] is `None`, which
every drop path treats as "not ours, ignore".

### `dock_panel_rects`

```rust
pub fn dock_panel_rects<T>(m : &DockModel<T>, size : DockSize) -> Vec<(PaneId, DockRect)>
```

Every panel's rect inside a dock of `size`, in layout order, from the split ratios alone.

### `dock_zone_at`

```rust
pub fn dock_zone_at<T>(m : &DockModel<T>, panel_id : &str, x : f32, y : f32, size : Option<DockSize>, edge : Option<f32>) -> DockZone
```

Zone a drop point over `panel_id` lands in. `x` and `y` are panel-local, so the hit test runs
against a rect at the origin. No size, or a panel not in the model, means `Center`, the one
zone that needs no geometry.

### `apply_dock_drop`

```rust
pub fn apply_dock_drop<T : Clone>(m : &DockModel<T>, payload : &str, target_panel_id : &str, zone : DockZone) -> DockModel<T>
```

Turns one drop into one model op, and is the whole drop policy:

- a panel drag is [`dock_panel`], merging into the target's tab stack on `Center` and
  splitting the target on an edge;
- a tab dropped on `Center` is [`move_tab`] into the target's stack;
- a tab dropped on an edge is [`move_tab`] followed by [`undock_tab`], landing it in a new
  panel on that side. A tab alone in its panel takes the [`dock_panel`] path instead: the
  panel IS that tab, so moving it keeps its id and its already-docked no-op.

A drag that ends where it started returns the same tree.

### `serialize_dock`

```rust
pub fn serialize_dock<T : Clone>(m : &DockModel<T>) -> DockSnapshot<T>
```

### `deserialize_dock`

```rust
pub fn deserialize_dock<T>(raw : DockSnapshot<T>, is_data : impl Fn(&T) -> bool) -> DockModel<T>
```

Rebuilds a dock from persisted data, on `migrate_panes` terms: anything malformed rejects the
whole tree back to [`empty_dock`]. A panel with no tabs, a tab without an id, tab data
failing `is_data` and a tab id used twice all count as malformed; an `active_tab_id` naming a
tab that is gone is repaired to the panel's first tab instead.

## `panes/tiles`

### `empty_tiles`

```rust
pub fn empty_tiles<T>(columns : i32) -> TileModel<T>
```

### `seed_tiles`

```rust
pub fn seed_tiles<T : Clone>(items : Vec<TilePlacement<T>>, columns : i32) -> TileModel<T>
```

Places `items` in order, each one dropped at its requested cell and pushed clear of what is
already down. Ids default to `"1"` to `"n"`.

### `find_tile`

```rust
pub fn find_tile<'a, T>(m : &'a TileModel<T>, id : &str) -> Option<&'a Rc<Tile<T>>>
```

### `place_tile`

```rust
pub fn place_tile<T : Clone>(m : &TileModel<T>, placement : TilePlacement<T>) -> TileModel<T>
```

Adds a tile at the cells it asks for, pushing whatever was there down. An id already in the
model is rejected (same tree), the way `add_tab` rejects a duplicate tab id.

### `remove_tile`

```rust
pub fn remove_tile<T>(m : &TileModel<T>, id : &str) -> TileModel<T>
```

### `move_tile`

```rust
pub fn move_tile<T : Clone>(m : &TileModel<T>, id : &str, x : i32, y : i32) -> TileModel<T>
```

### `resize_tile`

```rust
pub fn resize_tile<T : Clone>(m : &TileModel<T>, id : &str, w : i32, h : i32) -> TileModel<T>
```

### `raise_tile`

```rust
pub fn raise_tile<T>(m : &TileModel<T>, id : &str) -> TileModel<T>
```

Moves a tile last in layout order, which is the top of the paint order.

### `update_tile`

```rust
pub fn update_tile<T : Clone + PartialEq>(m : &TileModel<T>, id : &str, f : impl FnOnce(&T) -> T) -> TileModel<T>
```

Replaces a tile's data with `f(current)`. Equal data is a same-tree no-op.

### `tile_drag_payload`

```rust
pub fn tile_drag_payload(id : &str) -> String
```

The drag payload a tile carries, namespaced for the same reason as `dock_drag_payload`: text
dragged in from another application arrives on the same drop handler.

### `parse_tile_drag`

```rust
pub fn parse_tile_drag(payload : &str) -> Option<&str>
```

### `tile_cell_at`

```rust
pub fn tile_cell_at<T>(m : &TileModel<T>, size : TileSize, x : f32, y : f32) -> TileCell
```

Cell under a point in the grid's coordinate space. Cells are taken as uniform, which is what
the grid draws when every tile expands. Points outside the grid clamp to its edge cells.

### `apply_tile_drop`

```rust
pub fn apply_tile_drop<T : Clone>(m : &TileModel<T>, payload : &str, size : TileSize, x : f32, y : f32) -> TileModel<T>
```

Turns one drop into one model op: the cell under the pointer becomes the dragged tile's
top-left, and [`move_tile`] pushes whatever it lands on clear. A tile dropped back on the cell
it already occupies returns the same tree, as does a payload from anything but a tile.

### `serialize_tiles`

```rust
pub fn serialize_tiles<T : Clone>(m : &TileModel<T>) -> TileSnapshot<T>
```

### `deserialize_tiles`

```rust
pub fn deserialize_tiles<T : Clone>(raw : TileSnapshot<T>, columns : i32, is_data : impl Fn(&T) -> bool) -> TileModel<T>
```

Rebuilds a tile layout from persisted data. An empty or duplicate id, or data failing
`is_data`, rejects the whole layout back to `empty_tiles(columns)`; `columns` is also the
fallback when the persisted column count is absent. Loaded tiles are clamped and pushed clear
of each other, so a hand-edited file cannot land an overlapping layout.

## `panes/views`

### `pane_tree`

```rust
pub fn pane_tree<T : 'static>(id : impl Into<SharedString>, tree : &PaneTree<T>, leaf : impl Fn(Leaf<'_, T>, bool) -> AnyElement + 'static) -> PaneTreeView<T>
```

Renders `tree`; `leaf` draws each leaf, told whether it is the focused one.

| `PaneTreeView` method | Does |
| --- | --- |
| `.on_resize(f : impl Fn(&PaneResized, &mut Window, &mut App) + 'static)` | A divider moved; the app applies it with `set_pane_ratio`. |

### `dock_view`

```rust
pub fn dock_view<T : 'static>(id : impl Into<SharedString>, model : &DockModel<T>, tab : impl Fn(&DockTab<T>) -> AnyElement + 'static) -> DockView<T>
```

Renders `model`; `tab` draws a tab's content. Every tab stays mounted, so a terminal or a
page in a background tab keeps running.

| `DockView` method | Does |
| --- | --- |
| `.on_activate(f : impl Fn(&TabChanged, &mut Window, &mut App) + 'static)` | A tab was picked; the app applies it with `activate_tab`. |
| `.on_close(f : impl Fn(&TabCloseRequested, &mut Window, &mut App) + 'static)` | A tab's close was pressed; the app applies it with `close_tab`. |
| `.on_resize(f : impl Fn(&PaneResized, &mut Window, &mut App) + 'static)` |  |

### `tiles_view`

```rust
pub fn tiles_view<T : 'static>(id : impl Into<SharedString>, model : &TileModel<T>, row_height : Pixels, tile : impl Fn(&Tile<T>) -> AnyElement + 'static) -> TilesView<T>
```

## `presentation`

### `presentation`

```rust
pub fn presentation(id : impl Into<SharedString>, state : &Presentation) -> PresentationView
```

`content` presented over `base` while `state` is open. Style it with the backdrop's
background.

| `PresentationView` method | Does |
| --- | --- |
| `.base(base : impl IntoElement)` | What sits under the presentation, mounted throughout. |
| `.backdrop(backdrop : impl IntoElement)` | Drawn over the background and under the content, fading with it: blurred artwork, say. It fills the region and is clipped to it. |
| `.content(content : impl IntoElement)` | The presented view, mounted only while shown. |

## `rich`

### `text_color`

```rust
pub fn text_color(theme : &Theme, color : TextColor, ink : Option<Hsla>) -> Hsla
```

The colour `color` names under `theme`. `ink` is the ink of a filled surface the text sits
on (a sent bubble): every token but a custom colour resolves to it there, since the
surface's own ink is the only colour that reads on it at 4.5:1.

## `scaffold`

### `scaffold`

```rust
pub fn scaffold() -> Scaffold
```

| `Scaffold` method | Does |
| --- | --- |
| `.toolbar(toolbar : Toolbar)` |  |
| `.sidebar(sidebar : Pane)` |  |
| `.inspector(inspector : Pane)` |  |
| `.content(content : impl IntoElement)` |  |
| `.content_under_toolbar()` | The content runs up under the toolbar, the way a transcript scrolls under a unified toolbar on macOS: its lists keep their rows clear of the bar at rest. |
| `.content_bottom_bar(points : f32)` | A bar `points` tall floats over the content's foot: the content's scroll views scroll under it and rest clear of it. Zero where the bar docks below the content instead. |
| `.toolbar_extension(points : f32)` | The toolbar's band, and its blur, reach `points` further down over the content: room for what the content shows at its top under the toolbar (Messages' conversation name). |
| `.content_edge_on_hover()` | The blur and bottom edge over content under the toolbar show only while the pointer is over the toolbar's band, as Messages' transcript on macOS 26; at rest the content runs under the toolbar untouched. |
| `.overlay(overlay : impl IntoElement)` | Floats over the content: palettes, sheets drawn in-window. |

### `sidebar`

```rust
pub fn sidebar() -> Pane
```

The sidebar. On macOS its material, width and collapse come from the split view.

| `Pane` method | Does |
| --- | --- |
| `.collapsed(collapsed : bool)` | Controlled: the pane shows or hides when this changes. A collapse the user makes is reported through [`Pane::on_collapse_change`]. |
| `.on_collapse_change(handler : impl Fn(&PaneCollapsed, &mut Window, &mut App) + 'static)` |  |
| `.edge_reveal()` | While collapsed, the sidebar slides in over the content as a floating panel when the pointer touches the window's leading edge, and away again 250 ms after the pointer leaves it (200 ms in, 150 ms out; a fade with reduce motion). The content is not resized, and window controls in the sidebar ride along. Arc's hidden sidebar. |
| `.on_reveal_change(handler : impl Fn(&SidebarRevealed, &mut Window, &mut App) + 'static)` |  |
| `.resizable()` | The user drags the pane's inner edge to resize it, between its `min_w` and `max_w` ([`PANE_MIN_WIDTH`] and [`PANE_MAX_WIDTH`] where unset). macOS's split view lets the user drag every pane's divider whether or not this is set. |
| `.on_resize(handler : impl Fn(&PaneResized, &mut Window, &mut App) + 'static)` | A divider drag, as it moves. Pass the width back through [`Pane::width`] to keep it, and store it to open the pane at that width next time. |
| `.width(width : Pixels)` | The pane's width. The width a drag gives the pane holds until this changes. |
| `.under_toolbar()` | The pane's content runs up under the toolbar, its lists scrolling under the bar's blur, as Messages' conversation list does under its search field. |
| `.toolbar_extension(points : f32)` | The toolbar's band, and its blur, reach `points` further down over this pane. |

### `inspector`

```rust
pub fn inspector() -> Pane
```

The inspector, on the trailing side.

| `Pane` method | Does |
| --- | --- |
| `.collapsed(collapsed : bool)` | Controlled: the pane shows or hides when this changes. A collapse the user makes is reported through [`Pane::on_collapse_change`]. |
| `.on_collapse_change(handler : impl Fn(&PaneCollapsed, &mut Window, &mut App) + 'static)` |  |
| `.edge_reveal()` | While collapsed, the sidebar slides in over the content as a floating panel when the pointer touches the window's leading edge, and away again 250 ms after the pointer leaves it (200 ms in, 150 ms out; a fade with reduce motion). The content is not resized, and window controls in the sidebar ride along. Arc's hidden sidebar. |
| `.on_reveal_change(handler : impl Fn(&SidebarRevealed, &mut Window, &mut App) + 'static)` |  |
| `.resizable()` | The user drags the pane's inner edge to resize it, between its `min_w` and `max_w` ([`PANE_MIN_WIDTH`] and [`PANE_MAX_WIDTH`] where unset). macOS's split view lets the user drag every pane's divider whether or not this is set. |
| `.on_resize(handler : impl Fn(&PaneResized, &mut Window, &mut App) + 'static)` | A divider drag, as it moves. Pass the width back through [`Pane::width`] to keep it, and store it to open the pane at that width next time. |
| `.width(width : Pixels)` | The pane's width. The width a drag gives the pane holds until this changes. |
| `.under_toolbar()` | The pane's content runs up under the toolbar, its lists scrolling under the bar's blur, as Messages' conversation list does under its search field. |
| `.toolbar_extension(points : f32)` | The toolbar's band, and its blur, reach `points` further down over this pane. |

## `source_list`

### `source_node`

```rust
pub fn source_node(id : impl Into<SharedString>, title : impl Into<SharedString>) -> SourceNode
```

A row with `id` showing `title`.

| `SourceNode` method | Does |
| --- | --- |
| `.parent(parent : impl Into<SharedString>)` |  |
| `.caption(caption : impl Into<SharedString>)` | A second, smaller line under the title. With a `meter` the row grows to hold the caption over the bar. |
| `.icon(icon : Icon)` |  |
| `.artwork(source : impl Into<Option<ImageSource>>)` |  |
| `.badge(badge : impl Into<SharedString>)` |  |
| `.meter(fraction : f32)` | A capacity meter under the title, clamped to `0..=1`, as Finder and Files show a volume's used space. The GPUI backend draws it; on macOS the sidebar shows none. |
| `.has_children(has : bool)` |  |
| `.expanded(expanded : bool)` |  |
| `.selectable(selectable : bool)` |  |
| `.actions(ids : impl IntoIterator<Item = impl Into<SharedString>>)` |  |
| `.movable(movable : bool)` |  |

### `source_section`

```rust
pub fn source_section(id : impl Into<SharedString>, title : impl Into<SharedString>) -> SourceNode
```

A section header; rows name it as their parent. Expanded unless the app collapses it.

| `SourceNode` method | Does |
| --- | --- |
| `.parent(parent : impl Into<SharedString>)` |  |
| `.caption(caption : impl Into<SharedString>)` | A second, smaller line under the title. With a `meter` the row grows to hold the caption over the bar. |
| `.icon(icon : Icon)` |  |
| `.artwork(source : impl Into<Option<ImageSource>>)` |  |
| `.badge(badge : impl Into<SharedString>)` |  |
| `.meter(fraction : f32)` | A capacity meter under the title, clamped to `0..=1`, as Finder and Files show a volume's used space. The GPUI backend draws it; on macOS the sidebar shows none. |
| `.has_children(has : bool)` |  |
| `.expanded(expanded : bool)` |  |
| `.selectable(selectable : bool)` |  |
| `.actions(ids : impl IntoIterator<Item = impl Into<SharedString>>)` |  |
| `.movable(movable : bool)` |  |

### `source_action`

```rust
pub fn source_action(id : impl Into<SharedString>, icon : Icon) -> SourceAction
```

| `SourceAction` method | Does |
| --- | --- |
| `.label(label : impl Into<SharedString>)` |  |
| `.tooltip(tooltip : impl Into<SharedString>)` |  |
| `.destructive()` |  |

### `source_tree`

```rust
pub fn source_tree(id : impl Into<SharedString>) -> SourceTree
```

| `SourceTree` method | Does |
| --- | --- |
| `.nodes(nodes : impl IntoIterator<Item = SourceNode>)` |  |
| `.actions(actions : impl IntoIterator<Item = SourceAction>)` | The action catalog rows reference by id. |
| `.selected(id : impl Into<SharedString>)` |  |
| `.selected_opt(id : Option<SharedString>)` |  |
| `.action_visibility(visibility : ActionVisibility)` |  |
| `.empty_state(icon : Option<Icon>, title : impl Into<SharedString>, description : Option<SharedString>)` |  |
| `.section(title : impl Into<SharedString>, items : impl IntoIterator<Item = SourceItem>)` | A titled group of rows; nested items are expanded. |
| `.items(items : impl IntoIterator<Item = SourceItem>)` | Rows with no group row above them; nested items are expanded. |
| `.on_select(f : impl Fn(&SourceSelected, &mut Window, &mut App) + 'static)` |  |
| `.on_activate(f : impl Fn(&SourceActivated, &mut Window, &mut App) + 'static)` |  |
| `.on_expand(f : impl Fn(&SourceExpanded, &mut Window, &mut App) + 'static)` |  |
| `.on_collapse(f : impl Fn(&SourceCollapsed, &mut Window, &mut App) + 'static)` |  |
| `.on_action(f : impl Fn(&SourceActionClicked, &mut Window, &mut App) + 'static)` |  |
| `.context_menu(build : impl Fn(&SharedString, ContextMenu, &mut Window, &mut App) -> ContextMenu + 'static)` | Each row answers a right click with the menu `build` fills for its id. A row that selects is selected first, as GTK and Windows lists do. |
| `.on_middle_click(f : impl Fn(&SourceMiddleClicked, &mut Window, &mut App) + 'static)` |  |
| `.draggable_rows(kind : impl Into<SharedString>)` | Rows drag as [`DragItem`]s of `kind` with the row's id, except sections and rows that are not `movable`. |
| `.accepts_drops(kinds : impl IntoIterator<Item = impl Into<SharedString>>)` | The list takes drags of these kinds (its own rows' kind, to reorder them). |
| `.drops_onto_rows()` | A drag over the middle of a row lands on it: the row is outlined and the drop's [`DropSlot::on`] names it. Above and below the middle it still lands between rows. |
| `.on_drag_over(f : impl Fn(&DragOver, &mut Window, &mut App) + 'static)` |  |
| `.on_drop(f : impl Fn(&Dropped, &mut Window, &mut App) + 'static)` | A drag was dropped on the list; its `slot` says where among the rows. |
| `.on_drag_end(f : impl Fn(&DragEnded, &mut Window, &mut App) + 'static)` | A row's drag is over: dropped, cancelled, or released outside the app's windows. |

### `source_item`

```rust
pub fn source_item(id : impl Into<SharedString>, title : impl Into<SharedString>) -> SourceItem
```

One row: an id the app selects by, a title, and optionally an icon, a badge and children.

| `SourceItem` method | Does |
| --- | --- |
| `.icon(icon : Icon)` |  |
| `.badge(badge : impl Into<SharedString>)` |  |
| `.caption(caption : impl Into<SharedString>)` | A second, smaller line under the title: a volume's free space over its meter. |
| `.meter(fraction : f32)` | See [`SourceNode::meter`]. |
| `.children(children : impl IntoIterator<Item = SourceItem>)` |  |

### `source_list`

```rust
pub fn source_list(id : impl Into<SharedString>) -> SourceTree
```

A sidebar of fixed places in titled sections: [`SourceTree::section`] and
[`SourceTree::items`] fill it.

| `SourceTree` method | Does |
| --- | --- |
| `.nodes(nodes : impl IntoIterator<Item = SourceNode>)` |  |
| `.actions(actions : impl IntoIterator<Item = SourceAction>)` | The action catalog rows reference by id. |
| `.selected(id : impl Into<SharedString>)` |  |
| `.selected_opt(id : Option<SharedString>)` |  |
| `.action_visibility(visibility : ActionVisibility)` |  |
| `.empty_state(icon : Option<Icon>, title : impl Into<SharedString>, description : Option<SharedString>)` |  |
| `.section(title : impl Into<SharedString>, items : impl IntoIterator<Item = SourceItem>)` | A titled group of rows; nested items are expanded. |
| `.items(items : impl IntoIterator<Item = SourceItem>)` | Rows with no group row above them; nested items are expanded. |
| `.on_select(f : impl Fn(&SourceSelected, &mut Window, &mut App) + 'static)` |  |
| `.on_activate(f : impl Fn(&SourceActivated, &mut Window, &mut App) + 'static)` |  |
| `.on_expand(f : impl Fn(&SourceExpanded, &mut Window, &mut App) + 'static)` |  |
| `.on_collapse(f : impl Fn(&SourceCollapsed, &mut Window, &mut App) + 'static)` |  |
| `.on_action(f : impl Fn(&SourceActionClicked, &mut Window, &mut App) + 'static)` |  |
| `.context_menu(build : impl Fn(&SharedString, ContextMenu, &mut Window, &mut App) -> ContextMenu + 'static)` | Each row answers a right click with the menu `build` fills for its id. A row that selects is selected first, as GTK and Windows lists do. |
| `.on_middle_click(f : impl Fn(&SourceMiddleClicked, &mut Window, &mut App) + 'static)` |  |
| `.draggable_rows(kind : impl Into<SharedString>)` | Rows drag as [`DragItem`]s of `kind` with the row's id, except sections and rows that are not `movable`. |
| `.accepts_drops(kinds : impl IntoIterator<Item = impl Into<SharedString>>)` | The list takes drags of these kinds (its own rows' kind, to reorder them). |
| `.drops_onto_rows()` | A drag over the middle of a row lands on it: the row is outlined and the drop's [`DropSlot::on`] names it. Above and below the middle it still lands between rows. |
| `.on_drag_over(f : impl Fn(&DragOver, &mut Window, &mut App) + 'static)` |  |
| `.on_drop(f : impl Fn(&Dropped, &mut Window, &mut App) + 'static)` | A drag was dropped on the list; its `slot` says where among the rows. |
| `.on_drag_end(f : impl Fn(&DragEnded, &mut Window, &mut App) + 'static)` | A row's drag is over: dropped, cancelled, or released outside the app's windows. |

## `split`

### `split`

```rust
pub fn split(id : impl Into<SharedString>, axis : Axis) -> Split
```

A split of two panes along `axis`. `id` keys it, so the panes keep their content when a
sibling appears or goes.

| `Split` method | Does |
| --- | --- |
| `.ratio(ratio : f32)` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.first(content : impl IntoElement)` | The leading (or top) pane's content. |
| `.second(content : impl IntoElement)` |  |
| `.first_pane(pane : SplitPane)` | The leading pane, for one with a minimum or maximum size. |
| `.second_pane(pane : SplitPane)` |  |
| `.on_resize(f : impl Fn(&SplitResized, &mut Window, &mut App) + 'static)` |  |

### `split_pane`

```rust
pub fn split_pane() -> SplitPane
```

| `SplitPane` method | Does |
| --- | --- |
| `.min_size(min : Pixels)` | The pane never shrinks below `min` points along the split's axis. |
| `.max_size(max : Pixels)` |  |

## `status_page`

### `status_page`

```rust
pub fn status_page(title : impl Into<SharedString>) -> StatusPage
```

An empty state titled `title`, centred in the room it is given.

| `StatusPage` method | Does |
| --- | --- |
| `.icon(icon : Icon)` |  |
| `.description(description : impl Into<SharedString>)` |  |
| `.compact()` |  |
| `.id(id : impl Into<SharedString>)` | Keys the header, for automation and for two status pages side by side. |

## `tabs`

### `tab_strip`

```rust
pub fn tab_strip(id : impl Into<SharedString>) -> TabStrip
```

| `TabStrip` method | Does |
| --- | --- |
| `.tab(id : impl Into<SharedString>, title : impl Into<SharedString>)` |  |
| `.tabs(tabs : impl IntoIterator<Item = TabSpec>)` |  |
| `.selected(id : impl Into<SharedString>)` |  |
| `.presentation(presentation : TabStyle)` |  |
| `.add_button(shown : bool)` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.on_select(f : impl Fn(&TabChanged, &mut Window, &mut App) + 'static)` |  |
| `.on_close(f : impl Fn(&TabCloseRequested, &mut Window, &mut App) + 'static)` |  |
| `.on_add(f : impl Fn(&TabAddRequested, &mut Window, &mut App) + 'static)` |  |
| `.context_menu(build : impl Fn(&SharedString, ContextMenu, &mut Window, &mut App) -> ContextMenu + 'static)` | Each tab answers a right click with the menu `build` fills for its id. The tab is not selected by it. |
| `.accepts_drops(kinds : impl IntoIterator<Item = impl Into<SharedString>>)` | The strip takes drags of these kinds. Over a tab, the drag's [`DropSlot::on`] names it and its `index` is the tab's; past the last tab `on` is `None`. |
| `.on_drag_over(f : impl Fn(&nd_ui::DragOver, &mut Window, &mut App) + 'static)` |  |
| `.on_drop(f : impl Fn(&nd_ui::Dropped, &mut Window, &mut App) + 'static)` | A drag was dropped on the strip; its `slot` names the tab under it. |

### `tab_page`

```rust
pub fn tab_page(id : impl Into<SharedString>, title : impl Into<SharedString>) -> TabPage
```

| `TabPage` method | Does |
| --- | --- |
| `.icon(icon : Icon)` |  |
| `.closable()` | Shows a close button on the tab (strip style); a press reports [`TabCloseRequested`]. |

### `tab_view`

```rust
pub fn tab_view(id : impl Into<SharedString>) -> TabView
```

In-window tabs. `id` keys the strip, which is what automation finds (`setValue` with a tab's
title or id selects it); each page is keyed by its tab's id.

| `TabView` method | Does |
| --- | --- |
| `.tab(page : TabPage)` |  |
| `.tabs(pages : impl IntoIterator<Item = TabPage>)` |  |
| `.selected(id : impl Into<SharedString>)` |  |
| `.presentation(presentation : TabStyle)` |  |
| `.add_button(shown : bool)` |  |
| `.label(label : impl Into<SharedString>)` |  |
| `.homogeneous(homogeneous : bool)` | Measures as the biggest page and keeps every page mounted (the default), or mounts only the selected page and takes its size. |
| `.disabled(disabled : bool)` |  |
| `.on_select(f : impl Fn(&TabChanged, &mut Window, &mut App) + 'static)` |  |
| `.on_close(f : impl Fn(&TabCloseRequested, &mut Window, &mut App) + 'static)` |  |
| `.on_add(f : impl Fn(&TabAddRequested, &mut Window, &mut App) + 'static)` |  |
| `.context_menu(build : impl Fn(&SharedString, ContextMenu, &mut Window, &mut App) -> ContextMenu + 'static)` |  |

## `tile_grid`

### `tile`

```rust
pub fn tile(id : impl Into<SharedString>, content : impl IntoElement) -> Tile
```

### `tile_grid`

```rust
pub fn tile_grid(id : impl Into<SharedString>) -> TileGrid
```

A grid of at most four columns of tiles at least 40 points wide, 0.74 as tall as wide.

| `TileGrid` method | Does |
| --- | --- |
| `.tiles(tiles : impl IntoIterator<Item = Tile>)` |  |
| `.max_columns(columns : usize)` |  |
| `.min_tile_width(width : f32)` |  |
| `.aspect(aspect : f32)` | A tile's height over its width. |
| `.gap(gap : f32)` |  |
| `.draggable_tiles(kind : impl Into<SharedString>)` | Tiles drag as items of `kind`, reordering within the grid and onto any target taking it. |
| `.accepts_drops(kinds : impl IntoIterator<Item = impl Into<SharedString>>)` | Kinds from elsewhere the grid takes (a list's rows, to pin them). |
| `.on_move(f : impl Fn(&TileMoved, &mut Window, &mut App) + 'static)` |  |
| `.on_drop(f : impl Fn(&Dropped, &mut Window, &mut App) + 'static)` | A drag from outside the grid was dropped on it; `slot.index` is where. |
| `.on_drag_end(f : impl Fn(&DragEnded, &mut Window, &mut App) + 'static)` | A tile's drag is over (dropped elsewhere, cancelled, released outside the app). |

## `titlebar`

### `titlebar`

```rust
pub fn titlebar() -> Titlebar
```

| `Titlebar` method | Does |
| --- | --- |
| `.title(title : impl Into<SharedString>)` | Replaces the window's title, which the row shows when nothing else sits leading. |
| `.leading(item : impl IntoElement)` |  |
| `.trailing(item : impl IntoElement)` |  |
| `.controls(controls : WindowControls)` | Places the OS window controls itself (at a point, or in an embedded slot here) instead of where the OS puts them. |

## `toast`

### `toast`

```rust
pub fn toast(id : impl Into<SharedString>, title : impl Into<SharedString>) -> Toast
```

A toast with `id` (echoed in its events) showing `title` for [`DEFAULT_TIMEOUT`].

| `Toast` method | Does |
| --- | --- |
| `.action(label : impl Into<SharedString>)` | A button; clicking it fires [`ToastActionClicked`] and dismisses the toast. |
| `.timeout(timeout : Duration)` |  |
| `.persistent()` | Stays until dismissed. |
| `.high_priority()` |  |

### `toast_overlay`

```rust
pub fn toast_overlay(id : impl Into<SharedString>) -> ToastOverlay
```

The window's toasts. Takes no space where it sits; one per window.

| `ToastOverlay` method | Does |
| --- | --- |
| `.toasts(toasts : impl IntoIterator<Item = Toast>)` | The queue, oldest first. |
| `.on_dismiss(f : impl Fn(&ToastDismissed, &mut Window, &mut App) + 'static)` |  |
| `.on_action(f : impl Fn(&ToastActionClicked, &mut Window, &mut App) + 'static)` |  |

### `banner`

```rust
pub fn banner(id : impl Into<SharedString>, title : impl Into<SharedString>) -> Banner
```

A message bar across its container: `title` and an optional button. Hidden until revealed.

| `Banner` method | Does |
| --- | --- |
| `.action(label : impl Into<SharedString>)` |  |
| `.revealed(revealed : bool)` |  |
| `.on_action(f : impl Fn(&BannerActionClicked, &mut Window, &mut App) + 'static)` |  |

## `toolbar`

### `system_item`

```rust
pub fn system_item(item : SystemItem) -> AnyElement
```

### `toolbar_sidebar_toggle`

```rust
pub fn toolbar_sidebar_toggle() -> AnyElement
```

The system sidebar toggle.

### `toolbar`

```rust
pub fn toolbar() -> Toolbar
```

| `Toolbar` method | Does |
| --- | --- |
| `.item(item : impl IntoElement)` |  |
| `.labeled_item(label : impl Into<SharedString>, item : impl IntoElement)` | An item with the label the overflow menu and customization show. |
| `.leading(item : impl IntoElement)` | Sits before the title: window controls embedded in the toolbar, a back button. |
| `.navigation(item : impl IntoElement)` | Starts the content's part of the toolbar, ahead of the title: a compose or back button. |
| `.persistent_search(field : impl IntoElement)` | A `search_field` that always shows in the header. On Linux a toolbar's search field otherwise sits behind a toggle that opens libadwaita's search bar under the header; Windows and macOS keep it in the toolbar either way. |
| `.flexible_item(item : impl IntoElement)` | Takes the room the row leaves, and gives it back before any other item when the window narrows: a path bar or a location field. Its content keeps its own least width. |
| `.centered_item(item : impl IntoElement)` | Kept in the middle of the window's toolbar: the conversation in a chat window. |
| `.hide_title()` | Leaves the window's title out of the toolbar. |
| `.title(title : impl Into<SharedString>)` |  |
| `.display(display : ToolbarDisplay)` |  |
| `.flexible_space()` | Pushes the items after it to the trailing edge. |
| `.space()` |  |
| `.sidebar_toggle()` |  |
| `.tab(id : impl Into<SharedString>, label : impl Into<SharedString>, icon : crate::icon::Icon)` | A selectable tab with an icon and a label, as settings windows show. Controlled: the app sets [`Toolbar::selected_tab`] from [`TabSelected`]. |
| `.selected_tab(id : impl Into<SharedString>)` |  |
| `.on_tab(handler : impl Fn(&TabSelected, &mut Window, &mut App) + 'static)` |  |
| `.primary_menu()` | The primary menu at the trailing edge, holding the app's menus where the platform has no menu bar (libadwaita's header bar menu, WinUI's "More" button). Nothing on macOS, where the menu bar holds them. |
| `.inspector_toggle()` |  |


