Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supported font size customisation #53

Merged
merged 4 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ jobs:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '16.0'
- name: Build all platforms
run: bash scripts/build.sh ${{ github.event.repository.name }}
- name: Build iOS
run: xcodebuild -scheme $SCHEME -derivedDataPath .build -destination 'generic/platform=iOS' | xcpretty --color;
- name: Build macOS
run: xcodebuild -scheme $SCHEME -derivedDataPath .build -destination 'generic/platform=OS X' | xcpretty --color;
- name: Build tvOS
run: xcodebuild -scheme $SCHEME -derivedDataPath .build -destination 'generic/platform=tvOS' | xcpretty --color;
- name: Build watchOS
run: xcodebuild -scheme $SCHEME -derivedDataPath .build -destination 'generic/platform=watchOS' | xcpretty --color;
- name: Build visionOS
run: xcodebuild -scheme $SCHEME -derivedDataPath .build -destination 'generic/platform=xrOS' | xcpretty --color;
- name: Test iOS
run: bash scripts/test.sh ${{ github.event.repository.name }}
run: xcodebuild test -scheme $SCHEME -derivedDataPath .build -destination 'platform=iOS Simulator,name=iPhone 16 Pro,OS=18.0' -enableCodeCoverage YES | xcpretty --color;
8 changes: 4 additions & 4 deletions RichEditorDemo/RichEditorDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,11 @@
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = NO;
SDKROOT = auto;
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,3";
TARGETED_DEVICE_FAMILY = "1,2,3,7";
TVOS_DEPLOYMENT_TARGET = 17.0;
};
name = Debug;
Expand Down Expand Up @@ -353,11 +353,11 @@
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = NO;
SDKROOT = auto;
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,3";
TARGETED_DEVICE_FAMILY = "1,2,3,7";
TVOS_DEPLOYMENT_TARGET = 17.0;
};
name = Release;
Expand Down
2 changes: 2 additions & 0 deletions RichEditorDemo/RichEditorDemo/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ struct ContentView: View {
var body: some View {
NavigationStack {
VStack {
#if os(iOS) || os(macOS) || os(visionOS)
EditorToolBarView(state: state)
#endif

RichTextEditor(
context: _state,
Expand Down
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
Loading