From 2c22685b688cf1e857280207487f404dffc55c2b Mon Sep 17 00:00:00 2001 From: me0106 Date: Mon, 26 Jan 2026 09:23:11 +0800 Subject: [PATCH] init --- ui/components/button.slint | 61 ++++++++++++++++++++++++++------------ ui/demo.slint | 6 ++-- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/ui/components/button.slint b/ui/components/button.slint index 3f441f2..87f8977 100644 --- a/ui/components/button.slint +++ b/ui/components/button.slint @@ -14,9 +14,6 @@ export component Button { // Callbacks callback clicked(); - // Internal state - private property hovered: false; - // Calculate background color based on variant private property base-bg-color: { if disabled { Theme.colors.muted } @@ -27,16 +24,6 @@ export component Button { else { Theme.colors.primary } }; - // Calculate hover background color - private property hover-bg-color: { - if disabled { Theme.colors.muted } - else if variant == "destructive" { #dc2626 } - else if variant == "outline" { Theme.colors.accent } - else if variant == "secondary" { #e4e4e7 } - else if variant == "ghost" { Theme.colors.accent } - else { #27272a } - }; - // Calculate text color based on variant private property text-color: { if disabled { Theme.colors.muted-foreground } @@ -57,7 +44,7 @@ export component Button { // Main container container := Rectangle { - background: hovered ? hover-bg-color : base-bg-color; + background: base-bg-color; border-radius: SpacingSystem.radius.md; border-width: variant == "outline" ? 1px : 0px; border-color: Theme.colors.border; @@ -68,6 +55,28 @@ export component Button { easing: Animations.ease-in-out; } + // Hover overlay - light mask + hover-overlay := Rectangle { + background: Colors.transparent; + border-radius: SpacingSystem.radius.md; + + animate background { + duration: Animations.durations.fast; + easing: Animations.ease-in-out; + } + } + + // Press overlay - darker mask + press-overlay := Rectangle { + background: Colors.transparent; + border-radius: SpacingSystem.radius.md; + + animate background { + duration: 100ms; + easing: Animations.ease-out; + } + } + // Content layout HorizontalLayout { padding-left: btn-padding-x; @@ -87,16 +96,30 @@ export component Button { } // Touch interaction area - TouchArea { + touch := TouchArea { enabled: !disabled; clicked => { root.clicked(); } - - moved => { - hovered = self.has-hover; - } } + + // States for visual feedback with color overlays + states [ + pressed when touch.pressed && !disabled: { + press-overlay.background: #00000040; // Dark overlay for press + } + hovered when touch.has-hover && !disabled && !touch.pressed: { + hover-overlay.background: #ffffff15; // Light overlay for hover + } + normal when !disabled: { + hover-overlay.background: Colors.transparent; + press-overlay.background: Colors.transparent; + } + disabled-state when disabled: { + hover-overlay.background: Colors.transparent; + press-overlay.background: Colors.transparent; + } + ] } } diff --git a/ui/demo.slint b/ui/demo.slint index 590e0ed..388e637 100644 --- a/ui/demo.slint +++ b/ui/demo.slint @@ -107,14 +107,14 @@ export component Demo inherits Window { } } - // Main content area + // Main content area - fixed height Rectangle { background: Theme.colors.background; Flickable { width: 100%; - height: 100%; - viewport-height: content-layout.preferred-height + 100px; + height: parent.height; + viewport-height: content-layout.preferred-height; content-layout := VerticalLayout { padding: SpacingSystem.spacing.s6;