import SwiftUI /// A reusable sheet for editing an existing word replacement entry. /// Mirrors the UI of `AddReplacementSheet` for consistency while pre-populating /// the fields with the existing values. struct EditReplacementSheet: View { @ObservedObject var manager: WordReplacementManager let originalKey: String @Environment(\.dismiss) private var dismiss @State private var originalWord: String @State private var replacementWord: String // MARK: – Initialiser init(manager: WordReplacementManager, originalKey: String) { self.manager = manager self.originalKey = originalKey _originalWord = State(initialValue: originalKey) _replacementWord = State(initialValue: manager.replacements[originalKey] ?? "") } var body: some View { VStack(spacing: 0) { header Divider() formContent } .frame(width: 460, height: 480) } // MARK: – Subviews private var header: some View { HStack { Button("Cancel", role: .cancel) { dismiss() } .buttonStyle(.borderless) .keyboardShortcut(.escape, modifiers: []) Spacer() Text("Edit Word Replacement") .font(.headline) Spacer() Button("Save") { saveChanges() } .buttonStyle(.borderedProminent) .controlSize(.small) .disabled(originalWord.isEmpty || replacementWord.isEmpty) .keyboardShortcut(.return, modifiers: []) } .padding(.horizontal) .padding(.vertical, 12) .background(CardBackground(isSelected: false)) } private var formContent: some View { ScrollView { VStack(spacing: 20) { descriptionSection inputSection } .padding(.vertical) } } private var descriptionSection: some View { Text("Update the word or phrase that should be automatically replaced during AI enhancement.") .font(.subheadline) .foregroundColor(.secondary) .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal) .padding(.top, 8) } private var inputSection: some View { VStack(spacing: 16) { // Original Text Field VStack(alignment: .leading, spacing: 6) { HStack { Text("Original Text") .font(.headline) Text("Required") .font(.caption) .foregroundColor(.secondary) } TextField("Enter word or phrase to replace", text: $originalWord) .textFieldStyle(.roundedBorder) } .padding(.horizontal) // Replacement Text Field VStack(alignment: .leading, spacing: 6) { HStack { Text("Replacement Text") .font(.headline) Text("Required") .font(.caption) .foregroundColor(.secondary) } TextEditor(text: $replacementWord) .font(.body) .frame(height: 100) .padding(8) .background(Color(.textBackgroundColor)) .cornerRadius(6) .overlay( RoundedRectangle(cornerRadius: 6) .stroke(Color(.separatorColor), lineWidth: 1) ) } .padding(.horizontal) } } // MARK: – Actions private func saveChanges() { let newOriginal = originalWord.trimmingCharacters(in: .whitespacesAndNewlines) let newReplacement = replacementWord.trimmingCharacters(in: .whitespacesAndNewlines) guard !newOriginal.isEmpty, !newReplacement.isEmpty else { return } manager.updateReplacement(oldOriginal: originalKey, newOriginal: newOriginal, newReplacement: newReplacement) dismiss() } } // MARK: – Preview #if DEBUG struct EditReplacementSheet_Previews: PreviewProvider { static var previews: some View { EditReplacementSheet(manager: WordReplacementManager(), originalKey: "hello") } } #endif