// 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; } // 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; 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(); } } // 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; } ] } }