Skip to content

Commit

Permalink
Separate format toolbar from sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsaidi committed Feb 16, 2024
1 parent 931bfff commit 21ba8c3
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 74 deletions.
5 changes: 3 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ By deprecating these functions, we can simplify the library in 1.0, and focus mo
* `RichTextAction` has a new `label` property.
* `RichTextCommand.ActionButtonGroup` has new inits.
* `RichTextCommand.FormatMenu` is a lot more configurable.
* `RichTextFormatToolbar` is now available on all platforms.
* `RichTextFormatToolbar` has new configuration and style types.
* `RichTextFormatSheet` is now available on all platforms.
* `RichTextFormatSheet` has new configuration and style types.
* `RichTextFormatSidebar` has new configuration and style types.
* `RichTextFormatToolbar` is a new rich text formatting toolbar.
* `RichTextKeyboardToolbar` has a new config to always be shown.
* `RichTextStyle.Button` now supports using custom button styles.
* `RichTextView` has a new theme that lets you define its style.
Expand Down
3 changes: 2 additions & 1 deletion Sources/RichTextKit/Fonts/RichTextFont+SizePicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public extension RichTextFont {
self._selection = selection
self.values = Self.fontSizePickerSizes(
for: values,
selection: selection.wrappedValue)
selection: selection.wrappedValue
)
}

private let values: [CGFloat]
Expand Down
124 changes: 124 additions & 0 deletions Sources/RichTextKit/Format/RichTextFormatSheet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//
// RichTextFormatSheet.swift
// RichTextKit
//
// Created by Daniel Saidi on 2022-12-13.
// Copyright © 2022-2024 Daniel Saidi. All rights reserved.
//

#if iOS || macOS || os(visionOS)
import SwiftUI

/**
This sheet contains a font list picker and a bottom toolbar.

You can inject a custom toolbar configuration to adjust the
toolbar. The font picker will take up all available height.

You can style this view by applying a style anywhere in the
view hierarchy, using `.richTextFormatToolbarStyle`.
*/
public struct RichTextFormatSheet: RichTextFormatToolbarBase {

/**
Create a rich text format sheet.

- Parameters:
- context: The context to apply changes to.
- config: The configuration to use, by default `.standard`.
*/
public init(
context: RichTextContext,
config: Configuration = .standard
) {
self._context = ObservedObject(wrappedValue: context)
self.config = config
}

public typealias Configuration = RichTextFormatToolbar.Configuration

@ObservedObject
private var context: RichTextContext

let config: Configuration

@Environment(\.richTextFormatToolbarStyle)
var style

@Environment(\.dismiss)
private var dismiss

@Environment(\.horizontalSizeClass)
private var horizontalSizeClass

public var body: some View {
NavigationView {
VStack(spacing: 0) {
fontListPicker(value: $context.fontName)
RichTextFormatToolbar(
context: context,
config: config
)
}
.padding(.top, -35)
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button(RTKL10n.done.text) {
dismiss()
}
}
}
.navigationTitle("")
#if iOS
.navigationBarTitleDisplayMode(.inline)
#endif
}
#if iOS
.navigationViewStyle(.stack)
#endif
}
}

struct RichTextFormatSheet_Previews: PreviewProvider {

struct Preview: View {

@StateObject
private var context = RichTextContext()

@State
private var isSheetPresented = false

var body: some View {
VStack(spacing: 0) {
Color.red
Button("Toggle sheet") {
isSheetPresented.toggle()
}
}
.sheet(isPresented: $isSheetPresented) {
RichTextFormatSheet(
context: context,
config: .init(
alignments: .all,
colorPickers: [.foreground, .background],
colorPickersDisclosed: [.stroke],
fontPicker: true,
fontSizePicker: true,
indentButtons: true,
styles: .all
)
)
}
.richTextFormatToolbarStyle(.init(
padding: 10,
spacing: 10
))
}
}

static var previews: some View {
Preview()
}
}
#endif
4 changes: 4 additions & 0 deletions Sources/RichTextKit/Format/RichTextFormatSidebar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import SwiftUI
/**
This sidebar view provides various text format options, and
is meant to be used on macOS, in a trailing sidebar.

You can provide custom configurations to adjust the toolbar
and style it by applying a `.richTextFormatToolbarStyle` to
the view hierarchy.

> Note: The sidebar is currently designed for macOS, but it
should also be made to look good on iPadOS in landscape, to
Expand Down
6 changes: 0 additions & 6 deletions Sources/RichTextKit/Format/RichTextFormatToolbar+Style.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,16 @@ import SwiftUI
public extension RichTextFormatToolbar {

/// This struct can be used to style a format sheet.
///
/// Don't specify a font picker height if the toolbar is
/// used in a sheet. Use detents to the toolbar's height.
struct Style {

public init(
fontPickerHeight: CGFloat? = nil,
padding: Double = 10,
spacing: Double = 10
) {
self.fontPickerHeight = fontPickerHeight
self.padding = padding
self.spacing = spacing
}

public var fontPickerHeight: CGFloat?
public var padding: Double
public var spacing: Double
}
Expand Down
75 changes: 15 additions & 60 deletions Sources/RichTextKit/Format/RichTextFormatToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ import SwiftUI
class. The control row will be split in two in compact size,
while macOS and regular sizes get a single row.

You can provide a custom configuration to adjust the format
options. The font picker will take up all available height.

You can style this view by applying a style anywhere in the
view hierarchy, using `.richTextFormatToolbarStyle`.
You can provide custom configurations to adjust the toolbar
and style it by applying a `.richTextFormatToolbarStyle` to
the view hierarchy.
*/
public struct RichTextFormatToolbar: RichTextFormatToolbarBase {

Expand Down Expand Up @@ -51,45 +49,6 @@ public struct RichTextFormatToolbar: RichTextFormatToolbarBase {
private var horizontalSizeClass

public var body: some View {
VStack(spacing: 0) {
fontListPicker(value: $context.fontName)
toolbar
}
}
}


#if iOS
// MARK: - Sheet

public extension RichTextFormatToolbar {

/// Convert the toolbar to a sheet, with a close button.
func asSheet(
dismiss: @escaping () -> Void
) -> some View {
NavigationView {
self
.padding(.top, -35)
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button(RTKL10n.done.text, action: dismiss)
}
}
.navigationTitle("")
.navigationBarTitleDisplayMode(.inline)
}
.navigationViewStyle(.stack)
}
}
#endif


// MARK: - Views

private extension RichTextFormatToolbar {

var toolbar: some View {
VStack(spacing: style.spacing) {
controls
if hasColorPickers {
Expand All @@ -100,7 +59,16 @@ private extension RichTextFormatToolbar {
.padding(.vertical, style.padding)
.environment(\.sizeCategory, .medium)
.background(background)
#if macOS
.frame(minWidth: 650)
#endif
}
}


// MARK: - Views

private extension RichTextFormatToolbar {

var useSingleLine: Bool {
#if macOS
Expand Down Expand Up @@ -138,6 +106,9 @@ private extension RichTextFormatToolbar {
@ViewBuilder
var controlsContent: some View {
HStack {
#if macOS
fontPicker(value: $context.fontName)
#endif
styleToggleGroup(for: context)
if !useSingleLine {
Spacer()
Expand All @@ -161,9 +132,6 @@ struct RichTextFormatToolbar_Previews: PreviewProvider {

@StateObject
private var context = RichTextContext()

@State
private var isSheetPresented = false

var toolbar: RichTextFormatToolbar {
.init(
Expand All @@ -183,22 +151,9 @@ struct RichTextFormatToolbar_Previews: PreviewProvider {
var body: some View {
VStack(spacing: 0) {
Color.red
Button("Toggle sheet") {
isSheetPresented.toggle()
}
toolbar
}
.sheet(isPresented: $isSheetPresented) {
toolbar
#if iOS
.asSheet { isSheetPresented = false }
#endif
.richTextFormatToolbarStyle(.init(
fontPickerHeight: nil
))
}
.richTextFormatToolbarStyle(.init(
fontPickerHeight: 100,
padding: 10,
spacing: 10
))
Expand Down
1 change: 0 additions & 1 deletion Sources/RichTextKit/Format/RichTextFormatToolbarBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ extension RichTextFormatToolbarBase {
) -> some View {
if config.fontPicker {
RichTextFont.ListPicker(selection: value)
.frame(height: style.fontPickerHeight)
Divider()
}
}
Expand Down
1 change: 1 addition & 0 deletions Sources/RichTextKit/RichTextKit.docc/RichTextKit.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ RichTextKit is available under the MIT license. See the [LICENSE][License] file

### Format

- ``RichTextFormatSheet``
- ``RichTextFormatSidebar``
- ``RichTextFormatToolbar``

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
#if iOS || macOS || os(visionOS)
import SwiftUI

@available(*, deprecated, renamed: "RichTextFormatToolbar")
public typealias RichTextFormatSheet = RichTextFormatToolbar

public extension RichTextFormatToolbar {
public extension RichTextFormatSheet {

@available(*, deprecated, message: "Use the config initializer instead.")
init(
Expand Down

0 comments on commit 21ba8c3

Please sign in to comment.