Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
feat(app): create ui element LargeDropdownMenu
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreaBrighi committed Jun 20, 2023
1 parent c1fd982 commit 000444e
Showing 1 changed file with 152 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package com.intelligentbackpack.app.ui.common

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.IntrinsicSize
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.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.ArrowDropUp
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog

@Composable
fun <T> LargeDropdownMenu(
modifier: Modifier = Modifier,
enabled: Boolean = true,
label: String,
notSetLabel: String? = null,
items: List<T>,
selectedIndex: Int = -1,
onItemSelected: (index: Int, item: T) -> Unit,
selectedItemToString: (T) -> String = { it.toString() },
drawItem: @Composable (T, Boolean, Boolean, () -> Unit) -> Unit = { item, _, itemEnabled, onClick ->
LargeDropdownMenuItem(
text = item.toString(),
enabled = itemEnabled,
onClick = onClick,
)
},
) {
var expanded by remember { mutableStateOf(false) }

Box(modifier = modifier.height(IntrinsicSize.Min)) {
OutlinedTextField(
colors = TextFieldDefaults.outlinedTextFieldColors(
backgroundColor = MaterialTheme.colors.background,
trailingIconColor = MaterialTheme.colors.onBackground,
textColor = MaterialTheme.colors.onBackground,
),
label = { Text(label) },
value = items.getOrNull(selectedIndex)?.let { selectedItemToString(it) } ?: "",
enabled = enabled,
modifier = Modifier.fillMaxWidth(),
trailingIcon = {
val icon = if (expanded) {
Icons.Filled.ArrowDropUp
} else {
Icons.Filled.ArrowDropDown
}
Icon(icon, "")
},
onValueChange = { },
readOnly = true,
)

// Transparent clickable surface on top of OutlinedTextField
Surface(
modifier = Modifier
.fillMaxSize()
.padding(top = 8.dp)
.clip(MaterialTheme.shapes.small)
.clickable(enabled = enabled) { expanded = true },
color = Color.Transparent,
) {}
}

if (expanded) {
Dialog(
onDismissRequest = { expanded = false },
) {
Surface(
shape = RoundedCornerShape(12.dp),
) {
val listState = rememberLazyListState()
if (selectedIndex > -1) {
LaunchedEffect("ScrollToSelected") {
listState.scrollToItem(index = selectedIndex)
}
}

LazyColumn(modifier = Modifier.fillMaxWidth(), state = listState) {
if (notSetLabel != null) {
item {
LargeDropdownMenuItem(
text = notSetLabel,
enabled = false,
onClick = { },
)
}
}
itemsIndexed(items) { index, item ->
val selectedItem = index == selectedIndex
drawItem(
item,
selectedItem,
true,
) {
onItemSelected(index, item)
expanded = false
}

if (index < items.lastIndex) {
Divider(modifier = Modifier.padding(horizontal = 16.dp))
}
}
}
}
}
}
}

@Composable
fun LargeDropdownMenuItem(
text: String,
enabled: Boolean,
onClick: () -> Unit,
) {
Box(
modifier = Modifier
.clickable(enabled) { onClick() }
.fillMaxWidth()
.padding(16.dp),
) {
Text(
text = text,
style = MaterialTheme.typography.button,
)
}
}

0 comments on commit 000444e

Please sign in to comment.