Skip to content

Commit

Permalink
Add font picker config environment value
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsaidi committed Mar 4, 2024
1 parent 5dcb98d commit ee3134b
Show file tree
Hide file tree
Showing 15 changed files with 196 additions and 83 deletions.
9 changes: 6 additions & 3 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ This release removes all deprecated code and cleans up the library.

* All previously deprecated code has been deleted.

* `RichTextContextFocusedValueKey` is renamed to `RichTextContext.FocusedValueKey`
* `RichTextEditor` is configured with view modifiers instead of the initializer.
* `RichTextKeyboardToolbar` is configured with view modifiers instead of the initializer.
* `RichTextContextFocusedValueKey` has been renamed to `RichTextContext.FocusedValueKey`
* `RichTextEditor` is now configured and styled with view modifiers instead of with the initializer.
* `RichTextFont` pickers are now configured with a shared view modifier instead of with the initializer.
* `RichTextKeyboardToolbar` is now configured and styled with view modifiers instead of with the initializer.





Expand Down
2 changes: 1 addition & 1 deletion Sources/RichTextKit/Editor/RichTextEditor+Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public extension View {
}
}

extension RichTextEditorConfig {
private extension RichTextEditorConfig {

struct Key: EnvironmentKey {

Expand Down
2 changes: 1 addition & 1 deletion Sources/RichTextKit/Editor/RichTextEditor+Style.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public extension View {
}
}

extension RichTextEditorStyle {
private extension RichTextEditorStyle {

struct Key: EnvironmentKey {

Expand Down
6 changes: 4 additions & 2 deletions Sources/RichTextKit/Editor/RichTextView+Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import Foundation
#if iOS || macOS || os(tvOS) || os(visionOS)
public extension RichTextView.Configuration {

/// Get a standard rich text editor configuration.
static var standard: Self { .init() }
/// The standard rich text view configuration.
///
/// You can set a new value to change the global default.
static var standard = Self()
}
#endif
8 changes: 5 additions & 3 deletions Sources/RichTextKit/Editor/RichTextView+Theme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ public extension RichTextView {
}

public extension RichTextView.Theme {

/// Get a standard rich text editor configuration.
static var standard: Self { .init() }

/// The standard rich text view theme.
///
/// You can set a new value to change the global default.
static var standard = Self()
}
#endif
48 changes: 26 additions & 22 deletions Sources/RichTextKit/Fonts/RichTextFont+ForEachPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,20 @@ public extension RichTextFont {
This view uses a plain `ForEach` to list a set of fonts,
of which one can be selected.
Unlike ``RichTextFont/Picker`` this view displays fonts
on all platforms. It must be actively added & presented.
Unlike ``RichTextFont/Picker`` this picker presents all
pickers with proper previews on all platforms. You must
therefore add it ina way that gives it space.
You can configure this picker by applying a config view
modifier to your view hierarchy:
```swift
VStack {
RichTextFont.ForEachPicker(...)
...
}
.richTextFontPickerConfig(...)
```
*/
struct ForEachPicker: View {

Expand All @@ -24,36 +36,28 @@ public extension RichTextFont {
- Parameters:
- selection: The selected font name.
- selectionTopmost: Whether or not to place the selected font topmost.
- fonts: The fonts to display in the list, by default `all`.
- fontSize: The font size to use in the list items.
- dismissAfterPick: Whether or not to dismiss the picker after a font has been selected, by default `false`.
*/
public init(
selection: Binding<FontName>,
selectionTopmost: Bool = true,
fonts: [Font] = .all,
fontSize: CGFloat = 20,
dismissAfterPick: Bool = false
selection: Binding<FontName>
) {
self._selection = selection
self.fonts = fonts
self.fontSize = fontSize
self.dismissAfterPick = dismissAfterPick
if selectionTopmost {
self.fonts = self.fonts.moveTopmost(selection.wrappedValue)
self.fonts = .all
self.fonts = config.fonts
if config.moveSelectionTopmost {
self.fonts = config.fonts.moveTopmost(selection.wrappedValue)
}
}

public typealias Font = RichTextFont.PickerFont
public typealias FontName = String

private var fonts: [Font]
private let fontSize: CGFloat
private let dismissAfterPick: Bool

@Binding
private var selection: FontName

@Environment(\.richTextFontPickerConfig)
private var config

public var body: some View {
let font = Binding(
Expand All @@ -64,11 +68,11 @@ public extension RichTextFont {
RichTextKit.ForEachPicker(
items: fonts,
selection: font,
dismissAfterPick: dismissAfterPick
dismissAfterPick: config.dismissAfterPick
) { font, isSelected in
RichTextFont.PickerItem(
font: font,
fontSize: fontSize,
fontSize: config.fontSize,
isSelected: isSelected
)
}
Expand All @@ -87,12 +91,12 @@ struct RichTextFont_ForEachPicker_Previews: PreviewProvider {
NavigationView {
List {
RichTextFont.ForEachPicker(
selection: $selection,
selectionTopmost: false
selection: $selection
)
}
.withTitle("Pick a font")
}
.richTextFontPickerConfig(.init(moveSelectionTopmost: true))
}
}

Expand Down
42 changes: 25 additions & 17 deletions Sources/RichTextKit/Fonts/RichTextFont+ListPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,29 @@ public extension RichTextFont {
/**
This view uses a `List` to list a set of fonts of which
one can be selected.
Unlike ``RichTextFont/Picker`` this view displays fonts
on all platforms. It must be actively added & presented.
Unlike ``RichTextFont/Picker`` this picker presents all
pickers with proper previews on all platforms. You must
therefore add it ina way that gives it space.
You can configure this picker by applying a config view
modifier to your view hierarchy:
```swift
VStack {
RichTextFont.ListPicker(...)
...
}
.richTextFontPickerConfig(...)
```
*/
struct ListPicker: View {

/**
Create a font picker.
Create a font list picker.
- Parameters:
- selection: The selected font name.
- selectionTopmost: Whether or not to place the selected font topmost.
- fonts: The fonts to display in the list, by default `all`.
- fontSize: The font size to use in the list items.
- dismissAfterPick: Whether or not to dismiss the picker after a font has been selected, by default `true`.
*/
public init(
selection: Binding<FontName>,
Expand All @@ -37,23 +45,23 @@ public extension RichTextFont {
dismissAfterPick: Bool = true
) {
self._selection = selection
self.fonts = fonts ?? .all
self.fontSize = fontSize
self.dismissAfterPick = dismissAfterPick
if selectionTopmost {
self.fonts = self.fonts.moveTopmost(selection.wrappedValue)
self.fonts = .all
self.fonts = config.fonts
if config.moveSelectionTopmost {
self.fonts = config.fonts.moveTopmost(selection.wrappedValue)
}
}

public typealias Font = RichTextFont.PickerFont
public typealias FontName = String

private var fonts: [Font]
private let fontSize: CGFloat
private let dismissAfterPick: Bool

@Binding
private var selection: FontName

@Environment(\.richTextFontPickerConfig)
private var config

public var body: some View {
let font = Binding(
Expand All @@ -64,11 +72,11 @@ public extension RichTextFont {
RichTextKit.ListPicker(
items: fonts,
selection: font,
dismissAfterPick: dismissAfterPick
dismissAfterPick: config.dismissAfterPick
) { font, isSelected in
RichTextFont.PickerItem(
font: font,
fontSize: fontSize,
fontSize: config.fontSize,
isSelected: isSelected
)
}
Expand Down
35 changes: 22 additions & 13 deletions Sources/RichTextKit/Fonts/RichTextFont+Picker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ public extension RichTextFont {
macOS, but not on iOS. To render fonts correctly on all
platforms, you can use a ``RichTextFont/ListPicker`` or
a ``RichTextFont/ForEachPicker``.
You can configure this picker by applying a config view
modifier to your view hierarchy:
```swift
VStack {
RichTextFont.Picker(...)
...
}
.richTextFontPickerConfig(...)
```
Note that this picker will not apply all configurations.
*/
struct Picker: View {

Expand All @@ -26,36 +39,32 @@ public extension RichTextFont {
- Parameters:
- selection: The selected font name.
- fonts: The fonts to display in the list, by default `all`.
- fontSize: The font size to use in the list items.
*/
public init(
selection: Binding<FontName>,
fonts: [Font] = .all,
fontSize: CGFloat = 20
selection: Binding<FontName>
) {
self._selection = selection
self.fonts = fonts
self.itemFontSize = fontSize
self.selectedFont = fonts.last { $0.matches(selection.wrappedValue) }
self.selectedFont = nil
self.selectedFont = config.fonts.last { $0.matches(selection.wrappedValue) }
}

public typealias Font = RichTextFont.PickerFont
public typealias FontName = String

private let fonts: [Font]
private let itemFontSize: CGFloat
private let selectedFont: Font?
private var selectedFont: Font?

@Binding
private var selection: FontName

@Environment(\.richTextFontPickerConfig)
private var config

public var body: some View {
SwiftUI.Picker(selection: $selection) {
ForEach(fonts) { font in
ForEach(config.fonts) { font in
RichTextFont.PickerItem(
font: font,
fontSize: itemFontSize,
fontSize: config.fontSize,
isSelected: false
)
.tag(font.tag(for: selectedFont, selectedName: selection))
Expand Down
85 changes: 85 additions & 0 deletions Sources/RichTextKit/Fonts/RichTextFont+PickerConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// RichTextFont+PickerConfig.swift
// RichTextKit
//
// Created by Daniel Saidi on 2024-03-04.
// Copyright © 2024 Daniel Saidi. All rights reserved.
//

import SwiftUI

public extension RichTextFont {

/// This struct can configure a ``RichTextFont/Picker``.
///
/// This configuration contains configuration properties
/// for many different font pickers types. Some of these
/// properties are not used in some pickers.
struct PickerConfig {

/// Create a custom rich text font picker config.
///
/// - Parameters:
/// - fonts: The fonts to display in the list, by default `all`.
/// - fontSize: The font size to use in the list items, by default `20`.
/// - dismissAfterPick: Whether or not to dismiss the picker after a font is selected, by default `false`.
/// - moveSelectionTopmost: Whether or not to place the selected font topmost, by default `true`.
public init(
fonts: [RichTextFont.PickerFont] = .all,
fontSize: CGFloat = 20,
dismissAfterPick: Bool = false,
moveSelectionTopmost: Bool = true
) {
self.fonts = fonts
self.fontSize = fontSize
self.dismissAfterPick = dismissAfterPick
self.moveSelectionTopmost = moveSelectionTopmost
}

/// The fonts to display in the list.
public var fonts: [RichTextFont.PickerFont]

/// The font size to use in the list items.
public var fontSize: CGFloat

/// Whether or not to dismiss the picker after a font is selected.
public var dismissAfterPick: Bool

/// Whether or not to move the selected font topmost
public var moveSelectionTopmost: Bool
}
}

public extension RichTextFont.PickerConfig {

/// The standard rich text font picker configuration.
///
/// You can set a new value to change the global default.
static var standard = Self()
}

public extension View {

/// Apply a ``RichTextFont`` picker configuration.
func richTextFontPickerConfig(
_ config: RichTextFont.PickerConfig
) -> some View {
self.environment(\.richTextFontPickerConfig, config)
}
}

private extension RichTextFont.PickerConfig {

struct Key: EnvironmentKey {

public static var defaultValue: RichTextFont.PickerConfig = .standard
}
}

public extension EnvironmentValues {

var richTextFontPickerConfig: RichTextFont.PickerConfig {
get { self [RichTextFont.PickerConfig.Key.self] }
set { self [RichTextFont.PickerConfig.Key.self] = newValue }
}
}
Loading

0 comments on commit ee3134b

Please sign in to comment.