Patterns from production · One row per thing
One row per thing
Attempts belong inside the task that owns them.
One row per thing
Try the controls to see the rule.
The rule
Keep one row for the task and nest retries or attempts inside it. Name shipping work for the person and target so the list stays scannable.
Tokens used
space.md12pxmotion.duration.base260msmotion.easing.standardcubic-bezier(.2,.7,.2,1)size.tap44px
Native spec · generated from this pattern and the shared token registry
struct OvOneRow: View {
let status: String
@Environment(\.accessibilityReduceMotion) private var reduceMotion
var body: some View {
HStack(spacing: OvScale.spaceMd) {
Text(status).font(.body)
}
.frame(minHeight: OvScale.sizeTap)
.animation(reduceMotion ? .none : .easeOut(duration: OvScale.motionDurationBase), value: status)
}
}
// Tokens: space.md=12px, motion.duration.base=260ms, motion.easing.standard=cubic-bezier(.2,.7,.2,1), size.tap=44px@Composable
fun OvOneRow(status: String, reduceMotion: Boolean) {
Row(
modifier = Modifier.defaultMinSize(minHeight = OvScale.SizeTap),
horizontalArrangement = Arrangement.spacedBy(OvScale.SpaceMd),
) {
Text(status, style = MaterialTheme.typography.bodyMedium)
}
// Apply motion only when !reduceMotion.
}
// Tokens: space.md=12px, motion.duration.base=260ms, motion.easing.standard=cubic-bezier(.2,.7,.2,1), size.tap=44px