// // AppSelectionSheet.swift // Severed // import FamilyControls import SwiftUI /// App/category/website selection wrapping Apple's `FamilyActivityPicker`, /// presented as a plain sheet with a segmented Block / Allow Only control. struct AppSelectionSheet: View { @Binding var draft: RuleDraft @Environment(\.dismiss) private var dismiss @State private var selection: FamilyActivitySelection @State private var mode: SelectionMode init(draft: Binding) { self._draft = draft self._selection = State( initialValue: AppSelectionCodec.decode(draft.wrappedValue.selectionData) ) self._mode = State(initialValue: draft.wrappedValue.selectionMode) } var body: some View { NavigationStack { VStack(spacing: 0) { Picker("Mode", selection: $mode) { ForEach(SelectionMode.allCases, id: \.self) { mode in Text(mode.displayName).tag(mode) } } .pickerStyle(.segmented) .padding(.horizontal) .padding(.vertical, 8) .accessibilityIdentifier("selectionModePicker") FamilyActivityPicker(selection: $selection) } .navigationTitle("Selected") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Cancel") { dismiss() } .accessibilityIdentifier("selectionBackButton") } ToolbarItem(placement: .confirmationAction) { Button("Done") { save() } .accessibilityIdentifier("confirmSelectionButton") } } .safeAreaInset(edge: .bottom) { VStack(spacing: 8) { Text(selectionSummary) .font(.footnote) .foregroundStyle(.secondary) .accessibilityIdentifier("selectionCountLabel") Button { save() } label: { Text("Save") .frame(maxWidth: .infinity) } .buttonStyle(.borderedProminent) .controlSize(.large) .accessibilityIdentifier("saveSelectionButton") } .padding(.horizontal) .padding(.bottom, 8) } } } private var selectionSummary: String { let count = AppSelectionCodec.count(of: selection) return count == 1 ? "1 App Selected" : "\(count) Apps Selected" } private func save() { draft.selectionData = AppSelectionCodec.encode(selection) draft.selectionCount = AppSelectionCodec.count(of: selection) draft.selectionMode = mode dismiss() } }