Skip to content
Open
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
5 changes: 5 additions & 0 deletions Sources/Showcase/PlaygroundListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ enum PlaygroundType: CaseIterable, View {
case table
case tabView
case text
case textConcatenation
case textEditor
case textField
case toggle
Expand Down Expand Up @@ -263,6 +264,8 @@ enum PlaygroundType: CaseIterable, View {
return LocalizedStringResource("TabView", comment: "Title of TabView playground")
case .text:
return LocalizedStringResource("Text", comment: "Title of Text playground")
case .textConcatenation:
return LocalizedStringResource("Text Concatenation", comment: "Title of Text Concatenation playground")
case .textEditor:
return LocalizedStringResource("TextEditor", comment: "Title of Text playground")
case .textField:
Expand Down Expand Up @@ -470,6 +473,8 @@ enum PlaygroundType: CaseIterable, View {
TabViewPlayground()
case .text:
TextPlayground()
case .textConcatenation:
TextConcatenationPlayground()
case .textEditor:
TextEditorPlayground()
case .textField:
Expand Down
61 changes: 61 additions & 0 deletions Sources/Showcase/TextConcatenationPlayground.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2023–2026 Skip
import SwiftUI

/// Demonstrates `Text + Text` concatenation: each operand keeps its own styling, and the result
/// renders as a single flowing run (a Compose `AnnotatedString` on Android) rather than separate views.
struct TextConcatenationPlayground: View {
var body: some View {
ScrollView {
VStack(spacing: 16) {
Text("Per-run color").font(.headline)
Text("Plain ")
+ Text("red ").foregroundColor(.red)
+ Text("green ").foregroundColor(.green)
+ Text("blue").foregroundColor(.blue)

Divider()

Text("Weight, italic, monospaced").font(.headline)
Text("normal ")
+ Text("bold ").bold()
+ Text("heavy ").fontWeight(.heavy)
+ Text("italic ").italic()
+ Text("mono").monospaced()

Divider()

Text("Mixed font sizes").font(.headline)
Text("caption ").font(.caption)
+ Text("body ").font(.body)
+ Text("title ").font(.title)

Divider()

Text("Decorations").font(.headline)
Text("plain ")
+ Text("underline ").underline()
+ Text("strikethrough").strikethrough()

Divider()

Text("Gradient foreground").font(.headline)
Text("solid ")
+ Text("gradient run")
.foregroundStyle(LinearGradient(colors: [.blue, .purple, .pink], startPoint: .leading, endPoint: .trailing))
.bold()

Divider()

Text("Combined styles + wrapping").font(.headline)
Text("This ").foregroundColor(.orange).bold()
+ Text("concatenated ").italic()
+ Text("text ").underline()
+ Text("mixes several styles and wraps across multiple lines as one paragraph").foregroundColor(.secondary)
}
.padding()
}
.toolbar {
PlaygroundSourceLink(file: "TextConcatenationPlayground.swift")
}
}
}
Loading