Patterns from production · One row per thing

One row per thing

Attempts belong inside the task that owns them.

One row per thingLive demo

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.md12px
  • motion.duration.base260ms
  • motion.easing.standardcubic-bezier(.2,.7,.2,1)
  • size.tap44px

Native spec · generated from this pattern and the shared token registry

SwiftUI
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
Compose
@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