Skip to content

Commit

Permalink
Move font picker views into new RichTextFont namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsaidi committed Jan 22, 2024
1 parent e849315 commit e4dae8a
Show file tree
Hide file tree
Showing 21 changed files with 764 additions and 753 deletions.
15 changes: 7 additions & 8 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,32 @@ This release starts moving types and views that relate to other types into the t

* `RichTextAlignment.Picker` has a new style parameter.
* `RichTextCommand` is a new namespace for command-related views.
* `RichTextColorPicker` now shows a quick button to reset the color.
* `RichTextColor.Picker` now shows a quick button to reset the color.
* `RichTextLabelValue` is a new protocol to harmonize label-compatible label values.

### 💡 Adjustments

* Many value types implement `RichTextLabelValue` to get a `label` property.
* All types that implement `RichTextLabelValue` get a `label` that has improved accessibility.

* `RichTextColor` `.adjust` now takes an optional
* `RichTextColor` `.adjust` now takes an optional color.

### 🐛 Bug Fixes

* `Image.symbol(...)` removes `palette` rendering mode to fix incorrect color scheme behavior.
* `RichTextColorPicker` no longer auto-adjusts black and white to make it possible to actually set those colors.
* `RichTextColor.Picker` no longer auto-adjusts black and white to make it possible to actually set those colors.

### 🗑️ Deprecations

* `RichTextActionButton` has been renamed to `RichTextAction.Button`.
* `RichTextActionButtonGroup` has been renamed to `RichTextAction.ButtonGroup`.
* `RichTextActionButtonStack` has been renamed to `RichTextAction.ButtonStack`.
* `RichTextAlignmentPicker` has been renamed to `RichTextAlignment.Picker`.
* `RichTextAction*` views have been renamed to `RichTextAction.Button*`.
* `RichTextAlignment*` views have been renamed to `RichTextAlignment.*`.
* `RichTextArgumentReader` deprecates the font name and size functions.
* `RichTextArgumentWriter` deprecates the font name and size functions.
* `RichTextColorPicker` has been renamed to `RichTextColor.Picker`.
* `RichTextColor*` views have been renamed to `RichTextColor.*`.
* `RichTextCommand` views are now nested within the new `RichTextCommand` type.
* `RichTextComponent` deprecates the font name and size functions.
* `RichTextDataFormatMenu` has been renamed to `RichTextDataFormat.Menu`.
* `RichTextFont*` views have been renamed to `RichTextFont.*`.



Expand Down
12 changes: 8 additions & 4 deletions Sources/RichTextKit/Alignment/RichTextAlignment+Picker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ struct RichTextAlignment_Picker_Previews: PreviewProvider {
private var alignment = RichTextAlignment.left

var body: some View {
RichTextAlignment.Picker(
selection: $alignment,
values: .all
)
VStack(spacing: 10) {
RichTextAlignment.Picker(
selection: $alignment,
values: .all
)
.withPreviewPickerStyles()
}
.padding()
}
}

Expand Down
115 changes: 115 additions & 0 deletions Sources/RichTextKit/Fonts/RichTextFont+ForEachPicker.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//
// RichTextFont+ForEachPicker.swift
// RichTextKit
//
// Created by Daniel Saidi on 2022-06-01.
// Copyright © 2022-2023 Daniel Saidi. All rights reserved.
//

import SwiftUI

public extension RichTextFont {

/**
This view uses a plain `ForEach` to list a set of fonts,
of which one can be selected.

Unlike ``RichTextFont/Picker`` the picker renders fonts
correctly on all platforms. However, unlike the regular
SwiftUI `Picker`, it must actively be added & presented.
*/
struct ForEachPicker: View {

/**
Create a font 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 `false`.
*/
public init(
selection: Binding<FontName>,
selectionTopmost: Bool = true,
fonts: [Font] = .all,
fontSize: CGFloat = 20,
dismissAfterPick: Bool = false
) {
self._selection = selection
self.fonts = fonts
self.fontSize = fontSize
self.dismissAfterPick = dismissAfterPick
if selectionTopmost {
self.fonts = self.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

public var body: some View {
let font = Binding(
get: { Font(fontName: selection) },
set: { selection = $0.fontName }
)

RichTextKit.ForEachPicker(
items: fonts,
selection: font,
dismissAfterPick: dismissAfterPick
) { font, isSelected in
RichTextFont.PickerItem(
font: font,
fontSize: fontSize,
isSelected: isSelected
)
}
}
}
}

struct RichTextFont_ForEachPicker_Previews: PreviewProvider {

struct Preview: View {

@State
private var selection = ""

var body: some View {
NavigationView {
List {
RichTextFont.ForEachPicker(
selection: $selection,
selectionTopmost: false
)
}
.withTitle("Pick a font")
}
}
}

static var previews: some View {
Preview()
}
}

private extension View {

@ViewBuilder
func withTitle(_ title: String) -> some View {
#if iOS || os(tvOS) || os(watchOS) || os(visionOS)
self.navigationBarTitle(title)
#else
self
#endif
}
}
111 changes: 111 additions & 0 deletions Sources/RichTextKit/Fonts/RichTextFont+ListPicker.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//
// RichTextFont+ListPicker.swift
// RichTextKit
//
// Created by Daniel Saidi on 2022-06-01.
// Copyright © 2022-2023 Daniel Saidi. All rights reserved.
//

import SwiftUI

public extension RichTextFont {

/**
This view uses a `List` to list a set of fonts of which
one can be selected.

Unlike ``RichTextFont/Picker`` the picker renders fonts
correctly on all platforms. However, unlike the regular
SwiftUI `Picker`, it must actively be added & presented.
*/
struct ListPicker: View {

/**
Create a font 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>,
selectionTopmost: Bool = false,
fonts: [Font]? = nil,
fontSize: CGFloat = 20,
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)
}
}

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

public var body: some View {
let font = Binding(
get: { Font(fontName: selection) },
set: { selection = $0.fontName }
)

RichTextKit.ListPicker(
items: fonts,
selection: font,
dismissAfterPick: dismissAfterPick
) { font, isSelected in
RichTextFont.PickerItem(
font: font,
fontSize: fontSize,
isSelected: isSelected
)
}
}
}
}

struct RichTextFont_ListPicker_Previews: PreviewProvider {

struct Preview: View {

@State private var font = ""

var body: some View {
NavigationView {
RichTextFont.ListPicker(
selection: $font
)
.withTitle("Pick a font")
}
}
}

static var previews: some View {
Preview()
}
}

private extension View {

@ViewBuilder
func withTitle(_ title: String) -> some View {
#if iOS || os(tvOS) || os(watchOS) || os(visionOS)
self.navigationBarTitle(title)
#else
self
#endif
}
}
Loading

0 comments on commit e4dae8a

Please sign in to comment.