import SwiftUI /// A single-`TextField` alert — the "name a new thing" prompt shared by New Board, New Lane, and /// New Card, so each toolbar button does not grow its own `@State` pair and `.alert` block. private struct TitlePromptAlert: ViewModifier { @Binding var isPresented: Bool let titleText: String let message: String? let placeholder: String let onSubmit: (String) -> Void @State private var text = "" func body(content: Content) -> some View { content.alert(titleText, isPresented: $isPresented) { TextField(placeholder, text: $text) Button("Create") { let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines) text = "" onSubmit(trimmed) } Button("Cancel", role: .cancel) { text = "" } } message: { if let message { Text(message) } } } } extension View { /// Presents a title-only creation prompt. `onSubmit` receives the trimmed text, which may be /// empty — every create call this feeds (`BoardIndexStore.createBoard`, `BoardWriter.createLane`, /// `BoardWriter.createCard`) already treats an empty/whitespace title as "no title" and falls /// back to the untitled placeholder, exactly as a hand-emptied field would. func titlePromptAlert( _ titleText: String, isPresented: Binding, message: String? = nil, placeholder: String = "Title", onSubmit: @escaping (String) -> Void ) -> some View { modifier(TitlePromptAlert( isPresented: isPresented, titleText: titleText, message: message, placeholder: placeholder, onSubmit: onSubmit )) } }