Add a FAB on the Lexicon
This commit is contained in:
		
							parent
							
								
									c5fb8bf99e
								
							
						
					
					
						commit
						54e09e5f1d
					
				
					 6 changed files with 262 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -0,0 +1,182 @@
 | 
			
		|||
package com.pixelized.rplexicon.ui.composable
 | 
			
		||||
 | 
			
		||||
import androidx.compose.animation.*
 | 
			
		||||
import androidx.compose.animation.core.*
 | 
			
		||||
import androidx.compose.foundation.BorderStroke
 | 
			
		||||
import androidx.compose.foundation.interaction.MutableInteractionSource
 | 
			
		||||
import androidx.compose.foundation.layout.*
 | 
			
		||||
import androidx.compose.foundation.shape.CircleShape
 | 
			
		||||
import androidx.compose.material.*
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.CompositionLocalProvider
 | 
			
		||||
import androidx.compose.runtime.getValue
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.ui.Alignment
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.graphics.Shape
 | 
			
		||||
import androidx.compose.ui.res.painterResource
 | 
			
		||||
import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.tooling.preview.PreviewParameter
 | 
			
		||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 | 
			
		||||
import androidx.compose.ui.unit.Dp
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import com.pixelized.rplexicon.R
 | 
			
		||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun FloatingActionButton(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    expended: Boolean,
 | 
			
		||||
    enabled: Boolean = true,
 | 
			
		||||
    innerSpacing: Dp = 16.dp,
 | 
			
		||||
    contentPadding: PaddingValues = FlyingBlueFloatingActionButtonDefault.ContentPadding,
 | 
			
		||||
    elevation: ButtonElevation? = ButtonDefaults.elevation(
 | 
			
		||||
        defaultElevation = 0.dp,
 | 
			
		||||
        pressedElevation = 0.dp,
 | 
			
		||||
        disabledElevation = 0.dp,
 | 
			
		||||
    ),
 | 
			
		||||
    shape: Shape = CircleShape,
 | 
			
		||||
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
 | 
			
		||||
    colors: ButtonColors = ButtonDefaults.buttonColors(),
 | 
			
		||||
    onClick: () -> Unit,
 | 
			
		||||
    icon: @Composable (RowScope.() -> Unit),
 | 
			
		||||
    text: @Composable (RowScope.() -> Unit),
 | 
			
		||||
) {
 | 
			
		||||
    LocalButton(
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        onClick = onClick,
 | 
			
		||||
        enabled = enabled,
 | 
			
		||||
        interactionSource = interactionSource,
 | 
			
		||||
        elevation = elevation,
 | 
			
		||||
        shape = shape,
 | 
			
		||||
        colors = colors,
 | 
			
		||||
        contentPadding = contentPadding,
 | 
			
		||||
        content = {
 | 
			
		||||
            FabContent(
 | 
			
		||||
                expended = expended,
 | 
			
		||||
                innerSpacing = innerSpacing,
 | 
			
		||||
                icon = icon,
 | 
			
		||||
                text = text,
 | 
			
		||||
            )
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
private fun BoxWithConstraintsScope.FabContent(
 | 
			
		||||
    expended: Boolean,
 | 
			
		||||
    innerSpacing: Dp,
 | 
			
		||||
    icon: @Composable (RowScope.() -> Unit),
 | 
			
		||||
    text: @Composable (RowScope.() -> Unit),
 | 
			
		||||
) {
 | 
			
		||||
    val width by animateDpAsState(
 | 
			
		||||
        label = "FabContentWidth",
 | 
			
		||||
        targetValue = if (expended) maxWidth else minWidth,
 | 
			
		||||
        animationSpec = when (expended) {
 | 
			
		||||
            true -> tween(durationMillis = 300, easing = FastOutSlowInEasing)
 | 
			
		||||
            else -> tween(durationMillis = 300, delayMillis = 100, easing = FastOutSlowInEasing)
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
    Row(
 | 
			
		||||
        modifier = Modifier.size(
 | 
			
		||||
            height = 56.dp,
 | 
			
		||||
            width = width
 | 
			
		||||
        ),
 | 
			
		||||
        verticalAlignment = Alignment.CenterVertically,
 | 
			
		||||
        horizontalArrangement = Arrangement.Center,
 | 
			
		||||
    ) {
 | 
			
		||||
        icon()
 | 
			
		||||
        AnimatedVisibility(
 | 
			
		||||
            visible = expended,
 | 
			
		||||
            enter = fadeIn(
 | 
			
		||||
                tween(durationMillis = 300, delayMillis = 100, easing = FastOutSlowInEasing)
 | 
			
		||||
            ),
 | 
			
		||||
            exit = fadeOut(
 | 
			
		||||
                tween(durationMillis = 300, easing = FastOutSlowInEasing)
 | 
			
		||||
            ) + shrinkHorizontally(
 | 
			
		||||
                tween(durationMillis = 300, easing = FastOutSlowInEasing)
 | 
			
		||||
            ),
 | 
			
		||||
        ) {
 | 
			
		||||
            Row {
 | 
			
		||||
                Spacer(modifier = Modifier.width(innerSpacing))
 | 
			
		||||
                text()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@OptIn(ExperimentalMaterialApi::class)
 | 
			
		||||
@Composable
 | 
			
		||||
private fun LocalButton(
 | 
			
		||||
    onClick: () -> Unit,
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    enabled: Boolean = true,
 | 
			
		||||
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
 | 
			
		||||
    elevation: ButtonElevation? = ButtonDefaults.elevation(),
 | 
			
		||||
    shape: Shape = MaterialTheme.shapes.small,
 | 
			
		||||
    border: BorderStroke? = null,
 | 
			
		||||
    colors: ButtonColors = ButtonDefaults.buttonColors(),
 | 
			
		||||
    contentPadding: PaddingValues = FlyingBlueFloatingActionButtonDefault.ContentPadding,
 | 
			
		||||
    content: @Composable BoxWithConstraintsScope.() -> Unit
 | 
			
		||||
) {
 | 
			
		||||
    val contentColor by colors.contentColor(enabled)
 | 
			
		||||
    Surface(
 | 
			
		||||
        onClick = onClick,
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        enabled = enabled,
 | 
			
		||||
        shape = shape,
 | 
			
		||||
        color = colors.backgroundColor(enabled).value,
 | 
			
		||||
        contentColor = contentColor.copy(alpha = 1f),
 | 
			
		||||
        border = border,
 | 
			
		||||
        elevation = elevation?.elevation(enabled, interactionSource)?.value ?: 0.dp,
 | 
			
		||||
        interactionSource = interactionSource,
 | 
			
		||||
    ) {
 | 
			
		||||
        CompositionLocalProvider(LocalContentAlpha provides contentColor.alpha) {
 | 
			
		||||
            ProvideTextStyle(
 | 
			
		||||
                value = MaterialTheme.typography.button
 | 
			
		||||
            ) {
 | 
			
		||||
                BoxWithConstraints(
 | 
			
		||||
                    Modifier
 | 
			
		||||
                        .defaultMinSize(
 | 
			
		||||
                            minWidth = FlyingBlueFloatingActionButtonDefault.MinWidth,
 | 
			
		||||
                            minHeight = FlyingBlueFloatingActionButtonDefault.MinHeight
 | 
			
		||||
                        )
 | 
			
		||||
                        .padding(contentPadding),
 | 
			
		||||
                    content = content
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object FlyingBlueFloatingActionButtonDefault {
 | 
			
		||||
    val ContentPadding = PaddingValues(all = 0.dp)
 | 
			
		||||
    val MinWidth = 56.dp
 | 
			
		||||
    val MinHeight = 56.dp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@Preview
 | 
			
		||||
private fun FloatingActionButtonPreview(
 | 
			
		||||
    @PreviewParameter(FloatingActionButtonPreviewProvider::class) expended: Boolean
 | 
			
		||||
) {
 | 
			
		||||
    LexiconTheme {
 | 
			
		||||
        FloatingActionButton(
 | 
			
		||||
            expended = expended,
 | 
			
		||||
            icon = {
 | 
			
		||||
                Icon(
 | 
			
		||||
                    painter = painterResource(id = R.drawable.ic_baseline_search_24),
 | 
			
		||||
                    contentDescription = null,
 | 
			
		||||
                )
 | 
			
		||||
            },
 | 
			
		||||
            text = {
 | 
			
		||||
                Text(text = "Floating Action Button")
 | 
			
		||||
            },
 | 
			
		||||
            onClick = { }
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private class FloatingActionButtonPreviewProvider : PreviewParameterProvider<Boolean> {
 | 
			
		||||
    override val values: Sequence<Boolean> = sequenceOf(false, true)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
package com.pixelized.rplexicon.ui.navigation
 | 
			
		||||
 | 
			
		||||
import androidx.compose.foundation.lazy.LazyListState
 | 
			
		||||
import androidx.compose.foundation.lazy.rememberLazyListState
 | 
			
		||||
import androidx.navigation.NavGraphBuilder
 | 
			
		||||
import androidx.navigation.NavHostController
 | 
			
		||||
import androidx.navigation.NavOptionsBuilder
 | 
			
		||||
| 
						 | 
				
			
			@ -9,12 +11,16 @@ private const val ROUTE = "lexicon"
 | 
			
		|||
 | 
			
		||||
const val LEXICON_ROUTE = ROUTE
 | 
			
		||||
 | 
			
		||||
fun NavGraphBuilder.composableLexicon() {
 | 
			
		||||
fun NavGraphBuilder.composableLexicon(
 | 
			
		||||
    lazyListState: LazyListState,
 | 
			
		||||
) {
 | 
			
		||||
    animatedComposable(
 | 
			
		||||
        route = LEXICON_ROUTE,
 | 
			
		||||
        animation = NavigationAnimation.Fade,
 | 
			
		||||
    ) {
 | 
			
		||||
        LexiconScreen()
 | 
			
		||||
        LexiconScreen(
 | 
			
		||||
            lazyListState = lazyListState
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package com.pixelized.rplexicon.ui.navigation
 | 
			
		||||
 | 
			
		||||
import androidx.compose.animation.ExperimentalAnimationApi
 | 
			
		||||
import androidx.compose.foundation.lazy.rememberLazyListState
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.CompositionLocalProvider
 | 
			
		||||
import androidx.compose.runtime.staticCompositionLocalOf
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +20,8 @@ fun ScreenNavHost(
 | 
			
		|||
    navHostController: NavHostController = rememberAnimatedNavController(),
 | 
			
		||||
    startDestination: String = AUTHENTICATION_ROUTE,
 | 
			
		||||
) {
 | 
			
		||||
    val lexiconListState = rememberLazyListState()
 | 
			
		||||
 | 
			
		||||
    CompositionLocalProvider(
 | 
			
		||||
        LocalScreenNavHost provides navHostController,
 | 
			
		||||
    ) {
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +30,7 @@ fun ScreenNavHost(
 | 
			
		|||
            startDestination = startDestination,
 | 
			
		||||
        ) {
 | 
			
		||||
            composableAuthentication()
 | 
			
		||||
            composableLexicon()
 | 
			
		||||
            composableLexicon(lazyListState = lexiconListState)
 | 
			
		||||
            composableCharacterDetail()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,13 +13,17 @@ import androidx.compose.foundation.layout.fillMaxSize
 | 
			
		|||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
			
		||||
import androidx.compose.foundation.layout.padding
 | 
			
		||||
import androidx.compose.foundation.lazy.LazyColumn
 | 
			
		||||
import androidx.compose.foundation.lazy.LazyListState
 | 
			
		||||
import androidx.compose.foundation.lazy.items
 | 
			
		||||
import androidx.compose.foundation.lazy.rememberLazyListState
 | 
			
		||||
import androidx.compose.material.ExperimentalMaterialApi
 | 
			
		||||
import androidx.compose.material.pullrefresh.PullRefreshIndicator
 | 
			
		||||
import androidx.compose.material.pullrefresh.PullRefreshState
 | 
			
		||||
import androidx.compose.material.pullrefresh.pullRefresh
 | 
			
		||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
 | 
			
		||||
import androidx.compose.material3.ExperimentalMaterial3Api
 | 
			
		||||
import androidx.compose.material3.Icon
 | 
			
		||||
import androidx.compose.material3.MaterialTheme
 | 
			
		||||
import androidx.compose.material3.Scaffold
 | 
			
		||||
import androidx.compose.material3.Surface
 | 
			
		||||
import androidx.compose.material3.Text
 | 
			
		||||
| 
						 | 
				
			
			@ -28,17 +32,21 @@ import androidx.compose.runtime.Composable
 | 
			
		|||
import androidx.compose.runtime.LaunchedEffect
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.runtime.derivedStateOf
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.runtime.rememberCoroutineScope
 | 
			
		||||
import androidx.compose.ui.Alignment
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.res.painterResource
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
import androidx.compose.ui.text.font.FontWeight
 | 
			
		||||
import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import androidx.hilt.navigation.compose.hiltViewModel
 | 
			
		||||
import com.pixelized.rplexicon.LocalSnack
 | 
			
		||||
import com.pixelized.rplexicon.R
 | 
			
		||||
import com.pixelized.rplexicon.ui.composable.FloatingActionButton
 | 
			
		||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
 | 
			
		||||
import com.pixelized.rplexicon.ui.navigation.navigateToCharacterDetail
 | 
			
		||||
import com.pixelized.rplexicon.ui.screens.lexicon.LexiconErrorUio.Default
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +68,7 @@ sealed class LexiconErrorUio {
 | 
			
		|||
@Composable
 | 
			
		||||
fun LexiconScreen(
 | 
			
		||||
    viewModel: LexiconViewModel = hiltViewModel(),
 | 
			
		||||
    lazyListState: LazyListState,
 | 
			
		||||
) {
 | 
			
		||||
    val scope = rememberCoroutineScope()
 | 
			
		||||
    val screen = LocalScreenNavHost.current
 | 
			
		||||
| 
						 | 
				
			
			@ -73,11 +82,22 @@ fun LexiconScreen(
 | 
			
		|||
        },
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    val isFabExpended = remember {
 | 
			
		||||
        derivedStateOf {
 | 
			
		||||
            lazyListState.canScrollForward.not() && viewModel.items.value.isNotEmpty()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Surface {
 | 
			
		||||
        LexiconScreenContent(
 | 
			
		||||
            items = viewModel.items,
 | 
			
		||||
            refresh = refresh,
 | 
			
		||||
            lazyColumnState = lazyListState,
 | 
			
		||||
            refreshState = refresh,
 | 
			
		||||
            refreshing = viewModel.isLoading,
 | 
			
		||||
            isFabExpended = isFabExpended,
 | 
			
		||||
            onSearch = {
 | 
			
		||||
 | 
			
		||||
            },
 | 
			
		||||
            onItem = {
 | 
			
		||||
                screen.navigateToCharacterDetail(id = it.id)
 | 
			
		||||
            },
 | 
			
		||||
| 
						 | 
				
			
			@ -96,9 +116,12 @@ fun LexiconScreen(
 | 
			
		|||
@Composable
 | 
			
		||||
private fun LexiconScreenContent(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    refresh: PullRefreshState,
 | 
			
		||||
    lazyColumnState: LazyListState,
 | 
			
		||||
    refreshState: PullRefreshState,
 | 
			
		||||
    refreshing: State<Boolean>,
 | 
			
		||||
    isFabExpended: State<Boolean>,
 | 
			
		||||
    items: State<List<LexiconItemUio>>,
 | 
			
		||||
    onSearch: () -> Unit,
 | 
			
		||||
    onItem: (LexiconItemUio) -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    Scaffold(
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +132,28 @@ private fun LexiconScreenContent(
 | 
			
		|||
                    Text(text = stringResource(id = R.string.app_name))
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
        },
 | 
			
		||||
        floatingActionButton = {
 | 
			
		||||
            FloatingActionButton(
 | 
			
		||||
                modifier = Modifier.padding(start = 32.dp),
 | 
			
		||||
                expended = isFabExpended.value,
 | 
			
		||||
                onClick = onSearch,
 | 
			
		||||
                icon = {
 | 
			
		||||
                    Icon(
 | 
			
		||||
                        tint = MaterialTheme.colorScheme.onPrimary,
 | 
			
		||||
                        painter = painterResource(id = R.drawable.ic_baseline_search_24),
 | 
			
		||||
                        contentDescription = null,
 | 
			
		||||
                    )
 | 
			
		||||
                },
 | 
			
		||||
                text = {
 | 
			
		||||
                    val typography = MaterialTheme.typography
 | 
			
		||||
                    Text(
 | 
			
		||||
                        color = MaterialTheme.colorScheme.onPrimary,
 | 
			
		||||
                        style = remember { typography.bodyLarge.copy(fontWeight = FontWeight.Bold) },
 | 
			
		||||
                        text = "Rechercher",
 | 
			
		||||
                    )
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    ) {
 | 
			
		||||
        Box(
 | 
			
		||||
| 
						 | 
				
			
			@ -118,8 +163,12 @@ private fun LexiconScreenContent(
 | 
			
		|||
            LazyColumn(
 | 
			
		||||
                modifier = Modifier
 | 
			
		||||
                    .fillMaxSize()
 | 
			
		||||
                    .pullRefresh(state = refresh),
 | 
			
		||||
                contentPadding = PaddingValues(vertical = 8.dp),
 | 
			
		||||
                    .pullRefresh(state = refreshState),
 | 
			
		||||
                state = lazyColumnState,
 | 
			
		||||
                contentPadding = PaddingValues(
 | 
			
		||||
                    top = 8.dp,
 | 
			
		||||
                    bottom = 8.dp + 16.dp + 56.dp + 16.dp
 | 
			
		||||
                ),
 | 
			
		||||
            ) {
 | 
			
		||||
                items(items = items.value) { item ->
 | 
			
		||||
                    LexiconItem(
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +183,7 @@ private fun LexiconScreenContent(
 | 
			
		|||
 | 
			
		||||
            PullRefreshIndicator(
 | 
			
		||||
                refreshing = refreshing.value,
 | 
			
		||||
                state = refresh,
 | 
			
		||||
                state = refreshState,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -177,11 +226,13 @@ private fun LexiconScreenContentPreview() {
 | 
			
		|||
        Surface {
 | 
			
		||||
            LexiconScreenContent(
 | 
			
		||||
                modifier = Modifier.fillMaxSize(),
 | 
			
		||||
                refresh = rememberPullRefreshState(
 | 
			
		||||
                lazyColumnState = rememberLazyListState(),
 | 
			
		||||
                refreshState = rememberPullRefreshState(
 | 
			
		||||
                    refreshing = false,
 | 
			
		||||
                    onRefresh = {},
 | 
			
		||||
                ),
 | 
			
		||||
                refreshing = remember { mutableStateOf(false) },
 | 
			
		||||
                isFabExpended = remember { mutableStateOf(true) },
 | 
			
		||||
                items = remember {
 | 
			
		||||
                    mutableStateOf(
 | 
			
		||||
                        listOf(
 | 
			
		||||
| 
						 | 
				
			
			@ -195,6 +246,7 @@ private fun LexiconScreenContentPreview() {
 | 
			
		|||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                },
 | 
			
		||||
                onSearch = { },
 | 
			
		||||
                onItem = { },
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import androidx.compose.material3.darkColorScheme
 | 
			
		|||
import androidx.compose.material3.lightColorScheme
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.SideEffect
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import androidx.compose.ui.graphics.toArgb
 | 
			
		||||
import androidx.compose.ui.platform.LocalView
 | 
			
		||||
import androidx.core.view.WindowCompat
 | 
			
		||||
| 
						 | 
				
			
			@ -14,13 +15,15 @@ import androidx.core.view.WindowCompat
 | 
			
		|||
private val DarkColorScheme = darkColorScheme(
 | 
			
		||||
    primary = Purple80,
 | 
			
		||||
    secondary = PurpleGrey80,
 | 
			
		||||
    tertiary = Pink80
 | 
			
		||||
    tertiary = Pink80,
 | 
			
		||||
    onPrimary = Color.White,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
private val LightColorScheme = lightColorScheme(
 | 
			
		||||
    primary = Purple40,
 | 
			
		||||
    secondary = PurpleGrey40,
 | 
			
		||||
    tertiary = Pink40
 | 
			
		||||
    tertiary = Pink40,
 | 
			
		||||
    onPrimary = Color.White,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue