Skip to content

Commit 4b28145

Browse files
committed
Add text-styling modifiers (font, foregroundColor, bold, italic, lineLimit)
1 parent cc60c6a commit 4b28145

1 file changed

Lines changed: 155 additions & 0 deletions

File tree

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
//
2+
// TextModifiers.swift
3+
// AndroidSwiftUICore
4+
//
5+
// Text-styling modifiers. Unlike layout modifiers (padding, background…) that
6+
// fold into the Compose `Modifier` chain, these describe attributes of the
7+
// `Text` composable itself; the interpreter reads their kinds off a Text
8+
// node's modifier chain and applies them as `Text(...)` parameters.
9+
//
10+
11+
// MARK: - Font
12+
13+
/// A font: either a named text style (resolved to a size by the interpreter)
14+
/// or an explicit system size, with an optional weight.
15+
public struct Font: Equatable, Sendable {
16+
17+
internal var style: String?
18+
internal var size: Double?
19+
internal var weight: Weight?
20+
21+
internal init(style: String? = nil, size: Double? = nil, weight: Weight? = nil) {
22+
self.style = style
23+
self.size = size
24+
self.weight = weight
25+
}
26+
27+
public enum Weight: String, Equatable, Sendable {
28+
case ultraLight, thin, light, regular, medium, semibold, bold, heavy, black
29+
}
30+
31+
public static let largeTitle = Font(style: "largeTitle")
32+
public static let title = Font(style: "title")
33+
public static let title2 = Font(style: "title2")
34+
public static let title3 = Font(style: "title3")
35+
public static let headline = Font(style: "headline")
36+
public static let subheadline = Font(style: "subheadline")
37+
public static let body = Font(style: "body")
38+
public static let callout = Font(style: "callout")
39+
public static let footnote = Font(style: "footnote")
40+
public static let caption = Font(style: "caption")
41+
public static let caption2 = Font(style: "caption2")
42+
43+
public static func system(size: Double, weight: Weight? = nil) -> Font {
44+
Font(size: size, weight: weight)
45+
}
46+
47+
public func weight(_ weight: Weight) -> Font {
48+
var copy = self
49+
copy.weight = weight
50+
return copy
51+
}
52+
53+
public func bold() -> Font { weight(.bold) }
54+
}
55+
56+
public struct _FontModifier: RenderModifier {
57+
let font: Font
58+
public var _modifierNode: ModifierNode {
59+
var args: [String: PropValue] = [:]
60+
if let style = font.style { args["style"] = .string(style) }
61+
if let size = font.size { args["size"] = .double(size) }
62+
if let weight = font.weight { args["weight"] = .string(weight.rawValue) }
63+
return ModifierNode(kind: "font", args: args)
64+
}
65+
}
66+
67+
public extension View {
68+
func font(_ font: Font) -> ModifiedContent<Self, _FontModifier> {
69+
modifier(_FontModifier(font: font))
70+
}
71+
}
72+
73+
// MARK: - Foreground color
74+
75+
public struct _ForegroundColorModifier: RenderModifier {
76+
let color: Color
77+
public var _modifierNode: ModifierNode {
78+
ModifierNode(kind: "foregroundColor", args: ["color": color.propValue])
79+
}
80+
}
81+
82+
public extension View {
83+
func foregroundColor(_ color: Color) -> ModifiedContent<Self, _ForegroundColorModifier> {
84+
modifier(_ForegroundColorModifier(color: color))
85+
}
86+
func foregroundStyle(_ color: Color) -> ModifiedContent<Self, _ForegroundColorModifier> {
87+
modifier(_ForegroundColorModifier(color: color))
88+
}
89+
}
90+
91+
// MARK: - Weight
92+
93+
public struct _FontWeightModifier: RenderModifier {
94+
let weight: Font.Weight
95+
public var _modifierNode: ModifierNode {
96+
ModifierNode(kind: "fontWeight", args: ["weight": .string(weight.rawValue)])
97+
}
98+
}
99+
100+
public extension View {
101+
func fontWeight(_ weight: Font.Weight) -> ModifiedContent<Self, _FontWeightModifier> {
102+
modifier(_FontWeightModifier(weight: weight))
103+
}
104+
func bold() -> ModifiedContent<Self, _FontWeightModifier> {
105+
modifier(_FontWeightModifier(weight: .bold))
106+
}
107+
}
108+
109+
// MARK: - Italic
110+
111+
public struct _ItalicModifier: RenderModifier {
112+
public var _modifierNode: ModifierNode { ModifierNode(kind: "italic") }
113+
}
114+
115+
public extension View {
116+
func italic() -> ModifiedContent<Self, _ItalicModifier> {
117+
modifier(_ItalicModifier())
118+
}
119+
}
120+
121+
// MARK: - Line limit
122+
123+
public struct _LineLimitModifier: RenderModifier {
124+
let limit: Int?
125+
public var _modifierNode: ModifierNode {
126+
var args: [String: PropValue] = [:]
127+
if let limit { args["count"] = .int(limit) }
128+
return ModifierNode(kind: "lineLimit", args: args)
129+
}
130+
}
131+
132+
public extension View {
133+
func lineLimit(_ number: Int?) -> ModifiedContent<Self, _LineLimitModifier> {
134+
modifier(_LineLimitModifier(limit: number))
135+
}
136+
}
137+
138+
// MARK: - Multiline text alignment
139+
140+
public enum TextAlignment: String, Equatable, Sendable {
141+
case leading, center, trailing
142+
}
143+
144+
public struct _MultilineTextAlignmentModifier: RenderModifier {
145+
let alignment: TextAlignment
146+
public var _modifierNode: ModifierNode {
147+
ModifierNode(kind: "multilineTextAlignment", args: ["value": .string(alignment.rawValue)])
148+
}
149+
}
150+
151+
public extension View {
152+
func multilineTextAlignment(_ alignment: TextAlignment) -> ModifiedContent<Self, _MultilineTextAlignmentModifier> {
153+
modifier(_MultilineTextAlignmentModifier(alignment: alignment))
154+
}
155+
}

0 commit comments

Comments
 (0)