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.
This commit is contained in:
@@ -26,6 +26,7 @@ import androidx.compose.ui.semantics.clearAndSetSemantics
|
|||||||
import androidx.compose.ui.unit.Constraints
|
import androidx.compose.ui.unit.Constraints
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
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 de.jeanlucmakiola.floret.identity.rememberReduceMotion
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@@ -97,13 +98,17 @@ internal fun ScaledViewPreview(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bezel every preview picker frames its preview with, cross-fading as
|
* The stage every preview picker sets its preview on, cross-fading as [selected]
|
||||||
* [selected] changes.
|
* changes.
|
||||||
*
|
*
|
||||||
* A preview draws the app's own surface, so on a chooser screen — which draws the
|
* 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
|
* same surface — it had no edge of its own and dissolved into the page. A tonal
|
||||||
* ring gives it one: the preview reads as a screen being shown rather than as
|
* plate gives it one: the preview reads as a screen being shown rather than as
|
||||||
* part of the screen showing it.
|
* 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
|
@Composable
|
||||||
internal fun <T> ViewPreviewFrame(
|
internal fun <T> ViewPreviewFrame(
|
||||||
@@ -114,35 +119,35 @@ internal fun <T> ViewPreviewFrame(
|
|||||||
) {
|
) {
|
||||||
val reduceMotion = rememberReduceMotion()
|
val reduceMotion = rememberReduceMotion()
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier.fillMaxWidth(),
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = GroupedListInset)
|
||||||
|
.clip(FRAME_SHAPE)
|
||||||
|
.background(MaterialTheme.colorScheme.surfaceContainerHigh)
|
||||||
|
.padding(FRAME_INSET),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
Box(
|
Crossfade(
|
||||||
modifier = Modifier
|
targetState = selected,
|
||||||
.clip(FRAME_SHAPE)
|
animationSpec = if (reduceMotion) snap() else tween(durationMillis = 250),
|
||||||
.background(MaterialTheme.colorScheme.surfaceContainerHigh)
|
label = label,
|
||||||
.padding(FRAME_INSET),
|
) { shown ->
|
||||||
) {
|
// Each preview renders the real view at phone size and scales it
|
||||||
Crossfade(
|
// down, so its own corners are square — the plate rounds them.
|
||||||
targetState = selected,
|
Box(
|
||||||
animationSpec = if (reduceMotion) snap() else tween(durationMillis = 250),
|
modifier = Modifier
|
||||||
label = label,
|
.clip(PREVIEW_SHAPE)
|
||||||
) { shown ->
|
.background(MaterialTheme.colorScheme.surface)
|
||||||
// Each preview renders the real view at phone size and scales it
|
.clipToBounds(),
|
||||||
// down, so its own corners are square — the frame rounds them.
|
) {
|
||||||
Box(
|
content(shown)
|
||||||
modifier = Modifier
|
|
||||||
.clip(PREVIEW_SHAPE)
|
|
||||||
.background(MaterialTheme.colorScheme.surface)
|
|
||||||
.clipToBounds(),
|
|
||||||
) {
|
|
||||||
content(shown)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FRAME_INSET = 8.dp
|
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)
|
private val PREVIEW_SHAPE = RoundedCornerShape(12.dp)
|
||||||
|
|||||||
@@ -197,10 +197,7 @@ private fun <T> StepPreview(selected: T, content: @Composable (T) -> Unit) {
|
|||||||
ViewPreviewFrame(
|
ViewPreviewFrame(
|
||||||
selected = selected,
|
selected = selected,
|
||||||
label = "step-preview",
|
label = "step-preview",
|
||||||
modifier = Modifier.padding(
|
modifier = Modifier.padding(top = OnboardingSpace.xs, bottom = OnboardingSpace.md),
|
||||||
horizontal = 12.dp,
|
|
||||||
vertical = OnboardingSpace.xs,
|
|
||||||
).padding(bottom = OnboardingSpace.sm),
|
|
||||||
content = content,
|
content = content,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ internal fun MonthViewStylePicker(
|
|||||||
ViewPreviewFrame(
|
ViewPreviewFrame(
|
||||||
selected = selected,
|
selected = selected,
|
||||||
label = "month-style-preview",
|
label = "month-style-preview",
|
||||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp),
|
modifier = Modifier.padding(vertical = 8.dp),
|
||||||
) { shown ->
|
) { shown ->
|
||||||
MonthStylePreview(
|
MonthStylePreview(
|
||||||
style = shown,
|
style = shown,
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ internal fun WeekStartPicker(
|
|||||||
ViewPreviewFrame(
|
ViewPreviewFrame(
|
||||||
selected = resolved,
|
selected = resolved,
|
||||||
label = "week-start-preview",
|
label = "week-start-preview",
|
||||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp),
|
modifier = Modifier.padding(vertical = 8.dp),
|
||||||
) { day ->
|
) { day ->
|
||||||
MonthStylePreview(
|
MonthStylePreview(
|
||||||
style = monthStyle,
|
style = monthStyle,
|
||||||
|
|||||||
Reference in New Issue
Block a user