feat(design-system): add MsEnumDropdown component and update roadmap
- Introduced a reusable `MsEnumDropdown` component for selecting enum values with customizable options, labels, and error handling. - Updated `Frontend_Komponenten_Roadmap.md` to reflect progress in Phase 3, marking `MsEnumDropdown` as completed. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
@@ -39,11 +39,11 @@ Turniermanagement bedeutet Arbeit mit Listen. Wir benötigen mächtige, aber kom
|
||||
* [x] Filter-Chips für schnelle Status-Wechsel.
|
||||
* [x] Anzeige der Trefferanzahl (Result Count).
|
||||
|
||||
## Phase 3: Formular- & Eingabe-System (Die Datenerfassung) ⚪ [ZUKUNFT]
|
||||
## Phase 3: Formular- & Eingabe-System (Die Datenerfassung) 🔵 [IN ARBEIT]
|
||||
|
||||
Eingabe von Stammdaten muss schnell und fehlerfrei erfolgen.
|
||||
|
||||
* [ ] **`MsEnumDropdown`:** Automatisches Mapping von Backend-Enums (ÖTO) auf UI-Auswahl.
|
||||
* [x] **`MsEnumDropdown`:** Automatisches Mapping von Backend-Enums (ÖTO) auf UI-Auswahl.
|
||||
* [ ] **`MsValidationWrapper`:** Konsistente Anzeige von Fehlern (z.B. "Lizenz für diese Klasse nicht ausreichend").
|
||||
* [ ] **`MsSearchableSelect`:** Für die Verknüpfung von Reitern/Pferden (Autocomplete).
|
||||
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package at.mocode.frontend.core.designsystem.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Ein generisches Dropdown zur Auswahl von Enum-Werten.
|
||||
*
|
||||
* @param label Das Label über dem Dropdown.
|
||||
* @param options Alle verfügbaren Enum-Optionen (z.B. SparteE.values()).
|
||||
* @param selectedOption Der aktuell gewählte Wert.
|
||||
* @param onOptionSelected Callback bei Auswahl einer Option.
|
||||
* @param optionLabel Transformation des Enums in einen lesbaren Text (Standard: toString()).
|
||||
* @param modifier Modifier für die gesamte Komponente.
|
||||
* @param enabled Ob das Dropdown bearbeitbar ist.
|
||||
* @param isError Ob ein Fehler vorliegt.
|
||||
* @param errorMessage Die anzuzeigende Fehlermeldung.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun <T : Enum<T>> MsEnumDropdown(
|
||||
label: String,
|
||||
options: Array<T>,
|
||||
selectedOption: T?,
|
||||
onOptionSelected: (T) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
optionLabel: (T) -> String = { it.name },
|
||||
enabled: Boolean = true,
|
||||
isError: Boolean = false,
|
||||
errorMessage: String? = null
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
Column(modifier = modifier) {
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = expanded,
|
||||
onExpandedChange = { if (enabled) expanded = it }
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = selectedOption?.let { optionLabel(it) } ?: "",
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text(label, style = MaterialTheme.typography.bodySmall) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
|
||||
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
|
||||
modifier = Modifier
|
||||
.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryEditable, enabled)
|
||||
.fillMaxWidth(),
|
||||
isError = isError,
|
||||
enabled = enabled,
|
||||
singleLine = true,
|
||||
textStyle = MaterialTheme.typography.bodyMedium,
|
||||
shape = MaterialTheme.shapes.small
|
||||
)
|
||||
|
||||
ExposedDropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
options.forEach { option ->
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(
|
||||
text = optionLabel(option),
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
onOptionSelected(option)
|
||||
expanded = false
|
||||
},
|
||||
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isError && errorMessage != null) {
|
||||
Text(
|
||||
text = errorMessage,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
modifier = Modifier.padding(start = 16.dp, top = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user