pragma ComponentBehavior: Bound import Quickshell import QtQuick import QtQuick.Layouts import ZShell.Config import qs.Components import qs.Services DialogRowButton { id: root required property var model property var selectedItem property var initialSelect acceptAllowed: !!selectedItem horizontalContentMargin: -Tokens.padding.extraSmall separateContent: true content: Component { ColumnLayout { VerticalFadeListView { bottomMargin: Tokens.padding.large Layout.fillHeight: true Layout.fillWidth: true model: ScriptModel { values: { const s = searchField.text; var regex = new RegExp(s, "i"); return root.model.filter(n => regex.test(n)); } } spacing: 0 topMargin: Tokens.padding.large delegate: CustomRect { id: item required property var modelData readonly property bool selected: root.selectedItem === modelData anchors.left: ListView.view.contentItem.left anchors.margins: 1 // Gets cut off for some reason without this anchors.right: ListView.view.contentItem.right color: Qt.alpha(Colors.palette.m3tertiaryContainer, selected ? 1 : 0) implicitHeight: label.implicitHeight + Tokens.padding.small * 2 radius: stateLayer.pressed ? Tokens.rounding.extraSmall : selected ? Tokens.rounding.largeIncreased : Tokens.rounding.medium Behavior on radius { Anim { type: Anim.SlowEffects } } StateLayer { id: stateLayer onClicked: root.selectedItem = item.modelData } CustomText { id: label anchors.left: parent.left anchors.margins: Tokens.padding.large anchors.right: item.selected ? checkIcon.left : parent.right anchors.rightMargin: item.selected ? Tokens.spacing.medium : anchors.margins anchors.verticalCenter: parent.verticalCenter color: item.selected ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface elide: Text.ElideRight font.pointSize: Tokens.font.size.smaller text: item.modelData } MaterialIcon { id: checkIcon anchors.margins: Tokens.padding.large anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter color: Colors.palette.m3onTertiaryContainer font.pointSize: Tokens.font.size.normal opacity: item.selected ? 1 : 0 text: "check" Behavior on opacity { Anim { type: Anim.SlowEffects } } } } } SearchBar { id: searchField Layout.fillWidth: true bg.border.color: Colors.palette.m3outlineVariant bg.color: Colors.tPalette.m3surfaceContainerLowest clearIcon.font.pointSize: Tokens.font.size.large clearIcon.padding: Tokens.padding.extraSmall font.pointSize: Tokens.font.size.small placeholderText: qsTr("Search...") searchIcon.anchors.leftMargin: Tokens.padding.large searchIcon.font.pointSize: Tokens.font.size.large Behavior on bg.border.color { CAnim {} } } } } onOpenChanged: { if (open) { root.rootParent.interactive = false; if (!initialSelect) selectedItem = null; else selectedItem = initialSelect; } else { root.rootParent.interactive = true; } } }