feat(design-system): add MsMasterDetailLayout component and update roadmap

- Introduced `MsMasterDetailLayout` as a standardized layout for master-detail screens, including support for customizable headers and split proportions.
- Updated `Frontend_Komponenten_Roadmap.md` to mark this component as complete in Phase 4.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
2026-03-31 10:52:25 +02:00
parent b2a0883388
commit ad529f7395
2 changed files with 85 additions and 2 deletions
@@ -0,0 +1,83 @@
package at.mocode.frontend.core.designsystem.components
import androidx.compose.foundation.layout.*
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import at.mocode.frontend.core.designsystem.theme.Dimens
/**
* Ein standardisiertes Master-Detail Layout für die Stammdaten-Verwaltung.
*
* @param master Der Bereich auf der linken Seite (z.B. MsDataTable mit MsFilterBar).
* @param detail Der Bereich auf der rechten Seite (z.B. ein Editor-Formular).
* @param modifier Der Modifier für das gesamte Layout.
* @param masterWeight Der Anteil des Master-Bereichs (Standard: 0.4).
* @param detailHeader Optionaler Header für den Detail-Bereich (z.B. MsActionToolbar).
*/
@Composable
fun MsMasterDetailLayout(
master: @Composable BoxScope.() -> Unit,
detail: @Composable BoxScope.() -> Unit,
modifier: Modifier = Modifier,
masterWeight: Float = 0.4f,
detailHeader: @Composable (RowScope.() -> Unit)? = null
) {
Row(modifier = modifier.fillMaxSize()) {
// --- 1. Master-Bereich (z.B. Liste) ---
Box(
modifier = Modifier
.weight(masterWeight)
.fillMaxHeight()
.padding(Dimens.SpacingS)
) {
master()
}
// --- 2. Trennlinie (Vertikal) ---
VerticalDivider(
thickness = 1.dp,
color = MaterialTheme.colorScheme.outlineVariant
)
// --- 3. Detail-Bereich (z.B. Editor) ---
Column(
modifier = Modifier
.weight(1f - masterWeight)
.fillMaxHeight()
) {
// Optionaler Header für Aktionen
if (detailHeader != null) {
Surface(
color = MaterialTheme.colorScheme.surface,
tonalElevation = 1.dp
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = Dimens.SpacingM, vertical = Dimens.SpacingS),
horizontalArrangement = Arrangement.End
) {
detailHeader()
}
}
HorizontalDivider(
thickness = 1.dp,
color = MaterialTheme.colorScheme.outlineVariant
)
}
Box(
modifier = Modifier
.fillMaxSize()
.padding(Dimens.SpacingM)
) {
detail()
}
}
}
}