diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/PlaceholderTextEditor/PlaceholderTextEditor.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/PlaceholderTextEditor/PlaceholderTextEditor.swift new file mode 100644 index 0000000..1fddfe3 --- /dev/null +++ b/Packages/DesignSystem/Sources/DesignSystem/Views/PlaceholderTextEditor/PlaceholderTextEditor.swift @@ -0,0 +1,74 @@ +import SwiftUI + +/// A text editor with placeholder text support. +/// +/// `PlaceholderTextEditor` extends the standard `TextEditor` by adding placeholder text +/// that appears when the editor is empty. The placeholder text is displayed in a secondary +/// color and automatically disappears when the user begins typing. +public struct PlaceholderTextEditor: View { + + // MARK: - Properties + + private let placeholder: String + private var text: Binding + private var help: String + + // MARK: - Lifecycle + + /// Creates a text editor with placeholder support. + /// + /// - Parameters: + /// - placeholder: The text to display when the editor is empty. + /// - text: A binding to the text being edited. + /// - help: The help text displayed on hover. + public init( + placeholder: String, + text: Binding, + help: String + ) { + self.placeholder = placeholder + self.text = text + self.help = help + } + + // MARK: - Public + + public var body: some View { + ZStack(alignment: .topLeading) { + TextEditor(text: text) + .autocorrectionDisabled(false) + .font(.body.monospaced()) + .textEditorCard() + .help(help) + + if text.wrappedValue.isEmpty { + Text(placeholder) + .foregroundColor(.secondary) + .font(.body.monospaced()) + .padding(.vertical, 8) + .padding(.horizontal, 13) + .allowsHitTesting(false) + } + } + } +} + +// MARK: - Preview + +#Preview("Without Content") { + PlaceholderTextEditor( + placeholder: "Caption", + text: .constant(""), + help: "Add a caption for your image" + ) + .frame(width: 400) +} + +#Preview("With Content") { + PlaceholderTextEditor( + placeholder: "Alt text", + text: .constant("Photo of a beautiful beach on a sunny day"), + help: "Add descriptive alt text for accessibility" + ) + .frame(width: 400) +} diff --git a/Packages/Pics/Sources/Pics/Views/Edit Picture/EditPictureView.swift b/Packages/Pics/Sources/Pics/Views/Edit Picture/EditPictureView.swift index 5ebf9b4..627e21b 100644 --- a/Packages/Pics/Sources/Pics/Views/Edit Picture/EditPictureView.swift +++ b/Packages/Pics/Sources/Pics/Views/Edit Picture/EditPictureView.swift @@ -44,17 +44,17 @@ struct EditPictureView: View { @ViewBuilder private func makeEditorView() -> some View { VStack { - TextField("Caption", text: $viewModel.caption) - .autocorrectionDisabled(false) - .font(.body.monospaced()) - .textFieldCard() - .help("Add a caption for your image") + PlaceholderTextEditor( + placeholder: "Caption", + text: $viewModel.caption, + help: "Add a caption for your image" + ) - TextEditor(text: $viewModel.altText) - .autocorrectionDisabled(false) - .font(.body.monospaced()) - .textEditorCard() - .help("Add descriptive alt text for accessibility") + PlaceholderTextEditor( + placeholder: "Alt text", + text: $viewModel.altText, + help: "Add descriptive alt text for accessibility" + ) makeTagsView() } diff --git a/Packages/Pics/Sources/Pics/Views/Upload/UploadView.swift b/Packages/Pics/Sources/Pics/Views/Upload/UploadView.swift index 0e2ae3e..16ec9c4 100644 --- a/Packages/Pics/Sources/Pics/Views/Upload/UploadView.swift +++ b/Packages/Pics/Sources/Pics/Views/Upload/UploadView.swift @@ -123,17 +123,17 @@ struct UploadView: View { @ViewBuilder private func makeEditorView() -> some View { VStack { - TextField("Caption", text: $viewModel.caption) - .autocorrectionDisabled(false) - .font(.body.monospaced()) - .textFieldCard() - .help("Add a caption for your image") + PlaceholderTextEditor( + placeholder: "Caption", + text: $viewModel.caption, + help: "Add a caption for your image" + ) - TextEditor(text: $viewModel.altText) - .autocorrectionDisabled(false) - .font(.body.monospaced()) - .textEditorCard() - .help("Add descriptive alt text for accessibility") + PlaceholderTextEditor( + placeholder: "Alt text", + text: $viewModel.altText, + help: "Add descriptive alt text for accessibility" + ) makeTagsView() }