Skip to content

Commit b643e86

Browse files
authored
Rewrite README for 4.0.0 release (#35)
1 parent cb94194 commit b643e86

File tree

2 files changed

+69
-58
lines changed

2 files changed

+69
-58
lines changed

Package.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ let package = Package(
77
name: "TextBuilder",
88
platforms: [
99
.iOS(.v13),
10-
.tvOS(.v13),
10+
.macCatalyst(.v13),
1111
.macOS(.v10_15),
12+
.tvOS(.v13),
13+
.visionOS(.v1),
1214
.watchOS(.v6),
1315
],
1416
products: [

README.md

Lines changed: 66 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,114 +8,123 @@
88

99
`Text` composition in SwiftUI can often be cumbersome, especially when there's logic affecting its format and content.
1010

11-
TextBuilder leverages the power of Swift [Result Builders](https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md) to solve this problem. TextBuilder mimics SwiftUI's [ViewBuilder](https://developer.apple.com/documentation/swiftui/viewbuilder) to make for a familiar experience at the point of use.
11+
TextBuilder leverages the power of Swift [Macros](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/) to solve this problem. The `@TextBuilder` macro transforms functions into builder-style closures, making text composition intuitive and readable.
12+
13+
## Installation
14+
15+
Add `TextBuilder` to your Swift Package Manager dependencies:
16+
17+
```swift
18+
.package(url: "https://github.com/davdroman/swiftui-text-builder", from: "4.0.0"),
19+
```
20+
21+
Then, add the dependency to your desired target:
22+
23+
```swift
24+
.product(name: "TextBuilder", package: "swiftui-text-builder"),
25+
```
1226

1327
## Usage
1428

15-
TextBuilder offers 3 ready-made builders out of the box, depending on which text separator you need.
29+
### Basic Usage
1630

17-
### Default (unspaced)
31+
Apply `@TextBuilder` to functions that return `Text`. The macro will transform the function body into a builder-style closure that concatenates text segments.
1832

1933
```swift
2034
@TextBuilder
21-
var loremIpsum: Text {
35+
func loremIpsum() -> Text {
2236
Text("Lorem").underline().foregroundColor(.blue)
2337
Text("ipsum dolor")
2438
Text("sit").bold()
2539
Text("amet, consectetur")
2640
}
2741
```
2842

29-
![](https://github.com/davdroman/TextBuilder/blob/bd991543b123eebf60417b8567f68064655a9151/Tests/TextBuilderTests/__Snapshots__/TextBuilderTests/testBasicTextBuilder.iOS.png?raw=true)
43+
This creates a concatenated `Text` without any separators between segments.
44+
45+
### With Separators
3046

31-
### With Spaces
47+
You can specify a separator to be inserted between text segments:
3248

3349
```swift
34-
@TextBuilderWithSpaces
35-
var loremIpsum: Text {
50+
@TextBuilder(separator: " ")
51+
func spacedText() -> Text {
3652
Text("Lorem").underline().foregroundColor(.blue)
3753
Text("ipsum dolor")
3854
Text("sit").bold()
3955
Text("amet, consectetur")
4056
}
4157
```
4258

43-
![](https://github.com/davdroman/TextBuilder/blob/bd991543b123eebf60417b8567f68064655a9151/Tests/TextBuilderTests/__Snapshots__/TextBuilderTests/testSpacedTextBuilder.iOS.png?raw=true)
44-
45-
### Multiline
59+
For multiline text:
4660

4761
```swift
48-
@TextBuilderWithNewlines
49-
var loremIpsum: Text {
62+
@TextBuilder(separator: "\n")
63+
func multilineText() -> Text {
5064
Text("Lorem").underline().foregroundColor(.blue)
5165
Text("ipsum dolor")
5266
Text("sit").bold()
5367
Text("amet, consectetur")
5468
}
5569
```
5670

57-
![](https://github.com/davdroman/TextBuilder/blob/bd991543b123eebf60417b8567f68064655a9151/Tests/TextBuilderTests/__Snapshots__/TextBuilderTests/testMultilineTextBuilder.iOS.png?raw=true)
58-
59-
### Pro Tip ✨
71+
### String Support ✨
6072

61-
TextBuilder accepts `String` types directly as if they were plain `Text`, and also provides a `String.text` computed var to remove unwanted code noise when `Text` is explicitly needed.
73+
TextBuilder accepts `String` types directly and provides a convenient `.text` computed property:
6274

6375
```swift
64-
@TextBuilderWithNewlines
65-
var loremIpsum: Text {
66-
"Lorem".text.underline().foregroundColor(.blue)
67-
"ipsum dolor"
68-
"sit".text.bold()
69-
"amet, consectetur"
76+
@TextBuilder(separator: " ")
77+
func mixedText() -> Text {
78+
"Hello" // String literal becomes verbatim Text
79+
"world".text.bold() // Use .text for chaining modifiers
80+
String(2025) // Any StringProtocol works
7081
}
7182
```
7283

73-
### Other Separators
84+
### Control Flow
7485

75-
There are two options to customize the separator used to compose your `Text`.
76-
77-
First, you can use `Text.init(separator:content:)`:
86+
TextBuilder supports Swift's control flow statements:
7887

7988
```swift
80-
var loremIpsum: Text {
81-
Text(separator: " 🍆 ") {
82-
"Lorem".text.underline().foregroundColor(.blue)
83-
"ipsum dolor"
84-
"sit".text.bold()
85-
"amet, consectetur"
89+
@TextBuilder(separator: " ")
90+
func conditionalText(showDetails: Bool) -> Text {
91+
"Hello"
92+
93+
if showDetails {
94+
"with details"
95+
} else {
96+
"basic"
97+
}
98+
99+
if let name = userName {
100+
name.text.italic()
101+
}
102+
103+
for i in 1...3 {
104+
String(i)
86105
}
87106
}
88107
```
89108

90-
But if you prefer to keep using a result builder, you can:
109+
### Alternative API
91110

92-
```swift
93-
struct EggplantSeparator: TextBuilderSeparator {
94-
static var separator: String? { " 🍆 " }
95-
}
111+
If you prefer not to use macros, you can use the underlying `Text` initializer directly:
96112

97-
@TextBuilderWith<EggplantSeparator>
98-
var loremIpsum: Text {
99-
"Lorem".text.underline().foregroundColor(.blue)
100-
"ipsum dolor"
101-
"sit".text.bold()
102-
"amet, consectetur"
113+
```swift
114+
var body: some View {
115+
Text(separator: " 👏 ") {
116+
"Lorem".text.underline().foregroundColor(.blue)
117+
"ipsum dolor"
118+
"sit".text.bold()
119+
"amet, consectetur"
120+
}
103121
}
104122
```
105123

106-
![](https://github.com/davdroman/TextBuilder/blob/bd991543b123eebf60417b8567f68064655a9151/Tests/TextBuilderTests/__Snapshots__/TextBuilderTests/testCustomTextBuilder.iOS.png?raw=true)
107-
108-
## Benchmarks
124+
This is useful if you simply want to insert some rich text into a view body without defining a separate function.
109125

110-
```
111-
MacBook Pro (14-inch, 2021)
112-
Apple M1 Pro (10 cores, 8 performance and 2 efficiency)
113-
32 GB Memory
126+
## Limitations
114127

115-
$ swift run -c release Benchmarks
128+
The `@TextBuilder` macro currently cannot be applied to computed properties due to Swift limitations. Use functions instead.
116129

117-
name time std iterations
118-
------------------------------------------------
119-
Result Builder 1875.000 ns ± 26.15 % 729940
120-
Initializer 2542.000 ns ± 16.88 % 540826
121-
```
130+
See [Swift Issue #75715](https://github.com/swiftlang/swift/issues/75715) for updates on computed property support.

0 commit comments

Comments
 (0)