Skip to content

Commit

Permalink
Move style views into RichTextStyle namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsaidi committed Jan 22, 2024
1 parent e4dae8a commit 287b09d
Show file tree
Hide file tree
Showing 13 changed files with 555 additions and 551 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ This release starts moving types and views that relate to other types into the t
* `RichTextComponent` deprecates the font name and size functions.
* `RichTextDataFormatMenu` has been renamed to `RichTextDataFormat.Menu`.
* `RichTextFont*` views have been renamed to `RichTextFont.*`.
* `RichTextStyle*` views have been renamed to `RichTextStyle.*`.



Expand Down
2 changes: 1 addition & 1 deletion Sources/RichTextKit/Format/RichTextFormatSidebar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public struct RichTextFormatSidebar: View {
SidebarSection(title: RTKL10n.font.text) {
RichTextFont.Picker(selection: $context.fontName, fontSize: 12)
HStack {
RichTextStyleToggleGroup(context: context)
RichTextStyle.ToggleGroup(context: context)
RichTextFont.SizePickerStack(context: context)
}
}
Expand Down
4 changes: 0 additions & 4 deletions Sources/RichTextKit/RichTextKit.docc/RichTextKit.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,6 @@ RichTextKit is available under the MIT license. See the [LICENSE][License] file

- ``RichTextHighlightingStyle``
- ``RichTextStyle``
- ``RichTextStyleButton``
- ``RichTextStyleToggle``
- ``RichTextStyleToggleGroup``
- ``RichTextStyleToggleStack``



Expand Down
171 changes: 171 additions & 0 deletions Sources/RichTextKit/Styles/RichTextStyle+Button.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
//
// RichTextStyle+Button.swift
// RichTextKit
//
// Created by Daniel Saidi on 2022-06-04.
// Copyright © 2022-2023 Daniel Saidi. All rights reserved.
//

import SwiftUI

public extension RichTextStyle {

/**
This button can be used to toggle a ``RichTextStyle``.
This view renders a plain `Button`, which means you can
use and configure with plain SwiftUI. The one exception
is the content color, which is set with a style.
*/
struct Button: View {

/**
Create a rich text style button.
- Parameters:
- style: The style to toggle.
- buttonStyle: The button style to use, by default `.standard`.
- value: The value to bind to.
- fillVertically: Whether or not fill up vertical space in a non-greedy way, by default `false`.
*/
public init(
style: RichTextStyle,
buttonStyle: Style = .standard,
value: Binding<Bool>,
fillVertically: Bool = false
) {
self.style = style
self.buttonStyle = buttonStyle
self.value = value
self.fillVertically = fillVertically
}

/**
Create a rich text style button.
- Parameters:
- style: The style to toggle.
- buttonStyle: The button style to use, by default `.standard`.
- context: The context to affect.
- fillVertically: Whether or not fill up vertical space in a non-greedy way, by default `false`.
*/
public init(
style: RichTextStyle,
buttonStyle: Style = .standard,
context: RichTextContext,
fillVertically: Bool = false
) {
self.init(
style: style,
buttonStyle: buttonStyle,
value: context.binding(for: style),
fillVertically: fillVertically
)
}

private let style: RichTextStyle
private let buttonStyle: Style
private let value: Binding<Bool>
private let fillVertically: Bool

public var body: some View {
SwiftUI.Button(action: toggle) {
style.label
.labelStyle(.iconOnly)
.frame(maxHeight: fillVertically ? .infinity : nil)
.foregroundColor(tintColor)
.contentShape(Rectangle())
}
.keyboardShortcut(for: style)
.accessibilityLabel(style.title)
}
}
}

public extension RichTextStyle.Button {

struct Style {

/**
Create a rich text style button style.
- Parameters:
- inactiveColor: The color to apply when the button is inactive, by default `.primary`.
- activeColor: The color to apply when the button is active, by default `.blue`.
*/
public init(
inactiveColor: Color = .primary,
activeColor: Color = .blue
) {
self.inactiveColor = inactiveColor
self.activeColor = activeColor
}

/// The color to apply when the button is inactive.
public var inactiveColor: Color

/// The color to apply when the button is active.
public var activeColor: Color
}
}

public extension RichTextStyle.Button.Style {

/// The standard ``RichTextStyle/Button`` style.
static var standard = RichTextStyle.Button.Style()
}

private extension RichTextStyle.Button {

var isOn: Bool {
value.wrappedValue
}

var tintColor: Color {
isOn ? buttonStyle.activeColor : buttonStyle.inactiveColor
}

func toggle() {
value.wrappedValue.toggle()
}
}

struct RichTextStyle_Button_Previews: PreviewProvider {

struct Preview: View {

@State
private var isBoldOn = false

@State
private var isItalicOn = true

@State
private var isStrikethroughOn = false

@State
private var isUnderlinedOn = false

var body: some View {
HStack {
RichTextStyle.Button(
style: .bold,
value: $isBoldOn)
RichTextStyle.Button(
style: .italic,
value: $isItalicOn)
RichTextStyle.Button(
style: .strikethrough,
value: $isStrikethroughOn)
RichTextStyle.Button(
style: .underlined,
value: $isUnderlinedOn)
}
.padding()
}
}

static var previews: some View {
Preview()
}
}
183 changes: 183 additions & 0 deletions Sources/RichTextKit/Styles/RichTextStyle+Toggle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
//
// RichTextStyle+Toggle.swift
// RichTextKit
//
// Created by Daniel Saidi on 2022-12-08.
// Copyright © 2022-2023 Daniel Saidi. All rights reserved.
//

import SwiftUI

public extension RichTextStyle {

/**
This toggle can be used to toggle a ``RichTextStyle``.
This view renders a plain `Toggle`, which means you can
use and configure with plain SwiftUI. The one exception
is the tint color, which is set with a style.
> Note: The view uses a ``RichTextStyleButton`` if it's
used on iOS 14, macOS 11, tvOS 14 and watchOS 8.
*/
struct Toggle: View {

/**
Create a rich text style toggle toggle.
- Parameters:
- style: The style to toggle.
- buttonStyle: The button style to use, by default `.standard`.
- value: The value to bind to.
- fillVertically: Whether or not fill up vertical space in a non-greedy way, by default `false`.
*/
public init(
style: RichTextStyle,
buttonStyle: Style = .standard,
value: Binding<Bool>,
fillVertically: Bool = false
) {
self.style = style
self.buttonStyle = buttonStyle
self.value = value
self.fillVertically = fillVertically
}

/**
Create a rich text style toggle.
- Parameters:
- style: The style to toggle.
- buttonStyle: The button style to use, by default `.standard`.
- context: The context to affect.
- fillVertically: Whether or not fill up vertical space in a non-greedy way, by default `false`.
*/
public init(
style: RichTextStyle,
buttonStyle: Style = .standard,
context: RichTextContext,
fillVertically: Bool = false
) {
self.init(
style: style,
buttonStyle: buttonStyle,
value: context.binding(for: style),
fillVertically: fillVertically
)
}

private let style: RichTextStyle
private let buttonStyle: Style
private let value: Binding<Bool>
private let fillVertically: Bool

public var body: some View {
#if os(tvOS) || os(watchOS)
toggle
#else
toggle.toggleStyle(.button)
#endif
}

private var toggle: some View {
SwiftUI.Toggle(isOn: value) {
style.icon
.frame(maxHeight: fillVertically ? .infinity : nil)
}
.tint(tintColor)
.keyboardShortcut(for: style)
.accessibilityLabel(style.title)
}
}
}

private extension RichTextStyle.Toggle {

var backgroundColor: Color {
value.wrappedValue ? buttonStyle.activeColor.opacity(0.2) : .clear
}
}

public extension RichTextStyle.Toggle {

struct Style {

/**
Create a rich text style button style.
- Parameters:
- inactiveColor: The color to apply when the button is inactive, by default `nil`.
- activeColor: The color to apply when the button is active, by default `.blue`.
*/
public init(
inactiveColor: Color? = nil,
activeColor: Color = .blue
) {
self.inactiveColor = inactiveColor
self.activeColor = activeColor
}

/// The color to apply when the button is inactive.
public var inactiveColor: Color?

/// The color to apply when the button is active.
public var activeColor: Color
}
}

public extension RichTextStyle.Toggle.Style {

/// The standard ``RichTextStyle/Toggle`` style.
static var standard = RichTextStyle.Toggle.Style()
}

private extension RichTextStyle.Toggle {

var isOn: Bool {
value.wrappedValue
}

var tintColor: Color? {
isOn ? buttonStyle.activeColor : buttonStyle.inactiveColor
}
}

struct RichTextStyle_Toggle_Previews: PreviewProvider {

struct Preview: View {

@State
private var isBoldOn = false

@State
private var isItalicOn = true

@State
private var isStrikethroughOn = true

@State
private var isUnderlinedOn = true

var body: some View {
HStack {
RichTextStyle.Toggle(
style: .bold,
value: $isBoldOn)
RichTextStyle.Toggle(
style: .italic,
value: $isItalicOn)
RichTextStyle.Toggle(
style: .strikethrough,
value: $isStrikethroughOn)
RichTextStyle.Toggle(
style: .underlined,
value: $isUnderlinedOn)
}
.padding()
}
}

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

0 comments on commit 287b09d

Please sign in to comment.