|
| 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