# State APIs
Method-level reference for every public `*State` struct and its companions.
`docs/WIDGETS.md` lists **fields**; this document lists **methods** you can
call on those fields — validators, filters, selection helpers, page
navigation, toggle logic, and so on.
Every item below is declared `pub` in `src/widgets/*.rs`. Private helpers
and `pub(crate)` methods are intentionally omitted because they are not
part of the stable surface.
## Conventions
- Each type has H2 header with source file reference.
- "Fields" lists only public fields. Internal `pub(crate)` or private
fields (cursors, dirty flags, caches) are omitted.
- "Constructors" covers `new`, `with_*`, `from_*`, `default`.
- "Methods" covers all other public methods on the type.
- `Self` in signatures means the enclosing type.
## TextInputState
Source: `src/widgets/input.rs`.
Single-line text input state. Pass `&mut TextInputState` to
`Context::text_input` each frame.
### Fields
| `value` | `String` | Current input text. |
| `cursor` | `usize` | Cursor position as a char index into `value`. |
| `placeholder` | `String` | Placeholder shown when `value` is empty. |
| `max_length` | `Option<usize>` | Reject input past this char count. |
| `validation_error` | `Option<String>` | Latest single-shot validation error. |
| `masked` | `bool` | Render `•` instead of characters (passwords). |
| `suggestions` | `Vec<String>` | Autocomplete candidates. |
| `suggestion_index` | `usize` | Highlighted suggestion row. |
| `show_suggestions` | `bool` | Whether suggestions popup is visible. |
### Constructors
- `TextInputState::new() -> Self`
- `TextInputState::with_placeholder(p: impl Into<String>) -> Self`
- `TextInputState::default() -> Self` (same as `new`)
### Methods
| `max_length(self, len: usize) -> Self` | Builder: cap character count. |
| `validate(&mut self, validator: impl Fn(&str) -> Result<(), String>)` | Run one validator and store its error into `validation_error`. |
| `add_validator(&mut self, f: impl Fn(&str) -> Result<(), String> + 'static)` | Register a boxed validator. |
| `run_validators(&mut self)` | Run all validators; populates `errors()` and `validation_error`. |
| `errors(&self) -> &[String]` | All current validator errors. |
| `set_suggestions(&mut self, suggestions: Vec<String>)` | Replace suggestions and reset popup state. |
| `matched_suggestions(&self) -> Vec<&str>` | Suggestions whose prefix matches `value` (case-insensitive). |
### Minimal example
```rust
let mut input = TextInputState::with_placeholder("email");
input.add_validator(|v| {
if v.contains('@') { Ok(()) } else { Err("needs @".into()) }
});
ui.text_input(&mut input);
input.run_validators();
for err in input.errors() { ui.text(err).fg(Color::Red); }
```
## TextareaState
Source: `src/widgets/input.rs`.
Multi-line text area state. Pass with a row count to `Context::textarea`.
### Fields
| `lines` | `Vec<String>` | One entry per logical line. |
| `cursor_row` | `usize` | Logical row of the cursor. |
| `cursor_col` | `usize` | Character column within the row. |
| `max_length` | `Option<usize>` | Max total character count. |
| `wrap_width` | `Option<u32>` | Soft-wrap column; `None` disables wrap. |
| `scroll_offset` | `usize` | First visible visual line (managed by `textarea()`). |
### Constructors
- `TextareaState::new() -> Self`
- `TextareaState::default() -> Self` (single blank line)
### Methods
| `value(&self) -> String` | Join `lines` with `\n`. |
| `set_value(&mut self, text: impl Into<String>)` | Replace content, reset cursor and scroll. |
| `max_length(self, len: usize) -> Self` | Builder: cap total char count. |
| `word_wrap(self, width: u32) -> Self` | Builder: enable soft word-wrap. |
### Minimal example
```rust
let mut area = TextareaState::new().word_wrap(60).max_length(2000);
ui.textarea(&mut area, 8);
if ui.button("Save").clicked { save(&area.value()); }
```
## FormField
Source: `src/widgets/input.rs`.
One labeled input inside a `FormState`.
### Fields
| `label` | `String` | Label shown above the input. |
| `input` | `TextInputState` | Backing input state. |
| `error` | `Option<String>` | Error rendered below the input. |
### Constructors
- `FormField::new(label: impl Into<String>) -> Self`
- `FormField::default() -> Self`
### Methods
| `placeholder(self, p: impl Into<String>) -> Self` | Builder: set the nested input's placeholder. |
### Minimal example
```rust
let email = FormField::new("Email").placeholder("you@example.com");
```
## FormState
Source: `src/widgets/input.rs`.
Multi-field form.
### Fields
| `fields` | `Vec<FormField>` | Ordered field list. |
| `submitted` | `bool` | Whether the form has been submitted successfully. |
### Constructors
- `FormState::new() -> Self`
- `FormState::default() -> Self`
### Methods
| `field(self, field: FormField) -> Self` | Builder: append a field. |
| `validate(&mut self, validators: &[FormValidator]) -> bool` | Run per-field validators; returns `true` when every field passes. |
| `value(&self, index: usize) -> &str` | Read the Nth field's input value, `""` if out of range. |
### Minimal example
```rust
let mut form = FormState::new()
.field(FormField::new("Name"))
.field(FormField::new("Email"));
if form.validate(&validators) { form.submitted = true; }
```
## StaticOutput
Source: `src/widgets/input.rs`.
Buffer of static lines emitted above an inline TUI via `slt::run_static`.
### Fields
All fields are private.
### Constructors
- `StaticOutput::new() -> Self`
- `StaticOutput::default() -> Self`
### Methods
| `println(&mut self, line: impl Into<String>)` | Append one line. |
| `lines(&self) -> &[String]` | All accumulated lines. |
| `drain_new(&mut self) -> Vec<String>` | Drain lines added since the previous drain. |
| `clear(&mut self)` | Remove every line. |
### Minimal example
```rust
let mut out = StaticOutput::new();
out.println("Saved record 123");
```
## ListState
Source: `src/widgets/collections.rs`.
Selectable list.
### Fields
| `items` | `Vec<String>` | Display strings. |
| `selected` | `usize` | Current selection. |
| `filter` | `String` | Substring filter (AND-of-tokens, case-insensitive). |
### Constructors
- `ListState::new(items: Vec<impl Into<String>>) -> Self`
- `ListState::default() -> Self`
### Methods
| `set_items(&mut self, items: Vec<impl Into<String>>)` | Replace items and rebuild filtered view. |
| `set_filter(&mut self, filter: impl Into<String>)` | Update filter and recompute visible indices. |
| `visible_indices(&self) -> &[usize]` | Indices into `items` that survive the filter. |
| `selected_item(&self) -> Option<&str>` | Text of the currently selected item. |
### Minimal example
```rust
let mut list = ListState::new(vec!["apple", "banana", "cherry"]);
list.set_filter("an");
ui.list(&mut list);
if let Some(item) = list.selected_item() { println!("{item}"); }
```
## FilePickerState
Source: `src/widgets/collections.rs`.
Directory browser with extension and hidden-file filters.
### Fields
| `current_dir` | `PathBuf` | Directory currently being browsed. |
| `entries` | `Vec<FileEntry>` | Visible entries. |
| `selected` | `usize` | Index into `entries`. |
| `selected_file` | `Option<PathBuf>` | The file the user confirmed. |
| `show_hidden` | `bool` | Include dotfiles. |
| `extensions` | `Vec<String>` | Allowed extensions (lowercase, no dot). |
| `dirty` | `bool` | Set when `refresh()` should be called. |
### Constructors
- `FilePickerState::new(dir: impl Into<PathBuf>) -> Self`
- `FilePickerState::default() -> Self` (current directory)
### Methods
| `show_hidden(self, show: bool) -> Self` | Builder: include dotfiles. |
| `extensions(self, exts: &[&str]) -> Self` | Builder: restrict to given extensions. |
| `selected(&self) -> Option<&PathBuf>` | The chosen file, if any. |
| `refresh(&mut self)` | Re-read the directory listing. |
### Minimal example
```rust
let mut picker = FilePickerState::new(".").extensions(&["rs", "toml"]);
picker.refresh();
ui.file_picker(&mut picker);
```
## FileEntry
Source: `src/widgets/collections.rs`.
### Fields
| `name` | `String` | Base name. |
| `path` | `PathBuf` | Full path. |
| `is_dir` | `bool` | Directory flag. |
| `size` | `u64` | Size in bytes (0 for directories). |
### Constructors
- `FileEntry::default() -> Self`
### Methods
No additional methods beyond field access.
## TabsState
Source: `src/widgets/collections.rs`.
### Fields
| `labels` | `Vec<String>` | Tab labels. |
| `selected` | `usize` | Index of the active tab. |
### Constructors
- `TabsState::new(labels: Vec<impl Into<String>>) -> Self`
- `TabsState::default() -> Self`
### Methods
| `selected_label(&self) -> Option<&str>` | Text of the active tab. |
### Minimal example
```rust
let mut tabs = TabsState::new(vec!["General", "Keys", "About"]);
ui.tabs(&mut tabs);
match tabs.selected_label() {
Some("General") => ui.text("general pane"),
Some("Keys") => ui.text("key bindings"),
_ => ui.text("about pane"),
};
```
## TableState
Source: `src/widgets/collections.rs`.
Sortable, filterable, paginated table.
### Fields
| `headers` | `Vec<String>` | Column headers. |
| `rows` | `Vec<Vec<String>>` | Table data. |
| `selected` | `usize` | Selected row index (within the visible view). |
| `sort_column` | `Option<usize>` | Active sort column. |
| `sort_ascending` | `bool` | Sort direction. |
| `filter` | `String` | Filter text (AND of space-separated tokens). |
| `page` | `usize` | Current page (0-based). |
| `page_size` | `usize` | Rows per page; `0` disables pagination. |
| `zebra` | `bool` | Alternating row backgrounds. |
### Constructors
- `TableState::new(headers: Vec<impl Into<String>>, rows: Vec<Vec<impl Into<String>>>) -> Self`
- `TableState::default() -> Self`
### Methods
| `set_rows(&mut self, rows: Vec<Vec<impl Into<String>>>)` | Replace rows; clamps selection and rebuilds the filter cache. |
| `toggle_sort(&mut self, column: usize)` | Sort by column; toggles direction if already sorted. |
| `sort_by(&mut self, column: usize)` | Sort ascending by column. |
| `set_filter(&mut self, filter: impl Into<String>)` | Update filter; resets the page. |
| `clear_sort(&mut self)` | Clear any active sort. |
| `next_page(&mut self)` | Advance one page, clamped to last. |
| `prev_page(&mut self)` | Go back one page, clamped to 0. |
| `total_pages(&self) -> usize` | Pages given current filter and `page_size`. |
| `visible_indices(&self) -> &[usize]` | Row indices after filter + sort. |
| `selected_row(&self) -> Option<&[String]>` | The currently selected row. |
### Minimal example
```rust
let mut table = TableState::new(
vec!["Name", "Score"],
vec![vec!["Alice", "95"], vec!["Bob", "72"]],
);
table.sort_by(1);
ui.table(&mut table);
```
## ScrollState
Source: `src/widgets/collections.rs`.
Vertical scroll bookkeeping for `Context::scrollable`.
### Fields
| `offset` | `usize` | First visible row. |
### Constructors
- `ScrollState::new() -> Self`
- `ScrollState::default() -> Self`
### Methods
| `can_scroll_up(&self) -> bool` | `offset > 0`. |
| `can_scroll_down(&self) -> bool` | Content extends past the viewport. |
| `content_height(&self) -> u32` | Total content rows. |
| `viewport_height(&self) -> u32` | Visible rows. |
| `progress(&self) -> f32` | Scroll progress in `[0.0, 1.0]`. |
| `scroll_up(&mut self, amount: usize)` | Clamp to 0. |
| `scroll_down(&mut self, amount: usize)` | Clamp to max offset. |
## SelectState
Source: `src/widgets/selection.rs`.
Dropdown.
### Fields
| `items` | `Vec<String>` | Options. |
| `selected` | `usize` | Current option index. |
| `open` | `bool` | Whether the dropdown is expanded. |
| `placeholder` | `String` | Fallback label when `items` is empty. |
### Constructors
- `SelectState::new(items: Vec<impl Into<String>>) -> Self`
- `SelectState::default() -> Self`
### Methods
| `placeholder(self, p: impl Into<String>) -> Self` | Builder: set placeholder. |
| `selected_item(&self) -> Option<&str>` | Currently selected label. |
### Minimal example
```rust
let mut dropdown = SelectState::new(vec!["Low", "Medium", "High"])
.placeholder("select priority");
ui.select(&mut dropdown);
```
## RadioState
Source: `src/widgets/selection.rs`.
### Fields
| `items` | `Vec<String>` | Option labels. |
| `selected` | `usize` | Current selection. |
### Constructors
- `RadioState::new(items: Vec<impl Into<String>>) -> Self`
- `RadioState::default() -> Self`
### Methods
| `selected_item(&self) -> Option<&str>` | Current label. |
## MultiSelectState
Source: `src/widgets/selection.rs`.
### Fields
| `items` | `Vec<String>` | Option labels. |
| `cursor` | `usize` | Keyboard focus cursor. |
| `selected` | `HashSet<usize>` | Checked indices. |
### Constructors
- `MultiSelectState::new(items: Vec<impl Into<String>>) -> Self`
### Methods
| `selected_items(&self) -> Vec<&str>` | Selected labels in ascending-index order. |
| `toggle(&mut self, index: usize)` | Add or remove `index` from `selected`. |
### Minimal example
```rust
let mut ms = MultiSelectState::new(vec!["bold", "italic", "underline"]);
ms.toggle(0);
ui.multi_select(&mut ms);
```
## TreeNode
Source: `src/widgets/selection.rs`.
One node in a hierarchical tree.
### Fields
| `label` | `String` | Display label. |
| `children` | `Vec<TreeNode>` | Child nodes. |
| `expanded` | `bool` | Whether children are visible. |
### Constructors
- `TreeNode::new(label: impl Into<String>) -> Self`
### Methods
| `expanded(self) -> Self` | Builder: mark as expanded. |
| `children(self, children: Vec<TreeNode>) -> Self` | Builder: set children. |
| `is_leaf(&self) -> bool` | `true` when there are no children. |
## TreeState
Source: `src/widgets/selection.rs`.
### Fields
| `nodes` | `Vec<TreeNode>` | Root nodes. |
| `selected` | `usize` | Row index in the flattened visible tree. |
### Constructors
- `TreeState::new(nodes: Vec<TreeNode>) -> Self`
### Methods
The user-facing tree API is built on the public fields plus `TreeNode`
helpers above; `TreeState` itself exposes only `new`. Internal expand
and flatten helpers are `pub(crate)` and called by `Context::tree`.
### Minimal example
```rust
let root = TreeNode::new("project").expanded().children(vec![
TreeNode::new("src").children(vec![TreeNode::new("main.rs")]),
TreeNode::new("Cargo.toml"),
]);
let mut tree = TreeState::new(vec![root]);
ui.tree(&mut tree);
```
## DirectoryTreeState
Source: `src/widgets/selection.rs`.
Directory-flavored tree with icon toggle.
### Fields
| `tree` | `TreeState` | Underlying tree state. |
| `show_icons` | `bool` | Whether to render file icons. |
### Constructors
- `DirectoryTreeState::new(nodes: Vec<TreeNode>) -> Self`
- `DirectoryTreeState::from_paths(paths: &[&str]) -> Self`
- `DirectoryTreeState::default() -> Self` (empty)
### Methods
| `selected_label(&self) -> Option<&str>` | Label of the currently selected node. |
### Minimal example
```rust
let mut dt = DirectoryTreeState::from_paths(&[
"src/main.rs", "src/lib.rs", "Cargo.toml",
]);
ui.directory_tree(&mut dt);
```
## PaletteCommand
Source: `src/widgets/selection.rs`.
One entry in a command palette.
### Fields
| `label` | `String` | Primary label. |
| `description` | `String` | Supplemental description. |
| `shortcut` | `Option<String>` | Keyboard hint text. |
### Constructors
- `PaletteCommand::new(label: impl Into<String>, description: impl Into<String>) -> Self`
### Methods
| `shortcut(self, s: impl Into<String>) -> Self` | Builder: attach a shortcut hint. |
## CommandPaletteState
Source: `src/widgets/commanding.rs`.
Modal palette with fuzzy search.
### Fields
| `commands` | `Vec<PaletteCommand>` | Available commands. |
| `input` | `String` | Current search query. |
| `cursor` | `usize` | Cursor into `input`. |
| `open` | `bool` | Whether the modal is visible. |
| `last_selected` | `Option<usize>` | Last confirmed command index. Consume after `response.changed`. |
### Constructors
- `CommandPaletteState::new(commands: Vec<PaletteCommand>) -> Self`
### Methods
| `toggle(&mut self)` | Open or close; resets input when opening. |
### Minimal example
```rust
let mut palette = CommandPaletteState::new(vec![
PaletteCommand::new("Open File", "Pick a file").shortcut("Ctrl+O"),
]);
if ui.key_mod('p', KeyModifiers::CONTROL) { palette.toggle(); }
let r = ui.command_palette(&mut palette);
if r.changed { if let Some(i) = palette.last_selected { run(i); } }
```
## StreamingTextState
Source: `src/widgets/commanding.rs`.
Plain-text streaming buffer.
### Fields
| `content` | `String` | Accumulated text. |
| `streaming` | `bool` | Whether the stream is still active. |
### Constructors
- `StreamingTextState::new() -> Self`
- `StreamingTextState::default() -> Self`
### Methods
| `push(&mut self, chunk: &str)` | Append a chunk. |
| `finish(&mut self)` | Mark the stream complete. |
| `start(&mut self)` | Begin a fresh session, clearing previous content. |
| `clear(&mut self)` | Wipe everything. |
## StreamingMarkdownState
Source: `src/widgets/commanding.rs`.
Streaming markdown buffer with fenced-code awareness.
### Fields
| `content` | `String` | Accumulated markdown. |
| `streaming` | `bool` | Stream active flag. |
| `cursor_visible` | `bool` | Blink state for the typing indicator. |
| `cursor_tick` | `u64` | Cursor animation tick. |
| `in_code_block` | `bool` | Whether the parser is inside a fenced block. |
| `code_block_lang` | `String` | Language label of the active fenced block. |
### Constructors
- `StreamingMarkdownState::new() -> Self`
- `StreamingMarkdownState::default() -> Self`
### Methods
| `push(&mut self, chunk: &str)` | Append a chunk. |
| `start(&mut self)` | Begin a fresh session. |
| `finish(&mut self)` | Mark complete; hides the typing cursor. |
| `clear(&mut self)` | Reset state. |
## ScreenState
Source: `src/widgets/commanding.rs`.
Navigation stack for multi-screen apps. Used with `Context::screen`.
### Fields
All fields are private. Use the methods below to read and mutate state.
### Constructors
- `ScreenState::new(initial: impl Into<String>) -> Self`
### Methods
| `current(&self) -> &str` | Top-of-stack screen name. |
| `push(&mut self, name: impl Into<String>)` | Navigate forward. |
| `pop(&mut self)` | Navigate back; preserves the root screen. |
| `depth(&self) -> usize` | Stack size. |
| `can_pop(&self) -> bool` | `true` when more than one screen is pushed. |
| `reset(&mut self)` | Truncate to the root screen. |
### Minimal example
```rust
let mut screens = ScreenState::new("home");
if ui.button("Settings").clicked { screens.push("settings"); }
if screens.current() == "settings" && ui.button("Back").clicked {
screens.pop();
}
```
## ModeState
Source: `src/widgets/commanding.rs`.
Named modes, each containing an independent `ScreenState`.
### Fields
All fields are private.
### Constructors
- `ModeState::new(mode: impl Into<String>, screen: impl Into<String>) -> Self`
### Methods
| `add_mode(&mut self, mode: impl Into<String>, screen: impl Into<String>)` | Register a mode with its root screen. |
| `switch_mode(&mut self, mode: impl Into<String>)` | Switch; panics if the mode is unknown. |
| `try_switch_mode(&mut self, mode: impl Into<String>) -> bool` | Non-panicking variant that returns `false` for unknown modes. |
| `active_mode(&self) -> &str` | Current mode name. |
| `screens(&self) -> &ScreenState` | Immutable view of the active mode's screen stack. |
| `screens_mut(&mut self) -> &mut ScreenState` | Mutable view of the active mode's screen stack. |
### Minimal example
```rust
let mut modes = ModeState::new("app", "home");
modes.add_mode("settings", "general");
if ui.key('2') { modes.try_switch_mode("settings"); }
modes.screens_mut().push("advanced");
```
## ToolApprovalState
Source: `src/widgets/commanding.rs`.
Human-in-the-loop approval prompt for an AI tool call.
### Fields
| `tool_name` | `String` | Name of the tool. |
| `description` | `String` | What the tool will do. |
| `action` | `ApprovalAction` | Current status. |
### Constructors
- `ToolApprovalState::new(tool_name: impl Into<String>, description: impl Into<String>) -> Self`
### Methods
| `reset(&mut self)` | Set `action` back to `Pending`. |
### Related enum
`ApprovalAction` has variants `Pending`, `Approved`, `Rejected`.
## ContextItem
Source: `src/widgets/commanding.rs`.
Entry in a context bar for AI chat UIs.
### Fields
| `label` | `String` | Display label. |
| `tokens` | `usize` | Token count or size indicator. |
### Constructors
- `ContextItem::new(label: impl Into<String>, tokens: usize) -> Self`
### Methods
None beyond the constructor.
## RichLogState
Source: `src/widgets/feedback.rs`.
Multi-style append-only log.
### Fields
| `entries` | `Vec<RichLogEntry>` | Accumulated log rows. |
| `auto_scroll` | `bool` | Follow the tail when new rows arrive. |
| `max_entries` | `Option<usize>` | Optional ring-buffer cap. |
### Constructors
- `RichLogState::new() -> Self`
- `RichLogState::default() -> Self`
### Methods
| `push(&mut self, text: impl Into<String>, style: Style)` | Append one styled entry. |
| `push_plain(&mut self, text: impl Into<String>)` | Append with default style. |
| `push_segments(&mut self, segments: Vec<(String, Style)>)` | Append a mixed-style entry; honors `max_entries` and `auto_scroll`. |
| `clear(&mut self)` | Remove everything and reset scroll. |
| `len(&self) -> usize` | Entry count. |
| `is_empty(&self) -> bool` | `true` when there are no entries. |
### Related type
`RichLogEntry { pub segments: Vec<(String, Style)> }`.
## CalendarState
Source: `src/widgets/feedback.rs`.
Date picker.
### Fields
| `year` | `i32` | Displayed year. |
| `month` | `u32` | Displayed month (1–12). |
| `selected_day` | `Option<u32>` | Currently selected day. |
### Constructors
- `CalendarState::new() -> Self` (current month)
- `CalendarState::from_ym(year: i32, month: u32) -> Self`
- `CalendarState::default() -> Self`
### Methods
| `selected_date(&self) -> Option<(i32, u32, u32)>` | Returns `(year, month, day)` when a day is selected. |
| `prev_month(&mut self)` | Move view back one month. |
| `next_month(&mut self)` | Move view forward one month. |
### Minimal example
```rust
let mut cal = CalendarState::new();
ui.calendar(&mut cal);
if let Some((y, m, d)) = cal.selected_date() { println!("{y}-{m:02}-{d:02}"); }
```
## SpinnerState
Source: `src/widgets/input.rs`.
Tick-driven spinner.
### Fields
Internal character set only.
### Constructors
- `SpinnerState::dots() -> Self` — braille dots
- `SpinnerState::line() -> Self` — ASCII bar
- `SpinnerState::default() -> Self` — equivalent to `dots`
### Methods
| `frame(&self, tick: u64) -> char` | Character for the given frame tick. |
### Minimal example
```rust
let spinner = SpinnerState::dots();
let ch = spinner.frame(ui.tick());
ui.text(format!("{ch} Loading..."));
```
## ToastState
Source: `src/widgets/input.rs`.
Stack of timed toast notifications. Pass to `Context::toast` each frame.
### Fields
| `messages` | `Vec<ToastMessage>` | Active messages, oldest first. |
### Constructors
- `ToastState::new() -> Self`
- `ToastState::default() -> Self`
### Methods
| `info(&mut self, text: impl Into<String>, tick: u64)` | Push an info toast for 30 ticks. |
| `success(&mut self, text: impl Into<String>, tick: u64)` | Push a success toast for 30 ticks. |
| `warning(&mut self, text: impl Into<String>, tick: u64)` | Push a warning toast for 50 ticks. |
| `error(&mut self, text: impl Into<String>, tick: u64)` | Push an error toast for 80 ticks. |
| `push(&mut self, text: impl Into<String>, level: ToastLevel, tick: u64, duration_ticks: u64)` | Push a toast with a custom level and duration. |
| `cleanup(&mut self, current_tick: u64)` | Drop expired messages. Called automatically by `Context::toast`. |
### Related types
- `ToastMessage { pub text, level, created_tick, duration_ticks }` — impls `Default`.
- `ToastLevel` with variants `Info`, `Success`, `Warning`, `Error`.
- `AlertLevel` with variants `Info`, `Success`, `Warning`, `Error` (non-exhaustive). Used by alert widgets rather than toasts.
### Minimal example
```rust
let mut toasts = ToastState::new();
if ui.key('s') { toasts.success("Saved", ui.tick()); }
ui.toast(&mut toasts);
```
## ButtonVariant
Source: `src/widgets/feedback.rs`.
Visual variant accepted by `Context::button_with`.
### Variants
- `Default` — theme text color, primary when focused (same as `button()`).
- `Primary` — primary color background with contrasting text.
- `Danger` — error color for destructive actions.
- `Outline` — bordered appearance without fill.
`#[non_exhaustive]` — do not `match` without a wildcard arm. Derives
`Default` (to `Default`), `Clone`, `Copy`, `PartialEq`, `Eq`, `Hash`,
`Debug`.
## Trend
Source: `src/widgets/feedback.rs`.
### Variants
- `Up` — positive movement.
- `Down` — negative movement.
`#[non_exhaustive]`, `Clone`, `Copy`, `PartialEq`, `Eq`, `Debug`.
## Method coverage self-check
Public-method counts per source file:
| `src/widgets/input.rs` | 35 | 35 |
| `src/widgets/collections.rs` | 31 | 31 |
| `src/widgets/selection.rs` | 18 | 18 |
| `src/widgets/feedback.rs` | 12 | 12 |
| `src/widgets/commanding.rs` | 29 | 29 |
Totals match the live source. If you discover a public method missing from
this document, the source file is the source of truth — open a PR to add
it here.
## See also
- `docs/WIDGETS.md` — field-level reference
- `docs/PATTERNS.md` — how to combine state types with container layout
- `docs/AI_GUIDE.md` — general rules for AI agents
- `docs/PREVIOUS_FRAME_GUIDE.md` — when `Response.rect` is valid