import SwiftUI /// A view modifier that clears text and removes focus when return is pressed on empty content. /// /// This modifier monitors text changes and provides smart handling of newlines: /// - Empty text is allowed normally /// - Newlines at the end of whitespace-only text clear the field and remove focus /// - Multi-line content with actual text is preserved normally struct OnEmptyNewlineResignFocusModifier: ViewModifier { // MARK: Properties /// Binding to the text being edited. @Binding private var text: String /// Binding to the focus state. private let focusState: FocusState.Binding // MARK: Initializers /// Creates a modifier that clears text on empty newline. /// /// - Parameters: /// - text: A binding to the text being edited. /// - focusState: A binding to the focus state. init( text: Binding, focusState: FocusState.Binding ) { self._text = text self.focusState = focusState } // MARK: Body /// The content and behavior of the view modifier. func body(content: Content) -> some View { content .onChange(of: text) { oldValue, newValue in guard newValue.isEmpty == false else { return } if newValue.last == .newline { if newValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { text = "" focusState.wrappedValue = nil } } } } } // MARK: - View Extension extension View { /// Clears the text and removes focus when return is pressed on empty content. /// /// This modifier allows users to dismiss an optional text field by pressing return /// when the field is empty or contains only whitespace. Multi-line content is preserved normally. /// /// - Parameters: /// - focusState: A binding to the focus state. /// - text: A binding to the text being edited. /// - Returns: A modified view with clear-on-empty behavior. func onEmptyNewlineResignFocus( text: Binding, from focusState: FocusState.Binding ) -> some View { modifier( OnEmptyNewlineResignFocusModifier( text: text, focusState: focusState ) ) } }