Group design components in Showkase for the Compound team (#375)

* Screenshot tests changes:

    - Group components for Showkase.
    - Set special Paparazzi config for scrolling screens using non null `Preview.heightDp`.
    - Add merged theme preview with `ElementThemedPreview` component.
This commit is contained in:
Jorge Martin Espinosa 2023-05-02 18:13:35 +02:00 committed by GitHub
parent 79cc6161a3
commit 9a45e48d9e
413 changed files with 1451 additions and 1079 deletions

2
.gitignore vendored
View file

@ -53,6 +53,8 @@ captures/
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/inspectionProfiles
# Shelved changes in the IDE
.idea/shelf
# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.

View file

@ -21,7 +21,6 @@ import androidx.compose.material.icons.filled.DeveloperMode
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.features.logout.api.LogoutPreferenceView
import io.element.android.features.preferences.impl.user.UserPreferences
@ -32,6 +31,7 @@ import io.element.android.libraries.designsystem.components.preferences.Preferen
import io.element.android.libraries.designsystem.components.preferences.PreferenceView
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
import io.element.android.libraries.matrix.ui.components.MatrixUserProvider
import io.element.android.libraries.matrix.ui.model.MatrixUser
import io.element.android.libraries.ui.strings.R as StringR
@ -76,12 +76,12 @@ fun DeveloperPreferencesView(onOpenDeveloperSettings: () -> Unit) {
}
}
@Preview
@LargeHeightPreview
@Composable
fun PreferencesRootViewLightPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) =
ElementPreviewLight { ContentToPreview(matrixUser) }
@Preview
@LargeHeightPreview
@Composable
fun PreferencesRootViewDarkPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) =
ElementPreviewDark { ContentToPreview(matrixUser) }

View file

@ -41,28 +41,27 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.features.roomdetails.blockuser.BlockUserDialogs
import io.element.android.features.roomdetails.blockuser.BlockUserSection
import io.element.android.features.roomdetails.impl.members.details.RoomMemberHeaderSection
import io.element.android.features.roomdetails.impl.members.details.RoomMemberMainActionsSection
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.isLoading
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.button.MainActionButton
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
import io.element.android.libraries.designsystem.theme.LocalColors
import io.element.android.libraries.designsystem.components.button.MainActionButton
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TopAppBar
@ -271,12 +270,12 @@ internal fun ConfirmLeaveRoomDialog(
)
}
@Preview
@LargeHeightPreview
@Composable
fun RoomDetailsLightPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) =
ElementPreviewLight { ContentToPreview(state) }
@Preview
@LargeHeightPreview
@Composable
fun RoomDetailsDarkPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) =
ElementPreviewDark { ContentToPreview(state) }

View file

@ -37,7 +37,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.features.roomdetails.blockuser.BlockUserDialogs
@ -47,11 +46,12 @@ import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.button.MainActionButton
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.components.button.MainActionButton
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TopAppBar
@ -140,12 +140,12 @@ internal fun SendMessageSection(onSendMessage: () -> Unit, modifier: Modifier =
}
}
@Preview
@LargeHeightPreview
@Composable
fun RoomMemberDetailsViewLightPreview(@PreviewParameter(RoomMemberDetailsStateProvider::class) state: RoomMemberDetailsState) =
ElementPreviewLight { ContentToPreview(state) }
@Preview
@LargeHeightPreview
@Composable
fun RoomMemberDetailsViewDarkPreview(@PreviewParameter(RoomMemberDetailsStateProvider::class) state: RoomMemberDetailsState) =
ElementPreviewDark { ContentToPreview(state) }

View file

@ -35,7 +35,7 @@ test_core = "1.5.0"
coil = "2.3.0"
datetime = "0.4.0"
serialization_json = "1.5.0"
showkase = "1.0.0-beta17"
showkase = "1.0.0-beta18"
jsoup = "1.16.1"
appyx = "1.2.0"
dependencycheck = "8.2.1"

View file

@ -33,6 +33,8 @@ android {
implementation(libs.accompanist.systemui)
implementation(projects.libraries.elementresources)
implementation(projects.libraries.uiStrings)
ksp(libs.showkase.processor)
kspTest(libs.showkase.processor)
}
}

View file

@ -35,8 +35,8 @@ import androidx.compose.ui.text.ParagraphStyle
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Text
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf
@ -97,15 +97,10 @@ fun ClickableLinkText(
)
}
@Preview
@Preview(group = PreviewGroup.Text)
@Composable
internal fun ClickableLinkTextLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun ClickableLinkTextDarkPreview() =
ElementPreviewDark { ContentToPreview() }
internal fun ClickableLinkTextPreview() =
ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {
@ -117,3 +112,4 @@ private fun ContentToPreview() {
interactionSource = MutableInteractionSource(),
)
}

View file

@ -23,8 +23,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Checkbox
import io.element.android.libraries.designsystem.theme.components.Text
@ -52,13 +52,9 @@ fun LabelledCheckbox(
}
}
@Preview
@Preview(group = PreviewGroup.Toggles)
@Composable
internal fun LabelledCheckboxLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun LabelledCheckboxDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun LabelledCheckboxPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -30,8 +30,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.components.dialogs.DialogPreview
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.Text
@ -71,15 +72,43 @@ fun ProgressDialog(
}
}
@Preview
@Composable
internal fun ProgressDialogLightPreview() = ElementPreviewLight { ContentToPreview() }
private fun ProgressDialogContent(
modifier: Modifier = Modifier,
text: String? = null,
) {
Box(
contentAlignment = Alignment.Center,
modifier = modifier
.fillMaxWidth()
.background(
color = MaterialTheme.colorScheme.surfaceVariant,
shape = RoundedCornerShape(8.dp)
)
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
CircularProgressIndicator(
modifier = Modifier.padding(16.dp),
color = MaterialTheme.colorScheme.onSurfaceVariant
)
if (!text.isNullOrBlank()) {
Text(
text = text,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(16.dp)
)
}
}
}
}
@Preview
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun ProgressDialogDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun ProgressDialogPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {
ProgressDialog(text = "test dialog content")
DialogPreview {
ProgressDialogContent(text = "test dialog content")
}
}

View file

@ -34,8 +34,8 @@ import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import io.element.android.libraries.designsystem.AvatarGradientEnd
import io.element.android.libraries.designsystem.AvatarGradientStart
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar
import io.element.android.libraries.designsystem.theme.components.Text
import timber.log.Timber
@ -106,17 +106,7 @@ private fun InitialsAvatar(
}
}
@Preview
@Preview(group = PreviewGroup.Avatars)
@Composable
fun AvatarLightPreview(@PreviewParameter(AvatarDataProvider::class) avatarData: AvatarData) =
ElementPreviewLight { ContentToPreview(avatarData) }
@Preview
@Composable
fun AvatarDarkPreview(@PreviewParameter(AvatarDataProvider::class) avatarData: AvatarData) =
ElementPreviewDark { ContentToPreview(avatarData) }
@Composable
private fun ContentToPreview(avatarData: AvatarData) {
Avatar(avatarData)
}
fun AvatarPreview(@PreviewParameter(AvatarDataProvider::class) avatarData: AvatarData) =
ElementThemedPreview { Avatar(avatarData) }

View file

@ -24,8 +24,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.IconButton
import io.element.android.libraries.ui.strings.R as StringR
@ -47,16 +47,9 @@ fun BackButton(
}
}
@Preview
@Preview(group = PreviewGroup.Buttons)
@Composable
internal fun BackButtonPreviewLight() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun BackButtonPreviewDark() = ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
internal fun BackButtonPreview() = ElementThemedPreview {
Column {
BackButton(onClick = { }, enabled = true, contentDescription = "Back")
BackButton(onClick = { }, enabled = false, contentDescription = "Back")

View file

@ -33,8 +33,8 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.ElementButtonDefaults
@ -93,16 +93,9 @@ fun ButtonWithProgress(
}
}
@Preview
@Preview(group = PreviewGroup.Buttons)
@Composable
internal fun ButtonWithProgressLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun ButtonWithProgressDarkPreview() = ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
internal fun ButtonWithProgressPreview() = ElementThemedPreview {
ButtonWithProgress(
text = "Button with progress",
onClick = {},

View file

@ -37,8 +37,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
@ -77,18 +77,10 @@ fun MainActionButton(
}
}
@Preview
@Preview(group = PreviewGroup.Buttons)
@Composable
internal fun MainActionButtonLightPreview() {
ElementPreviewLight {
ContentsToPreview()
}
}
@Preview
@Composable
internal fun MainActionButtonDarkPreview() {
ElementPreviewDark {
internal fun MainActionButtonPreview() {
ElementThemedPreview {
ContentsToPreview()
}
}

View file

@ -0,0 +1,320 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.designsystem.components.dialogs
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.Surface
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.theme.components.Text
import kotlin.math.max
@Composable
internal fun SimpleAlertDialogContent(
content: String,
cancelText: String,
onCancelClicked: () -> Unit,
modifier: Modifier = Modifier,
title: String? = null,
submitText: String? = null,
onSubmitClicked: () -> Unit = {},
thirdButtonText: String? = null,
onThirdButtonClicked: () -> Unit = {},
emphasizeSubmitButton: Boolean = false,
shape: Shape = AlertDialogDefaults.shape,
containerColor: Color = AlertDialogDefaults.containerColor,
iconContentColor: Color = AlertDialogDefaults.iconContentColor,
titleContentColor: Color = AlertDialogDefaults.titleContentColor,
textContentColor: Color = AlertDialogDefaults.textContentColor,
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
icon: @Composable (() -> Unit)? = null,
) {
AlertDialogContent(
buttons = {
AlertDialogFlowRow(
mainAxisSpacing = ButtonsMainAxisSpacing,
crossAxisSpacing = ButtonsCrossAxisSpacing
) {
if (thirdButtonText != null) {
// If there is a 3rd item it should be at the end of the dialog
// Having this 3rd action is discouraged, see https://m3.material.io/components/dialogs/guidelines#e13b68f5-e367-4275-ad6f-c552ee8e358f
TextButton(onClick = onThirdButtonClicked) {
Text(thirdButtonText)
}
}
TextButton(onClick = onCancelClicked) {
Text(cancelText)
}
if (submitText != null) {
TextButton(
onClick = {
onSubmitClicked()
},
) {
Text(
submitText,
style = if (emphasizeSubmitButton) {
ElementTextStyles.Bold.subheadline
} else {
MaterialTheme.typography.labelLarge
}
)
}
}
}
},
modifier = modifier,
title = {
if (title != null) { Text(text = title) }
},
text = {
Text(content)
},
shape = shape,
containerColor = containerColor,
iconContentColor = iconContentColor,
titleContentColor = titleContentColor,
textContentColor = textContentColor,
tonalElevation = tonalElevation,
icon = icon,
// Note that a button content color is provided here from the dialog's token, but in
// most cases, TextButtons should be used for dismiss and confirm buttons.
// TextButtons will not consume this provided content color value, and will used their
// own defined or default colors.
buttonContentColor = MaterialTheme.colorScheme.primary,
)
}
@Composable
internal fun AlertDialogContent(
buttons: @Composable () -> Unit,
icon: (@Composable () -> Unit)?,
title: (@Composable () -> Unit)?,
text: @Composable (() -> Unit)?,
shape: Shape,
containerColor: Color,
tonalElevation: Dp,
buttonContentColor: Color,
iconContentColor: Color,
titleContentColor: Color,
textContentColor: Color,
modifier: Modifier = Modifier,
) {
Surface(
modifier = modifier,
shape = shape,
color = containerColor,
tonalElevation = tonalElevation,
) {
Column(
modifier = Modifier.padding(DialogPadding)
) {
icon?.let {
CompositionLocalProvider(LocalContentColor provides iconContentColor) {
Box(
Modifier
.padding(IconPadding)
.align(Alignment.CenterHorizontally)
) {
icon()
}
}
}
title?.let {
CompositionLocalProvider(LocalContentColor provides titleContentColor) {
val textStyle = MaterialTheme.typography.headlineSmall
ProvideTextStyle(textStyle) {
Box(
// Align the title to the center when an icon is present.
Modifier
.padding(TitlePadding)
.align(
if (icon == null) {
Alignment.Start
} else {
Alignment.CenterHorizontally
}
)
) {
title()
}
}
}
}
text?.let {
CompositionLocalProvider(LocalContentColor provides textContentColor) {
val textStyle =
MaterialTheme.typography.bodyMedium
ProvideTextStyle(textStyle) {
Box(
Modifier
.weight(weight = 1f, fill = false)
.padding(TextPadding)
.align(Alignment.Start)
) {
text()
}
}
}
}
Box(modifier = Modifier.align(Alignment.End)) {
CompositionLocalProvider(LocalContentColor provides buttonContentColor) {
val textStyle =
MaterialTheme.typography.labelLarge
ProvideTextStyle(value = textStyle, content = buttons)
}
}
}
}
}
/**
* Simple clone of FlowRow that arranges its children in a horizontal flow with limited
* customization.
*/
@Composable
internal fun AlertDialogFlowRow(
mainAxisSpacing: Dp,
crossAxisSpacing: Dp,
content: @Composable () -> Unit
) {
Layout(content) { measurables, constraints ->
val sequences = mutableListOf<List<Placeable>>()
val crossAxisSizes = mutableListOf<Int>()
val crossAxisPositions = mutableListOf<Int>()
var mainAxisSpace = 0
var crossAxisSpace = 0
val currentSequence = mutableListOf<Placeable>()
var currentMainAxisSize = 0
var currentCrossAxisSize = 0
// Return whether the placeable can be added to the current sequence.
fun canAddToCurrentSequence(placeable: Placeable) =
currentSequence.isEmpty() || currentMainAxisSize + mainAxisSpacing.roundToPx() +
placeable.width <= constraints.maxWidth
// Store current sequence information and start a new sequence.
fun startNewSequence() {
if (sequences.isNotEmpty()) {
crossAxisSpace += crossAxisSpacing.roundToPx()
}
sequences += currentSequence.toList()
crossAxisSizes += currentCrossAxisSize
crossAxisPositions += crossAxisSpace
crossAxisSpace += currentCrossAxisSize
mainAxisSpace = max(mainAxisSpace, currentMainAxisSize)
currentSequence.clear()
currentMainAxisSize = 0
currentCrossAxisSize = 0
}
for (measurable in measurables) {
// Ask the child for its preferred size.
val placeable = measurable.measure(constraints)
// Start a new sequence if there is not enough space.
if (!canAddToCurrentSequence(placeable)) startNewSequence()
// Add the child to the current sequence.
if (currentSequence.isNotEmpty()) {
currentMainAxisSize += mainAxisSpacing.roundToPx()
}
currentSequence.add(placeable)
currentMainAxisSize += placeable.width
currentCrossAxisSize = max(currentCrossAxisSize, placeable.height)
}
if (currentSequence.isNotEmpty()) startNewSequence()
val mainAxisLayoutSize = max(mainAxisSpace, constraints.minWidth)
val crossAxisLayoutSize = max(crossAxisSpace, constraints.minHeight)
val layoutWidth = mainAxisLayoutSize
val layoutHeight = crossAxisLayoutSize
layout(layoutWidth, layoutHeight) {
sequences.forEachIndexed { i, placeables ->
val childrenMainAxisSizes = IntArray(placeables.size) { j ->
placeables[j].width +
if (j < placeables.lastIndex) mainAxisSpacing.roundToPx() else 0
}
val arrangement = Arrangement.Bottom
// TODO(soboleva): rtl support
// Handle vertical direction
val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
with(arrangement) {
arrange(mainAxisLayoutSize, childrenMainAxisSizes, mainAxisPositions)
}
placeables.forEachIndexed { j, placeable ->
placeable.place(
x = mainAxisPositions[j],
y = crossAxisPositions[i]
)
}
}
}
}
}
@Composable
internal fun DialogPreview(content: @Composable () -> Unit) {
Box(
modifier = Modifier
.sizeIn(minWidth = DialogMinWidth, maxWidth = DialogMaxWidth)
.padding(20.dp),
propagateMinConstraints = true
) {
content()
}
}
// Paddings for each of the dialog's parts.
private val DialogPadding = PaddingValues(all = 24.dp)
private val IconPadding = PaddingValues(bottom = 16.dp)
private val TitlePadding = PaddingValues(bottom = 16.dp)
private val TextPadding = PaddingValues(bottom = 24.dp)
internal val ButtonsMainAxisSpacing = 8.dp
internal val ButtonsCrossAxisSpacing = 12.dp
internal val DialogMinWidth = 280.dp
internal val DialogMaxWidth = 560.dp

View file

@ -18,8 +18,8 @@ package io.element.android.libraries.designsystem.components.dialogs
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@ -28,13 +28,12 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.Dp
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.utils.BooleanProvider
import io.element.android.libraries.ui.strings.R as StringR
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ConfirmationDialog(
content: String,
@ -56,70 +55,82 @@ fun ConfirmationDialog(
textContentColor: Color = AlertDialogDefaults.textContentColor,
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
) {
AlertDialog(
modifier = modifier,
onDismissRequest = onDismiss,
title = {
if (title != null) { Text(text = title) }
},
text = {
Text(content)
},
dismissButton = {
if (thirdButtonText != null) {
// If there is a 3rd item it should be at the end of the dialog
// Having this 3rd action is discouraged, see https://m3.material.io/components/dialogs/guidelines#e13b68f5-e367-4275-ad6f-c552ee8e358f
TextButton(onClick = onThirdButtonClicked) {
Text(thirdButtonText)
}
}
TextButton(onClick = onCancelClicked) {
Text(cancelText)
}
},
confirmButton = {
TextButton(
onClick = {
onSubmitClicked()
},
) {
Text(
submitText,
style = if (emphasizeSubmitButton) {
ElementTextStyles.Bold.subheadline
} else {
MaterialTheme.typography.labelLarge
}
)
}
},
AlertDialog(modifier = modifier, onDismissRequest = onDismiss) {
ConfirmationDialogContent(
title = title,
content = content,
submitText = submitText,
cancelText = cancelText,
thirdButtonText = thirdButtonText,
onSubmitClicked = onSubmitClicked,
onCancelClicked = onCancelClicked,
onThirdButtonClicked = onThirdButtonClicked,
shape = shape,
containerColor = containerColor,
iconContentColor = iconContentColor,
titleContentColor = titleContentColor,
textContentColor = textContentColor,
tonalElevation = tonalElevation,
)
}
@Preview
@Composable
internal fun ConfirmationDialogLightPreview(@PreviewParameter(BooleanProvider::class) emphasizeSubmitButton: Boolean) =
ElementPreviewLight { ContentToPreview(emphasizeSubmitButton) }
@Preview
@Composable
internal fun ConfirmationDialogDarkPreview(@PreviewParameter(BooleanProvider::class) emphasizeSubmitButton: Boolean) =
ElementPreviewDark { ContentToPreview(emphasizeSubmitButton) }
@Composable
private fun ContentToPreview(emphasizeSubmitButton: Boolean) {
ConfirmationDialog(
title = "Title",
content = "Content",
thirdButtonText = "Disable",
onSubmitClicked = {},
onDismiss = {},
emphasizeSubmitButton = emphasizeSubmitButton,
)
}
}
@Composable
private fun ConfirmationDialogContent(
content: String,
submitText: String,
cancelText: String,
onSubmitClicked: () -> Unit,
onCancelClicked: () -> Unit,
modifier: Modifier = Modifier,
title: String? = null,
thirdButtonText: String? = null,
onThirdButtonClicked: () -> Unit = {},
emphasizeSubmitButton: Boolean = false,
shape: Shape = AlertDialogDefaults.shape,
containerColor: Color = AlertDialogDefaults.containerColor,
iconContentColor: Color = AlertDialogDefaults.iconContentColor,
titleContentColor: Color = AlertDialogDefaults.titleContentColor,
textContentColor: Color = AlertDialogDefaults.textContentColor,
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
icon: @Composable (() -> Unit)? = null,
) {
SimpleAlertDialogContent(
modifier = modifier,
title = title,
content = content,
submitText = submitText,
onSubmitClicked = onSubmitClicked,
cancelText = cancelText,
onCancelClicked = onCancelClicked,
thirdButtonText = thirdButtonText,
onThirdButtonClicked = onThirdButtonClicked,
emphasizeSubmitButton = emphasizeSubmitButton,
shape = shape,
containerColor = containerColor,
iconContentColor = iconContentColor,
titleContentColor = titleContentColor,
textContentColor = textContentColor,
tonalElevation = tonalElevation,
icon = icon,
)
}
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun ConfirmationDialogPreview(@PreviewParameter(BooleanProvider::class) emphasizeSubmitButton: Boolean) =
ElementThemedPreview {
DialogPreview {
ConfirmationDialogContent(
content = "Content",
title = "Title",
submitText = "OK",
cancelText = "Cancel",
thirdButtonText = "Disable",
onSubmitClicked = {},
onCancelClicked = {},
emphasizeSubmitButton = emphasizeSubmitButton,
)
}
}

View file

@ -18,7 +18,7 @@ package io.element.android.libraries.designsystem.components.dialogs
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.TextButton
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@ -26,11 +26,11 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.ui.strings.R as StringR
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ErrorDialog(
content: String,
@ -45,20 +45,42 @@ fun ErrorDialog(
textContentColor: Color = AlertDialogDefaults.textContentColor,
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
) {
AlertDialog(
modifier = modifier,
onDismissRequest = onDismiss,
title = {
Text(title)
},
text = {
Text(content)
},
confirmButton = {
TextButton(onClick = onDismiss) {
Text(submitText)
AlertDialog(modifier = modifier, onDismissRequest = onDismiss) {
ErrorDialogContent(
title = title,
content = content,
submitText = submitText,
onSubmitText = onDismiss,
shape = shape,
containerColor = containerColor,
iconContentColor = iconContentColor,
titleContentColor = titleContentColor,
textContentColor = textContentColor,
tonalElevation = tonalElevation,
)
}
},
}
@Composable
private fun ErrorDialogContent(
content: String,
modifier: Modifier = Modifier,
title: String = ErrorDialogDefaults.title,
submitText: String = ErrorDialogDefaults.submitText,
onSubmitText: () -> Unit = {},
shape: Shape = AlertDialogDefaults.shape,
containerColor: Color = AlertDialogDefaults.containerColor,
iconContentColor: Color = AlertDialogDefaults.iconContentColor,
titleContentColor: Color = AlertDialogDefaults.titleContentColor,
textContentColor: Color = AlertDialogDefaults.textContentColor,
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
) {
SimpleAlertDialogContent(
modifier = modifier,
title = title,
content = content,
cancelText = submitText,
onCancelClicked = onSubmitText,
shape = shape,
containerColor = containerColor,
iconContentColor = iconContentColor,
@ -73,17 +95,14 @@ object ErrorDialogDefaults {
val submitText: String @Composable get() = stringResource(id = StringR.string.action_ok)
}
@Preview
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun ErrorDialogLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun ErrorDialogDarkPreview() = ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
ErrorDialog(
internal fun ErrorDialogPreview() {
ElementThemedPreview {
DialogPreview {
ErrorDialogContent(
content = "Content",
)
}
}
}

View file

@ -26,8 +26,8 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.ui.strings.R as StringR
@ -75,23 +75,54 @@ fun RetryDialog(
)
}
@Composable
private fun RetryDialogContent(
content: String,
modifier: Modifier = Modifier,
title: String = RetryDialogDefaults.title,
retryText: String = RetryDialogDefaults.retryText,
dismissText: String = RetryDialogDefaults.dismissText,
onRetry: () -> Unit = {},
onDismiss: () -> Unit = {},
shape: Shape = AlertDialogDefaults.shape,
containerColor: Color = AlertDialogDefaults.containerColor,
iconContentColor: Color = AlertDialogDefaults.iconContentColor,
titleContentColor: Color = AlertDialogDefaults.titleContentColor,
textContentColor: Color = AlertDialogDefaults.textContentColor,
tonalElevation: Dp = AlertDialogDefaults.TonalElevation,
) {
SimpleAlertDialogContent(
modifier = modifier,
title = title,
content = content,
submitText = retryText,
onSubmitClicked = onRetry,
cancelText = dismissText,
onCancelClicked = onDismiss,
shape = shape,
containerColor = containerColor,
iconContentColor = iconContentColor,
titleContentColor = titleContentColor,
textContentColor = textContentColor,
tonalElevation = tonalElevation,
)
}
object RetryDialogDefaults {
val title: String @Composable get() = stringResource(id = StringR.string.dialog_title_error)
val retryText: String @Composable get() = stringResource(id = StringR.string.action_retry)
val dismissText: String @Composable get() = stringResource(id = StringR.string.action_cancel)
}
@Preview
@Preview(group = PreviewGroup.Dialogs)
@Composable
internal fun RetryDialogLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun RetryDialogDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun RetryDialogPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {
RetryDialog(
DialogPreview {
RetryDialogContent(
content = "Content",
)
}
}

View file

@ -28,9 +28,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Divider
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Text
@Composable
@ -64,13 +63,9 @@ fun PreferenceCategoryTitle(title: String, modifier: Modifier = Modifier) {
)
}
@Preview
@Preview(group = PreviewGroup.Preferences)
@Composable
internal fun PreferenceCategoryLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun PreferenceCategoryDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun PreferenceCategoryPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -16,12 +16,31 @@
package io.element.android.libraries.designsystem.components.preferences
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Divider
@Composable
fun PreferenceDivider(modifier: Modifier = Modifier) {
Divider(modifier, thickness = 0.5.dp)
}
@Preview(group = PreviewGroup.Dividers)
@Composable
internal fun PreferenceDividerPreview() {
ElementThemedPreview {
Box(Modifier.padding(vertical = 10.dp), contentAlignment = Alignment.Center) {
PreferenceDivider()
}
}
}

View file

@ -31,8 +31,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Slider
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.toEnabledColor
@ -87,13 +87,9 @@ fun PreferenceSlide(
}
}
@Preview
@Preview(group = PreviewGroup.Preferences)
@Composable
internal fun PreferenceSlideLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun PreferenceSlideDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun PreferenceSlidePreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -31,8 +31,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Checkbox
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.toEnabledColor
@ -60,13 +60,17 @@ fun PreferenceSwitch(
enabled = enabled
)
Text(
modifier = Modifier.weight(1f).padding(vertical = preferencePaddingVertical),
modifier = Modifier
.weight(1f)
.padding(vertical = preferencePaddingVertical),
style = MaterialTheme.typography.bodyLarge,
color = enabled.toEnabledColor(),
text = title
)
Checkbox(
modifier = Modifier.padding(end = preferencePaddingHorizontal).align(Alignment.CenterVertically),
modifier = Modifier
.padding(end = preferencePaddingHorizontal)
.align(Alignment.CenterVertically),
checked = isChecked,
enabled = enabled,
onCheckedChange = onCheckedChange
@ -75,13 +79,9 @@ fun PreferenceSwitch(
}
}
@Preview
@Preview(group = PreviewGroup.Preferences)
@Composable
internal fun PreferenceSwitchLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun PreferenceSwitchDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun PreferenceSwitchPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -39,8 +39,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.Text
@ -95,7 +95,9 @@ fun PreferenceText(
Text(currentValue, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.secondary)
Spacer(Modifier.width(16.dp))
} else if (loadingCurrentValue) {
CircularProgressIndicator(modifier = Modifier.progressSemantics().size(20.dp), strokeWidth = 2.dp)
CircularProgressIndicator(modifier = Modifier
.progressSemantics()
.size(20.dp), strokeWidth = 2.dp)
Spacer(Modifier.width(16.dp))
}
@ -103,13 +105,9 @@ fun PreferenceText(
}
}
@Preview
@Preview(group = PreviewGroup.Preferences)
@Composable
internal fun PreferenceTextLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun PreferenceTextDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun PreferenceTextPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -24,7 +24,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
open class ImageVectorProvider : PreviewParameterProvider<ImageVector?> {
override val values: Sequence<ImageVector?>
get() = sequenceOf(
null,
Icons.Default.BugReport,
null,
)
}

View file

@ -27,8 +27,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.toSecondaryEnabledColor
@ -57,15 +57,10 @@ fun PreferenceIcon(
}
}
@Preview
@Preview(group = PreviewGroup.Preferences)
@Composable
internal fun PreferenceIconLightPreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) =
ElementPreviewLight { ContentToPreview(content) }
@Preview
@Composable
internal fun PreferenceIconDarkPreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) =
ElementPreviewDark { ContentToPreview(content) }
internal fun PreferenceIconPreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) =
ElementThemedPreview { ContentToPreview(content) }
@Composable
private fun ContentToPreview(content: ImageVector?) {

View file

@ -16,7 +16,18 @@
package io.element.android.libraries.designsystem.preview
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.theme.ElementTheme
import io.element.android.libraries.designsystem.theme.components.Surface
@ -45,6 +56,45 @@ fun ElementPreviewDark(
}
@Composable
@Suppress("ModifierMissing")
fun ElementThemedPreview(
showBackground: Boolean = true,
vertical: Boolean = true,
content: @Composable () -> Unit,
) {
Box(modifier = Modifier
.background(Color.Gray)
.padding(4.dp)) {
if (vertical) {
Column {
ElementPreviewLight(
showBackground = showBackground,
content = content,
)
Spacer(modifier = Modifier.height(4.dp))
ElementPreviewDark(
showBackground = showBackground,
content = content
)
}
} else {
Row {
ElementPreviewLight(
showBackground = showBackground,
content = content,
)
Spacer(modifier = Modifier.width(4.dp))
ElementPreviewDark(
showBackground = showBackground,
content = content
)
}
}
}
}
@Composable
@Suppress("ModifierMissing")
private fun ElementPreview(
darkTheme: Boolean,
showBackground: Boolean,

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.designsystem.preview
import androidx.compose.ui.tooling.preview.Preview
/**
* Our Paparazzi tests will check components with non-null `heightDp` and use a custom rendering for them,
* adding extra vertical space so long scrolling components can be displayed. This is a helper for that functionality.
*/
@Preview(heightDp = 1000)
annotation class LargeHeightPreview

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.designsystem.preview
object PreviewGroup {
const val AppBars = "App Bars"
const val Avatars = "Avatars"
const val BottomSheets = "Bottom Sheets"
const val Buttons = "Buttons"
const val Dialogs = "Dialogs"
const val Dividers = "Dividers"
const val FABs = "Floating Action Buttons"
const val Icons = "Icons"
const val Preferences = "Preferences"
const val Progress = "Progress Indicators"
const val Search = "Search views"
const val Sliders = "Sliders"
const val Text = "Text"
const val TextFields = "TextFields"
const val Toggles = "Toggles"
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.designsystem.showkase
import com.airbnb.android.showkase.annotation.ShowkaseRoot
import com.airbnb.android.showkase.annotation.ShowkaseRootModule
@ShowkaseRoot
class DesignSystemShowkaseRootModule : ShowkaseRootModule

View file

@ -30,8 +30,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun Button(
@ -71,16 +71,9 @@ object ElementButtonDefaults {
}
@Preview
@Preview(group = PreviewGroup.Buttons)
@Composable
internal fun ButtonsLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun ButtonsDarkPreview() = ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
internal fun ButtonPreview() = ElementThemedPreview {
Column {
Button(onClick = {}, enabled = true) {
Text(text = "Click me! - Enabled")

View file

@ -27,8 +27,8 @@ import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -52,16 +52,12 @@ fun CenterAlignedTopAppBar(
)
}
@Preview
@Preview(group = PreviewGroup.AppBars)
@Composable
internal fun CenterAlignedTopAppBarLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun CenterAlignedTopAppBarDarkPreview() =
ElementPreviewDark { ContentToPreview() }
internal fun CenterAlignedTopAppBarPreview() =
ElementThemedPreview { ContentToPreview() }
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ContentToPreview() {
CenterAlignedTopAppBar(title = { Text(text = "Title") })

View file

@ -24,8 +24,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun Checkbox(
@ -46,13 +46,9 @@ fun Checkbox(
)
}
@Preview
@Preview(group = PreviewGroup.Toggles)
@Composable
internal fun CheckboxesLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun CheckboxesDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun CheckboxesPreview() = ElementThemedPreview(vertical = false) { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -25,8 +25,8 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun CircularProgressIndicator(
@ -56,13 +56,9 @@ fun CircularProgressIndicator(
)
}
@Preview
@Preview(group = PreviewGroup.Progress)
@Composable
internal fun CircularProgressIndicatorLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun CircularProgressIndicatorDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun CircularProgressIndicatorPreview() = ElementThemedPreview(vertical = false) { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -16,14 +16,19 @@
package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DividerDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun Divider(
@ -38,13 +43,13 @@ fun Divider(
)
}
@Preview
@Preview(group = PreviewGroup.Dividers)
@Composable
internal fun DividerLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun DividerDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun DividerPreview() = ElementThemedPreview {
Box(Modifier.padding(vertical = 10.dp), contentAlignment = Alignment.Center) {
ContentToPreview()
}
}
@Composable
private fun ContentToPreview() {

View file

@ -31,8 +31,8 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun FloatingActionButton(
@ -57,15 +57,10 @@ fun FloatingActionButton(
)
}
@Preview
@Preview(group = PreviewGroup.FABs)
@Composable
internal fun FloatingActionButtonLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun FloatingActionButtonDarkPreview() =
ElementPreviewDark { ContentToPreview() }
internal fun FloatingActionButtonPreview() =
ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -27,8 +27,8 @@ import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun Icon(
@ -75,15 +75,10 @@ fun Icon(
)
}
@Preview
@Preview(group = PreviewGroup.Icons)
@Composable
internal fun IconImageVectorLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun IconImageVectorDarkPreview() =
ElementPreviewDark { ContentToPreview() }
internal fun IconImageVectorPreview() =
ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -24,8 +24,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun IconButton(
@ -45,15 +45,10 @@ fun IconButton(
)
}
@Preview
@Preview(group = PreviewGroup.Buttons)
@Composable
internal fun IconButtonLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun IconButtonDarkPreview() =
ElementPreviewDark { ContentToPreview() }
internal fun IconButtonPreview() =
ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -27,8 +27,8 @@ import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -52,15 +52,10 @@ fun MediumTopAppBar(
)
}
@Preview
@Preview(group = PreviewGroup.AppBars)
@Composable
internal fun MediumTopAppBarLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun MediumTopAppBarDarkPreview() =
ElementPreviewDark { ContentToPreview() }
internal fun MediumTopAppBarPreview() =
ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -20,6 +20,8 @@ package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.ModalBottomSheetDefaults
import androidx.compose.material.ModalBottomSheetState
@ -33,8 +35,10 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewGroup
@OptIn(ExperimentalMaterialApi::class)
@Composable
@ -62,12 +66,12 @@ fun ModalBottomSheetLayout(
)
}
@Preview
@Preview(group = PreviewGroup.BottomSheets)
@Composable
internal fun ModalBottomSheetLayoutLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Preview(group = PreviewGroup.BottomSheets)
@Composable
internal fun ModalBottomSheetLayoutDarkPreview() =
ElementPreviewDark { ContentToPreview() }
@ -75,9 +79,10 @@ internal fun ModalBottomSheetLayoutDarkPreview() =
@Composable
private fun ContentToPreview() {
ModalBottomSheetLayout(
modifier = Modifier.height(100.dp),
sheetState = ModalBottomSheetState(ModalBottomSheetValue.Expanded),
sheetContent = {
Text(text = "Sheet Content", modifier = Modifier.background(color = Color.Green))
Text(text = "Sheet Content", modifier = Modifier.padding(16.dp).background(color = Color.Green))
}
) {
Text(text = "Content", modifier = Modifier.background(color = Color.Red))

View file

@ -30,8 +30,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun OutlinedButton(
@ -73,13 +73,9 @@ object ElementOutlinedButtonDefaults {
}
@Preview
@Preview(group = PreviewGroup.Buttons)
@Composable
internal fun OutlinedButtonsLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun OutlinedButtonsDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun OutlinedButtonsPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -39,13 +39,13 @@ import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.key.type
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.utils.allBooleans
import io.element.android.libraries.designsystem.utils.asInt
@ -109,11 +109,11 @@ fun Modifier.onTabOrEnterKeyFocusNext(focusManager: FocusManager): Modifier = on
}
}
@Preview
@Preview(group = PreviewGroup.TextFields)
@Composable
internal fun OutlinedTextFieldsLightPreview() = ElementPreviewLight { ContentToPreview() }
internal fun OutlinedTextFieldsPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Preview(group = PreviewGroup.TextFields)
@Composable
internal fun OutlinedTextFieldsDarkPreview() = ElementPreviewDark { ContentToPreview() }

View file

@ -24,8 +24,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun RadioButton(
@ -46,13 +46,9 @@ fun RadioButton(
)
}
@Preview
@Preview(group = PreviewGroup.Toggles)
@Composable
internal fun RadioButtonLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun RadioButtonDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun RadioButtonPreview() = ElementThemedPreview(vertical = false) { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -30,8 +30,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -73,13 +73,9 @@ fun SearchBar(
)
}
@Preview
@Preview(group = PreviewGroup.Search)
@Composable
internal fun DockedSearchBarLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun DockedSearchBarDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun DockedSearchBarPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -24,8 +24,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun Slider(
@ -53,13 +53,9 @@ fun Slider(
)
}
@Preview
@Preview(group = PreviewGroup.Sliders)
@Composable
internal fun SlidersLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun SlidersDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun SlidersPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -31,6 +31,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
@Composable
fun Surface(
@ -57,13 +58,8 @@ fun Surface(
@Preview
@Composable
internal fun SurfaceLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun SurfaceDarkPreview() =
ElementPreviewDark { ContentToPreview() }
internal fun SurfacePreview() =
ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -46,6 +46,7 @@ import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.utils.toHrf
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf
@ -130,11 +131,11 @@ fun Text(
)
}
@Preview
@Preview(group = PreviewGroup.Text)
@Composable
internal fun TextLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Preview(group = PreviewGroup.Text)
@Composable
internal fun TextDarkPreview() = ElementPreviewDark { ContentToPreview() }

View file

@ -29,8 +29,8 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Composable
fun TextButton(
@ -59,13 +59,9 @@ fun TextButton(
)
}
@Preview
@Preview(group = PreviewGroup.Buttons)
@Composable
internal fun TextButtonLightPreview() = ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun TextButtonDarkPreview() = ElementPreviewDark { ContentToPreview() }
internal fun TextButtonPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {

View file

@ -46,6 +46,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.utils.allBooleans
import io.element.android.libraries.designsystem.utils.asInt
@ -97,12 +98,12 @@ fun TextField(
)
}
@Preview
@Preview(group = PreviewGroup.TextFields)
@Composable
internal fun TextFieldLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Preview(group = PreviewGroup.TextFields)
@Composable
internal fun TextFieldDarkPreview() =
ElementPreviewDark { ContentToPreview() }

View file

@ -27,8 +27,8 @@ import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -52,16 +52,12 @@ fun TopAppBar(
)
}
@Preview
@Preview(group = PreviewGroup.AppBars)
@Composable
internal fun TopAppBarLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun TopAppBarDarkPreview() =
ElementPreviewDark { ContentToPreview() }
internal fun TopAppBarPreview() =
ElementThemedPreview { ContentToPreview() }
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ContentToPreview() {
TopAppBar(title = { Text(text = "Title") })

View file

@ -35,7 +35,6 @@ dependencies {
kspTest(libs.showkase.processor)
implementation(libs.showkase)
ksp(libs.showkase.processor)
allLibrariesImpl()
allFeaturesImpl(rootDir)

View file

@ -17,8 +17,13 @@
package io.element.android.tests.uitests
import android.app.Activity
import android.content.Intent
import com.airbnb.android.showkase.models.Showkase
import com.airbnb.android.showkase.ui.ShowkaseBrowserActivity
fun openShowkase(activity: Activity) {
activity.startActivity(Showkase.getBrowserIntent(activity))
val intent = Intent(activity, ShowkaseBrowserActivity::class.java)
intent.putExtra("SHOWKASE_ROOT_MODULE",
"io.element.android.libraries.designsystem.showkase.DesignSystemShowkaseRootModule")
activity.startActivity(intent)
}

View file

@ -24,5 +24,11 @@ class ComponentTestPreview(
) : TestPreview {
@Composable
override fun Content() = showkaseBrowserComponent.component()
override val needsScroll: Boolean = showkaseBrowserComponent.heightDp != null
override val customHeightDp: Int? = showkaseBrowserComponent.heightDp.takeIf { it != null }
override fun toString(): String = showkaseBrowserComponent.componentKey
}

View file

@ -24,6 +24,8 @@ import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
@ -32,11 +34,14 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import app.cash.paparazzi.Paparazzi
import com.airbnb.android.showkase.models.Showkase
import com.android.ide.common.rendering.api.SessionParams
import com.google.testing.junit.testparameterinjector.TestParameter
import com.google.testing.junit.testparameterinjector.TestParameterInjector
import io.element.android.libraries.designsystem.modifiers.applyIf
import io.element.android.libraries.designsystem.theme.ElementTheme
import org.junit.Rule
import org.junit.Test
@ -69,6 +74,7 @@ class ScreenshotTest {
@get:Rule
val paparazzi = Paparazzi(
maxPercentDifference = 0.01,
renderingMode = SessionParams.RenderingMode.SHRINK,
)
@Test
@ -78,10 +84,14 @@ class ScreenshotTest {
@TestParameter(value = ["1.0"/*, "1.5"*/]) fontScale: Float,
@TestParameter(value = ["en" /*"fr", "de", "ru"*/]) localeStr: String,
) {
val needsScrolling = componentTestPreview.needsScroll
val screenHeight = componentTestPreview.customHeightDp.takeIf { it != null }
paparazzi.unsafeUpdateConfig(
deviceConfig = baseDeviceConfig.deviceConfig.copy(
softButtons = false,
)
screenHeight = screenHeight ?: baseDeviceConfig.deviceConfig.screenHeight
),
renderingMode = if (needsScrolling) SessionParams.RenderingMode.V_SCROLL else SessionParams.RenderingMode.SHRINK
)
paparazzi.snapshot {
val lifecycleOwner = LocalLifecycleOwner.current
@ -101,7 +111,14 @@ class ScreenshotTest {
}
) {
ElementTheme {
Box(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
Box(
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.sizeIn(minWidth = 1.dp, minHeight = 1.dp)
.applyIf(needsScrolling, ifTrue = {
heightIn(max = 1000.dp)
})
) {
componentTestPreview.Content()
}
}

View file

@ -21,4 +21,8 @@ import androidx.compose.runtime.Composable
interface TestPreview {
@Composable
fun Content()
val needsScroll: Boolean get() = false
val customHeightDp: Int? get() = null
}

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0c51ed0a004218e97af5f34e3011e0c4e4b50cccf0eff1417234186bdb786839
size 4983
oid sha256:e3b1d5ed12147e8ea92953d84b1de10bf2c96cbb3c868fbe209888831fd010f8
size 4339

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1042b183b2703322af7a43d959992340b47618b27d706cfba8cf1556e70f793e
size 4984
oid sha256:77474ad44a4e8a0314679cd9499175c8d63d5eae201ac9796c0cd37f7a0beb72
size 4338

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:77dcd8feab45cb713f3ee6cdc8ad86189e73176e0eff88494a2cb109431ddb33
size 7097
oid sha256:b9d518b92413006ebab0823f0f119202e5ab20326570c532b905bdaf9ec0ad62
size 7305

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e60a495255bf6048af20f1cd7365caf6ca6f5d9e97bbf1519ce469f3cccec958
size 6064
oid sha256:8c1b33253bd5bd39ac698e3cd8327dfdf153a4bbbc798fbee978efc2a2f23d4d
size 4858

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3025338830e0e20781a727ef61751be208d2c633e271f42fe91dbf89df43dbf5
size 6681
oid sha256:ee55738ab4d23bca2377fc96668e5138edac796e6c691acbb172fda422f75f66
size 5994

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5c68a348292da117047095d945c7b3fa764e4894fbc25354a88607af33378b90
size 4775
oid sha256:e36cd3680e158264054df3e0d563fc0cfd5db4ce7380a968fb1135d664d35695
size 2035

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a8960ee49f84a98f0c309ea2d3cc208bfdf493c8843066830ee228e0c3b25634
size 9695
oid sha256:51e322f8ac8f57212645ea4b6bf3b0e8ca6a0a3d128cea7975d4595c7255eed1
size 14684

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dcfab4f43c1a796c9166116285353c4351182db3d5417f657c8a48e9798c6e87
size 9589
oid sha256:ec6c33cd9f7732a7a28888ba4db7bc60340e51c76d5506053724aed2ce08a96c
size 13543

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:12fdbd29d34a17ceec91dd37fddb46560a9047df5a4878491443e75c1fb2ad44
size 8214
oid sha256:1913eaf88a47a97ca6ef5106a7dbcc9cbaa08e665d0f8026efdda180cdd02749
size 10470

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5334cd5b273fc2e6ac65c730bc88adf74fa6b89fda0e76009d35a75bf2790559
size 7728
oid sha256:6cb15fafea839641ac3ac57ef360dfe9ab6552abf61084e6cd5ab60d4b08cde2
size 8527

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:310e8dfa7d52b5ee835243b1025a7e20ec3fb7dafee62c230c870720e91cf897
size 7044
oid sha256:7265ae7d1e0677debb66726f1bf25ae0476fe530f110ff6a3fa6652750466d8b
size 7066

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7c4cbc97971b8a1561c232f14cb8600fea59527e7315bca9d225dde13cb1edd9
size 6223
oid sha256:e55be94c2051ae76ad0b9e8b2789f8072a8e42c3725574bca1e7f7ea55d41f28
size 5003

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:aaeb60c55803711952413d99191209f467b4f77e1b03ad46601111691c2fc7fe
size 38188
oid sha256:cbfbfa08085539bbfa4f20bc5d149bf0db0036169a32747c96f956d0d0f4b42d
size 93741

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4c8ccd79709924e19793977ebe5ab4f6ded7f20507d9534dc24f46513fdd7a69
size 37844
oid sha256:9e0ba60e784a0dc582826a3f5679a6015531dc9aca22617ec1e0dede38b97f30
size 93678

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6b1243c92ee9f3735e81c2ab77910a7323b692a72c3c81c4b2ea776c1f0e5c84
size 16267
oid sha256:f92e4287ae8db895d18452840a29240989597dea560640244b8188ee61e8c266
size 30730

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7db235009f0e0a50eda1196f2cd24eb490af10ebe42e26cc73fdf8ea2fdb0bf8
size 15906
oid sha256:c66806646645afee1654b50818c539863e60129eba7fcd608e9801bd34d0fe30
size 30028

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5abeb4bb717e33b34ff0a61d657a01b4e7ad965b5d7f8e4252c7e956c4caada3
size 38719
oid sha256:d7b6554df9b22046a9f0d7e795b8d5d889038a6e3f947cf3dd5f6492d1efb782
size 89244

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:74c34325693f03c620a64493ea9bead27d8db1719d849ef4e1f589940efc73c9
size 34559
oid sha256:ebbff1db4c03049122f4c9bae92d3fd125b95684cad9adb4ef95a3341a013ead
size 80090

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ae7f920795745910f0df3a472d31b055fed52a9041a0b7894f9a732be8777b2e
size 22344
oid sha256:3b63f562e8b5360a66546fdd6e77de9a23530338b0e1a031c5c2d052f585985b
size 48392

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:52d02a23a34fbf2e3ba41547a10ecb774d8ef40940ef9cc30b79b98fbafe267e
size 25888
oid sha256:9f6d775fe3ecffe0c60b931e6d951a7da20d9832d940076d972821d268c58361
size 59646

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e9622f36ef930ce3b81e656c0447d971b9c2939ae4b48268689bf1256a6c9249
size 16978
oid sha256:a57b775eaad1b6e211d47588048c3722ec76083ca515ccface863b15ee497b5b
size 34216

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5f94f5fac1646765a8b07712d046c7446c8c019384e727899178ef0bd8bd78fb
size 21545
oid sha256:682acde00a6cbf13aa356ff4ec91368b11eae9fa2f8750d1590ceea334045ebd
size 47079

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f0272e8fc322038a054a94b516a0c36136da0c1d244790d72cfde97de85845d0
size 25178
oid sha256:237e3727252f29ec3953fb0a27d6cee741cd5b485c9466e81799315f3852f0c7
size 58267

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5cfeafe4170c00c0344ec5542279e947eb0a7cc4d6558a4c79564d6fc2fb3bab
size 16241
oid sha256:f2a733da2b24280b2d096e458a8bf470f2f8279008cc823553eee1072e9e3df5
size 33238

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a48ccf1ff3570915b0673de7c0367d951b795c833d7896645b37000b8dc09c15
size 9649
oid sha256:ee3b80087b280eaf0fe779d885443a8f2b1101c70c324809e8b39e3283ef22c4
size 13325

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:945b360a62877d16ec7c25942158ae47e244df85118ca861482ff3bbf0aef55f
size 9268
oid sha256:dca8884becdb8c50370935cdd8c60334c519a019f8888fb2224705d67b681470
size 13434

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5a1c7d44e491508deb7f85bf84afb5fd82dbfe30779a231957fb1117c4a9a555
size 8374
oid sha256:d66e1c9941304a57c3a6457e02ad3bd7b713c1eccdb03b000e3729b2a582e507
size 5179

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dd5d243ba8f4fc26b79f506fb0c1c36ebfccd07d8a49c6f2eac67ab23d3c1053
size 8157
oid sha256:7abab1af85b477fd87f5a6b58451c89f12dc601478251b6c92db791d2aded415
size 5006

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2e7b963daafe38fbf25c66d887c617820f2937e0f5467c04abee1458db722e29
size 263224
oid sha256:894636cd0aaeeb06b2117b96cbb0d4de5edf94eeb468134efbdebf86b623e082
size 270816

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:713bc925e6075a16b7a95d1083ead3b0230628f75c80cc911e3498544916edfd
size 262092
oid sha256:766b2d44b51a36d1b15d8a39434ce5237f8427d1150f9b4c1255043fc1e4bb79
size 492165

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eb7b807522be4a1d634935e9d3ffe2aa75fdcd143ff2c43df0c129133cab21d9
size 335599
oid sha256:b2dd9d63fe0a80bd1a5e1188b2ba4d05c99cba56fc82864fe7e62f394714d627
size 805682

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a3919408521a387dae59941c1579fa5c5010b02262b3fcc1cde4ce7ad1d27b25
size 262071
oid sha256:494e968f45a1ae8ec2e2f648d71b6024ec049f3a6f8ed93108d3084d0fe13185
size 271700

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ae843ae142724e84ab66262247091a850f5e51684b8c9d3bb234a4c04ab3edd9
size 262173
oid sha256:766b2d44b51a36d1b15d8a39434ce5237f8427d1150f9b4c1255043fc1e4bb79
size 492165

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a22b82aa32dd0a246c96a50a0acf68270d0b2b19e78b79c6f817dba510ab81db
size 335888
oid sha256:d680b2a314a2663ca14cb658ac35e2060da9f52823c0ec4844e3a7a4756e0dd4
size 806726

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1e90887d2e7d3ac6deb63e6877b9d7d173d094d005aa56850f15b0d0f7d8bef1
size 5846
oid sha256:78c0fce512476577e23120a27da878be9a114b6bad98dbe1f5ddde23a89da08d
size 2262

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0cabb7173940f98c41aae4788ccbd810811bdcdb98e9f4f3ba9351ea54389580
size 5682
oid sha256:6514ec1447c0138e1edf9f7e939defba64d435cd6e0506f580ce89520ed8293b
size 1958

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b33c8641461f71d857df7433443d1d6ec6634af237e47331d8d0f37765bf4459
size 8803
oid sha256:8d4a6ebdfc24ddfd508ad2d51e9a48ccbdee012c4191d799eab948819efe0606
size 5790

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3185d85cbd139779608bf05a22b4be9404158fb43eff622e0f7447bf36a6e35f
size 8386
oid sha256:53aa383d9c76314ca26fb7e826e9c1042d4ab072f61ac6354b4af03a2694bdc4
size 5463

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:06d2fc04aaf51576601032f41e5d8ff92b604cd03e15045bd42332fcc8db198f
size 6054
oid sha256:16fce9ddf4171d436df5059f589f6e2c67e3392436eda058a0b5150411122586
size 2210

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:06d2fc04aaf51576601032f41e5d8ff92b604cd03e15045bd42332fcc8db198f
size 6054
oid sha256:16fce9ddf4171d436df5059f589f6e2c67e3392436eda058a0b5150411122586
size 2210

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:61e4c27beae19cc5ce1c12f8321eaa4de3b78e3faf0e4adf0700366e49fe1652
size 6427
oid sha256:43fac1474819159aa9074d536593e7e04b91383adf27b352e28a5782ba47ec27
size 2692

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:61e4c27beae19cc5ce1c12f8321eaa4de3b78e3faf0e4adf0700366e49fe1652
size 6427
oid sha256:43fac1474819159aa9074d536593e7e04b91383adf27b352e28a5782ba47ec27
size 2692

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d43a623e695f97507c1bfce7e2034b407afbc790e0ba64b8ef5b016dedf2d21c
size 5594
oid sha256:8eb58e7d88bcc781c6a5c8cfaada23c13ee964a26e2a1e5263c65d1e6e35df08
size 1633

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d43a623e695f97507c1bfce7e2034b407afbc790e0ba64b8ef5b016dedf2d21c
size 5594
oid sha256:8eb58e7d88bcc781c6a5c8cfaada23c13ee964a26e2a1e5263c65d1e6e35df08
size 1633

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d106fa79f7bd95a730b7f8c8cdd16cb876728bc0cd290a2d7adbf122a2777e20
size 5936
oid sha256:6d66d9468c90544b45545af3ea4904730ff42724baef0420b0b94c9a7f506fae
size 2163

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d106fa79f7bd95a730b7f8c8cdd16cb876728bc0cd290a2d7adbf122a2777e20
size 5936
oid sha256:6d66d9468c90544b45545af3ea4904730ff42724baef0420b0b94c9a7f506fae
size 2163

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:34e59f52df4d9cc21073fe5e130691754b01080e96b049f8e3d27352d5e67db0
size 6236
oid sha256:55ffb9891501d4526b6d6aba40b0ac7f6148fb4fa29ff7cc9233fce76c079e61
size 2658

Some files were not shown because too many files have changed in this diff Show more