// Button Component // Shadcn-style button with multiple variants and sizes import { Theme, Typography, SpacingSystem } from "../theme/theme.slint"; import { Animations } from "../utils/animations.slint"; export component Button { // Public properties in property text: "Button"; in property variant: "default"; // default | destructive | outline | secondary | ghost in property size: "md"; // sm | md | lg in property disabled: false; // Callbacks callback clicked(); // Calculate background color based on variant private property base-bg-color: { if disabled { Theme.colors.muted } else if variant == "destructive" { Theme.colors.destructive } else if variant == "outline" { Colors.transparent } else if variant == "secondary" { Theme.colors.secondary } else if variant == "ghost" { Colors.transparent } else { Theme.colors.primary } }; // Calculate text color based on variant private property text-color: { if disabled { Theme.colors.muted-foreground } else if variant == "destructive" { Theme.colors.destructive-foreground } else if variant == "outline" { Theme.colors.foreground } else if variant == "secondary" { Theme.colors.secondary-foreground } else if variant == "ghost" { Theme.colors.foreground } else { Theme.colors.primary-foreground } }; // Calculate size-based dimensions private property btn-height: size == "sm" ? 36px : size == "lg" ? 44px : 40px; private property btn-padding-x: size == "sm" ? 12px : size == "lg" ? 24px : 16px; private property font-size: size == "sm" ? Typography.sizes.sm : size == "lg" ? Typography.sizes.lg : Typography.sizes.base; min-width: btn-height; min-height: btn-height; // Main container container := Rectangle { background: base-bg-color; border-radius: SpacingSystem.radius.md; border-width: variant == "outline" ? 1px : 0px; border-color: Theme.colors.border; // Smooth transitions animate background { duration: Animations.durations.fast; easing: Animations.ease-in-out; } // Content layout HorizontalLayout { padding-left: btn-padding-x; padding-right: btn-padding-x; spacing: SpacingSystem.spacing.s2; alignment: center; // Button text Text { text: root.text; color: text-color; font-size: font-size; font-weight: Typography.weights.medium; vertical-alignment: center; horizontal-alignment: center; } } // Touch interaction area touch := TouchArea { enabled: !disabled; clicked => { root.clicked(); } } // Combined overlay for both hover and press effects overlay := Rectangle { width: 100%; height: 100%; border-radius: SpacingSystem.radius.md; // 直接根据状态设置背景色,不使用 states 块 background: { if disabled { Colors.transparent } else if touch.pressed { #00000030 // 按压时深色 } else if touch.has-hover { #ffffff10 // 悬停时浅色 } else { Colors.transparent } }; animate background { duration: 200ms; easing: ease-in-out; } } } }