diff --git a/README.md b/README.md index a0f8878..a5409e4 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ All live in `tokito_ui::components` (aliased `c` above). Each takes | `list_row` | `list_row(ui, t, job, selected) -> Response` | A full-width, left-aligned, hover-highlighted row. | | `text_input` | `text_input(ui, t, id_source, &mut String, hint, width) -> Response` | A bordered single-line input. | | `search_field` | `search_field(ui, t, id_source, &mut String, hint, width) -> Response` | `text_input` with a leading magnifier. | +| `secret_input` | `secret_input(ui, t, id_source, &mut String, hint, width) -> Response` | `text_input` that masks its content (API keys, secrets). | | `toggle` | `toggle(ui, t, &mut bool, label) -> Response` | An animated switch with a trailing label. | | `menu_button` | `menu_button(ui, t, id_source, glyph, side, \|ui\| …)` | A kebab trigger that opens a popup of `menu_item`s. | | `menu_item` | `menu_item(ui, t, glyph, label) -> bool` | One row of a `menu_button` popup. | diff --git a/src/components.rs b/src/components.rs index ecab280..32c1362 100644 --- a/src/components.rs +++ b/src/components.rs @@ -314,7 +314,22 @@ pub fn text_input( hint: &str, width: f32, ) -> Response { - bordered_input(ui, t, egui::Id::new(id_source), value, hint, width, None) + bordered_input(ui, t, egui::Id::new(id_source), value, hint, width, None, false) +} + +/// A bordered single-line input that **masks** its content (API keys, secrets). +/// +/// Identical to [`text_input`] but the characters render as dots. Same +/// stable-`id_source` rule. +pub fn secret_input( + ui: &mut Ui, + t: &Tokens, + id_source: impl Hash, + value: &mut String, + hint: &str, + width: f32, +) -> Response { + bordered_input(ui, t, egui::Id::new(id_source), value, hint, width, None, true) } /// A bordered search field: a magnifier glyph + a single-line text edit. @@ -336,10 +351,12 @@ pub fn search_field( hint, width, Some(icons::ph::MAGNIFYING_GLASS), + false, ) } -/// Shared implementation behind [`text_input`] and [`search_field`]. +/// Shared implementation behind [`text_input`], [`search_field`] and +/// [`secret_input`]. fn bordered_input( ui: &mut Ui, t: &Tokens, @@ -348,6 +365,7 @@ fn bordered_input( hint: &str, width: f32, leading_glyph: Option<&str>, + mask: bool, ) -> Response { let height = 34.0; let (rect, _) = ui.allocate_exact_size(vec2(width, height), Sense::hover()); @@ -382,6 +400,7 @@ fn bordered_input( .id(id) .hint_text(hint) .frame(false) + .password(mask) .desired_width(edit_rect.width()), ) }