ui: make filter card collapsible with 2x2 grid layout
- Collapsed: compact row showing 'Filtres' + active filter count + expand arrow - Expanded: 2x2 grid (Compte+Type, Age+Sous-groupe) halves vertical space - Animated expand/collapse with AnimatedVisibility - FilterDropdown now respects weight() modifier for row layout
This commit is contained in:
@@ -28,7 +28,7 @@ fun FilterDropdown(
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
modifier = modifier,
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = selectedValue ?: "",
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package ch.parano.myice.ui.screens
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.foundation.clickable
|
||||
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.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@@ -11,6 +16,7 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
@@ -20,6 +26,9 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -81,30 +90,62 @@ fun ScheduleScreen(
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(padding),
|
||||
) {
|
||||
var filtersExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
val activeFilterCount = listOf(
|
||||
scheduleState.selectedAccount,
|
||||
scheduleState.selectedAgegroup,
|
||||
scheduleState.selectedSubgroup,
|
||||
).count { it != null } + if (scheduleState.typeFilter != TypeFilter.GAMES) 1 else 0
|
||||
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth().padding(16.dp),
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { filtersExpanded = !filtersExpanded }
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = "Filtres",
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.Medium,
|
||||
)
|
||||
if (activeFilterCount > 0) {
|
||||
Spacer(Modifier.height(0.dp))
|
||||
Text(
|
||||
text = "($activeFilterCount actif${if (activeFilterCount > 1) "s" else ""})",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
Text(
|
||||
text = if (filtersExpanded) "▲" else "▼",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = filtersExpanded,
|
||||
enter = expandVertically(),
|
||||
exit = shrinkVertically(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
FilterDropdown(
|
||||
label = "Compte",
|
||||
selectedValue = scheduleState.selectedAccount,
|
||||
options = scheduleState.accounts.map { it.name },
|
||||
onSelect = { it?.let { acc -> scheduleViewModel.setAccount(acc) } },
|
||||
)
|
||||
FilterDropdown(
|
||||
label = "Age",
|
||||
selectedValue = scheduleState.selectedAgegroup,
|
||||
options = scheduleState.agegroups,
|
||||
onSelect = { scheduleViewModel.setAgegroup(it) },
|
||||
)
|
||||
FilterDropdown(
|
||||
label = "Sous-groupe",
|
||||
selectedValue = scheduleState.selectedSubgroup,
|
||||
options = scheduleState.subgroups,
|
||||
onSelect = { scheduleViewModel.setSubgroup(it) },
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
FilterDropdown(
|
||||
label = "Type",
|
||||
@@ -119,8 +160,29 @@ fun ScheduleScreen(
|
||||
}
|
||||
scheduleViewModel.setTypeFilter(filter)
|
||||
},
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
FilterDropdown(
|
||||
label = "Age",
|
||||
selectedValue = scheduleState.selectedAgegroup,
|
||||
options = scheduleState.agegroups,
|
||||
onSelect = { scheduleViewModel.setAgegroup(it) },
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
FilterDropdown(
|
||||
label = "Sous-groupe",
|
||||
selectedValue = scheduleState.selectedSubgroup,
|
||||
options = scheduleState.subgroups,
|
||||
onSelect = { scheduleViewModel.setSubgroup(it) },
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
|
||||
Reference in New Issue
Block a user