From 2ba2b51c516ab32ee37515da11f277d564fcd24b Mon Sep 17 00:00:00 2001 From: Daniel Saidi Date: Mon, 4 Mar 2024 14:09:49 +0100 Subject: [PATCH] Use view extensions to configure and style the text editor --- RELEASE_NOTES.md | 9 ++-- .../Editor/RichTextEditor+Config.swift | 40 +++++++++++++++++ .../Editor/RichTextEditor+Style.swift | 41 +++++++++++++++++ .../{ => Editor}/RichTextEditor.swift | 44 ++++++++++++------- .../RichTextKeyboardToolbar+Config.swift | 1 + .../RichTextKeyboardToolbar+Style.swift | 2 +- .../RichTextKit.docc/RichTextKit.md | 7 ++- 7 files changed, 122 insertions(+), 22 deletions(-) create mode 100644 Sources/RichTextKit/Editor/RichTextEditor+Config.swift create mode 100644 Sources/RichTextKit/Editor/RichTextEditor+Style.swift rename Sources/RichTextKit/{ => Editor}/RichTextEditor.swift (83%) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f1f75d592..76193663e 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -8,18 +8,19 @@ Until then, minor updates may remove deprecated features and introduce breaking ## 1.0 -This release removes all deprecated code and cleans up the library somewhat. +This release removes all deprecated code and cleans up the library. ### ✨ Features -* The new `richTextKeyboardToolbarConfig` view extension can be used to configure the `RichTextKeyboardToolbar`. -* The new `richTextKeyboardToolbarStyle` view extension can be used to style the `RichTextKeyboardToolbar`. +* There are new `richTextEditor` config and style view extensions. +* There are new `richTextKeyboardToolbar` config and style view extensions. ### 💥 Breaking Changes * All previously deprecated code has been deleted. -* `RichTextKeyboardToolbar` is now configured with view extensions instead of with the initializer. +* `RichTextEditor` is configured with view extensions instead of the initializer. +* `RichTextKeyboardToolbar` is configured with view extensions instead of the initializer. diff --git a/Sources/RichTextKit/Editor/RichTextEditor+Config.swift b/Sources/RichTextKit/Editor/RichTextEditor+Config.swift new file mode 100644 index 000000000..974c713a0 --- /dev/null +++ b/Sources/RichTextKit/Editor/RichTextEditor+Config.swift @@ -0,0 +1,40 @@ +// +// RichTextEditor+Config.swift +// RichTextKit +// +// Created by Daniel Saidi on 2024-02-24. +// Copyright © 2024 Daniel Saidi. All rights reserved. +// + +#if iOS || macOS || os(visionOS) +import SwiftUI + +/// This struct be used to configure a ``RichTextEditor``. +public typealias RichTextEditorConfig = RichTextView.Configuration + +public extension View { + + /// Apply a ``RichTextEditor`` configuration. + func richTextEditorConfig( + _ config: RichTextEditorConfig + ) -> some View { + self.environment(\.richTextEditorConfig, config) + } +} + +extension RichTextEditorConfig { + + struct Key: EnvironmentKey { + + public static var defaultValue: RichTextEditorConfig = .standard + } +} + +public extension EnvironmentValues { + + var richTextEditorConfig: RichTextEditorConfig { + get { self [RichTextEditorConfig.Key.self] } + set { self [RichTextEditorConfig.Key.self] = newValue } + } +} +#endif diff --git a/Sources/RichTextKit/Editor/RichTextEditor+Style.swift b/Sources/RichTextKit/Editor/RichTextEditor+Style.swift new file mode 100644 index 000000000..07981104a --- /dev/null +++ b/Sources/RichTextKit/Editor/RichTextEditor+Style.swift @@ -0,0 +1,41 @@ +// +// RichTextEditor+Style.swift +// RichTextKit +// +// Created by Ryan Jarvis on 2024-02-24. +// + + +#if iOS || macOS || os(visionOS) +import SwiftUI + +/// This struct can be used to style a ``RichTextEditor``. +public typealias RichTextEditorStyle = RichTextView.Theme + +public extension View { + + /// Apply a ``RichTextEditor`` style. + func richTextEditorStyle( + _ style: RichTextEditorStyle + ) -> some View { + self.environment(\.richTextEditorStyle, style) + } +} + +extension RichTextEditorStyle { + + struct Key: EnvironmentKey { + + static var defaultValue: RichTextEditorStyle = .standard + } +} + +public extension EnvironmentValues { + + var richTextEditorStyle: RichTextEditorStyle { + get { self [RichTextEditorStyle.Key.self] } + set { self [RichTextEditorStyle.Key.self] = newValue } + } +} + +#endif diff --git a/Sources/RichTextKit/RichTextEditor.swift b/Sources/RichTextKit/Editor/RichTextEditor.swift similarity index 83% rename from Sources/RichTextKit/RichTextEditor.swift rename to Sources/RichTextKit/Editor/RichTextEditor.swift index 729bf7946..195b52932 100644 --- a/Sources/RichTextKit/RichTextEditor.swift +++ b/Sources/RichTextKit/Editor/RichTextEditor.swift @@ -10,11 +10,11 @@ import SwiftUI /** - This SwiftUI editor can be used to view and edit rich text. + This view can be used to view and edit rich text in SwiftUI. The view uses a platform-specific ``RichTextView`` together with a ``RichTextContext`` and a ``RichTextCoordinator`` to - make view and context changes sync correctly. + keep the view and context in sync. You can use the provided context to trigger and observe any changes to the text editor. Note that changing the value of @@ -34,12 +34,25 @@ import SwiftUI } ``` - This code will not show anything when you start to edit the - text. To work around this use a ``RichTextKeyboardToolbar``. + This will not show anything. To work around this limitation, + use a ``RichTextKeyboardToolbar`` instead. - You may have noticed that `updateUIView/updateNSView` don't - contain any code. This is because having updates there will - update this view, which in turn makes typing very slow. + You can configure and style the view by applying config and + style view extensions to your view hierarchy: + + ```swift + VStack { + RichTextEditor(...) + ... + } + .richTextEditorStyle(...) + .richTextEditorConfig(...) + ``` + + For more information, see ``RichTextKeyboardToolbarConfig`` + and ``RichTextKeyboardToolbarStyle``. + + */ public struct RichTextEditor: ViewRepresentable { @@ -56,14 +69,10 @@ public struct RichTextEditor: ViewRepresentable { public init( text: Binding, context: RichTextContext, - config: RichTextView.Configuration = .standard, - theme: RichTextView.Theme = .standard, format: RichTextDataFormat = .archivedData, viewConfiguration: @escaping ViewConfiguration = { _ in } ) { self.text = text - self.config = config - self.theme = theme self._context = ObservedObject(wrappedValue: context) self.format = format self.viewConfiguration = viewConfiguration @@ -75,10 +84,14 @@ public struct RichTextEditor: ViewRepresentable { private var context: RichTextContext private var text: Binding - private let config: RichTextView.Configuration - private let theme: RichTextView.Theme private var format: RichTextDataFormat private var viewConfiguration: ViewConfiguration + + @Environment(\.richTextEditorConfig) + private var config + + @Environment(\.richTextEditorStyle) + private var style #if iOS || os(tvOS) || os(visionOS) public let textView = RichTextView() @@ -104,7 +117,7 @@ public struct RichTextEditor: ViewRepresentable { public func makeUIView(context: Context) -> some UIView { textView.setup(with: text.wrappedValue, format: format) textView.configuration = config - textView.theme = theme + textView.theme = style viewConfiguration(textView) return textView } @@ -116,7 +129,7 @@ public struct RichTextEditor: ViewRepresentable { public func makeNSView(context: Context) -> some NSView { textView.setup(with: text.wrappedValue, format: format) textView.configuration = config - textView.theme = theme + textView.theme = style viewConfiguration(textView) return scrollView } @@ -154,5 +167,4 @@ public extension RichTextEditor { textView.mutableAttributedString } } - #endif diff --git a/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar+Config.swift b/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar+Config.swift index 67432a4e2..766b8858e 100644 --- a/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar+Config.swift +++ b/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar+Config.swift @@ -3,6 +3,7 @@ // RichTextKit // // Created by Ryan Jarvis on 2024-02-24. +// Copyright © 2023-2024 Daniel Saidi. All rights reserved. // #if iOS || macOS || os(visionOS) diff --git a/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar+Style.swift b/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar+Style.swift index 7ea0b3b90..650a870d4 100644 --- a/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar+Style.swift +++ b/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar+Style.swift @@ -3,9 +3,9 @@ // RichTextKit // // Created by Ryan Jarvis on 2024-02-24. +// Copyright © 2023-2024 Daniel Saidi. All rights reserved. // - #if iOS || macOS || os(visionOS) import SwiftUI diff --git a/Sources/RichTextKit/RichTextKit.docc/RichTextKit.md b/Sources/RichTextKit/RichTextKit.docc/RichTextKit.md index ad6f577cb..a84ee6830 100644 --- a/Sources/RichTextKit/RichTextKit.docc/RichTextKit.md +++ b/Sources/RichTextKit/RichTextKit.docc/RichTextKit.md @@ -96,6 +96,11 @@ RichTextKit is available under the MIT license. See the [LICENSE][License] file - ``RichTextDataFormat`` - ``RichTextDataReader`` +### Editor + +- ``RichTextEditorConfig`` +- ``RichTextEditorStyle`` + ### Export - ``RichTextExportError`` @@ -135,7 +140,7 @@ RichTextKit is available under the MIT license. See the [LICENSE][License] file ### Keyboard - ``RichTextKeyboardToolbar`` -- ``RichTextKeyboardToolbarConfiguration`` +- ``RichTextKeyboardToolbarConfig`` - ``RichTextKeyboardToolbarMenu`` - ``RichTextKeyboardToolbarStyle``