This commit is contained in:
2026-01-26 09:23:11 +08:00
parent f218a21377
commit 2c22685b68
2 changed files with 45 additions and 22 deletions

View File

@@ -14,9 +14,6 @@ export component Button {
// Callbacks // Callbacks
callback clicked(); callback clicked();
// Internal state
private property <bool> hovered: false;
// Calculate background color based on variant // Calculate background color based on variant
private property <color> base-bg-color: { private property <color> base-bg-color: {
if disabled { Theme.colors.muted } if disabled { Theme.colors.muted }
@@ -27,16 +24,6 @@ export component Button {
else { Theme.colors.primary } else { Theme.colors.primary }
}; };
// Calculate hover background color
private property <color> 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 // Calculate text color based on variant
private property <color> text-color: { private property <color> text-color: {
if disabled { Theme.colors.muted-foreground } if disabled { Theme.colors.muted-foreground }
@@ -57,7 +44,7 @@ export component Button {
// Main container // Main container
container := Rectangle { container := Rectangle {
background: hovered ? hover-bg-color : base-bg-color; background: base-bg-color;
border-radius: SpacingSystem.radius.md; border-radius: SpacingSystem.radius.md;
border-width: variant == "outline" ? 1px : 0px; border-width: variant == "outline" ? 1px : 0px;
border-color: Theme.colors.border; border-color: Theme.colors.border;
@@ -68,6 +55,28 @@ export component Button {
easing: Animations.ease-in-out; 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 // Content layout
HorizontalLayout { HorizontalLayout {
padding-left: btn-padding-x; padding-left: btn-padding-x;
@@ -87,16 +96,30 @@ export component Button {
} }
// Touch interaction area // Touch interaction area
TouchArea { touch := TouchArea {
enabled: !disabled; enabled: !disabled;
clicked => { clicked => {
root.clicked(); root.clicked();
} }
}
moved => { // States for visual feedback with color overlays
hovered = self.has-hover; 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;
}
]
} }
} }

View File

@@ -107,14 +107,14 @@ export component Demo inherits Window {
} }
} }
// Main content area // Main content area - fixed height
Rectangle { Rectangle {
background: Theme.colors.background; background: Theme.colors.background;
Flickable { Flickable {
width: 100%; width: 100%;
height: 100%; height: parent.height;
viewport-height: content-layout.preferred-height + 100px; viewport-height: content-layout.preferred-height;
content-layout := VerticalLayout { content-layout := VerticalLayout {
padding: SpacingSystem.spacing.s6; padding: SpacingSystem.spacing.s6;