From 287b09d3132a92e062e73ca51ff5a1f23b7968a2 Mon Sep 17 00:00:00 2001 From: Daniel Saidi Date: Tue, 23 Jan 2024 00:57:12 +0100 Subject: [PATCH] Move style views into RichTextStyle namespace --- RELEASE_NOTES.md | 1 + .../Format/RichTextFormatSidebar.swift | 2 +- .../RichTextKit.docc/RichTextKit.md | 4 - .../Styles/RichTextStyle+Button.swift | 171 ++++++++++++++++ .../Styles/RichTextStyle+Toggle.swift | 183 +++++++++++++++++ .../Styles/RichTextStyle+ToggleGroup.swift | 104 ++++++++++ .../Styles/RichTextStyle+ToggleStack.swift | 81 ++++++++ .../RichTextKit/Styles/RichTextStyle.swift | 2 +- .../Styles/RichTextStyleButton.swift | 176 ----------------- .../Styles/RichTextStyleToggle.swift | 185 ------------------ .../Styles/RichTextStyleToggleGroup.swift | 103 ---------- .../Styles/RichTextStyleToggleStack.swift | 81 -------- .../RichTextStyle+Deprecated.swift | 13 ++ 13 files changed, 555 insertions(+), 551 deletions(-) create mode 100644 Sources/RichTextKit/Styles/RichTextStyle+Button.swift create mode 100644 Sources/RichTextKit/Styles/RichTextStyle+Toggle.swift create mode 100644 Sources/RichTextKit/Styles/RichTextStyle+ToggleGroup.swift create mode 100644 Sources/RichTextKit/Styles/RichTextStyle+ToggleStack.swift delete mode 100644 Sources/RichTextKit/Styles/RichTextStyleButton.swift delete mode 100644 Sources/RichTextKit/Styles/RichTextStyleToggle.swift delete mode 100644 Sources/RichTextKit/Styles/RichTextStyleToggleGroup.swift delete mode 100644 Sources/RichTextKit/Styles/RichTextStyleToggleStack.swift create mode 100644 Sources/RichTextKit/_Deprecated/RichTextStyle+Deprecated.swift diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 1feb36db7..3187427ef 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -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.*`. diff --git a/Sources/RichTextKit/Format/RichTextFormatSidebar.swift b/Sources/RichTextKit/Format/RichTextFormatSidebar.swift index 7f50729e4..d8fcc7e0d 100644 --- a/Sources/RichTextKit/Format/RichTextFormatSidebar.swift +++ b/Sources/RichTextKit/Format/RichTextFormatSidebar.swift @@ -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) } } diff --git a/Sources/RichTextKit/RichTextKit.docc/RichTextKit.md b/Sources/RichTextKit/RichTextKit.docc/RichTextKit.md index 3fdc3d602..dc612ebfe 100644 --- a/Sources/RichTextKit/RichTextKit.docc/RichTextKit.md +++ b/Sources/RichTextKit/RichTextKit.docc/RichTextKit.md @@ -161,10 +161,6 @@ RichTextKit is available under the MIT license. See the [LICENSE][License] file - ``RichTextHighlightingStyle`` - ``RichTextStyle`` -- ``RichTextStyleButton`` -- ``RichTextStyleToggle`` -- ``RichTextStyleToggleGroup`` -- ``RichTextStyleToggleStack`` diff --git a/Sources/RichTextKit/Styles/RichTextStyle+Button.swift b/Sources/RichTextKit/Styles/RichTextStyle+Button.swift new file mode 100644 index 000000000..e865bb105 --- /dev/null +++ b/Sources/RichTextKit/Styles/RichTextStyle+Button.swift @@ -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, + 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 + 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() + } +} diff --git a/Sources/RichTextKit/Styles/RichTextStyle+Toggle.swift b/Sources/RichTextKit/Styles/RichTextStyle+Toggle.swift new file mode 100644 index 000000000..9523bfd84 --- /dev/null +++ b/Sources/RichTextKit/Styles/RichTextStyle+Toggle.swift @@ -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, + 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 + 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() + } +} diff --git a/Sources/RichTextKit/Styles/RichTextStyle+ToggleGroup.swift b/Sources/RichTextKit/Styles/RichTextStyle+ToggleGroup.swift new file mode 100644 index 000000000..5c19476f2 --- /dev/null +++ b/Sources/RichTextKit/Styles/RichTextStyle+ToggleGroup.swift @@ -0,0 +1,104 @@ +// +// RichTextStyle+ToggleGroup.swift +// RichTextKit +// +// Created by Daniel Saidi on 2023-06-01. +// Copyright © 2023 Daniel Saidi. All rights reserved. +// + +#if iOS || macOS || os(visionOS) +import SwiftUI + +public extension RichTextStyle { + + /** + This view can list ``RichTextStyle/Toggle``s for a list + of ``RichTextStyle`` values, in a bordered button group. + + Since this view uses multiple styles, it binds directly + to a ``RichTextContext`` instead of individual values. + */ + struct ToggleGroup: View { + + /** + Create a rich text style toggle button group. + + - Parameters: + - context: The context to affect. + - styles: The styles to list, by default ``RichTextStyle/all``. + - greedy: Whether or not the group is horizontally greedy, by default `true`. + - buttonStyle: The button style to use, by default ``RichTextStyleToggle/Style/standard``. + */ + public init( + context: RichTextContext, + styles: [RichTextStyle] = .all, + greedy: Bool = true, + buttonStyle: RichTextStyle.Toggle.Style = .standard + ) { + self._context = ObservedObject(wrappedValue: context) + self.isGreedy = greedy + self.styles = styles + self.buttonStyle = buttonStyle + } + + private let styles: [RichTextStyle] + private let isGreedy: Bool + private let buttonStyle: RichTextStyle.Toggle.Style + + private var groupWidth: CGFloat? { + if isGreedy { return nil } + let count = Double(styles.count) + #if macOS + return 30 * count + #else + return 50 * count + #endif + } + + @ObservedObject + private var context: RichTextContext + + public var body: some View { + ControlGroup { + ForEach(styles) { + RichTextStyle.Toggle( + style: $0, + buttonStyle: buttonStyle, + context: context, + fillVertically: true + ) + } + } + .frame(width: groupWidth) + } + } +} + +struct RichTextStyle_ToggleGroup_Previews: PreviewProvider { + + struct Preview: View { + + @StateObject + private var context = RichTextContext() + + func group(greedy: Bool) -> some View { + RichTextStyle.ToggleGroup( + context: context, + greedy: greedy + ) + } + + var body: some View { + VStack { + group(greedy: true) + group(greedy: false) + } + .padding() + } + } + + static var previews: some View { + Preview() + } +} +#endif diff --git a/Sources/RichTextKit/Styles/RichTextStyle+ToggleStack.swift b/Sources/RichTextKit/Styles/RichTextStyle+ToggleStack.swift new file mode 100644 index 000000000..8d38b98e7 --- /dev/null +++ b/Sources/RichTextKit/Styles/RichTextStyle+ToggleStack.swift @@ -0,0 +1,81 @@ +// +// RichTextStyleToggleStack.swift +// RichTextKit +// +// Created by Daniel Saidi on 2022-12-08. +// Copyright © 2022-2023 Daniel Saidi. All rights reserved. +// + +import SwiftUI + +public extension RichTextStyle { + + /** + This view can list ``RichTextStyle/Toggle``s for a list + of ``RichTextStyle`` values, in a horizontal stack. + + Since this view uses multiple styles, it binds directly + to a ``RichTextContext`` instead of individual values. + */ + struct ToggleStack: View { + + /** + Create a rich text style toggle button group. + + - Parameters: + - context: The context to affect. + - styles: The styles to list, by default ``RichTextStyle/all``. + - buttonStyle: The button style to use, by default `.standard`. + - spacing: The spacing to apply to stack items, by default `5`. + */ + public init( + context: RichTextContext, + styles: [RichTextStyle] = .all, + buttonStyle: RichTextStyle.Toggle.Style = .standard, + spacing: Double = 5 + ) { + self._context = ObservedObject(wrappedValue: context) + self.styles = styles + self.buttonStyle = buttonStyle + self.spacing = spacing + } + + private let styles: [RichTextStyle] + private let buttonStyle: RichTextStyle.Toggle.Style + private let spacing: Double + + @ObservedObject + private var context: RichTextContext + + public var body: some View { + HStack(spacing: spacing) { + ForEach(styles) { + RichTextStyle.Toggle( + style: $0, + buttonStyle: buttonStyle, + context: context, + fillVertically: true + ) + } + }.fixedSize(horizontal: false, vertical: true) + } + } +} + +struct RichTextStyle_ToggleStack_Previews: PreviewProvider { + + struct Preview: View { + + @StateObject + private var context = RichTextContext() + + var body: some View { + RichTextStyle.ToggleStack(context: context) + .padding() + } + } + + static var previews: some View { + Preview() + } +} diff --git a/Sources/RichTextKit/Styles/RichTextStyle.swift b/Sources/RichTextKit/Styles/RichTextStyle.swift index d1b77d988..430f6cb3e 100644 --- a/Sources/RichTextKit/Styles/RichTextStyle.swift +++ b/Sources/RichTextKit/Styles/RichTextStyle.swift @@ -16,7 +16,7 @@ import SwiftUI a single way to toggle certain traits and attributes on and off, although they may be handled differently by the system. */ -public enum RichTextStyle: String, CaseIterable, Identifiable { +public enum RichTextStyle: String, CaseIterable, Identifiable, RichTextLabelValue { case bold case italic diff --git a/Sources/RichTextKit/Styles/RichTextStyleButton.swift b/Sources/RichTextKit/Styles/RichTextStyleButton.swift deleted file mode 100644 index 8771263c7..000000000 --- a/Sources/RichTextKit/Styles/RichTextStyleButton.swift +++ /dev/null @@ -1,176 +0,0 @@ -// -// RichTextStyleButton.swift -// RichTextKit -// -// Created by Daniel Saidi on 2022-06-04. -// Copyright © 2022-2023 Daniel Saidi. All rights reserved. -// - -import SwiftUI - -/** - This button can be used to toggle a ``RichTextStyle`` value. - - This view renders a plain `Button`, which means you can use - and configure it in all ways supported by SwiftUI. The only - exception is the content color, which is set by a style you - can provide in the initializer. - - If you want a more prominent button, you may consider using - a ``RichTextStyleToggle`` instead, but it requires a higher - deployment target. - */ -public struct RichTextStyleButton: View { - - /** - Create a rich text style button. - - - Parameters: - - style: The style to toggle. - - buttonStyle: The button style to use, by default ``RichTextStyleButton/Style/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, - 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 ``RichTextStyleButton/Style/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 - private let fillVertically: Bool - - public var body: some View { - Button(action: toggle) { - style.icon - .frame(maxHeight: fillVertically ? .infinity : nil) - .foregroundColor(tintColor) - .contentShape(Rectangle()) - } - .keyboardShortcut(for: style) - .accessibilityLabel(style.title) - } -} - -public extension RichTextStyleButton { - - /** - This style can be used to style a ``RichTextStyleButton``. - */ - 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 RichTextStyleButton.Style { - - /** - The standard ``RichTextStyleButton`` style. - */ - static var standard = RichTextStyleButton.Style() -} - -private extension RichTextStyleButton { - - var isOn: Bool { - value.wrappedValue - } - - var tintColor: Color { - isOn ? buttonStyle.activeColor : buttonStyle.inactiveColor - } - - func toggle() { - value.wrappedValue.toggle() - } -} - -struct RichTextStyleButton_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 { - RichTextStyleButton( - style: .bold, - value: $isBoldOn) - RichTextStyleButton( - style: .italic, - value: $isItalicOn) - RichTextStyleButton( - style: .strikethrough, - value: $isStrikethroughOn) - RichTextStyleButton( - style: .underlined, - value: $isUnderlinedOn) - }.padding() - } - } - - static var previews: some View { - Preview() - } -} diff --git a/Sources/RichTextKit/Styles/RichTextStyleToggle.swift b/Sources/RichTextKit/Styles/RichTextStyleToggle.swift deleted file mode 100644 index c082f89dc..000000000 --- a/Sources/RichTextKit/Styles/RichTextStyleToggle.swift +++ /dev/null @@ -1,185 +0,0 @@ -// -// RichTextStyleToggle.swift -// RichTextKit -// -// Created by Daniel Saidi on 2022-12-08. -// Copyright © 2022-2023 Daniel Saidi. All rights reserved. -// - -import SwiftUI - -/** - This button can be used to toggle a ``RichTextStyle`` value. - - This view renders a plain `Toggle` that uses a button style. - This means that you can use and configure it as normal. The - only exception is the tint, which is specified by the style - that you can inject. - - Note that the view will use a ``RichTextStyleButton`` if it - is used on iOS 14, macOS 11, tvOS 14 and watchOS 8. - */ -public struct RichTextStyleToggle: View { - - /** - Create a rich text style toggle toggle. - - - Parameters: - - style: The style to toggle. - - buttonStyle: The button style to use, by default ``RichTextStyleToggle/Style/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, - 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 ``RichTextStyleToggle/Style/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 - 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 { - Toggle(isOn: value) { - style.icon - .frame(maxHeight: fillVertically ? .infinity : nil) - } - .tint(tintColor) - .keyboardShortcut(for: style) - .accessibilityLabel(style.title) - } -} - -private extension RichTextStyleToggle { - - var backgroundColor: Color { - value.wrappedValue ? buttonStyle.activeColor.opacity(0.2) : .clear - } -} - -public extension RichTextStyleToggle { - - /** - This style can be used to style a ``RichTextStyleToggle``. - */ - 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 RichTextStyleToggle.Style { - - /** - The standard ``RichTextStyleToggle`` style. - */ - static var standard = RichTextStyleToggle.Style() -} - -private extension RichTextStyleToggle { - - var isOn: Bool { - value.wrappedValue - } - - var tintColor: Color? { - isOn ? buttonStyle.activeColor : buttonStyle.inactiveColor - } -} - -struct RichTextStyleToggle_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 { - RichTextStyleToggle( - style: .bold, - value: $isBoldOn) - RichTextStyleToggle( - style: .italic, - value: $isItalicOn) - RichTextStyleToggle( - style: .strikethrough, - value: $isStrikethroughOn) - RichTextStyleToggle( - style: .underlined, - value: $isUnderlinedOn) - }.padding() - } - } - - static var previews: some View { - Preview() - } -} diff --git a/Sources/RichTextKit/Styles/RichTextStyleToggleGroup.swift b/Sources/RichTextKit/Styles/RichTextStyleToggleGroup.swift deleted file mode 100644 index dd43a4750..000000000 --- a/Sources/RichTextKit/Styles/RichTextStyleToggleGroup.swift +++ /dev/null @@ -1,103 +0,0 @@ -// -// RichTextStyleToggleGroup.swift -// RichTextKit -// -// Created by Daniel Saidi on 2023-06-01. -// Copyright © 2023 Daniel Saidi. All rights reserved. -// - -#if iOS || macOS || os(visionOS) -import SwiftUI - -/** - This view can be used to list a collection of toggles for a - set of ``RichTextStyle`` values in a bordered button group. - - See the ``RichTextStyleToggle`` for more information on the - toggle views that are rendered by this view. - - Since this view controls multiple styles, it binds directly - to a ``RichTextContext`` instead of individual values. - */ -public struct RichTextStyleToggleGroup: View { - - /** - Create a rich text style toggle button group. - - - Parameters: - - context: The context to affect. - - styles: The styles to list, by default ``RichTextStyle/all``. - - greedy: Whether or not the group is horizontally greedy, by default `true`. - - buttonStyle: The button style to use, by default ``RichTextStyleToggle/Style/standard``. - */ - public init( - context: RichTextContext, - styles: [RichTextStyle] = .all, - greedy: Bool = true, - buttonStyle: RichTextStyleButton.Style = .standard - ) { - self._context = ObservedObject(wrappedValue: context) - self.isGreedy = greedy - self.styles = styles - self.buttonStyle = buttonStyle - } - - private let styles: [RichTextStyle] - private let isGreedy: Bool - private let buttonStyle: RichTextStyleButton.Style - - private var groupWidth: CGFloat? { - if isGreedy { return nil } - let count = Double(styles.count) - #if macOS - return 30 * count - #else - return 50 * count - #endif - } - - @ObservedObject - private var context: RichTextContext - - public var body: some View { - ControlGroup { - ForEach(styles) { - RichTextStyleButton( - style: $0, - buttonStyle: buttonStyle, - context: context, - fillVertically: true - ) - } - }.frame(width: groupWidth) - } -} - -struct RichTextStyleToggleGroup_Previews: PreviewProvider { - - struct Preview: View { - - @StateObject - private var context = RichTextContext() - - func group(greedy: Bool) -> some View { - RichTextStyleToggleGroup( - context: context, - greedy: greedy - ) - } - - var body: some View { - VStack { - group(greedy: true) - group(greedy: false) - }.padding() - - } - } - - static var previews: some View { - Preview() - } -} -#endif diff --git a/Sources/RichTextKit/Styles/RichTextStyleToggleStack.swift b/Sources/RichTextKit/Styles/RichTextStyleToggleStack.swift deleted file mode 100644 index 10b062d76..000000000 --- a/Sources/RichTextKit/Styles/RichTextStyleToggleStack.swift +++ /dev/null @@ -1,81 +0,0 @@ -// -// RichTextStyleToggleStack.swift -// RichTextKit -// -// Created by Daniel Saidi on 2022-12-08. -// Copyright © 2022-2023 Daniel Saidi. All rights reserved. -// - -import SwiftUI - -/** - This view can be used to list a collection of toggles for a - set of ``RichTextStyle`` values in a horizontal line. - - See the ``RichTextStyleToggle`` for more information on the - toggle views that are rendered by this view. - - Since this view controls multiple styles, it binds directly - to a ``RichTextContext`` instead of individual values. - */ -public struct RichTextStyleToggleStack: View { - - /** - Create a rich text style toggle button group. - - - Parameters: - - context: The context to affect. - - styles: The styles to list, by default ``RichTextStyle/all``. - - buttonStyle: The button style to use, by default ``RichTextStyleToggle/Style/standard``. - - spacing: The spacing to apply to stack items, by default `5`. - */ - public init( - context: RichTextContext, - styles: [RichTextStyle] = .all, - buttonStyle: RichTextStyleToggle.Style = .standard, - spacing: Double = 5 - ) { - self._context = ObservedObject(wrappedValue: context) - self.styles = styles - self.buttonStyle = buttonStyle - self.spacing = spacing - } - - private let styles: [RichTextStyle] - private let buttonStyle: RichTextStyleToggle.Style - private let spacing: Double - - @ObservedObject - private var context: RichTextContext - - public var body: some View { - HStack(spacing: spacing) { - ForEach(styles) { - RichTextStyleToggle( - style: $0, - buttonStyle: buttonStyle, - context: context, - fillVertically: true - ) - } - }.fixedSize(horizontal: false, vertical: true) - } -} - -struct RichTextStyleToggleStack_Previews: PreviewProvider { - - struct Preview: View { - - @StateObject - private var context = RichTextContext() - - var body: some View { - RichTextStyleToggleStack(context: context) - .padding() - } - } - - static var previews: some View { - Preview() - } -} diff --git a/Sources/RichTextKit/_Deprecated/RichTextStyle+Deprecated.swift b/Sources/RichTextKit/_Deprecated/RichTextStyle+Deprecated.swift new file mode 100644 index 000000000..04e962cb5 --- /dev/null +++ b/Sources/RichTextKit/_Deprecated/RichTextStyle+Deprecated.swift @@ -0,0 +1,13 @@ +import SwiftUI + +@available(*, deprecated, renamed: "RichTextStyle.Button") +public typealias RichTextStyleButton = RichTextStyle.Button + +@available(*, deprecated, renamed: "RichTextStyle.Toggle") +public typealias RichTextStyleToggle = RichTextStyle.Toggle + +@available(*, deprecated, renamed: "RichTextStyle.ToggleGroup") +public typealias RichTextStyleToggleGroup = RichTextStyle.ToggleGroup + +@available(*, deprecated, renamed: "RichTextStyle.ToggleStack") +public typealias RichTextStyleToggleStack = RichTextStyle.ToggleStack