-
-
Notifications
You must be signed in to change notification settings - Fork 133
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move RichTextAction views into enum namespace
- Loading branch information
1 parent
c47e01f
commit 85b3b60
Showing
15 changed files
with
319 additions
and
304 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
Sources/RichTextKit/Actions/RichTextAction+Button.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// | ||
// RichTextActionButton.swift | ||
// RichTextKit | ||
// | ||
// Created by Daniel Saidi on 2022-12-08. | ||
// Copyright © 2022-2024 Daniel Saidi. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
|
||
public extension RichTextAction { | ||
|
||
/** | ||
This button can be used to trigger a ``RichTextAction``. | ||
|
||
This renders a plain `Button`, which means that you can | ||
use and configure it as a normal button. | ||
*/ | ||
struct Button: View { | ||
|
||
/** | ||
Create a rich text action button. | ||
|
||
- Parameters: | ||
- action: The action to trigger. | ||
- context: The context to affect. | ||
- fillVertically: WhetherP or not fill up vertical space, by default `false`. | ||
*/ | ||
public init( | ||
action: RichTextAction, | ||
context: RichTextContext, | ||
fillVertically: Bool = false | ||
) { | ||
self.action = action | ||
self._context = ObservedObject(wrappedValue: context) | ||
self.fillVertically = fillVertically | ||
} | ||
|
||
private let action: RichTextAction | ||
private let fillVertically: Bool | ||
|
||
@ObservedObject | ||
private var context: RichTextContext | ||
|
||
public var body: some View { | ||
SwiftUI.Button(action: triggerAction) { | ||
action.icon | ||
.frame(maxHeight: fillVertically ? .infinity : nil) | ||
.contentShape(Rectangle()) | ||
} | ||
.keyboardShortcut(for: action) | ||
.accessibilityLabel(action.title) | ||
.disabled(!context.canHandle(action)) | ||
} | ||
} | ||
} | ||
|
||
private extension RichTextAction.Button { | ||
|
||
func triggerAction() { | ||
context.handle(action) | ||
} | ||
} | ||
|
||
struct RichTextAction_Button_Previews: PreviewProvider { | ||
|
||
struct Preview: View { | ||
|
||
@StateObject | ||
private var context = RichTextContext() | ||
|
||
var body: some View { | ||
HStack { | ||
RichTextAction.Button( | ||
action: .copy, | ||
context: context, | ||
fillVertically: true | ||
) | ||
RichTextAction.Button( | ||
action: .redoLatestChange, | ||
context: context, | ||
fillVertically: true | ||
) | ||
RichTextAction.Button( | ||
action: .undoLatestChange, | ||
context: context, | ||
fillVertically: true | ||
) | ||
RichTextAction.Button( | ||
action: .stepFontSize(points: 1), | ||
context: context, | ||
fillVertically: true | ||
) | ||
RichTextAction.Button( | ||
action: .stepFontSize(points: -1), | ||
context: context, | ||
fillVertically: true | ||
) | ||
RichTextAction.Button( | ||
action: .decreaseIndent(), | ||
context: context, | ||
fillVertically: true | ||
) | ||
RichTextAction.Button( | ||
action: .increaseIndent(), | ||
context: context, | ||
fillVertically: true | ||
) | ||
} | ||
.fixedSize(horizontal: false, vertical: true) | ||
.padding() | ||
.buttonStyle(.bordered) | ||
} | ||
} | ||
|
||
static var previews: some View { | ||
Preview() | ||
} | ||
} |
102 changes: 102 additions & 0 deletions
102
Sources/RichTextKit/Actions/RichTextAction+ButtonGroup.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// | ||
// RichTextActionButtonGroup.swift | ||
// RichTextKit | ||
// | ||
// Created by Daniel Saidi on 2022-12-08. | ||
// Copyright © 2022-2024 Daniel Saidi. All rights reserved. | ||
// | ||
|
||
#if iOS || macOS || os(visionOS) | ||
import SwiftUI | ||
|
||
public extension RichTextAction { | ||
|
||
/** | ||
This view lists ``RichTextAction`` buttons in a group. | ||
|
||
Since this view uses multiple values, it binds directly | ||
to a ``RichTextContext`` instead of individual values. | ||
*/ | ||
struct ButtonGroup: View { | ||
|
||
/** | ||
Create a rich text action button stack. | ||
|
||
- Parameters: | ||
- context: The context to affect. | ||
- actions: The actions to list, by default all non-size actions. | ||
- greedy: Whether or not the group is horizontally greedy, by default `true`. | ||
*/ | ||
public init( | ||
context: RichTextContext, | ||
actions: [RichTextAction], | ||
greedy: Bool = true | ||
) { | ||
self._context = ObservedObject(wrappedValue: context) | ||
self.actions = actions | ||
self.isGreedy = greedy | ||
} | ||
|
||
private let actions: [RichTextAction] | ||
private let isGreedy: Bool | ||
|
||
@ObservedObject | ||
private var context: RichTextContext | ||
|
||
public var body: some View { | ||
ControlGroup { | ||
ForEach(actions) { | ||
RichTextAction.Button( | ||
action: $0, | ||
context: context, | ||
fillVertically: true | ||
) | ||
} | ||
} | ||
.frame(width: groupWidth) | ||
} | ||
} | ||
} | ||
|
||
private extension RichTextAction.ButtonGroup { | ||
|
||
var groupWidth: CGFloat? { | ||
if isGreedy { return nil } | ||
let count = Double(actions.count) | ||
#if macOS | ||
return 30 * count | ||
#else | ||
return 50 * count | ||
#endif | ||
} | ||
} | ||
|
||
struct RichTextAction_ButtonGroup_Previews: PreviewProvider { | ||
|
||
struct Preview: View { | ||
|
||
@StateObject | ||
private var context = RichTextContext() | ||
|
||
func group(greedy: Bool) -> some View { | ||
RichTextAction.ButtonGroup( | ||
context: context, | ||
actions: [.undoLatestChange, .redoLatestChange, .copy], | ||
greedy: greedy | ||
) | ||
} | ||
|
||
var body: some View { | ||
VStack { | ||
group(greedy: true) | ||
group(greedy: false) | ||
} | ||
.padding() | ||
} | ||
} | ||
|
||
static var previews: some View { | ||
Preview() | ||
} | ||
} | ||
#endif |
80 changes: 80 additions & 0 deletions
80
Sources/RichTextKit/Actions/RichTextAction+ButtonStack.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// | ||
// RichTextAction+ButtonStack.swift | ||
// RichTextKit | ||
// | ||
// Created by Daniel Saidi on 2023-06-01. | ||
// Copyright © 2023-2024 Daniel Saidi. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
|
||
public extension RichTextAction { | ||
|
||
/** | ||
This view lists ``RichTextAction`` buttons in a stack. | ||
|
||
Since this view controls multiple values, it binds directly | ||
to a ``RichTextContext`` instead of to individual values. | ||
*/ | ||
struct ButtonStack: View { | ||
|
||
/** | ||
Create a rich text action button stack. | ||
|
||
- Parameters: | ||
- context: The context to affect. | ||
- actions: The actions to list, by default all non-size actions. | ||
- spacing: The spacing to apply to stack items, by default `5`. | ||
*/ | ||
public init( | ||
context: RichTextContext, | ||
actions: [RichTextAction], | ||
spacing: Double = 5 | ||
) { | ||
self._context = ObservedObject(wrappedValue: context) | ||
self.actions = actions | ||
self.spacing = spacing | ||
} | ||
|
||
private let actions: [RichTextAction] | ||
private let spacing: Double | ||
|
||
@ObservedObject | ||
private var context: RichTextContext | ||
|
||
public var body: some View { | ||
HStack(spacing: spacing) { | ||
ForEach(actions) { | ||
RichTextAction.Button( | ||
action: $0, | ||
context: context, | ||
fillVertically: true | ||
).frame(maxHeight: .infinity) | ||
} | ||
} | ||
.fixedSize(horizontal: false, vertical: true) | ||
} | ||
} | ||
} | ||
|
||
struct RichTextAction_ButtonStack_Previews: PreviewProvider { | ||
|
||
struct Preview: View { | ||
|
||
@StateObject | ||
private var context = RichTextContext() | ||
|
||
var body: some View { | ||
RichTextAction.ButtonStack( | ||
context: context, | ||
actions: [.undoLatestChange, .redoLatestChange, .copy] | ||
) | ||
.buttonStyle(.bordered) | ||
.padding() | ||
} | ||
} | ||
|
||
static var previews: some View { | ||
Preview() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.