From 9bce899f7ac716fb6de73450dca6fb84c11d7834 Mon Sep 17 00:00:00 2001 From: Daniel Saidi Date: Thu, 15 Feb 2024 14:35:51 +0100 Subject: [PATCH] Rename format sheet and add configuration --- RELEASE_NOTES.md | 7 +- .../Format/RichTextFormatSheet.swift | 117 ++++++++++++------ .../Keyboard/RichTextKeyboardToolbar.swift | 12 +- .../RichTextFormatSheet+Deprecated.swift | 17 +++ 4 files changed, 105 insertions(+), 48 deletions(-) create mode 100644 Sources/RichTextKit/_Deprecated/RichTextFormatSheet+Deprecated.swift diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e0d69b926..4c5225db0 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -20,8 +20,10 @@ By deprecating these functions, we can simplify the library in 1.0, and focus mo * `FontRepresentable` has new extensions. * `RichTextAction` has a new `label` property. -* `RichTextCommand.ActionButtonGroup` has many new initializers. -* `RichTextCommand.FormatMenu` is more configurable than before. +* `RichTextCommand.ActionButtonGroup` has new inits. +* `RichTextCommand.FormatMenu` is a lot more configurable. +* `RichTextFormatToolbar` is now available on all platforms. +* `RichTextFormatToolbar` now has a custom configuration type. * `RichTextKeyboardToolbar` has a new config to always be shown. * `RichTextView` has a new theme that lets you define its style. * `RichTextViewComponent` has a new `hasRichTextStyle` function. @@ -55,6 +57,7 @@ By deprecating these functions, we can simplify the library in 1.0, and focus mo * `RichTextContext` replaces individual styles with a single `styles`. * `RichTextContext` `userActionPublisher` is renamed to `actionPublisher`. * `RichTextCoordinator` functions calling `handle(_:)` have been deprecated. +* `RichTextFormatSheet` has been renamed to `RichTextFormatToolbar`. * `RTKL10n.bundle` has been deprecated since we can use the `.module` bundle. ### 💥 Breaking Changes diff --git a/Sources/RichTextKit/Format/RichTextFormatSheet.swift b/Sources/RichTextKit/Format/RichTextFormatSheet.swift index 84d93f77d..6a277e9ce 100644 --- a/Sources/RichTextKit/Format/RichTextFormatSheet.swift +++ b/Sources/RichTextKit/Format/RichTextFormatSheet.swift @@ -3,34 +3,37 @@ // RichTextKit // // Created by Daniel Saidi on 2022-12-13. -// Copyright © 2022-2023 Daniel Saidi. All rights reserved. +// Copyright © 2022-2024 Daniel Saidi. All rights reserved. // -#if iOS || os(visionOS) import SwiftUI /** - This sheet view provides different text format options, and - is meant to be used on iOS, where space is limited. - - The font picker will take up as much height as it can after - the other rows have allocated their height. + This toolbar provides different text format options, and is + meant to be used on iOS, where space is limited. + + Consider presenting this view from the bottom in a way that + doesn't cause the underlying text view to dim. + + You can provide a custom configuration to adjust the format + options that are presented. When presented, the font picker + will take up the available vertical height. */ -public struct RichTextFormatSheet: View { +public struct RichTextFormatToolbar: View { /** Create a rich text format sheet. - Parameters: - context: The context to apply changes to. - - colorPickers: The color pickers to use, by default `.foreground` and `.background`. + - config: The configuration to use, by default `.standard`. */ public init( context: RichTextContext, - colorPickers: [RichTextColor] = [.foreground, .background] + config: Configuration = .standard ) { self._context = ObservedObject(wrappedValue: context) - self.colorPickers = colorPickers + self.config = config } @ObservedObject @@ -45,16 +48,13 @@ public struct RichTextFormatSheet: View { /// The sheet top offset. public var topOffset = -35.0 - /// The color pickers to use. - public var colorPickers: [RichTextColor] + /// The configuration to use. + private let config: Configuration public var body: some View { NavigationView { VStack(spacing: 0) { - RichTextFont.ListPicker(selection: $context.fontName) - .offset(y: topOffset) - .padding(.bottom, topOffset) - Divider() + fontPicker VStack(spacing: padding) { VStack { fontRow @@ -62,7 +62,7 @@ public struct RichTextFormatSheet: View { Divider() }.padding(.horizontal, padding) VStack(spacing: padding) { - ForEach(colorPickers) { + ForEach(config.colorPickers) { RichTextColor.Picker( type: $0, value: context.binding(for: $0), @@ -88,40 +88,63 @@ public struct RichTextFormatSheet: View { } .navigationTitle("") .navigationBarTitleDisplayMode(.inline) - }.navigationViewStyle(.stack) - } -} - -private extension RichTextFormatSheet { - - var fontRow: some View { - HStack { - styleButtons - Spacer() - RichTextFont.SizePickerStack(context: context) - .buttonStyle(.bordered) } + .navigationViewStyle(.stack) } +} - var paragraphRow: some View { - HStack { - RichTextAlignment.Picker(selection: $context.textAlignment) - .pickerStyle(.segmented) - Spacer() - indentButtons +public extension RichTextFormatToolbar { + + /// This struct can be used to configure a format sheet. + struct Configuration { + + public init( + colorPickers: [RichTextColor] = [.foreground], + fontPicker: Bool = true + ) { + self.colorPickers = colorPickers + self.fontPicker = fontPicker } + + public var colorPickers: [RichTextColor] + public var fontPicker: Bool } } -private extension RichTextFormatSheet { +public extension RichTextFormatToolbar.Configuration { + + /// The standard rich text format toolbar configuration. + static var standard = Self.init() +} +private extension RichTextFormatToolbar { + var background: some View { Color.clear .overlay(Color.primary.opacity(0.1)) .shadow(color: .black.opacity(0.1), radius: 5) .edgesIgnoringSafeArea(.all) } + + @ViewBuilder + var fontPicker: some View { + if config.fontPicker { + RichTextFont.ListPicker(selection: $context.fontName) + .offset(y: topOffset) + .padding(.bottom, topOffset) + Divider() + } + } + var fontRow: some View { + HStack { + styleButtons + Spacer() + RichTextFont.SizePickerStack(context: context) + .buttonStyle(.bordered) + } + } + @ViewBuilder var indentButtons: some View { RichTextAction.ButtonGroup( @@ -131,6 +154,15 @@ private extension RichTextFormatSheet { ) } + var paragraphRow: some View { + HStack { + RichTextAlignment.Picker(selection: $context.textAlignment) + .pickerStyle(.segmented) + Spacer() + indentButtons + } + } + @ViewBuilder var styleButtons: some View { RichTextStyle.ToggleGroup( @@ -151,7 +183,7 @@ private extension View { } } -struct RichTextFormatSheet_Previews: PreviewProvider { +struct RichTextFormatToolbar_Previews: PreviewProvider { struct Preview: View { @@ -159,7 +191,13 @@ struct RichTextFormatSheet_Previews: PreviewProvider { private var context = RichTextContext() var body: some View { - RichTextFormatSheet(context: context) + RichTextFormatToolbar( + context: context, + config: .init( + colorPickers: [.foreground], + fontPicker: false + ) + ) } } @@ -167,4 +205,3 @@ struct RichTextFormatSheet_Previews: PreviewProvider { Preview() } } -#endif diff --git a/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar.swift b/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar.swift index cfca1675d..04c51580f 100644 --- a/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar.swift +++ b/Sources/RichTextKit/Keyboard/RichTextKeyboardToolbar.swift @@ -48,7 +48,7 @@ public struct RichTextKeyboardToolbar LeadingButtons, @ViewBuilder trailingButtons: @escaping () -> TrailingButtons, - @ViewBuilder richTextFormatSheet: @escaping (RichTextFormatSheet) -> FormatSheet + @ViewBuilder richTextFormatSheet: @escaping (RichTextFormatToolbar) -> FormatSheet ) { self._context = ObservedObject(wrappedValue: context) self.leadingActions = leadingActions @@ -81,7 +81,7 @@ public struct RichTextKeyboardToolbar LeadingButtons, @ViewBuilder trailingButtons: @escaping () -> TrailingButtons - ) where FormatSheet == RichTextFormatSheet { + ) where FormatSheet == RichTextFormatToolbar { self.init( context: context, style: style, @@ -111,7 +111,7 @@ public struct RichTextKeyboardToolbar LeadingButtons private let trailingButtons: () -> TrailingButtons - private let richTextFormatSheet: (RichTextFormatSheet) -> FormatSheet + private let richTextFormatSheet: (RichTextFormatToolbar) -> FormatSheet @ObservedObject private var context: RichTextContext @@ -143,7 +143,7 @@ public struct RichTextKeyboardToolbar