input: Add readonly mode for Input, Textarea and Editor (#2705)
Fixes #2702 A read-only editor previously had to use `disabled`, which dims the whole editor with `opacity(0.5)`. That is not what a file preview (e.g.: a Git application) should look like. `readonly` keeps the normal appearance and only rejects the changes made by the user. The name follows the HTML `readonly` attribute. ```rust Editor::new(&state).readonly(true) Textarea::new(&state).readonly(true) Input::new(&state).readonly(true) ``` ## What a read-only input keeps | | `disabled` | `readonly` | | --- | --- | --- | | Normal colors (no `opacity(0.5)`) | ✗ | ✓ | | Focus, caret, selection | ✗ | ✓ | | Copy, Select All | ✗ | ✓ | | Search (`Find`) | ✓ | ✓ | | Go to Definition, hover | ✗ | ✓ | | Replace, Cut, Paste, Code Actions | ✗ | ✗ | | Typing, IME, undo/redo, indent | ✗ | ✗ | | `set_value`, `insert`, `replace` | ✓ | ✓ | ## Implementation - `InputBaseState` gets a `readonly` field, `set_readonly()`, and a single `is_editable()` predicate (`!disabled && !readonly`) that all the write paths now go through: `replace_text_in_range`, `replace_and_mark_text_in_range` (IME), and the edit action registration. - The scattered "temporarily clear `disabled`" blocks in `insert` / `replace` / `replace_text` are folded into `with_edits_allowed()`, so a programmatic write is never blocked by either mode. - `is_replaceable()` becomes `replaceable && is_editable()`, so the search panel offers find-only in read-only mode. - The context menu disables Cut / Paste / Show Code Actions, but keeps Copy and Go to Definition — the two a code preview needs. - The clear button is hidden, and the OS autofill content type is no longer synced for a read-only input. ## Testing `crates/story/examples/editor.rs` — the status bar toggle at the bottom is now `Read only` instead of `Disabled`. The Editor story has a `Read only` switch, and the Input story shows a read-only field beside the disabled one. Added `test_readonly_rejects_user_edits_only`: user input (including IME) is rejected, programmatic writes still apply, and editing resumes after leaving the mode. --- Written with Claude Code, reviewed and adjusted by hand. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
J
Jason Lee committed
bc1b70d6cdfbb39fc952d95b8e10394a1258d157
Parent: 7cf072b
Committed by GitHub <noreply@github.com>
on 8/14/2026, 7:18:24 AM