diff --git a/.changeset/timer-monospaced-digit-fix.md b/.changeset/timer-monospaced-digit-fix.md new file mode 100644 index 00000000..4346c7ee --- /dev/null +++ b/.changeset/timer-monospaced-digit-fix.md @@ -0,0 +1,5 @@ +--- +'voltra': patch +--- + +Fix timer digits shifting during countdown and stopwatch in relative mode. diff --git a/ios/ui/Views/VoltraTimer.swift b/ios/ui/Views/VoltraTimer.swift index 27b7903c..cc2924d6 100644 --- a/ios/ui/Views/VoltraTimer.swift +++ b/ios/ui/Views/VoltraTimer.swift @@ -28,7 +28,9 @@ public struct VoltraTimer: VoltraView { ) } - private func resolvedEndDate(params: TimerParameters) -> Date? { progressRange(params: params)?.upperBound } + private func resolvedEndDate(params: TimerParameters) -> Date? { + progressRange(params: params)?.upperBound + } private func countsDown(params: TimerParameters) -> Bool { (params.direction.lowercased()) != "up" @@ -45,7 +47,8 @@ public struct VoltraTimer: VoltraView { private func textTemplates(params: TimerParameters) -> TextTemplates? { guard let raw = params.textTemplates, - let data = raw.data(using: .utf8) else { return nil } + let data = raw.data(using: .utf8) + else { return nil } return try? JSONDecoder().decode(TextTemplates.self, from: data) } @@ -87,7 +90,7 @@ public struct VoltraTimer: VoltraView { if style == "relative" { let targetDate = isCountDown ? range.upperBound : range.lowerBound - Text(targetDate, style: .relative) + Text(targetDate, style: .relative).monospacedDigit() } else { // Live Activities require Text(timerInterval:...) for automatic updates Text(timerInterval: range, countsDown: isCountDown, showsHours: showHours) @@ -98,7 +101,7 @@ public struct VoltraTimer: VoltraView { @ViewBuilder private func staticZeroText(style: String, showHours: Bool) -> some View { if style == "relative" { - Text("0s") + Text("0s").monospacedDigit() } else { Text(showHours ? "0:00:00" : "0:00") .monospacedDigit() @@ -106,7 +109,9 @@ public struct VoltraTimer: VoltraView { } @ViewBuilder - private func renderTemplate(template: String, @ViewBuilder timeView: @escaping () -> T) -> some View { + private func renderTemplate(template: String, @ViewBuilder timeView: @escaping () -> T) + -> some View + { let placeholder = "{time}" let segments = template.components(separatedBy: placeholder) @@ -124,9 +129,3 @@ public struct VoltraTimer: VoltraView { } } } - -// MARK: - Formatters - -extension VoltraTimer { - // Formatters are no longer needed for live updates but kept if we need static fallbacks. -}