Skip to content

Commit 612d717

Browse files
committed
Apply text styling to Text composable
1 parent 3f0681c commit 612d717

1 file changed

Lines changed: 84 additions & 4 deletions

File tree

  • Demo/swiftui/src/commonMain/kotlin/com/pureswift/swiftui

Demo/swiftui/src/commonMain/kotlin/com/pureswift/swiftui/Render.kt

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ import androidx.compose.ui.draw.clip
6464
import androidx.compose.ui.draw.rotate
6565
import androidx.compose.ui.draw.scale
6666
import androidx.compose.ui.graphics.Color
67+
import androidx.compose.ui.text.font.FontStyle
68+
import androidx.compose.ui.text.font.FontWeight
69+
import androidx.compose.ui.text.style.TextAlign
6770
import androidx.compose.ui.text.input.TextFieldValue
71+
import androidx.compose.ui.unit.TextUnit
72+
import androidx.compose.ui.unit.sp
6873
import androidx.compose.ui.unit.IntOffset
6974
import androidx.compose.ui.unit.dp
7075
import androidx.compose.foundation.layout.fillMaxWidth
@@ -79,10 +84,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
7984
fun Render(node: ViewNode) {
8085
key(node.id) {
8186
when (node.type) {
82-
"Text" -> Text(
83-
text = node.string("text") ?: "",
84-
modifier = node.composeModifiers(),
85-
)
87+
"Text" -> RenderText(node)
8688

8789
"Button" -> {
8890
val onTap = node.long("onTap")
@@ -332,6 +334,84 @@ private fun zStackAlignment(node: ViewNode): Alignment {
332334
}
333335
}
334336

337+
// Text-styling modifiers describe attributes of the Text composable itself,
338+
// not the layout Modifier chain, so they are read off the node here and passed
339+
// as `Text(...)` parameters. Later (innermost) entries win for scalar
340+
// attributes. Layout modifiers in the same chain still apply via composeModifiers().
341+
@Composable
342+
private fun RenderText(node: ViewNode) {
343+
var color = Color.Unspecified
344+
var fontSize: TextUnit = TextUnit.Unspecified
345+
var weight: FontWeight? = null
346+
var fontStyle: FontStyle? = null
347+
var maxLines = Int.MAX_VALUE
348+
var textAlign: TextAlign? = null
349+
for (m in node.modifiers) {
350+
when (m.kind) {
351+
"font" -> {
352+
m.args.string("style")?.let { style ->
353+
fontSize = fontSizeForStyle(style).sp
354+
if (weight == null) weight = defaultWeightForStyle(style)
355+
}
356+
m.args.double("size")?.let { fontSize = it.sp }
357+
m.args.string("weight")?.let { weight = fontWeightFor(it) }
358+
}
359+
"fontWeight" -> m.args.string("weight")?.let { weight = fontWeightFor(it) }
360+
"italic" -> fontStyle = FontStyle.Italic
361+
"foregroundColor" -> m.args.long("color")?.let { color = Color(it.toInt()) }
362+
"lineLimit" -> maxLines = m.args.long("count")?.toInt() ?: Int.MAX_VALUE
363+
"multilineTextAlignment" -> textAlign = when (m.args.string("value")) {
364+
"leading" -> TextAlign.Start
365+
"trailing" -> TextAlign.End
366+
else -> TextAlign.Center
367+
}
368+
}
369+
}
370+
Text(
371+
text = node.string("text") ?: "",
372+
color = color,
373+
fontSize = fontSize,
374+
fontWeight = weight,
375+
fontStyle = fontStyle,
376+
maxLines = maxLines,
377+
textAlign = textAlign,
378+
modifier = node.composeModifiers(),
379+
)
380+
}
381+
382+
// SwiftUI named text styles → point sizes (Compose has no built-in analog).
383+
private fun fontSizeForStyle(style: String): Double = when (style) {
384+
"largeTitle" -> 34.0
385+
"title" -> 28.0
386+
"title2" -> 22.0
387+
"title3" -> 20.0
388+
"headline" -> 17.0
389+
"body" -> 17.0
390+
"callout" -> 16.0
391+
"subheadline" -> 15.0
392+
"footnote" -> 13.0
393+
"caption" -> 12.0
394+
"caption2" -> 11.0
395+
else -> 17.0
396+
}
397+
398+
// Only headline carries a non-regular default weight in SwiftUI.
399+
private fun defaultWeightForStyle(style: String): FontWeight? =
400+
if (style == "headline") FontWeight.SemiBold else null
401+
402+
private fun fontWeightFor(name: String): FontWeight = when (name) {
403+
"ultraLight" -> FontWeight.ExtraLight
404+
"thin" -> FontWeight.Thin
405+
"light" -> FontWeight.Light
406+
"regular" -> FontWeight.Normal
407+
"medium" -> FontWeight.Medium
408+
"semibold" -> FontWeight.SemiBold
409+
"bold" -> FontWeight.Bold
410+
"heavy" -> FontWeight.ExtraBold
411+
"black" -> FontWeight.Black
412+
else -> FontWeight.Normal
413+
}
414+
335415
/// Folds a node's ordered modifier chain into a Compose `Modifier`.
336416
/// The chain arrives outermost-first, which is exactly Compose's order.
337417
internal fun ViewNode.composeModifiers(): Modifier {

0 commit comments

Comments
 (0)