Created
September 30, 2023 21:55
-
-
Save fergdev/b8255a604b0521c3d0701f8a3733742d to your computer and use it in GitHub Desktop.
M3 - Compose Component Mash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ferg.componentmash | |
import android.app.Activity | |
import android.os.Bundle | |
import androidx.activity.compose.setContent | |
import androidx.compose.animation.animateColorAsState | |
import androidx.compose.foundation.background | |
import androidx.compose.foundation.layout.Arrangement | |
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.fillMaxSize | |
import androidx.compose.foundation.layout.fillMaxWidth | |
import androidx.compose.foundation.layout.height | |
import androidx.compose.foundation.layout.padding | |
import androidx.compose.foundation.layout.width | |
import androidx.compose.foundation.layout.wrapContentSize | |
import androidx.compose.foundation.lazy.LazyColumn | |
import androidx.compose.foundation.lazy.LazyRow | |
import androidx.compose.foundation.shape.RoundedCornerShape | |
import androidx.compose.material.icons.Icons | |
import androidx.compose.material.icons.filled.AddCircle | |
import androidx.compose.material.icons.filled.Done | |
import androidx.compose.material.icons.filled.Edit | |
import androidx.compose.material.icons.filled.ExitToApp | |
import androidx.compose.material.icons.filled.Favorite | |
import androidx.compose.material.icons.filled.Home | |
import androidx.compose.material.icons.filled.Info | |
import androidx.compose.material3.AlertDialog | |
import androidx.compose.material3.AssistChip | |
import androidx.compose.material3.Badge | |
import androidx.compose.material3.BadgedBox | |
import androidx.compose.material3.BottomAppBar | |
import androidx.compose.material3.Button | |
import androidx.compose.material3.Card | |
import androidx.compose.material3.Checkbox | |
import androidx.compose.material3.DatePicker | |
import androidx.compose.material3.DatePickerDialog | |
import androidx.compose.material3.DatePickerState | |
import androidx.compose.material3.DateRangePicker | |
import androidx.compose.material3.DateRangePickerState | |
import androidx.compose.material3.DismissValue | |
import androidx.compose.material3.DisplayMode | |
import androidx.compose.material3.Divider | |
import androidx.compose.material3.DropdownMenu | |
import androidx.compose.material3.DropdownMenuItem | |
import androidx.compose.material3.ElevatedAssistChip | |
import androidx.compose.material3.ElevatedButton | |
import androidx.compose.material3.ElevatedCard | |
import androidx.compose.material3.ElevatedFilterChip | |
import androidx.compose.material3.ElevatedSuggestionChip | |
import androidx.compose.material3.ExperimentalMaterial3Api | |
import androidx.compose.material3.ExposedDropdownMenuBox | |
import androidx.compose.material3.ExposedDropdownMenuDefaults | |
import androidx.compose.material3.ExtendedFloatingActionButton | |
import androidx.compose.material3.FilledIconButton | |
import androidx.compose.material3.FilledIconToggleButton | |
import androidx.compose.material3.FilledTonalButton | |
import androidx.compose.material3.FilledTonalIconButton | |
import androidx.compose.material3.FilledTonalIconToggleButton | |
import androidx.compose.material3.FilterChip | |
import androidx.compose.material3.FloatingActionButton | |
import androidx.compose.material3.FloatingActionButtonDefaults | |
import androidx.compose.material3.Icon | |
import androidx.compose.material3.IconButton | |
import androidx.compose.material3.IconToggleButton | |
import androidx.compose.material3.InputChip | |
import androidx.compose.material3.ListItem | |
import androidx.compose.material3.MaterialTheme | |
import androidx.compose.material3.ModalBottomSheet | |
import androidx.compose.material3.OutlinedButton | |
import androidx.compose.material3.OutlinedCard | |
import androidx.compose.material3.OutlinedIconButton | |
import androidx.compose.material3.OutlinedIconToggleButton | |
import androidx.compose.material3.OutlinedTextField | |
import androidx.compose.material3.PlainTooltipBox | |
import androidx.compose.material3.PlainTooltipState | |
import androidx.compose.material3.RadioButton | |
import androidx.compose.material3.RangeSlider | |
import androidx.compose.material3.RichTooltipBox | |
import androidx.compose.material3.RichTooltipState | |
import androidx.compose.material3.Slider | |
import androidx.compose.material3.Snackbar | |
import androidx.compose.material3.SnackbarData | |
import androidx.compose.material3.SnackbarDuration | |
import androidx.compose.material3.SnackbarVisuals | |
import androidx.compose.material3.SuggestionChip | |
import androidx.compose.material3.Surface | |
import androidx.compose.material3.SwipeToDismiss | |
import androidx.compose.material3.Switch | |
import androidx.compose.material3.Tab | |
import androidx.compose.material3.TabRow | |
import androidx.compose.material3.Text | |
import androidx.compose.material3.TextButton | |
import androidx.compose.material3.TextField | |
import androidx.compose.material3.TimeInput | |
import androidx.compose.material3.TimePicker | |
import androidx.compose.material3.TopAppBar | |
import androidx.compose.material3.TriStateCheckbox | |
import androidx.compose.material3.rememberDismissState | |
import androidx.compose.material3.rememberTimePickerState | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.getValue | |
import androidx.compose.runtime.mutableStateOf | |
import androidx.compose.runtime.remember | |
import androidx.compose.runtime.rememberCoroutineScope | |
import androidx.compose.runtime.setValue | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.graphics.vector.ImageVector | |
import androidx.compose.ui.platform.LocalContext | |
import androidx.compose.ui.res.vectorResource | |
import androidx.compose.ui.state.ToggleableState.Indeterminate | |
import androidx.compose.ui.state.ToggleableState.Off | |
import androidx.compose.ui.state.ToggleableState.On | |
import androidx.compose.ui.text.TextStyle | |
import androidx.compose.ui.text.font.Font | |
import androidx.compose.ui.text.font.FontFamily | |
import androidx.compose.ui.text.font.FontWeight | |
import androidx.compose.ui.text.style.TextAlign | |
import androidx.compose.ui.text.style.TextOverflow | |
import androidx.compose.ui.unit.dp | |
import androidx.compose.ui.unit.sp | |
import kotlinx.coroutines.launch | |
import org.joda.time.DateTime | |
class ComponentMash : ComponentActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContent { | |
AppTheme { | |
Surface { | |
ScreenContent() | |
} | |
} | |
} | |
} | |
} | |
object Dates { | |
val today: DateTime = DateTime.now() | |
val todayPlus5Days: DateTime = today.plusDays(5) | |
val todayMinusOneMonth: DateTime = today.minusMonths(1) | |
val todayPlusOneMonth: DateTime = today.plusMonths(1) | |
val todayMinus2Years: DateTime = today.minusYears(2) | |
val todayPlus2Years: DateTime = today.plusYears(2) | |
} | |
@OptIn(ExperimentalMaterial3Api::class) | |
@Composable | |
private fun ScreenContent() { | |
val activity = LocalContext.current as? Activity | |
var datePickerVisible by remember { mutableStateOf(false) } | |
var dateRangePickerVisible by remember { mutableStateOf(false) } | |
var alertDialogVisible by remember { mutableStateOf(false) } | |
var bottomSheetVisible by remember { mutableStateOf(false) } | |
var timePickDialogVisible by remember { mutableStateOf(false) } | |
var timeInputDialogVisible by remember { mutableStateOf(false) } | |
Column { | |
TopAppBar(title = { | |
Text( | |
text = "App bar", | |
style = AppTheme.typography.titleLargeBold, | |
) | |
}, navigationIcon = { | |
IconButton(onClick = { | |
activity?.finish() | |
}) { | |
Icon( | |
imageVector = ImageVector.vectorResource(R.drawable.sg_icon_arrow_back_blue_24dp), | |
contentDescription = "Back" | |
) | |
} | |
}, actions = { | |
IconButton(onClick = { /*TODO*/ }) { | |
Icon( | |
imageVector = ImageVector.vectorResource(id = R.drawable.ic_xml), | |
contentDescription = null | |
) | |
} | |
IconButton(onClick = { /*TODO*/ }) { | |
Icon( | |
imageVector = ImageVector.vectorResource(id = R.drawable.ic_compose), | |
contentDescription = null | |
) | |
} | |
}) | |
LazyColumn( | |
verticalArrangement = Arrangement.spacedBy(24.dp), modifier = Modifier.padding(8.dp) | |
) { | |
item { | |
Heading(text = "Badge") | |
Row( | |
modifier = Modifier | |
.padding(16.dp) | |
.fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceAround | |
) { | |
BadgedBox(badge = { Badge { Text("8") } }) { | |
Icon( | |
Icons.Filled.Favorite, contentDescription = "Favorite" | |
) | |
} | |
BadgedBox(badge = { Badge { Text("4") } }) { | |
Icon( | |
Icons.Filled.Done, contentDescription = "Favorite" | |
) | |
} | |
BadgedBox(badge = { Badge { Text("200") } }) { | |
Icon( | |
Icons.Filled.Home, contentDescription = "Favorite" | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Bottom app bar") | |
BottomAppBar(actions = { | |
Row( | |
horizontalArrangement = Arrangement.spacedBy(8.dp), | |
modifier = Modifier.padding(horizontal = 8.dp) | |
) { | |
Icon( | |
Icons.Filled.Favorite, contentDescription = "Favorite" | |
) | |
Icon( | |
Icons.Filled.Done, contentDescription = "Favorite" | |
) | |
Icon( | |
Icons.Filled.Home, contentDescription = "Favorite" | |
) | |
} | |
}, floatingActionButton = { | |
FloatingActionButton(onClick = {}) { | |
Icon( | |
imageVector = ImageVector.vectorResource(id = R.drawable.ic_xml), | |
contentDescription = null | |
) | |
} | |
}) | |
} | |
item { | |
Heading(text = "Bottom sheet") | |
Button(onClick = { bottomSheetVisible = true }) { | |
Text(text = "Bottom sheet") | |
} | |
} | |
item { | |
Heading(text = "Buttons") | |
Column( | |
modifier = Modifier.fillMaxWidth(), | |
) { | |
Button(onClick = {}) { | |
Text(text = "Button") | |
} | |
ElevatedButton(onClick = {}) { | |
Text(text = "Elevated Button") | |
} | |
FilledTonalButton(onClick = {}) { | |
Text(text = "Filled Tonal Button") | |
} | |
OutlinedButton(onClick = {}) { | |
Text(text = "Outlined Button") | |
} | |
TextButton(onClick = {}) { | |
Text(text = "Text Button") | |
} | |
} | |
} | |
item { | |
Heading(text = "Cards") | |
Row( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceAround | |
) { | |
Card { | |
Text( | |
modifier = Modifier.padding(16.dp), text = "Filled Card" | |
) | |
} | |
ElevatedCard { | |
Text( | |
modifier = Modifier.padding(16.dp), text = "Elevated Card" | |
) | |
} | |
OutlinedCard { | |
Text( | |
modifier = Modifier.padding(16.dp), text = "Outlined Card" | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Check box") | |
Row( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceEvenly | |
) { | |
var checked by remember { mutableStateOf(true) } | |
Row(verticalAlignment = Alignment.CenterVertically) { | |
Text(text = "Enabled") | |
Checkbox(checked = checked, onCheckedChange = { checked = it }) | |
} | |
Row(verticalAlignment = Alignment.CenterVertically) { | |
Text(text = "Disabled O") | |
Checkbox(enabled = false, checked = false, onCheckedChange = {}) | |
} | |
Row(verticalAlignment = Alignment.CenterVertically) { | |
Text(text = "Disabled x") | |
Checkbox(enabled = false, checked = true, onCheckedChange = {}) | |
} | |
} | |
} | |
item { | |
Heading(text = "Check box tri-state") | |
Row( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceEvenly, | |
verticalAlignment = Alignment.CenterVertically | |
) { | |
var state by remember { mutableStateOf(On) } | |
Text(text = "Enabled") | |
TriStateCheckbox(state = state, onClick = { | |
state = when (state) { | |
On -> Off | |
Off -> Indeterminate | |
Indeterminate -> On | |
} | |
}) | |
Text(text = "O") | |
TriStateCheckbox(enabled = false, state = Off, onClick = null) | |
Text(text = "X") | |
TriStateCheckbox(enabled = false, state = On, onClick = null) | |
Text(text = "-") | |
TriStateCheckbox(enabled = false, state = Indeterminate, onClick = null) | |
} | |
} | |
item { | |
Heading(text = "Chips") | |
LazyRow(modifier = Modifier.fillMaxWidth()) { | |
item { | |
AssistChip( | |
onClick = {}, | |
label = { Text(text = "Assist chip") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
} | |
item { | |
AssistChip( | |
enabled = false, | |
onClick = {}, | |
label = { Text(text = "Assist chip disabled") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
} | |
} | |
LazyRow( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalArrangement = Arrangement.spacedBy(8.dp) | |
) { | |
item { | |
ElevatedAssistChip( | |
onClick = {}, | |
label = { Text(text = "ElevatedAssistChip chip") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
} | |
item { | |
ElevatedAssistChip( | |
enabled = false, | |
onClick = {}, | |
label = { Text(text = "ElevatedAssistChip chip disabled") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
} | |
} | |
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { | |
FilterChip( | |
onClick = {}, | |
selected = true, | |
label = { Text(text = "Filter chip X") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
FilterChip( | |
onClick = {}, | |
selected = false, | |
label = { Text(text = "Filter chip 0") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
} | |
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { | |
ElevatedFilterChip( | |
onClick = {}, | |
selected = true, | |
label = { Text(text = "Elevated Filter chip X") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
ElevatedFilterChip( | |
onClick = {}, | |
selected = false, | |
label = { Text(text = "Elevated Filter chip 0") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
} | |
InputChip( | |
onClick = {}, | |
selected = false, | |
label = { Text(text = "Input chip") }, | |
leadingIcon = { | |
Icon(imageVector = Icons.Filled.Home, contentDescription = null) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = Icons.Filled.ExitToApp, | |
contentDescription = null | |
) | |
}, | |
) | |
SuggestionChip( | |
onClick = {}, | |
label = { Text(text = "Suggestion chip") }, | |
) | |
ElevatedSuggestionChip(onClick = {}, | |
label = { Text(text = "Elevated suggestion chip") }) | |
} | |
item { | |
Heading(text = "Date picker") | |
Column { | |
Button(onClick = { datePickerVisible = true }) { | |
Text(text = "Show date picker") | |
} | |
} | |
} | |
item { | |
Heading(text = "Date range picker") | |
Column { | |
Button(onClick = { dateRangePickerVisible = true }) { | |
Text(text = "Show range date picker") | |
} | |
} | |
} | |
item { | |
Heading(text = "Dialogs - alert") | |
Button(onClick = { alertDialogVisible = true }) { | |
Text("Show alert dialog") | |
} | |
} | |
item { | |
Heading(text = "FAB") | |
Row( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceAround | |
) { | |
FloatingActionButton(onClick = {}) { | |
Icon( | |
imageVector = ImageVector.vectorResource(id = R.drawable.ic_xml), | |
contentDescription = null | |
) | |
} | |
FloatingActionButton( | |
onClick = {}, shape = FloatingActionButtonDefaults.smallShape | |
) { | |
Icon( | |
imageVector = ImageVector.vectorResource(id = R.drawable.ic_xml), | |
contentDescription = null | |
) | |
} | |
FloatingActionButton( | |
onClick = {}, shape = FloatingActionButtonDefaults.largeShape | |
) { | |
Icon( | |
imageVector = ImageVector.vectorResource(id = R.drawable.ic_xml), | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "FAB extended") | |
Row( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceAround | |
) { | |
ExtendedFloatingActionButton(onClick = {}) { | |
Text(text = "Navigate") | |
} | |
} | |
} | |
item { | |
Heading(text = "Icon Button") | |
Row(modifier = Modifier.fillMaxWidth()) { | |
IconButton(onClick = {}) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
IconButton(onClick = {}, enabled = false) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Icon Toggle Button") | |
Row(modifier = Modifier.fillMaxWidth()) { | |
IconToggleButton(checked = true, onCheckedChange = {}) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
IconToggleButton(checked = false, onCheckedChange = {}) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
IconToggleButton(checked = true, enabled = false, onCheckedChange = {}) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
IconToggleButton(checked = false, enabled = false, onCheckedChange = {}) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Filled Icon Button") | |
Row(modifier = Modifier.fillMaxWidth()) { | |
FilledIconButton(onClick = {}) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
FilledIconButton(onClick = {}, enabled = false) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Filled Icon Toggle Button") | |
Row(modifier = Modifier.fillMaxWidth()) { | |
FilledIconToggleButton(onCheckedChange = {}, checked = true) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
FilledIconToggleButton(onCheckedChange = {}, checked = false) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
FilledIconToggleButton(onCheckedChange = {}, checked = true, enabled = false) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Filled Tonal Icon Button") | |
Row(modifier = Modifier.fillMaxWidth()) { | |
FilledTonalIconButton(onClick = {}) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
FilledTonalIconButton(onClick = {}, enabled = false) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Filled Tonal Icon Toggle Button") | |
Row(modifier = Modifier.fillMaxWidth()) { | |
FilledTonalIconToggleButton(onCheckedChange = {}, checked = true) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
FilledTonalIconToggleButton(onCheckedChange = {}, checked = false) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
FilledTonalIconToggleButton( | |
onCheckedChange = {}, | |
checked = true, | |
enabled = false | |
) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Filled Tonal Icon Toggle Button") | |
Row(modifier = Modifier.fillMaxWidth()) { | |
OutlinedIconButton(onClick = {}) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
OutlinedIconButton(onClick = {}, enabled = false) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Filled Tonal Icon Toggle Button") | |
Row(modifier = Modifier.fillMaxWidth()) { | |
OutlinedIconToggleButton(onCheckedChange = {}, checked = true) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
OutlinedIconToggleButton(onCheckedChange = {}, checked = false) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
OutlinedIconToggleButton( | |
onCheckedChange = {}, | |
checked = true, | |
enabled = false | |
) { | |
Icon( | |
imageVector = Icons.Filled.Edit, | |
contentDescription = null | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "List Item") | |
ListItem(leadingContent = { | |
Box( | |
Modifier | |
.width(40.dp) | |
.height(40.dp) | |
.background( | |
color = Color(0xFFF4D5C4), | |
shape = RoundedCornerShape(size = 100.dp) | |
), | |
contentAlignment = Alignment.Center | |
) { | |
Text( | |
text = "RA", | |
style = TextStyle( | |
fontSize = 14.sp, | |
lineHeight = 24.sp, | |
fontFamily = FontFamily(Font(R.font.serranopro)), | |
fontWeight = FontWeight(700), | |
color = Color(0xFFD14900), | |
textAlign = TextAlign.Center, | |
) | |
) | |
} | |
}, | |
headlineContent = { Text(text = "List item") }, | |
supportingContent = { Text(text = "Supporting content") }, | |
trailingContent = { | |
Icon( | |
imageVector = ImageVector.vectorResource(id = R.drawable.sg_navigate_next_dn), | |
contentDescription = null | |
) | |
}) | |
} | |
item { | |
Heading(text = "Menu - drop down") | |
var showMenu by remember { mutableStateOf(false) } | |
Box { | |
IconButton(onClick = { showMenu = !showMenu }) { | |
Icon( | |
imageVector = ImageVector.vectorResource(R.drawable.sg_icon_more), | |
contentDescription = null | |
) | |
} | |
DropdownMenu(expanded = showMenu, onDismissRequest = { showMenu = false }) { | |
DropdownMenuItem( | |
text = { Text(text = "Item 1") }, | |
onClick = { showMenu = false }, | |
leadingIcon = { | |
Icon( | |
imageVector = ImageVector.vectorResource(R.drawable.ic_xml), | |
contentDescription = null | |
) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = ImageVector.vectorResource(R.drawable.ic_compose), | |
contentDescription = null | |
) | |
}, | |
) | |
DropdownMenuItem( | |
text = { Text(text = "Item 2") }, | |
onClick = { showMenu = false }, | |
leadingIcon = { | |
Icon( | |
imageVector = ImageVector.vectorResource(R.drawable.ic_xml), | |
contentDescription = null | |
) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = ImageVector.vectorResource(R.drawable.ic_compose), | |
contentDescription = null | |
) | |
}, | |
) | |
DropdownMenuItem( | |
text = { Text(text = "Item 3") }, | |
onClick = { showMenu = false }, | |
leadingIcon = { | |
Icon( | |
imageVector = ImageVector.vectorResource(R.drawable.ic_xml), | |
contentDescription = null | |
) | |
}, | |
trailingIcon = { | |
Icon( | |
imageVector = ImageVector.vectorResource(R.drawable.ic_compose), | |
contentDescription = null | |
) | |
}, | |
) | |
} | |
} | |
} | |
item { | |
Heading(text = "Menu - exposed drop down") | |
val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5") | |
var expanded by remember { mutableStateOf(false) } | |
var selectedOptionText by remember { mutableStateOf(options[0]) } | |
ExposedDropdownMenuBox( | |
expanded = expanded, | |
onExpandedChange = { expanded = !expanded }, | |
) { | |
TextField( | |
modifier = Modifier.menuAnchor(), | |
readOnly = true, | |
value = selectedOptionText, | |
onValueChange = {}, | |
label = { Text("Label") }, | |
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, | |
colors = ExposedDropdownMenuDefaults.textFieldColors(), | |
) | |
ExposedDropdownMenu( | |
expanded = expanded, | |
onDismissRequest = { expanded = false }, | |
) { | |
options.forEach { selectionOption -> | |
DropdownMenuItem( | |
text = { Text(selectionOption) }, | |
onClick = { | |
selectedOptionText = selectionOption | |
expanded = false | |
}, | |
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding, | |
) | |
} | |
} | |
} | |
} | |
item { | |
Heading(text = "Menu - outlined exposed drop down") | |
val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5") | |
var expanded by remember { mutableStateOf(false) } | |
var selectedOptionText by remember { mutableStateOf(options[0]) } | |
ExposedDropdownMenuBox( | |
expanded = expanded, | |
onExpandedChange = { expanded = !expanded }, | |
) { | |
OutlinedTextField( | |
modifier = Modifier.menuAnchor(), | |
readOnly = true, | |
value = selectedOptionText, | |
onValueChange = {}, | |
label = { Text("Label") }, | |
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, | |
// colors = ExposedDropdownMenuDefaults.textFieldColors(), | |
) | |
ExposedDropdownMenu( | |
expanded = expanded, | |
onDismissRequest = { expanded = false }, | |
) { | |
options.forEach { selectionOption -> | |
DropdownMenuItem( | |
text = { Text(selectionOption) }, | |
onClick = { | |
selectedOptionText = selectionOption | |
expanded = false | |
}, | |
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding, | |
) | |
} | |
} | |
} | |
} | |
item { | |
Heading(text = "Radio button") | |
Row( | |
modifier = Modifier.fillMaxWidth(), | |
verticalAlignment = Alignment.CenterVertically, | |
horizontalArrangement = Arrangement.SpaceEvenly | |
) { | |
var radioSelected by remember { | |
mutableStateOf(0) | |
} | |
Text(text = "Option A") | |
RadioButton(selected = radioSelected == 0, onClick = { radioSelected = 0 }) | |
Text(text = "Option B") | |
RadioButton(selected = radioSelected == 1, onClick = { radioSelected = 1 }) | |
Text(text = "Disabled") | |
RadioButton(enabled = false, | |
selected = radioSelected == 2, | |
onClick = { radioSelected = 2 }) | |
} | |
} | |
item { | |
Heading(text = "Slider") | |
Column { | |
var value by remember { mutableStateOf(0.5f) } | |
Slider(value = value, onValueChange = { value = it }) | |
Slider(value = 0.5f, onValueChange = {}, enabled = false) | |
var steppedValue by remember { mutableStateOf(5f) } | |
Slider( | |
value = steppedValue, | |
steps = 10, | |
onValueChange = { steppedValue = it }) | |
Slider( | |
value = 0.4f, steps = 10, onValueChange = {}, enabled = false | |
) | |
} | |
} | |
item { | |
Heading(text = "Slider - ranged") | |
Column { | |
var value by remember { mutableStateOf(0.25f.rangeTo(0.75f)) } | |
RangeSlider(value = value, onValueChange = { value = it }) | |
RangeSlider( | |
enabled = false, | |
value = 0.25f.rangeTo(0.75f), | |
onValueChange = { value = it }) | |
} | |
} | |
item { | |
Heading(text = "SnackBar") | |
Column { | |
val snackbarData = object : SnackbarData { | |
override val visuals = object : SnackbarVisuals { | |
override val actionLabel: String | |
get() = "Action label" | |
override val duration: SnackbarDuration | |
get() = SnackbarDuration.Indefinite | |
override val message: String | |
get() = "Message" | |
override val withDismissAction: Boolean | |
get() = true | |
} | |
override fun performAction() { | |
} | |
override fun dismiss() { | |
} | |
} | |
Snackbar(snackbarData) | |
} | |
} | |
item { | |
Heading(text = "Swipe to dismiss") | |
val dismissState = rememberDismissState() | |
SwipeToDismiss( | |
state = dismissState, | |
background = { | |
val color by animateColorAsState( | |
when (dismissState.targetValue) { | |
DismissValue.Default -> Color.LightGray | |
DismissValue.DismissedToEnd -> AppTheme.sgColors.onSuccess | |
DismissValue.DismissedToStart -> AppTheme.sgColors.onWarning | |
}, label = "" | |
) | |
Box( | |
Modifier | |
.fillMaxSize() | |
.background(color) | |
) | |
}, | |
dismissContent = { | |
Card { | |
ListItem( | |
headlineContent = { | |
Text("Headline content") | |
}, | |
supportingContent = { Text("Swipe me left or right!") } | |
) | |
} | |
} | |
) | |
} | |
item { | |
Heading(text = "Switches") | |
Row { | |
var switchChecked by remember { mutableStateOf(true) } | |
Row(verticalAlignment = Alignment.CenterVertically) { | |
Text(text = "Switch", modifier = Modifier.padding(8.dp)) | |
Switch( | |
checked = switchChecked, | |
onCheckedChange = { switchChecked = it }) | |
} | |
var disabled by remember { mutableStateOf(true) } | |
Row(verticalAlignment = Alignment.CenterVertically) { | |
Text(text = "Disabled X", modifier = Modifier.padding(8.dp)) | |
Switch( | |
enabled = false, | |
checked = disabled, | |
onCheckedChange = { disabled = it }) | |
} | |
Row(verticalAlignment = Alignment.CenterVertically) { | |
Text(text = "Disabled O", modifier = Modifier.padding(8.dp)) | |
Switch( | |
enabled = false, | |
checked = false, | |
onCheckedChange = { disabled = it }) | |
} | |
} | |
} | |
item { | |
Heading(text = "Tabs") | |
var state by remember { mutableStateOf(0) } | |
val titles = listOf("Tab 1", "Tab 2", "Tab 3 with lots of text") | |
Column { | |
TabRow(selectedTabIndex = state) { | |
titles.forEachIndexed { index, title -> | |
Tab( | |
selected = state == index, | |
onClick = { state = index }, | |
text = { | |
Text( | |
text = title, | |
maxLines = 2, | |
overflow = TextOverflow.Ellipsis | |
) | |
} | |
) | |
} | |
} | |
Text( | |
modifier = Modifier.align(Alignment.CenterHorizontally), | |
text = "Text tab ${state + 1} selected", | |
style = MaterialTheme.typography.bodyLarge | |
) | |
} | |
} | |
item { | |
Heading(text = "Text field") | |
Row( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceEvenly | |
) { | |
var textField by remember { mutableStateOf("") } | |
val width = 125.dp | |
TextField(modifier = Modifier.width(width), | |
label = { Text(text = "Enabled") }, | |
supportingText = { Text(text = "Supporting text") }, | |
value = textField, | |
onValueChange = { textField = it }) | |
var textField2 by remember { mutableStateOf("") } | |
TextField(modifier = Modifier.width(width), | |
label = { Text(text = "Error") }, | |
isError = true, | |
supportingText = { Text(text = "Supporting text 2") }, | |
value = textField2, | |
onValueChange = { textField2 = it }) | |
TextField(modifier = Modifier.width(width), | |
label = { Text(text = "Disabled") }, | |
enabled = false, | |
supportingText = { Text(text = "Supporting text 3") }, | |
value = "", | |
onValueChange = {}) | |
} | |
} | |
item { | |
Heading(text = "Text field - outlined") | |
Row( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalArrangement = Arrangement.SpaceEvenly | |
) { | |
var textField by remember { mutableStateOf("") } | |
val width = 125.dp | |
OutlinedTextField(modifier = Modifier.width(width), | |
label = { Text(text = "Enabled") }, | |
supportingText = { Text(text = "Supporting text") }, | |
value = textField, | |
onValueChange = { textField = it }) | |
var textField2 by remember { mutableStateOf("") } | |
OutlinedTextField(modifier = Modifier.width(width), | |
label = { Text(text = "Error") }, | |
isError = true, | |
supportingText = { Text(text = "Supporting text 2") }, | |
value = textField2, | |
onValueChange = { textField2 = it }) | |
OutlinedTextField(modifier = Modifier.width(width), | |
label = { Text(text = "Disabled") }, | |
enabled = false, | |
supportingText = { Text(text = "Supporting text 3") }, | |
value = "", | |
onValueChange = {}) | |
} | |
} | |
item { | |
Heading(text = "Time picker") | |
Button(onClick = { timePickDialogVisible = true }) { | |
Text(text = "Show time picker") | |
} | |
} | |
item { | |
Heading(text = "Time input") | |
Button(onClick = { timeInputDialogVisible = true }) { | |
Text(text = "Show time input") | |
} | |
} | |
item { | |
Heading(text = "Tooltip") | |
PlainTooltipBox( | |
tooltip = { Text("Add to favorites") } | |
) { | |
IconButton( | |
onClick = { /* Icon button's click event */ }, | |
modifier = Modifier | |
.wrapContentSize() | |
.tooltipAnchor() | |
) { | |
Icon( | |
imageVector = Icons.Filled.Favorite, | |
contentDescription = "Localized Description" | |
) | |
} | |
} | |
Text(text = "Press and hold") | |
} | |
item { | |
Heading(text = "Tooltip - manual invocation") | |
val tooltipState by remember { mutableStateOf(PlainTooltipState()) } | |
val scope = rememberCoroutineScope() | |
Column( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalAlignment = Alignment.CenterHorizontally | |
) { | |
PlainTooltipBox( | |
tooltip = { Text("Add to list") }, | |
tooltipState = tooltipState | |
) { | |
Icon( | |
imageVector = Icons.Filled.AddCircle, | |
contentDescription = "Localized Description" | |
) | |
} | |
OutlinedButton( | |
onClick = { scope.launch { tooltipState.show() } } | |
) { | |
Text("Display tooltip") | |
} | |
} | |
} | |
item { | |
Heading(text = "Rich tooltip") | |
val tooltipState by remember { mutableStateOf(RichTooltipState()) } | |
val scope = rememberCoroutineScope() | |
RichTooltipBox( | |
title = { Text("Add others") }, | |
action = { | |
TextButton( | |
onClick = { scope.launch { tooltipState.dismiss() } } | |
) { Text("Learn more") } | |
}, | |
text = { Text("Here is something really long text that will go into the rich tool and show off how this component works.") }, | |
tooltipState = tooltipState | |
) { | |
IconButton( | |
onClick = { /* Icon button's click event */ }, | |
modifier = Modifier.tooltipAnchor() | |
) { | |
Icon( | |
imageVector = Icons.Filled.Info, | |
contentDescription = "Localized Description" | |
) | |
} | |
} | |
Text(text = "Press and hold") | |
} | |
item { | |
Heading(text = "Rich tooltip - manual invocation") | |
val tooltipState by remember { mutableStateOf(RichTooltipState()) } | |
val scope = rememberCoroutineScope() | |
Column( | |
modifier = Modifier.fillMaxWidth(), | |
horizontalAlignment = Alignment.CenterHorizontally | |
) { | |
RichTooltipBox( | |
title = { Text("Add others") }, | |
action = { | |
TextButton( | |
onClick = { scope.launch { tooltipState.dismiss() } } | |
) { Text("Learn more") } | |
}, | |
text = { Text("Here is something really long text that will go into the rich tool and show off how this component works.") }, | |
tooltipState = tooltipState | |
) { | |
IconButton( | |
onClick = { /* Icon button's click event */ }, | |
) { | |
Icon( | |
imageVector = Icons.Filled.Info, | |
contentDescription = "Localized Description" | |
) | |
} | |
} | |
OutlinedButton(onClick = { | |
scope.launch { tooltipState.show() } | |
}) { | |
Text(text = "Display rich tool tip") | |
} | |
} | |
} | |
} | |
} | |
if (timeInputDialogVisible) { | |
val state = rememberTimePickerState(4, 20, false) | |
AlertDialog(onDismissRequest = { timeInputDialogVisible = false }) { | |
Surface { | |
Box(modifier = Modifier.padding(16.dp)) { | |
TimeInput(state = state) | |
} | |
} | |
} | |
} | |
if (timePickDialogVisible) { | |
val state = rememberTimePickerState(4, 20, false) | |
AlertDialog(onDismissRequest = { timePickDialogVisible = false }) { | |
Surface { | |
Box(modifier = Modifier.padding(16.dp)) { | |
TimePicker(state = state) | |
} | |
} | |
} | |
} | |
if (alertDialogVisible) { | |
AlertDialog(onDismissRequest = { alertDialogVisible = false }, confirmButton = { | |
Button(onClick = { | |
alertDialogVisible = false | |
}) { Text(text = "Confirm") } | |
}, dismissButton = { | |
Button(onClick = { | |
alertDialogVisible = false | |
}) { Text(text = "Dismiss") } | |
}, icon = { | |
Icon( | |
imageVector = ImageVector.vectorResource(id = R.drawable.ic_xml), | |
contentDescription = null | |
) | |
}, title = { | |
Text(text = "Title") | |
}, text = { | |
Text(text = "Here is the text of the dialog") | |
}) | |
} | |
if (bottomSheetVisible) { | |
ModalBottomSheet(onDismissRequest = { bottomSheetVisible = false }) { | |
Spacer(modifier = Modifier.height(100.dp)) | |
Text(text = "Here is a bottom sheet") | |
Spacer(modifier = Modifier.height(100.dp)) | |
} | |
} | |
if (dateRangePickerVisible) { | |
val dateRangePickerState = DateRangePickerState( | |
initialSelectedStartDateMillis = Dates.today.millis, | |
initialSelectedEndDateMillis = Dates.todayPlus5Days.millis, | |
initialDisplayedMonthMillis = Dates.today.millis, | |
yearRange = IntRange(Dates.todayMinus2Years.year, Dates.todayPlus2Years.year), | |
initialDisplayMode = DisplayMode.Picker | |
) | |
DatePickerDialog( | |
onDismissRequest = { dateRangePickerVisible = false }, | |
confirmButton = { | |
TextButton(onClick = { dateRangePickerVisible = false }) { | |
Text(text = "Confirm") | |
} | |
}, | |
dismissButton = { | |
TextButton(onClick = { dateRangePickerVisible = false }) { | |
Text(text = "Dismiss") | |
} | |
}) { | |
DateRangePicker(state = dateRangePickerState, dateValidator = { | |
it > Dates.todayMinusOneMonth.millis && it < Dates.todayPlusOneMonth.millis | |
}) | |
} | |
} | |
if (datePickerVisible) { | |
val datePickerState = DatePickerState( | |
initialDisplayedMonthMillis = Dates.today.millis, | |
initialSelectedDateMillis = Dates.today.millis, | |
yearRange = IntRange( | |
start = Dates.todayMinus2Years.year, endInclusive = Dates.todayPlus2Years.year | |
), | |
initialDisplayMode = DisplayMode.Picker | |
) | |
DatePickerDialog(onDismissRequest = { datePickerVisible = false }, confirmButton = { | |
TextButton(onClick = { datePickerVisible = false }) { | |
Text(text = "Confirm") | |
} | |
}, dismissButton = { | |
TextButton(onClick = { datePickerVisible = false }) { | |
Text(text = "Dismiss") | |
} | |
}) { | |
DatePicker(state = datePickerState, dateValidator = { | |
it > Dates.todayMinusOneMonth.millis && it < Dates.todayPlusOneMonth.millis | |
}) | |
} | |
} | |
} | |
@Composable | |
private fun Heading(text: String) { | |
Divider(modifier = Modifier.fillMaxWidth()) | |
Text( | |
text = text, | |
style = AppTheme.typography.titleLarge | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment