Move Previews to screenshotTest directory and apply compose-screenshot test plugin

pull/1787/head
hummer 8 months ago
parent d15c739812
commit eb778fee07

@ -183,7 +183,7 @@ class NiaAppState(
* Stores information about navigation events to be used with JankStats
*/
@Composable
private fun NavigationTrackingSideEffect(navController: NavHostController) {
internal fun NavigationTrackingSideEffect(navController: NavHostController) {
TrackDisposableJank(navController) { metricsHolder ->
val listener = NavController.OnDestinationChangedListener { _, destination, _ ->
metricsHolder.state?.putState("Navigation", destination.route.toString())

@ -16,6 +16,7 @@
import com.android.build.api.dsl.ApplicationExtension
import com.google.samples.apps.nowinandroid.configureAndroidCompose
import com.google.samples.apps.nowinandroid.configureAndroidComposeScreenshotTest
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
@ -26,9 +27,11 @@ class AndroidApplicationComposeConventionPlugin : Plugin<Project> {
with(target) {
apply(plugin = "com.android.application")
apply(plugin = "org.jetbrains.kotlin.plugin.compose")
apply(plugin = "com.android.compose.screenshot")
val extension = extensions.getByType<ApplicationExtension>()
configureAndroidCompose(extension)
configureAndroidComposeScreenshotTest(extension)
}
}

@ -16,6 +16,7 @@
import com.android.build.gradle.LibraryExtension
import com.google.samples.apps.nowinandroid.configureAndroidCompose
import com.google.samples.apps.nowinandroid.configureAndroidComposeScreenshotTest
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
@ -26,9 +27,11 @@ class AndroidLibraryComposeConventionPlugin : Plugin<Project> {
with(target) {
apply(plugin = "com.android.library")
apply(plugin = "org.jetbrains.kotlin.plugin.compose")
apply(plugin = "com.android.compose.screenshot")
val extension = extensions.getByType<LibraryExtension>()
configureAndroidCompose(extension)
configureAndroidComposeScreenshotTest(extension)
}
}

@ -0,0 +1,31 @@
/*
* Copyright 2024 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid
import com.android.build.api.dsl.CommonExtension
import org.gradle.api.Project
/**
* Configure project to enable compose screenshot test.
*/
internal fun Project.configureAndroidComposeScreenshotTest(
commonExtension: CommonExtension<*, *, *, *, *, *>,
) {
commonExtension.apply {
experimentalProperties["android.experimental.enableScreenshotTest"] = true
}
}

@ -49,6 +49,7 @@ plugins {
alias(libs.plugins.android.test) apply false
alias(libs.plugins.baselineprofile) apply false
alias(libs.plugins.compose) apply false
alias(libs.plugins.compose.screenshot.test) apply false
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.dependencyGuard) apply false

@ -19,7 +19,6 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component
import android.content.res.Configuration
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.LocalAbsoluteTonalElevation
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
@ -37,7 +36,6 @@ import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.designsystem.theme.GradientColors
import com.google.samples.apps.nowinandroid.core.designsystem.theme.LocalBackgroundTheme
import com.google.samples.apps.nowinandroid.core.designsystem.theme.LocalGradientColors
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import kotlin.math.tan
/**
@ -146,51 +144,3 @@ fun NiaGradientBackground(
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, name = "Light theme")
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, name = "Dark theme")
annotation class ThemePreviews
@ThemePreviews
@Composable
fun BackgroundDefault() {
NiaTheme(disableDynamicTheming = true) {
NiaBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun BackgroundDynamic() {
NiaTheme(disableDynamicTheming = false) {
NiaBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun BackgroundAndroid() {
NiaTheme(androidTheme = true) {
NiaBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun GradientBackgroundDefault() {
NiaTheme(disableDynamicTheming = true) {
NiaGradientBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun GradientBackgroundDynamic() {
NiaTheme(disableDynamicTheming = false) {
NiaGradientBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun GradientBackgroundAndroid() {
NiaTheme(androidTheme = true) {
NiaGradientBackground(Modifier.size(100.dp), content = {})
}
}

@ -242,7 +242,7 @@ fun NiaTextButton(
* @param leadingIcon The button leading icon content. Default is `null` for no leading icon.Ï
*/
@Composable
private fun NiaButtonContent(
internal fun NiaButtonContent(
text: @Composable () -> Unit,
leadingIcon: @Composable (() -> Unit)? = null,
) {

@ -32,9 +32,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -73,18 +70,3 @@ fun NiaTopAppBar(
modifier = modifier.testTag("niaTopAppBar"),
)
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview("Top App Bar")
@Composable
private fun NiaTopAppBarPreview() {
NiaTheme {
NiaTopAppBar(
titleRes = android.R.string.untitled,
navigationIcon = NiaIcons.Search,
navigationIconContentDescription = "Navigation icon",
actionIcon = NiaIcons.MoreVert,
actionIconContentDescription = "Action icon",
)
}
}

@ -24,15 +24,11 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
/**
* Now in Android view toggle button with included trailing icon as well as compact and expanded
@ -84,7 +80,7 @@ fun NiaViewToggleButton(
* @param trailingIcon The button trailing icon content. Default is `null` for no trailing icon.
*/
@Composable
private fun NiaViewToggleButtonContent(
internal fun NiaViewToggleButtonContent(
text: @Composable () -> Unit,
trailingIcon: @Composable (() -> Unit)? = null,
) {
@ -109,36 +105,6 @@ private fun NiaViewToggleButtonContent(
}
}
@ThemePreviews
@Composable
fun ViewTogglePreviewExpanded() {
NiaTheme {
Surface {
NiaViewToggleButton(
expanded = true,
onExpandedChange = { },
compactText = { Text(text = "Compact view") },
expandedText = { Text(text = "Expanded view") },
)
}
}
}
@Preview
@Composable
fun ViewTogglePreviewCompact() {
NiaTheme {
Surface {
NiaViewToggleButton(
expanded = false,
onExpandedChange = { },
compactText = { Text(text = "Compact view") },
expandedText = { Text(text = "Expanded view") },
)
}
}
}
/**
* Now in Android view toggle default values.
*/

@ -128,7 +128,7 @@ fun ScrollableState.DecorativeScrollbar(
* A scrollbar thumb that is intended to also be a touch target for fast scrolling.
*/
@Composable
private fun ScrollableState.DraggableScrollbarThumb(
internal fun ScrollableState.DraggableScrollbarThumb(
interactionSource: InteractionSource,
orientation: Orientation,
) {
@ -148,7 +148,7 @@ private fun ScrollableState.DraggableScrollbarThumb(
* A decorative scrollbar thumb used solely for communicating a user's position in a list.
*/
@Composable
private fun ScrollableState.DecorativeScrollbarThumb(
internal fun ScrollableState.DecorativeScrollbarThumb(
interactionSource: InteractionSource,
orientation: Orientation,
) {
@ -168,7 +168,7 @@ private fun ScrollableState.DecorativeScrollbarThumb(
// remove when project is upgraded
@SuppressLint("ComposableModifierFactory")
@Composable
private fun Modifier.scrollThumb(
internal fun Modifier.scrollThumb(
scrollableState: ScrollableState,
interactionSource: InteractionSource,
): Modifier {
@ -214,7 +214,7 @@ private class ScrollThumbNode(var colorProducer: ColorProducer) : DrawModifierNo
* @param interactionSource source of interactions in the scrolling container
*/
@Composable
private fun scrollbarThumbColor(
internal fun scrollbarThumbColor(
scrollableState: ScrollableState,
interactionSource: InteractionSource,
): State<Color> {

@ -71,7 +71,7 @@ fun LazyStaggeredGridState.rememberDraggableScroller(
* @param scroll a function to be invoked when an index has been identified to scroll to.
*/
@Composable
private inline fun rememberDraggableScroller(
internal inline fun rememberDraggableScroller(
itemsAvailable: Int,
crossinline scroll: suspend (index: Int) -> Unit,
): (Float) -> Unit {

@ -0,0 +1,71 @@
/*
* Copyright 2024 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid.core.designsystem.component
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
@ThemePreviews
@Composable
fun BackgroundDefault() {
NiaTheme(disableDynamicTheming = true) {
NiaBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun BackgroundDynamic() {
NiaTheme(disableDynamicTheming = false) {
NiaBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun BackgroundAndroid() {
NiaTheme(androidTheme = true) {
NiaBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun GradientBackgroundDefault() {
NiaTheme(disableDynamicTheming = true) {
NiaGradientBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun GradientBackgroundDynamic() {
NiaTheme(disableDynamicTheming = false) {
NiaGradientBackground(Modifier.size(100.dp), content = {})
}
}
@ThemePreviews
@Composable
fun GradientBackgroundAndroid() {
NiaTheme(androidTheme = true) {
NiaGradientBackground(Modifier.size(100.dp), content = {})
}
}

@ -0,0 +1,37 @@
/*
* Copyright 2024 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid.core.designsystem.component
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
@OptIn(ExperimentalMaterial3Api::class)
@Preview("Top App Bar")
@Composable
fun NiaTopAppBarPreview() {
NiaTheme {
NiaTopAppBar(
titleRes = android.R.string.untitled,
navigationIcon = NiaIcons.Search,
navigationIconContentDescription = "Navigation icon",
actionIcon = NiaIcons.MoreVert,
actionIconContentDescription = "Action icon",
)
}
}

@ -0,0 +1,52 @@
/*
* Copyright 2024 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid.core.designsystem.component
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
@ThemePreviews
@Composable
fun ViewTogglePreviewExpanded() {
NiaTheme {
Surface {
NiaViewToggleButton(
expanded = true,
onExpandedChange = { },
compactText = { Text(text = "Compact view") },
expandedText = { Text(text = "Expanded view") },
)
}
}
}
@Preview
@Composable
fun ViewTogglePreviewCompact() {
NiaTheme {
Surface {
NiaViewToggleButton(
expanded = false,
onExpandedChange = { },
compactText = { Text(text = "Compact view") },
expandedText = { Text(text = "Expanded view") },
)
}
}
}

@ -228,7 +228,7 @@ fun <A : ComponentActivity> AndroidComposeTestRule<ActivityScenarioRule<A>, A>.c
}
@Composable
private fun generateDescription(
internal fun generateDescription(
shouldCompareDarkMode: Boolean,
darkMode: Boolean,
shouldCompareAndroidTheme: Boolean,

@ -24,7 +24,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@ -32,12 +31,10 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.selected
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.designsystem.component.DynamicAsyncImage
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.ui.R.string
@Composable
@ -100,7 +97,7 @@ fun InterestsItem(
}
@Composable
private fun InterestsIcon(topicImageUrl: String, modifier: Modifier = Modifier) {
internal fun InterestsIcon(topicImageUrl: String, modifier: Modifier = Modifier) {
if (topicImageUrl.isEmpty()) {
Icon(
modifier = modifier
@ -118,90 +115,3 @@ private fun InterestsIcon(topicImageUrl: String, modifier: Modifier = Modifier)
)
}
}
@Preview
@Composable
private fun InterestsCardPreview() {
NiaTheme {
Surface {
InterestsItem(
name = "Compose",
description = "Description",
following = false,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
)
}
}
}
@Preview
@Composable
private fun InterestsCardLongNamePreview() {
NiaTheme {
Surface {
InterestsItem(
name = "This is a very very very very long name",
description = "Description",
following = true,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
)
}
}
}
@Preview
@Composable
private fun InterestsCardLongDescriptionPreview() {
NiaTheme {
Surface {
InterestsItem(
name = "Compose",
description = "This is a very very very very very very very " +
"very very very long description",
following = false,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
)
}
}
}
@Preview
@Composable
private fun InterestsCardWithEmptyDescriptionPreview() {
NiaTheme {
Surface {
InterestsItem(
name = "Compose",
description = "",
following = true,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
)
}
}
}
@Preview
@Composable
private fun InterestsCardSelectedPreview() {
NiaTheme {
Surface {
InterestsItem(
name = "Compose",
description = "",
following = true,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
isSelected = true,
)
}
}
}

@ -24,20 +24,13 @@ import androidx.browser.customtabs.CustomTabsIntent
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.analytics.LocalAnalyticsHelper
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
/**
@ -121,37 +114,3 @@ sealed interface NewsFeedUiState {
val feed: List<UserNewsResource>,
) : NewsFeedUiState
}
@Preview
@Composable
private fun NewsFeedLoadingPreview() {
NiaTheme {
LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Adaptive(300.dp)) {
newsFeed(
feedState = NewsFeedUiState.Loading,
onNewsResourcesCheckedChanged = { _, _ -> },
onNewsResourceViewed = {},
onTopicClick = {},
)
}
}
}
@Preview
@Preview(device = Devices.TABLET)
@Composable
private fun NewsFeedContentPreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
) {
NiaTheme {
LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Adaptive(300.dp)) {
newsFeed(
feedState = NewsFeedUiState.Success(userNewsResources),
onNewsResourcesCheckedChanged = { _, _ -> },
onNewsResourceViewed = {},
onTopicClick = {},
)
}
}
}

@ -42,10 +42,8 @@ import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -62,8 +60,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImagePainter
import coil.compose.rememberAsyncImagePainter
@ -71,7 +67,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.R.drawable
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
@ -350,47 +345,3 @@ fun NewsResourceTopics(
}
}
}
@Preview("Bookmark Button")
@Composable
private fun BookmarkButtonPreview() {
NiaTheme {
Surface {
BookmarkButton(isBookmarked = false, onClick = { })
}
}
}
@Preview("Bookmark Button Bookmarked")
@Composable
private fun BookmarkButtonBookmarkedPreview() {
NiaTheme {
Surface {
BookmarkButton(isBookmarked = true, onClick = { })
}
}
}
@Preview("NewsResourceCardExpanded")
@Composable
private fun ExpandedNewsResourcePreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
) {
CompositionLocalProvider(
LocalInspectionMode provides true,
) {
NiaTheme {
Surface {
NewsResourceCardExpanded(
userNewsResource = userNewsResources[0],
isBookmarked = true,
hasBeenViewed = false,
onToggleBookmark = {},
onClick = {},
onTopicClick = {},
)
}
}
}
}

@ -0,0 +1,108 @@
/*
* Copyright 2024 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
@Preview
@Composable
fun InterestsCardPreview() {
NiaTheme {
Surface {
InterestsItem(
name = "Compose",
description = "Description",
following = false,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
)
}
}
}
@Preview
@Composable
fun InterestsCardLongNamePreview() {
NiaTheme {
Surface {
InterestsItem(
name = "This is a very very very very long name",
description = "Description",
following = true,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
)
}
}
}
@Preview
@Composable
fun InterestsCardLongDescriptionPreview() {
NiaTheme {
Surface {
InterestsItem(
name = "Compose",
description = "This is a very very very very very very very " +
"very very very long description",
following = false,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
)
}
}
}
@Preview
@Composable
fun InterestsCardWithEmptyDescriptionPreview() {
NiaTheme {
Surface {
InterestsItem(
name = "Compose",
description = "",
following = true,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
)
}
}
}
@Preview
@Composable
fun InterestsCardSelectedPreview() {
NiaTheme {
Surface {
InterestsItem(
name = "Compose",
description = "",
following = true,
topicImageUrl = "",
onClick = { },
onFollowButtonClick = { },
isSelected = true,
)
}
}
}

@ -0,0 +1,60 @@
/*
* Copyright 2024 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
@Preview
@Composable
fun NewsFeedLoadingPreview() {
NiaTheme {
LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Adaptive(300.dp)) {
newsFeed(
feedState = NewsFeedUiState.Loading,
onNewsResourcesCheckedChanged = { _, _ -> },
onNewsResourceViewed = {},
onTopicClick = {},
)
}
}
}
@Preview
@Preview(device = Devices.TABLET)
@Composable
fun NewsFeedContentPreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
) {
NiaTheme {
LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Adaptive(300.dp)) {
newsFeed(
feedState = NewsFeedUiState.Success(userNewsResources),
onNewsResourcesCheckedChanged = { _, _ -> },
onNewsResourceViewed = {},
onTopicClick = {},
)
}
}
}

@ -0,0 +1,72 @@
/*
* Copyright 2024 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
@Preview("Bookmark Button")
@Composable
fun BookmarkButtonPreview() {
NiaTheme {
Surface {
BookmarkButton(isBookmarked = false, onClick = { })
}
}
}
@Preview("Bookmark Button Bookmarked")
@Composable
fun BookmarkButtonBookmarkedPreview() {
NiaTheme {
Surface {
BookmarkButton(isBookmarked = true, onClick = { })
}
}
}
@Preview("NewsResourceCardExpanded")
@Composable
fun ExpandedNewsResourcePreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
) {
CompositionLocalProvider(
LocalInspectionMode provides true,
) {
NiaTheme {
Surface {
NewsResourceCardExpanded(
userNewsResource = userNewsResources[0],
isBookmarked = true,
hasBeenViewed = false,
onToggleBookmark = {},
onClick = {},
onTopicClick = {},
)
}
}
}
}

@ -53,8 +53,6 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle
@ -65,14 +63,11 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollba
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.rememberDraggableScroller
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState
import com.google.samples.apps.nowinandroid.core.designsystem.theme.LocalTintTheme
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success
import com.google.samples.apps.nowinandroid.core.ui.TrackScreenViewEvent
import com.google.samples.apps.nowinandroid.core.ui.TrackScrollJank
import com.google.samples.apps.nowinandroid.core.ui.UserNewsResourcePreviewParameterProvider
import com.google.samples.apps.nowinandroid.core.ui.newsFeed
@Composable
@ -149,7 +144,7 @@ internal fun BookmarksScreen(
}
@Composable
private fun LoadingState(modifier: Modifier = Modifier) {
internal fun LoadingState(modifier: Modifier = Modifier) {
NiaLoadingWheel(
modifier = modifier
.fillMaxWidth()
@ -160,7 +155,7 @@ private fun LoadingState(modifier: Modifier = Modifier) {
}
@Composable
private fun BookmarksGrid(
internal fun BookmarksGrid(
feedState: NewsFeedUiState,
removeFromBookmarks: (String) -> Unit,
onNewsResourceViewed: (String) -> Unit,
@ -216,7 +211,7 @@ private fun BookmarksGrid(
}
@Composable
private fun EmptyState(modifier: Modifier = Modifier) {
internal fun EmptyState(modifier: Modifier = Modifier) {
Column(
modifier = modifier
.padding(16.dp)
@ -253,35 +248,3 @@ private fun EmptyState(modifier: Modifier = Modifier) {
)
}
}
@Preview
@Composable
private fun LoadingStatePreview() {
NiaTheme {
LoadingState()
}
}
@Preview
@Composable
private fun BookmarksGridPreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
) {
NiaTheme {
BookmarksGrid(
feedState = Success(userNewsResources),
removeFromBookmarks = {},
onNewsResourceViewed = {},
onTopicClick = {},
)
}
}
@Preview
@Composable
private fun EmptyStatePreview() {
NiaTheme {
EmptyState()
}
}

@ -0,0 +1,57 @@
/*
* Copyright 2024 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid.feature.bookmarks
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success
import com.google.samples.apps.nowinandroid.core.ui.UserNewsResourcePreviewParameterProvider
@Preview
@Composable
fun LoadingStatePreview() {
NiaTheme {
LoadingState()
}
}
@Preview
@Composable
fun BookmarksGridPreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
) {
NiaTheme {
BookmarksGrid(
feedState = Success(userNewsResources),
removeFromBookmarks = {},
onNewsResourceViewed = {},
onTopicClick = {},
)
}
}
@Preview
@Composable
fun EmptyStatePreview() {
NiaTheme {
EmptyState()
}
}

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

Loading…
Cancel
Save