import { Colors, Spacing, Type, FluentIcons } from "../tokens/theme.slint";
import { Sizes } from "../tokens/sizes.slint";
// TreeViewNode — a single tree node row with expand toggle, icon, and label.
/// T re ev ie wn od e component.
export component TreeViewNode inherits Rectangle {
/// Input property "node-id".
in property <string> node-id;
/// Input property "label".
in property <string> label;
/// Input property "icon".
in property <string> icon;
/// Input property "level".
in property <int> level;
/// Input property "expanded".
in property <bool> expanded;
/// Input property "leaf".
in property <bool> leaf;
/// Input property "is-selected".
in property <bool> is-selected: false;
/// Callback fired for s el ec te d.
callback selected();
/// Callback fired for t og gl e e xp an de d.
callback toggle-expanded();
height: Spacing.xl;
background: root.is-selected ? Colors.accent :
node-ta.has-hover ? Colors.bg-elevated : transparent;
HorizontalLayout {
padding-left: root.level * Spacing.lg;
spacing: Spacing.xs;
alignment: start;
// Expand/collapse toggle
if !root.leaf: Rectangle {
width: Spacing.md;
height: Spacing.md;
background: transparent;
Text {
text: root.expanded ? "\u{25BC}" : "\u{25B6}";
font-size: Type.caption-size;
color: root.is-selected
? Colors.accent-text : Colors.text-secondary;
horizontal-alignment: center;
vertical-alignment: center;
}
expand-ta := TouchArea {
clicked => { root.toggle-expanded(); }
}
}
// Spacer for leaf nodes (alignment)
if root.leaf: Rectangle {
width: Spacing.md;
background: transparent;
}
// Icon
if root.icon != "": Text {
text: root.icon;
font-family: FluentIcons.icon-font;
font-size: Type.body-size;
color: root.is-selected
? Colors.accent-text : Colors.text-secondary;
vertical-alignment: center;
}
// Label
Text {
text: root.label;
font-size: Type.body-size;
color: root.is-selected
? Colors.accent-text : Colors.text-primary;
vertical-alignment: center;
horizontal-stretch: Sizes.one;
}
}
node-ta := TouchArea {
clicked => { root.selected(); }
}
}