Skip to content

Commit

Permalink
Supported font size customization
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-divyesh-v committed Nov 15, 2024
1 parent 97e8871 commit 382eb14
Show file tree
Hide file tree
Showing 28 changed files with 1,539 additions and 418 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// RichTextAction+KeyboardShortcutModifier.swift
// RichEditorSwiftUI
//
// Created by Divyesh Vekariya on 30/10/24.
//

import SwiftUI

public extension RichTextAction {

/**
This view modifier can apply keyboard shortcuts for any
``RichTextAction`` to any view.

You can also apply it with the `.keyboardShortcut(for:)`
view modifier.
*/
struct KeyboardShortcutModifier: ViewModifier {

public init(_ action: RichTextAction) {
self.action = action
}

private let action: RichTextAction

public func body(content: Content) -> some View {
content.keyboardShortcut(for: action)
}
}
}

public extension View {

/// Apply a ``RichTextAction/KeyboardShortcutModifier``.
@ViewBuilder
func keyboardShortcut(for action: RichTextAction) -> some View {
#if iOS || macOS || os(visionOS)
switch action {
case .copy: keyboardShortcut("c", modifiers: .command)
case .dismissKeyboard: self
case .print: keyboardShortcut("p", modifiers: .command)
case .redoLatestChange: keyboardShortcut("z", modifiers: [.command, .shift])
// case .setAlignment(let align): keyboardShortcut(for: align)
case .stepFontSize(let points): keyboardShortcut(points < 0 ? "-" : "+", modifiers: .command)
case .stepIndent(let steps): keyboardShortcut(steps < 0 ? "Ö" : "Ä", modifiers: .command)
case .stepSuperscript: self
// case .toggleStyle(let style): keyboardShortcut(for: style)
case .undoLatestChange: keyboardShortcut("z", modifiers: .command)
default: self // TODO: Probably not defined, object to discuss.
}
#else
self
#endif
}
}

80 changes: 77 additions & 3 deletions Sources/RichEditorSwiftUI/Actions/RichTextAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,92 @@ public enum RichTextAction: Identifiable, Equatable {
case undoLatestChange

/// Set HeaderStyle.
case setHeaderStyle(_ style: RichTextStyle, range: NSRange)
case setHeaderStyle(_ style: RichTextStyle)
}

public extension RichTextAction {

typealias Publisher = PassthroughSubject<Self, Never>

/// The action's unique identifier.
var id: String { UUID().uuidString }
var id: String { title }

/// The action's standard icon.

var icon: Image {
switch self {
case .copy: .richTextCopy
case .dismissKeyboard: .richTextDismissKeyboard
// case .pasteImage: .richTextDocuments
// case .pasteImages: .richTextDocuments
// case .pasteText: .richTextDocuments
case .print: .richTextPrint
case .redoLatestChange: .richTextRedo
case .selectRange: .richTextSelection
case .setAlignment(let val): val.icon
case .setAttributedString: .richTextDocument
case .setColor(let color, _): color.icon
case .setHighlightedRange: .richTextAlignmentCenter
case .setHighlightingStyle: .richTextAlignmentCenter
case .setStyle(let style, _): style.icon
case .stepFontSize(let val): .richTextStepFontSize(val)
case .stepIndent(let val): .richTextStepIndent(val)
case .stepLineSpacing(let val): .richTextStepLineSpacing(val)
case .stepSuperscript(let val): .richTextStepSuperscript(val)
case .toggleStyle(let val): val.icon
case .undoLatestChange: .richTextUndo
case .setHeaderStyle: .richTextIgnoreIt
}
}

/// The localized label to use for the action.
var label: some View {
icon.label(title)
}

/// The localized title to use in the main menu.
var menuTitle: String {
menuTitleKey.text
}

/// The localized title key to use in the main menu.
var menuTitleKey: RTEL10n {
switch self {
case .stepIndent(let points): .menuIndent(points)
default: titleKey
}
}

/// The localized action title.
var title: String {
titleKey.text
}

/// The localized action title key.
var titleKey: RTEL10n {
switch self {
case .copy: .actionCopy
case .dismissKeyboard: .actionDismissKeyboard
// case .pasteImage: .pasteImage
// case .pasteImages: .pasteImages
// case .pasteText: .pasteText
case .print: .actionPrint
case .redoLatestChange: .actionRedoLatestChange
case .selectRange: .selectRange
case .setAlignment(let alignment): alignment.titleKey
case .setAttributedString: .setAttributedString
case .setColor(let color, _): color.titleKey
case .setHighlightedRange: .highlightedRange
case .setHighlightingStyle: .highlightingStyle
case .setStyle(let style, _): style.titleKey
case .stepFontSize(let points): .actionStepFontSize(points)
case .stepIndent(let points): .actionStepIndent(points)
case .stepLineSpacing(let points): .actionStepLineSpacing(points)
case .stepSuperscript(let steps): .actionStepSuperscript(steps)
case .toggleStyle(let style): style.titleKey
case .undoLatestChange: .actionUndoLatestChange
case .setHeaderStyle: .ignoreIt
}
}
}

// MARK: - Aliases
Expand Down
61 changes: 61 additions & 0 deletions Sources/RichEditorSwiftUI/Actions/RichTextActionButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// RichTextActionButton.swift
// RichEditorSwiftUI
//
// Created by Divyesh Vekariya on 29/10/24.
//

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: RichEditorState,
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: RichEditorState

public var body: some View {
SwiftUI.Button(action: triggerAction) {
action.label
.labelStyle(.iconOnly)
.frame(maxHeight: fillVertically ? .infinity : nil)
.contentShape(Rectangle())
}
.keyboardShortcut(for: action)
.disabled(!context.canHandle(action))
}
}
}

private extension RichTextAction.Button {

func triggerAction() {
context.handle(action)
}
}
52 changes: 34 additions & 18 deletions Sources/RichEditorSwiftUI/Alignment/RichTextAlignment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,38 +53,54 @@ public extension RichTextAlignment {
var id: String { rawValue }

/// The standard icon to use for the alignment.
// var icon: Image { nativeAlignment.icon }
var icon: Image { nativeAlignment.icon }

/// The standard title to use for the alignment.
// var title: String { nativeAlignment.title }
var title: String { nativeAlignment.title }

/// The standard title key to use for the alignment.
// var titleKey: RTKL10n { nativeAlignment.titleKey }
var titleKey: RTEL10n { nativeAlignment.titleKey }

/// The native alignment of the alignment.
var nativeAlignment: NSTextAlignment {
switch self {
case .left: .left
case .right: .right
case .center: .center
case .justified: .justified
case .left: .left
case .right: .right
case .center: .center
case .justified: .justified
}
}
}

//extension NSTextAlignment: RichTextLabelValue {}
extension NSTextAlignment: RichTextLabelValue {}

public extension NSTextAlignment {

// /// The standard icon to use for the alignment.
// var icon: Image {
// switch self {
// case .left: .richTextAlignmentLeft
// case .right: .richTextAlignmentRight
// case .center: .richTextAlignmentCenter
// case .justified: .richTextAlignmentJustified
// default: .richTextAlignmentLeft
// }
// }
/// The standard icon to use for the alignment.
var icon: Image {
switch self {
case .left: .richTextAlignmentLeft
case .right: .richTextAlignmentRight
case .center: .richTextAlignmentCenter
case .justified: .richTextAlignmentJustified
default: .richTextAlignmentLeft
}
}

/// The standard title to use for the alignment.
var title: String {
titleKey.text
}

/// The standard title key to use for the alignment.
var titleKey: RTEL10n {
switch self {
case .left: .textAlignmentLeft
case .right: .textAlignmentRight
case .center: .textAlignmentCentered
case .justified: .textAlignmentJustified
default: .textAlignmentLeft
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import Foundation

public extension RichTextAttributes {

/**
Whether or not the attributes has a strikethrough style.
*/
Expand Down
Loading

0 comments on commit 382eb14

Please sign in to comment.