Files
shadcn-slint/ui/components/switch.slint
2026-01-30 20:32:37 +08:00

79 lines
2.1 KiB
Plaintext

import { Theme, SpacingSystem } from "../theme/theme.slint";
import { Animations } from "../utils/animations.slint";
export component Switch {
in property <bool> checked: false;
in property <bool> enabled: true;
callback toggled(bool);
private property <bool> pressed: false;
private property <bool> hovered: false;
min-width: 32px;
min-height: 18px;
states [
disabled when !root.enabled: {
track.opacity: 0.5;
thumb.opacity: 0.5;
}
checked when root.checked: {
track.background: Theme.colors.primary;
thumb.x: root.width - thumb.width - 2px;
}
unchecked when !root.checked: {
track.background: Theme.colors.input;
thumb.x: 2px;
}
]
track := Rectangle {
width: 32px;
height: 18px;
border-radius: 9px;
background: Theme.colors.input;
border-width: 1px;
border-color: transparent;
animate background { duration: Animations.durations.fast; easing: Animations.ease-out; }
thumb := Rectangle {
width: 14px;
height: 14px;
y: (parent.height - self.height) / 2;
x: 2px;
border-radius: 7px;
background: Theme.colors.background;
drop-shadow-blur: 2px;
drop-shadow-color: #00000040;
drop-shadow-offset-y: 1px;
animate x { duration: Animations.durations.fast; easing: Animations.ease-out; }
}
}
touch := TouchArea {
enabled: root.enabled;
clicked => {
if (root.enabled) {
root.toggled(!root.checked);
}
}
pointer-event(event) => {
if (event.kind == PointerEventKind.down) {
root.pressed = true;
} else if (event.kind == PointerEventKind.up || event.kind == PointerEventKind.cancel) {
root.pressed = false;
}
}
moved => {
root.hovered = self.has-hover;
}
}
}