From 8b22e1b2af94dcbb6e00bec28d5557762ba0c630 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 6 Jul 2026 22:11:02 +0200 Subject: [PATCH] refactor: share WeekNumberBadge; use it in Month gutter, centered Extract the Week view's calendar-week badge into a shared ui/common component and reuse it for the Month grid's week-number gutter, so the two views show week numbers in the exact same format. The gutter now centres the badge vertically in each row (was pinned to the day-number band) and is widened to seat the badge. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../calendula/ui/common/WeekNumberBadge.kt | 38 +++++++++++++++++++ .../calendula/ui/month/MonthScreen.kt | 34 ++++++----------- .../calendula/ui/week/WeekScreen.kt | 21 +--------- 3 files changed, 51 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/de/jeanlucmakiola/calendula/ui/common/WeekNumberBadge.kt diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/WeekNumberBadge.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/WeekNumberBadge.kt new file mode 100644 index 0000000..771adf9 --- /dev/null +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/WeekNumberBadge.kt @@ -0,0 +1,38 @@ +package de.jeanlucmakiola.calendula.ui.common + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import de.jeanlucmakiola.calendula.R + +/** + * Calendar-week badge — a filled tonal chip with a bold number, deliberately set + * apart from the surrounding day numbers. Shared by the Week and Month views so + * the week-of-year indicator reads identically wherever it appears. + */ +@Composable +fun WeekNumberBadge(weekNumber: Int, modifier: Modifier = Modifier) { + val label = stringResource(R.string.week_number_label) + Surface( + shape = RoundedCornerShape(8.dp), + color = MaterialTheme.colorScheme.secondaryContainer, + contentColor = MaterialTheme.colorScheme.onSecondaryContainer, + modifier = modifier.semantics { contentDescription = "$label $weekNumber" }, + ) { + Text( + text = weekNumber.toString(), + style = MaterialTheme.typography.titleSmall, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 3.dp), + ) + } +} diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/month/MonthScreen.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/month/MonthScreen.kt index 8aa3ace..f73a5f1 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/month/MonthScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/month/MonthScreen.kt @@ -73,6 +73,7 @@ import de.jeanlucmakiola.calendula.ui.common.EventDimAlpha import de.jeanlucmakiola.calendula.ui.common.LocalDimCutoff import de.jeanlucmakiola.calendula.ui.common.rememberCurrentMinute import de.jeanlucmakiola.calendula.ui.common.ViewSwitcherPill +import de.jeanlucmakiola.calendula.ui.common.WeekNumberBadge import de.jeanlucmakiola.calendula.ui.common.calendarSlideTransition import de.jeanlucmakiola.calendula.ui.common.rememberCalendarFadeSpec import de.jeanlucmakiola.calendula.ui.common.rememberReduceMotion @@ -360,8 +361,9 @@ private fun WeekdayHeader(weekStart: DayOfWeek, showWeekNumbers: Boolean) { private val EVENT_ROW_HEIGHT = 20.dp private val DAY_NUMBER_HEIGHT = 22.dp -/** Width of the optional left gutter holding the calendar-week number (#25). */ -private val WEEK_NUMBER_GUTTER = 24.dp +/** Width of the optional left gutter holding the calendar-week badge (#25); wide + * enough to seat the shared [WeekNumberBadge] with a little breathing room. */ +private val WEEK_NUMBER_GUTTER = 40.dp private val DAY_NUMBER_GAP = 4.dp private val CELL_TOP_PADDING = 6.dp private val CELL_GAP = 2.dp @@ -562,10 +564,10 @@ private fun MonthWeekRow( } /** - * Left-gutter calendar-week number (#25), aligned with the day-number band. The - * ISO week-of-week-based-year computed on the row's first day — the same basis - * as the Week view's badge — so the two views agree. A low-emphasis label rather - * than a filled badge: it repeats on all six rows, so it must recede. + * Left-gutter calendar-week indicator (#25), centred vertically in the row. Uses + * the shared [WeekNumberBadge] so it's identical to the Week view's, and computes + * the ISO week-of-week-based-year on the row's first day — the same basis — so the + * two views always agree. */ @Composable private fun WeekNumberGutter(weekStart: LocalDate, modifier: Modifier = Modifier) { @@ -573,23 +575,11 @@ private fun WeekNumberGutter(weekStart: LocalDate, modifier: Modifier = Modifier java.time.LocalDate.of(weekStart.year, weekStart.month.ordinal + 1, weekStart.day) .get(java.time.temporal.IsoFields.WEEK_OF_WEEK_BASED_YEAR) } - val label = stringResource(R.string.week_number_label) - Column( - modifier = modifier - .padding(top = CELL_TOP_PADDING) - .semantics { contentDescription = "$label $weekNumber" }, - horizontalAlignment = Alignment.CenterHorizontally, + Box( + modifier = modifier, + contentAlignment = Alignment.Center, ) { - Box( - modifier = Modifier.height(DAY_NUMBER_HEIGHT), - contentAlignment = Alignment.Center, - ) { - Text( - text = weekNumber.toString(), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - ) - } + WeekNumberBadge(weekNumber = weekNumber) } } diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/week/WeekScreen.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/week/WeekScreen.kt index 3af71f0..a2a59de 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/week/WeekScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/week/WeekScreen.kt @@ -87,6 +87,7 @@ import de.jeanlucmakiola.calendula.ui.common.LocalDimCutoff import de.jeanlucmakiola.calendula.ui.common.NowLine import de.jeanlucmakiola.calendula.ui.common.rememberCurrentMinute import de.jeanlucmakiola.calendula.ui.common.ViewSwitcherPill +import de.jeanlucmakiola.calendula.ui.common.WeekNumberBadge import de.jeanlucmakiola.calendula.ui.common.calendarSlideTransition import de.jeanlucmakiola.calendula.ui.common.rememberCalendarFadeSpec import de.jeanlucmakiola.calendula.ui.common.rememberReduceMotion @@ -507,26 +508,6 @@ private fun WeekDayHeader( } } -/** Calendar-week badge shown in the header gutter, deliberately set apart with a - * filled box and bold number. */ -@Composable -private fun WeekNumberBadge(weekNumber: Int, modifier: Modifier = Modifier) { - val label = stringResource(R.string.week_number_label) - Surface( - shape = RoundedCornerShape(8.dp), - color = MaterialTheme.colorScheme.secondaryContainer, - contentColor = MaterialTheme.colorScheme.onSecondaryContainer, - modifier = modifier.semantics { contentDescription = "$label $weekNumber" }, - ) { - Text( - text = weekNumber.toString(), - style = MaterialTheme.typography.titleSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 8.dp, vertical = 3.dp), - ) - } -} - @Composable private fun AllDayStrip( state: WeekUiState.Success,