import { Theme, SpacingSystem, Typography, Animations } from "../theme/theme.slint"; export struct TabItem { title: string, } export component Tabs { in property <[TabItem]> tabs: []; in-out property current-index: 0; callback tab-changed(int); min-height: 200px; VerticalLayout { spacing: SpacingSystem.spacing.s2; // Tab List tab-list := HorizontalLayout { height: 36px; spacing: 0; Rectangle { background: Theme.colors.muted; border-radius: SpacingSystem.radius.lg; padding: 3px; HorizontalLayout { spacing: 0; padding: 0; for tab[index] in root.tabs: TabTrigger { text: tab.title; active: index == root.current-index; clicked => { root.current-index = index; root.tab-changed(index); } } } } } // Tab Content Area content-area := Rectangle { // Content will be provided by @children in parent component @children } } } component TabTrigger { in property text: ""; in property active: false; callback clicked(); private property hovered: false; min-width: 60px; height: 30px; states [ active when root.active: { container.background: Theme.colors.background; label.color: Theme.colors.foreground; container.border-color: Theme.colors.input; } inactive when !root.active: { container.background: transparent; label.color: Theme.colors.muted-foreground; container.border-color: transparent; } hovered when root.hovered && !root.active: { label.color: Theme.colors.foreground; } ] container := Rectangle { border-radius: SpacingSystem.radius.md; background: transparent; border-width: 1px; border-color: transparent; drop-shadow-blur: root.active ? 2px : 0; drop-shadow-color: root.active ? #00000010 : transparent; drop-shadow-offset-y: root.active ? 1px : 0; animate background { duration: Animations.durations.fast; } animate border-color { duration: Animations.durations.fast; } label := Text { text: root.text; color: Theme.colors.muted-foreground; font-size: Typography.sizes.sm; font-weight: Typography.weights.medium; horizontal-alignment: center; vertical-alignment: center; animate color { duration: Animations.durations.fast; } } } touch := TouchArea { clicked => { root.clicked(); } moved => { root.hovered = self.has-hover; } } } // TabContent component for wrapping content export component TabContent { in property index: 0; in property current-index: 0; visible: root.index == root.current-index; VerticalLayout { @children } }