import SwiftUI import KeeVaultCore struct GroupFilterView: View { @ObservedObject var vm: GroupFilterViewModel let rootGroup: KeeVaultCore.Group var body: some View { List { if !vm.selectedGroupIds.isEmpty { Button("Clear Filter", action: vm.clear) } GroupFilterNode(group: rootGroup, vm: vm) } .scrollContentBackground(.hidden) .background(Color("VaultBackground")) .navigationTitle("Groups") } } private struct GroupFilterNode: View { let group: KeeVaultCore.Group @ObservedObject var vm: GroupFilterViewModel var depth: Int = 0 var body: some View { // A plain SwiftUI.Group (not a container view) flattens its children into // separate List rows, so the whole subtree renders always-expanded -- // no DisclosureGroup, no tap-to-reveal -- active filters are visible at a glance. SwiftUI.Group { row ForEach(group.subgroups) { sub in GroupFilterNode(group: sub, vm: vm, depth: depth + 1) } } } private var row: some View { Button { vm.toggle(group) } label: { HStack { Image(systemName: vm.isSelected(group) ? "checkmark.circle.fill" : "circle") .foregroundStyle(vm.isSelected(group) ? Color.accentColor : Color.secondary) Label(group.name, systemImage: "folder") } } .buttonStyle(.plain) .padding(.leading, CGFloat(depth) * 16) } }