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 977c87c141
commit 921fb55220
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
}

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