pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import QtQuick.Templates import Quickshell import ZShell.Config import qs.Components import qs.Services Item { id: root readonly property alias count: bar.count required property PersistentProperties dashState required property real nonAnimWidth implicitHeight: bar.implicitHeight + indicator.implicitHeight + indicator.anchors.topMargin + separator.implicitHeight TabBar { id: bar anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top background: null currentIndex: root.dashState.currentTab implicitHeight: contentHeight contentItem: RowLayout { spacing: 0 Repeater { model: bar.contentModel } } onCurrentIndexChanged: root.state.currentTab = currentIndex Tab { iconName: "notifications" text: qsTr("Notifications") } Tab { iconName: "chat" text: qsTr("Chat") } } Item { id: indicator anchors.top: bar.bottom clip: true implicitHeight: 3 implicitWidth: bar.currentItem.implicitWidth x: { const tab = bar.currentItem; const width = (root.nonAnimWidth - bar.spacing * (bar.count - 1)) / bar.count; return width * tab.TabBar.index + (width - tab.implicitWidth) / 2; } Behavior on implicitWidth { Anim { } } Behavior on x { Anim { } } CustomRect { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top color: Colors.palette.m3primary implicitHeight: parent.implicitHeight * 2 radius: Tokens.rounding.full } } CustomRect { id: separator anchors.left: parent.left anchors.right: parent.right anchors.top: indicator.bottom color: Colors.palette.m3outlineVariant implicitHeight: 1 } component Tab: TabButton { id: tab readonly property bool current: TabBar.tabBar.currentItem === this required property string iconName Layout.fillWidth: true Layout.preferredWidth: 1 background: null implicitHeight: implicitContentHeight implicitWidth: implicitContentWidth contentItem: Item { implicitHeight: icon.height + label.height implicitWidth: Math.max(icon.width, label.width) StateLayer { color: tab.current ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface radius: Tokens.rounding.small onClicked: root.dashState.currentTab = tab.TabBar.index } MaterialIcon { id: icon anchors.bottom: label.top anchors.horizontalCenter: parent.horizontalCenter color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant fill: tab.current ? 1 : 0 font.pointSize: 18 text: tab.iconName Behavior on fill { Anim { } } } CustomText { id: label anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant text: tab.text } } } }