From 944365e5a13dde417c5c7a3bd3f7f11127ddd1ad Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sat, 8 Aug 2026 22:04:37 +0200 Subject: [PATCH] Run the preview plate the full row width (#163) The plate now spans the same width as the option rows beneath it and takes their outer radius, so preview and options read as one stack instead of a card floating over a list. --- .../calendula/ui/common/ViewPreview.kt | 61 ++++++++++--------- .../calendula/ui/onboarding/ViewStep.kt | 5 +- .../ui/settings/MonthViewStylePicker.kt | 2 +- .../calendula/ui/settings/WeekStartPicker.kt | 2 +- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/ViewPreview.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/ViewPreview.kt index 3168ac9..6ca3a1f 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/ViewPreview.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/ViewPreview.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import de.jeanlucmakiola.floret.components.GroupedListInset import de.jeanlucmakiola.floret.identity.rememberReduceMotion import kotlin.math.roundToInt @@ -97,13 +98,17 @@ internal fun ScaledViewPreview( } /** - * The bezel every preview picker frames its preview with, cross-fading as - * [selected] changes. + * The stage every preview picker sets its preview on, cross-fading as [selected] + * changes. * * A preview draws the app's own surface, so on a chooser screen — which draws the - * same surface — it had no edge of its own and dissolved into the page. The tonal - * ring gives it one: the preview reads as a screen being shown rather than as - * part of the screen showing it. + * same surface — it had no edge of its own and dissolved into the page. A tonal + * plate gives it one: the preview reads as a screen being shown rather than as + * part of the screen showing it. The plate takes the width and the outer radius + * of the grouped rows underneath, so the two read as one stack. + * + * Only vertical spacing is the caller's to pass — the horizontal inset is the + * rows' own, and the alignment is the point. */ @Composable internal fun ViewPreviewFrame( @@ -114,35 +119,35 @@ internal fun ViewPreviewFrame( ) { val reduceMotion = rememberReduceMotion() Box( - modifier = modifier.fillMaxWidth(), + modifier = modifier + .fillMaxWidth() + .padding(horizontal = GroupedListInset) + .clip(FRAME_SHAPE) + .background(MaterialTheme.colorScheme.surfaceContainerHigh) + .padding(FRAME_INSET), contentAlignment = Alignment.Center, ) { - Box( - modifier = Modifier - .clip(FRAME_SHAPE) - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(FRAME_INSET), - ) { - Crossfade( - targetState = selected, - animationSpec = if (reduceMotion) snap() else tween(durationMillis = 250), - label = label, - ) { shown -> - // Each preview renders the real view at phone size and scales it - // down, so its own corners are square — the frame rounds them. - Box( - modifier = Modifier - .clip(PREVIEW_SHAPE) - .background(MaterialTheme.colorScheme.surface) - .clipToBounds(), - ) { - content(shown) - } + Crossfade( + targetState = selected, + animationSpec = if (reduceMotion) snap() else tween(durationMillis = 250), + label = label, + ) { shown -> + // Each preview renders the real view at phone size and scales it + // down, so its own corners are square — the plate rounds them. + Box( + modifier = Modifier + .clip(PREVIEW_SHAPE) + .background(MaterialTheme.colorScheme.surface) + .clipToBounds(), + ) { + content(shown) } } } } private val FRAME_INSET = 8.dp -private val FRAME_SHAPE = RoundedCornerShape(20.dp) + +/** The grouped rows' own outer radius, so the stack shares one silhouette. */ +private val FRAME_SHAPE = RoundedCornerShape(22.dp) private val PREVIEW_SHAPE = RoundedCornerShape(12.dp) diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/onboarding/ViewStep.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/onboarding/ViewStep.kt index aa6d5ab..463fab6 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/onboarding/ViewStep.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/onboarding/ViewStep.kt @@ -197,10 +197,7 @@ private fun StepPreview(selected: T, content: @Composable (T) -> Unit) { ViewPreviewFrame( selected = selected, label = "step-preview", - modifier = Modifier.padding( - horizontal = 12.dp, - vertical = OnboardingSpace.xs, - ).padding(bottom = OnboardingSpace.sm), + modifier = Modifier.padding(top = OnboardingSpace.xs, bottom = OnboardingSpace.md), content = content, ) } diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/MonthViewStylePicker.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/MonthViewStylePicker.kt index 3570772..4fd7986 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/MonthViewStylePicker.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/MonthViewStylePicker.kt @@ -47,7 +47,7 @@ internal fun MonthViewStylePicker( ViewPreviewFrame( selected = selected, label = "month-style-preview", - modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp), + modifier = Modifier.padding(vertical = 8.dp), ) { shown -> MonthStylePreview( style = shown, diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/WeekStartPicker.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/WeekStartPicker.kt index 8540c0d..543a67b 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/WeekStartPicker.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/WeekStartPicker.kt @@ -43,7 +43,7 @@ internal fun WeekStartPicker( ViewPreviewFrame( selected = resolved, label = "week-start-preview", - modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp), + modifier = Modifier.padding(vertical = 8.dp), ) { day -> MonthStylePreview( style = monthStyle,