NTagFilter: created

TemplateSubTab: use NTagFilter
AvailableSubTab: use NTagFilter
This commit is contained in:
Ly-sec
2026-01-15 14:30:43 +01:00
parent 5b50a0b426
commit 662154f390
3 changed files with 65 additions and 64 deletions
@@ -173,41 +173,13 @@ ColumnLayout {
}
// Category filter chips
NCollapsible {
Layout.fillWidth: true
NTagFilter {
tags: root.availableCategories
selectedTag: root.selectedCategory
onSelectedTagChanged: root.selectedCategory = selectedTag
label: I18n.tr("panels.color-scheme.templates-filter-label")
description: I18n.tr("panels.color-scheme.templates-filter-description")
expanded: true
contentSpacing: Style.marginXS
Flow {
Layout.fillWidth: true
spacing: Style.marginXS
flow: Flow.LeftToRight
Repeater {
model: [""].concat(root.availableCategories)
delegate: NButton {
text: {
if (modelData === "")
return I18n.tr("launcher.categories.all");
// Special case for UI to keep it uppercase
if (modelData === "system")
return "System";
// Capitalize first letter for others
return modelData.charAt(0).toUpperCase() + modelData.slice(1);
}
backgroundColor: root.selectedCategory === modelData ? Color.mPrimary : Color.mSurfaceVariant
textColor: root.selectedCategory === modelData ? Color.mOnPrimary : Color.mOnSurfaceVariant
onClicked: root.selectedCategory = modelData
fontSize: Style.fontSizeS
iconSize: Style.fontSizeS
fontWeight: Style.fontWeightSemiBold
buttonRadius: Style.iRadiusM
}
}
}
}
// Search/filter input row
@@ -17,7 +17,7 @@ ColumnLayout {
property int availablePluginsRefreshCounter: 0
// Pseudo tags for filtering by download status
readonly property var pseudoTags: ["", "downloaded", "notDownloaded"]
readonly property var pseudoTags: ["downloaded", "notDownloaded"]
readonly property var availableTags: {
// Reference counter to force re-evaluation
@@ -44,41 +44,22 @@ ColumnLayout {
}
// Tag filter chips in collapsible
NCollapsible {
Layout.fillWidth: true
NTagFilter {
tags: root.pseudoTags.concat(root.availableTags)
selectedTag: root.selectedTag
onSelectedTagChanged: root.selectedTag = selectedTag
label: I18n.tr("panels.plugins.filter-tags-label")
description: I18n.tr("panels.plugins.filter-tags-description")
expanded: true
contentSpacing: Style.marginXS
Flow {
Layout.fillWidth: true
spacing: Style.marginXS
flow: Flow.LeftToRight
Repeater {
id: tagRepeater
model: root.pseudoTags.concat(root.availableTags)
delegate: NButton {
text: {
if (modelData === "")
return I18n.tr("launcher.categories.all");
if (modelData === "downloaded")
return I18n.tr("panels.plugins.filter-downloaded");
if (modelData === "notDownloaded")
return I18n.tr("panels.plugins.filter-not-downloaded");
return modelData;
}
backgroundColor: root.selectedTag === modelData ? Color.mPrimary : Color.mSurfaceVariant
textColor: root.selectedTag === modelData ? Color.mOnPrimary : Color.mOnSurfaceVariant
onClicked: root.selectedTag = modelData
fontSize: Style.fontSizeS
iconSize: Style.fontSizeS
fontWeight: Style.fontWeightSemiBold
buttonRadius: Style.iRadiusM
}
}
formatTag: function (tag) {
if (tag === "")
return I18n.tr("launcher.categories.all");
if (tag === "downloaded")
return I18n.tr("panels.plugins.filter-downloaded");
if (tag === "notDownloaded")
return I18n.tr("panels.plugins.filter-not-downloaded");
return tag;
}
}
+48
View File
@@ -0,0 +1,48 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Widgets
NCollapsible {
id: root
// Public API
property var tags: [] // Array of tag strings
property string selectedTag: ""
property alias label: root.label
property alias description: root.description
property alias expanded: root.expanded
// Formatting function for tag display (optional override)
property var formatTag: function (tag) {
if (tag === "")
return I18n.tr("launcher.categories.all");
// Default: capitalize first letter
return tag.charAt(0).toUpperCase() + tag.slice(1);
}
Layout.fillWidth: true
contentSpacing: Style.marginXS
Flow {
Layout.fillWidth: true
spacing: Style.marginXS
flow: Flow.LeftToRight
Repeater {
model: [""].concat(root.tags)
delegate: NButton {
text: root.formatTag(modelData)
backgroundColor: root.selectedTag === modelData ? Color.mPrimary : Color.mSurfaceVariant
textColor: root.selectedTag === modelData ? Color.mOnPrimary : Color.mOnSurfaceVariant
onClicked: root.selectedTag = modelData
fontSize: Style.fontSizeS
iconSize: Style.fontSizeS
fontWeight: Style.fontWeightSemiBold
buttonRadius: Style.iRadiusM
}
}
}
}