import { Theme } from "theme.slint"; // --- IconButton ------------------------------------------------------------ // A small square action button that accepts a single-character glyph (or short text). // Keeps visual language consistent across the app. export component IconButton inherits Rectangle { in property glyph; in property tooltip; in property size: 28px; in property fg: Theme.text-secondary; in property fg-hover: Theme.text-primary; callback clicked(); width: size; height: size; border-radius: Theme.radius-sm; background: touch.has-hover ? Theme.bg-hover : transparent; animate background { duration: 120ms; } Text { width: parent.width; height: parent.height; text: glyph; color: touch.has-hover ? fg-hover : fg; font-size: Theme.fs-md; horizontal-alignment: center; vertical-alignment: center; } touch := TouchArea { mouse-cursor: pointer; clicked => { root.clicked(); } } } // --- PrimaryButton --------------------------------------------------------- export component PrimaryButton inherits Rectangle { in property text; in property disabled: false; callback clicked(); height: 30px; min-width: 80px; border-radius: Theme.radius-sm; background: disabled ? Theme.bg-elevated : (touch.pressed ? Theme.accent-pressed : (touch.has-hover ? Theme.accent-hover : Theme.accent)); animate background { duration: 120ms; } HorizontalLayout { height: parent.height; padding-left: 14px; padding-right: 14px; alignment: center; Text { height: parent.height; text: root.text; color: disabled ? Theme.text-muted : white; font-size: Theme.fs-md; font-weight: 600; horizontal-alignment: center; vertical-alignment: center; } } touch := TouchArea { enabled: !disabled; mouse-cursor: disabled ? default : pointer; clicked => { root.clicked(); } } } // --- GhostButton ----------------------------------------------------------- export component GhostButton inherits Rectangle { in property text; callback clicked(); height: 30px; min-width: 80px; border-radius: Theme.radius-sm; border-width: 1px; border-color: touch.has-hover ? Theme.border-strong : Theme.border-subtle; background: touch.pressed ? Theme.bg-active : (touch.has-hover ? Theme.bg-hover : Theme.bg-panel); animate background, border-color { duration: 120ms; } HorizontalLayout { height: parent.height; padding-left: 14px; padding-right: 14px; alignment: center; Text { height: parent.height; text: root.text; color: Theme.text-primary; font-size: Theme.fs-md; horizontal-alignment: center; vertical-alignment: center; } } touch := TouchArea { mouse-cursor: pointer; clicked => { root.clicked(); } } } // --- LabeledInput ---------------------------------------------------------- export component LabeledInput inherits VerticalLayout { in property label; in property placeholder; in-out property value; in property password: false; spacing: 4px; Text { text: label; color: Theme.text-secondary; font-size: Theme.fs-sm; } Rectangle { height: 32px; border-radius: Theme.radius-sm; border-width: 1px; border-color: input.has-focus ? Theme.accent : Theme.border-subtle; background: Theme.bg-root; input := TextInput { x: 10px; y: 0px; width: parent.width - 20px; height: parent.height; text <=> root.value; color: Theme.text-primary; font-size: Theme.fs-md; vertical-alignment: center; single-line: true; input-type: root.password ? InputType.password : InputType.text; } // Lightweight placeholder — shown when value is empty. if value == "" : Text { x: 10px; y: 0px; height: parent.height; text: placeholder; color: Theme.text-muted; font-size: Theme.fs-md; vertical-alignment: center; } } } // --- Sparkline ------------------------------------------------------------- // Compact horizontal bar chart used in the stats sidebar. export component Sparkline inherits Rectangle { in property <[float]> values; in property line-color: Theme.accent; background: Theme.bg-root; border-radius: Theme.radius-sm; clip: true; for v[i] in values : Rectangle { x: i * (parent.width / max(1, values.length)); y: parent.height - (parent.height * clamp(v, 0.0, 1.0)); width: (parent.width / max(1, values.length)) - 1px; height: parent.height * clamp(v, 0.0, 1.0); background: line-color.with-alpha(0.85); border-radius: 1px; } }