This commit is contained in:
2026-01-26 23:40:05 +08:00
parent 1ec60e3cbb
commit 24bf9dc3dd
7 changed files with 163 additions and 188 deletions

View File

@@ -14,10 +14,10 @@ export component Button {
// Callbacks
callback clicked();
// Calculate text color based on variant
// Calculate text color based on variant (shadcn design tokens)
private property <color> text-color: {
if disabled { Theme.colors.muted-foreground }
else if variant == "destructive" { Theme.colors.destructive-foreground }
else if variant == "destructive" { Theme.colors.destructive } // destructive uses destructive color for text
else if variant == "outline" { Theme.colors.foreground }
else if variant == "secondary" { Theme.colors.secondary-foreground }
else if variant == "ghost" { Theme.colors.foreground }
@@ -48,8 +48,9 @@ export component Button {
// Main container
container := Rectangle {
border-radius: SpacingSystem.radius.md;
border-width: variant == "outline" ? 1px : 0px;
border-color: Theme.colors.border;
// Outline variant always has border
border-width: root.variant == "outline" ? 1px : 0px;
border-color: root.variant == "outline" ? Theme.colors.border : Colors.transparent;
// Touch interaction area (must be defined before using touch.pressed/has-hover)
touch := TouchArea {
@@ -61,45 +62,42 @@ export component Button {
}
}
// Background with state-based colors (shadcn style)
background-rect := Rectangle {
width: 100%;
height: 100%;
border-radius: parent.border-radius;
// Calculate background color based on variant and state
background: {
if root.disabled {
Theme.colors.muted
} else if root.variant == "destructive" {
if touch.pressed { Theme.colors.destructive.darker(0.1) }
else if touch.has-hover { Theme.colors.destructive.darker(0.05) }
else { Theme.colors.destructive }
} else if root.variant == "outline" {
if touch.pressed { Theme.colors.accent.darker(0.05) }
else if touch.has-hover { Theme.colors.accent }
else { Colors.transparent }
} else if root.variant == "secondary" {
if touch.pressed { Theme.colors.secondary.darker(0.1) }
else if touch.has-hover { Theme.colors.secondary.darker(0.05) }
else { Theme.colors.secondary }
} else if root.variant == "ghost" {
if touch.pressed { Theme.colors.accent.darker(0.05) }
else if touch.has-hover { Theme.colors.accent }
else { Colors.transparent }
} else {
// default variant
if touch.pressed { Theme.colors.primary.darker(0.1) }
else if touch.has-hover { Theme.colors.primary.darker(0.05) }
else { Theme.colors.primary }
}
};
// Smooth transitions
animate background {
duration: Animations.durations.fast;
easing: Animations.ease-in-out;
// Calculate background color based on variant and state (shadcn official design)
background: {
if root.disabled {
Theme.colors.muted
} else if root.variant == "destructive" {
// destructive: bg-destructive/10 hover:bg-destructive/20
if touch.pressed { Theme.colors.destructive.with-alpha(0.25) }
else if touch.has-hover { Theme.colors.destructive.with-alpha(0.2) }
else { Theme.colors.destructive.with-alpha(0.1) }
} else if root.variant == "outline" {
// outline: bg-background hover:bg-muted
if touch.pressed { Theme.colors.muted.darker(0.05) }
else if touch.has-hover { Theme.colors.muted }
else { Theme.colors.background }
} else if root.variant == "secondary" {
// secondary: bg-secondary hover:bg-secondary/80
if touch.pressed { Theme.colors.secondary.with-alpha(0.7) }
else if touch.has-hover { Theme.colors.secondary.with-alpha(0.8) }
else { Theme.colors.secondary }
} else if root.variant == "ghost" {
// ghost: transparent hover:bg-muted
if touch.pressed { Theme.colors.muted.darker(0.05) }
else if touch.has-hover { Theme.colors.muted }
else { Colors.transparent }
} else {
// default (primary): bg-primary hover:bg-primary/80
if touch.pressed { Theme.colors.primary.with-alpha(0.7) }
else if touch.has-hover { Theme.colors.primary.with-alpha(0.8) }
else { Theme.colors.primary }
}
};
// Smooth transitions
animate background {
duration: Animations.durations.fast;
easing: Animations.ease-in-out;
}
// Content layout