From 89ee8c06306ff778ff0f813dc325f40a8ea41c75 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sat, 5 Jul 2025 14:12:20 +0800 Subject: [PATCH] otp_input: Fix to keep showing focus border when all code has filled. (#1047) https://github.com/user-attachments/assets/dd10793e-668e-4c01-9bc9-fe00b539a5d1 --- crates/ui/src/input/otp_input.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/ui/src/input/otp_input.rs b/crates/ui/src/input/otp_input.rs index 09082689..393b5d7f 100644 --- a/crates/ui/src/input/otp_input.rs +++ b/crates/ui/src/input/otp_input.rs @@ -222,6 +222,11 @@ impl RenderOnce for OtpInput { Size::Size(v) => v * 0.5, }; + let cursor_ix = state + .value + .chars() + .count() + .min(state.length.saturating_sub(1)); let mut groups: Vec> = Vec::with_capacity(self.number_of_groups); let mut group_ix = 0; let group_items_count = state.length / self.number_of_groups; @@ -229,17 +234,17 @@ impl RenderOnce for OtpInput { groups.push(vec![]); } - for i in 0..state.length { - let c = state.value.chars().nth(i); - if i % group_items_count == 0 && i != 0 { + for ix in 0..state.length { + let c = state.value.chars().nth(ix); + if ix % group_items_count == 0 && ix != 0 { group_ix += 1; } - let is_input_focused = i == state.value.chars().count() && is_focused; + let is_input_focused = ix == cursor_ix && is_focused; groups[group_ix].push( h_flex() - .id(("input-otp", i)) + .id(("input-otp", ix)) .border_1() .border_color(cx.theme().input) .bg(cx.theme().background)