From 74e83d2334dc436b7b6dd23e1ce62323826c1e07 Mon Sep 17 00:00:00 2001 From: reugenio Date: Wed, 17 Dec 2025 01:12:21 +0100 Subject: [PATCH] feat: Transiciones hover en Select widget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SelectState ahora incluye: - hover: HoverTransition para transiciones suaves - last_time_ms: tracking de tiempo para delta El color de fondo del botón principal del Select ahora transiciona suavemente entre normal y hover (lighten 5%). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/widgets/select.zig | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/widgets/select.zig b/src/widgets/select.zig index 17908cb..bb9cb41 100644 --- a/src/widgets/select.zig +++ b/src/widgets/select.zig @@ -2,6 +2,7 @@ //! //! A dropdown menu for selecting one option from a list. //! The dropdown opens on click and closes when an option is selected. +//! Supports smooth hover transitions via HoverTransition. const std = @import("std"); const Context = @import("../core/context.zig").Context; @@ -9,6 +10,7 @@ const Command = @import("../core/command.zig"); const Layout = @import("../core/layout.zig"); const Style = @import("../core/style.zig"); const Input = @import("../core/input.zig"); +const animation = @import("../render/animation.zig"); /// Select state (caller-managed) pub const SelectState = struct { @@ -20,6 +22,10 @@ pub const SelectState = struct { scroll_offset: usize = 0, /// Whether this widget has focus focused: bool = false, + /// Hover transition for smooth effects + hover: animation.HoverTransition = .{}, + /// Last frame time for delta calculation + last_time_ms: u64 = 0, /// Get selected index as optional usize pub fn selectedIndex(self: SelectState) ?usize { @@ -110,15 +116,22 @@ pub fn selectRect( const has_focus = ctx.hasFocus(widget_id); state.focused = has_focus; - // Determine button colors + // Update hover transition + const current_time = ctx.current_time_ms; + const dt_ms: u64 = if (state.last_time_ms > 0 and current_time > state.last_time_ms) + current_time - state.last_time_ms + else + 16; + state.last_time_ms = current_time; + state.hover.update(hovered and !config.disabled and !state.open, dt_ms); + + // Determine button colors with smooth transition const bg_color = if (config.disabled) theme.button_bg.darken(20) else if (state.open) theme.button_bg.lighten(10) - else if (hovered) - theme.button_bg.lighten(5) else - theme.button_bg; + state.hover.blend(theme.button_bg, theme.button_bg.lighten(5)); const border_color = if (has_focus or state.open) theme.primary else theme.border;