Skip to content

Commit 7be885d

Browse files
authored
Refactored whole structure to inherit featurs from other libraries (#51)
1 parent 2a07709 commit 7be885d

File tree

55 files changed

+3701
-577
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+3701
-577
lines changed

Package.swift

+21-9
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,39 @@
1-
// swift-tools-version: 5.5
2-
// The swift-tools-version declares the minimum version of Swift required to build this package.
1+
// swift-tools-version: 5.9
32

43
import PackageDescription
54

65
let package = Package(
76
name: "RichEditorSwiftUI",
87
platforms: [
9-
//Add supported platforms here
10-
.iOS(.v14),
8+
.iOS(.v15),
9+
.macOS(.v12),
10+
.tvOS(.v15),
11+
.watchOS(.v8),
12+
.visionOS(.v1)
1113
],
1214
products: [
13-
// Products define the executables and libraries a package produces, making them visible to other packages.
1415
.library(
1516
name: "RichEditorSwiftUI",
1617
targets: ["RichEditorSwiftUI"]),
1718
],
19+
dependencies: [],
1820
targets: [
19-
// Targets are the basic building blocks of a pack.age, defining a module or a test suite.
20-
// Targets can depend on other targets in this package and products from dependencies.
2121
.target(
22-
name: "RichEditorSwiftUI"),
22+
name: "RichEditorSwiftUI",
23+
dependencies: [],
24+
resources: [],
25+
swiftSettings: [
26+
.define("macOS", .when(platforms: [.macOS])),
27+
.define("iOS", .when(platforms: [.iOS, .macCatalyst]))
28+
]
29+
),
2330
.testTarget(
2431
name: "RichEditorSwiftUITests",
25-
dependencies: ["RichEditorSwiftUI"]),
32+
dependencies: ["RichEditorSwiftUI"],
33+
swiftSettings: [
34+
.define("macOS", .when(platforms: [.macOS])),
35+
.define("iOS", .when(platforms: [.iOS, .macCatalyst]))
36+
]
37+
)
2638
]
2739
)

RichEditorDemo/RichEditorDemo.xcodeproj/project.pbxproj

+8-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 56;
6+
objectVersion = 77;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -126,14 +126,14 @@
126126
};
127127
};
128128
buildConfigurationList = 2A0D57912AD66C7200BCF488 /* Build configuration list for PBXProject "RichEditorDemo" */;
129-
compatibilityVersion = "Xcode 14.0";
130129
developmentRegion = en;
131130
hasScannedForEncodings = 0;
132131
knownRegions = (
133132
en,
134133
Base,
135134
);
136135
mainGroup = 2A0D578D2AD66C7200BCF488;
136+
preferredProjectObjectVersion = 77;
137137
productRefGroup = 2A0D57972AD66C7200BCF488 /* Products */;
138138
projectDirPath = "";
139139
projectRoot = "";
@@ -312,12 +312,13 @@
312312
MARKETING_VERSION = 1.0;
313313
PRODUCT_BUNDLE_IDENTIFIER = com.canopas.RichEditorDemo;
314314
PRODUCT_NAME = "$(TARGET_NAME)";
315+
REGISTER_APP_GROUPS = NO;
315316
SDKROOT = auto;
316-
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
317+
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
317318
SUPPORTS_MACCATALYST = NO;
318319
SWIFT_EMIT_LOC_STRINGS = YES;
319320
SWIFT_VERSION = 5.0;
320-
TARGETED_DEVICE_FAMILY = "1,2";
321+
TARGETED_DEVICE_FAMILY = "1,2,3";
321322
};
322323
name = Debug;
323324
};
@@ -349,12 +350,13 @@
349350
MARKETING_VERSION = 1.0;
350351
PRODUCT_BUNDLE_IDENTIFIER = com.canopas.RichEditorDemo;
351352
PRODUCT_NAME = "$(TARGET_NAME)";
353+
REGISTER_APP_GROUPS = NO;
352354
SDKROOT = auto;
353-
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
355+
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
354356
SUPPORTS_MACCATALYST = NO;
355357
SWIFT_EMIT_LOC_STRINGS = YES;
356358
SWIFT_VERSION = 5.0;
357-
TARGETED_DEVICE_FAMILY = "1,2";
359+
TARGETED_DEVICE_FAMILY = "1,2,3";
358360
};
359361
name = Release;
360362
};

RichEditorDemo/RichEditorDemo/ContentView.swift

+10-5
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,18 @@ struct ContentView: View {
3131
VStack {
3232
EditorToolBarView(state: state)
3333

34-
RichEditor(state: _state)
35-
.textPadding(12)
36-
.cornerRadius(10)
34+
RichTextEditor(
35+
context: _state,
36+
viewConfiguration: { _ in
37+
38+
}
39+
)
40+
.cornerRadius(10)
3741
}
3842
.padding(10)
3943
.toolbar {
40-
ToolbarItem(placement: .topBarTrailing) {
44+
ToolbarItem() {
4145
Button(action: {
42-
4346
print("Exported JSON == \(state.output())")
4447
}, label: {
4548
Image(systemName: "checkmark")
@@ -49,7 +52,9 @@ struct ContentView: View {
4952
}
5053
.background(colorScheme == .dark ? .black : .gray.opacity(0.07))
5154
.navigationTitle("Rich Editor")
55+
#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst)
5256
.navigationBarTitleDisplayMode(.inline)
57+
#endif
5358
}
5459
}
5560
}

RichEditorDemo/RichEditorDemo/Sample_json.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,15 @@
108108
"attributes": {}
109109
},
110110
{
111-
"insert": "Canopas Team.\n\n",
111+
"insert": "Canopas Team.",
112112
"attributes": {
113113
"bold": true,
114114
"italic": true,
115115
"underline": true
116116
}
117117
},
118118
{
119-
"insert": "Thank You! 😊\n\n",
119+
"insert": "\n\nThank You! 😊\n\n",
120120
"attributes": {}
121121
}
122122
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//
2+
// RichTextAction.swift
3+
// RichEditorSwiftUI
4+
//
5+
// Created by Divyesh Vekariya on 21/10/24.
6+
//
7+
8+
import SwiftUI
9+
import Combine
10+
11+
/**
12+
This enum defines rich text actions that can be executed on
13+
a rich text editor.
14+
15+
This type also serves as a type namespace for other related
16+
types and views, like ``RichTextAction/Button``.
17+
*/
18+
public enum RichTextAction: Identifiable, Equatable {
19+
20+
/// Copy the currently selected text, if any.
21+
case copy
22+
23+
/// Dismiss any presented software keyboard.
24+
case dismissKeyboard
25+
26+
/// Paste a single image.
27+
// case pasteImage(RichTextInsertion<ImageRepresentable>)
28+
//
29+
// /// Paste multiple images.
30+
// case pasteImages(RichTextInsertion<[ImageRepresentable]>)
31+
//
32+
// /// Paste plain text.
33+
// case pasteText(RichTextInsertion<String>)
34+
35+
/// A print command.
36+
case print
37+
38+
/// Redo the latest undone change.
39+
case redoLatestChange
40+
41+
/// Select a range.
42+
case selectRange(NSRange)
43+
44+
/// Set the text alignment.
45+
case setAlignment(_ alignment: RichTextAlignment)
46+
47+
/// Set the entire attributed string.
48+
case setAttributedString(NSAttributedString)
49+
50+
// Change background color
51+
case setColor(RichTextColor, ColorRepresentable)
52+
53+
// Highlighted renge
54+
case setHighlightedRange(NSRange?)
55+
56+
// Change highlighting style
57+
case setHighlightingStyle(RichTextHighlightingStyle)
58+
59+
/// Set a certain ``RichTextStyle``.
60+
case setStyle(RichTextStyle, Bool)
61+
62+
/// Step the font size.
63+
case stepFontSize(points: Int)
64+
65+
/// Step the indent level.
66+
case stepIndent(points: CGFloat)
67+
68+
/// Step the line spacing.
69+
case stepLineSpacing(points: CGFloat)
70+
71+
/// Step the superscript level.
72+
case stepSuperscript(steps: Int)
73+
74+
/// Toggle a certain style.
75+
case toggleStyle(_ style: RichTextStyle)
76+
77+
/// Undo the latest change.
78+
case undoLatestChange
79+
80+
/// Set HeaderStyle.
81+
case setHeaderStyle(_ style: RichTextStyle, range: NSRange)
82+
}
83+
84+
public extension RichTextAction {
85+
86+
typealias Publisher = PassthroughSubject<Self, Never>
87+
88+
/// The action's unique identifier.
89+
var id: String { UUID().uuidString }
90+
91+
/// The action's standard icon.
92+
93+
}
94+
95+
// MARK: - Aliases
96+
97+
public extension RichTextAction {
98+
99+
/// A name alias for `.redoLatestChange`.
100+
static var redo: RichTextAction { .redoLatestChange }
101+
102+
/// A name alias for `.undoLatestChange`.
103+
static var undo: RichTextAction { .undoLatestChange }
104+
}
105+
106+
public extension CGFloat {
107+
108+
/// The default rich text indent step size.
109+
static var defaultRichTextIntentStepSize: CGFloat = 30.0
110+
}
111+
112+
public extension UInt {
113+
114+
/// The default rich text indent step size.
115+
static var defaultRichTextIntentStepSize: UInt = 30
116+
}
117+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//
2+
// RichTextAlignment.swift
3+
// RichEditorSwiftUI
4+
//
5+
// Created by Divyesh Vekariya on 21/10/24.
6+
//
7+
8+
import SwiftUI
9+
10+
/**
11+
This enum defines supported rich text alignments, like left,
12+
right, center, and justified.
13+
*/
14+
public enum RichTextAlignment: String, CaseIterable, Codable, Equatable, Identifiable {
15+
16+
/**
17+
Initialize a rich text alignment with a native alignment.
18+
19+
- Parameters:
20+
- alignment: The native alignment to use.
21+
*/
22+
public init(_ alignment: NSTextAlignment) {
23+
switch alignment {
24+
case .left: self = .left
25+
case .right: self = .right
26+
case .center: self = .center
27+
case .justified: self = .justified
28+
default: self = .left
29+
}
30+
}
31+
32+
/// Left text alignment.
33+
case left
34+
35+
/// Center text alignment.
36+
case center
37+
38+
/// Justified text alignment.
39+
case justified
40+
41+
/// Right text alignment.
42+
case right
43+
}
44+
45+
public extension Collection where Element == RichTextAlignment {
46+
47+
static var all: [Element] { RichTextAlignment.allCases }
48+
}
49+
50+
public extension RichTextAlignment {
51+
52+
/// The unique alignment ID.
53+
var id: String { rawValue }
54+
55+
/// The standard icon to use for the alignment.
56+
// var icon: Image { nativeAlignment.icon }
57+
58+
/// The standard title to use for the alignment.
59+
// var title: String { nativeAlignment.title }
60+
61+
/// The standard title key to use for the alignment.
62+
// var titleKey: RTKL10n { nativeAlignment.titleKey }
63+
64+
/// The native alignment of the alignment.
65+
var nativeAlignment: NSTextAlignment {
66+
switch self {
67+
case .left: .left
68+
case .right: .right
69+
case .center: .center
70+
case .justified: .justified
71+
}
72+
}
73+
}
74+
75+
//extension NSTextAlignment: RichTextLabelValue {}
76+
77+
public extension NSTextAlignment {
78+
79+
// /// The standard icon to use for the alignment.
80+
// var icon: Image {
81+
// switch self {
82+
// case .left: .richTextAlignmentLeft
83+
// case .right: .richTextAlignmentRight
84+
// case .center: .richTextAlignmentCenter
85+
// case .justified: .richTextAlignmentJustified
86+
// default: .richTextAlignmentLeft
87+
// }
88+
// }
89+
90+
}

Sources/RichEditorSwiftUI/Attributes/RichTextAttributeWriter+List.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private extension RichTextAttributeWriter {
9494
let paragraphStyle = NSMutableParagraphStyle()
9595

9696
paragraphStyle.alignment = .left
97-
let listItem = NSTextList(markerFormat: listType.getMarkerFormat(), options: 0)
97+
let listItem = TextList(markerFormat: listType.getMarkerFormat(), options: 0)
9898

9999
if paragraphStyle.textLists.isEmpty && newValue {
100100
paragraphStyle.textLists.append(listItem)

Sources/RichEditorSwiftUI/Attributes/RichTextAttributeWriter+Style.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import Foundation
99

1010
public extension NSMutableAttributedString {
11-
11+
1212
/**
1313
Set a rich text style at a certain range.
1414

@@ -37,7 +37,7 @@ public extension NSMutableAttributedString {
3737
let attributeValue = newValue ? 1 : 0
3838
if style == .underline { return setRichTextAttribute(.underlineStyle, to: attributeValue, at: range) }
3939
if style == .strikethrough { return setRichTextAttribute(.strikethroughStyle, to: attributeValue, at: range) }
40-
guard let font = richTextFont(at: range) else { return }
40+
let font = richTextFont(at: range) ?? .standardRichTextFont
4141
let styles = richTextStyles(at: range)
4242
let shouldAdd = newValue && !styles.hasStyle(style)
4343
let shouldRemove = !newValue && styles.hasStyle(style)

0 commit comments

Comments
 (0)