Add scrim when ExpandedFab is open
#28
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Enhancement / UX
The
ExpandedFabon the Expenses screen (app/src/main/java/dev/achmad/ledgerr/ui/screens/expenses/ExpenseListScreen.kt:126-159) reveals its mini-FABs without any backdrop. The list behind the FAB stays fully visible and interactive, so the user has no visual cue that the FAB is the active surface, and tapping the list does not dismiss the expansion.Current code —
app/src/main/java/dev/achmad/ledgerr/ui/components/ExpandedFab.kt:28-58ExpandedFabrenders only the column of mini-FABs and the main FAB. There is no scrim.Expected behavior
When
ExpandedFab.expanded == true, a semi-transparent scrim covers the underlying content. The scrim:fadeIn/fadeOutanimation).fillMaxSizeBox overlay is fine).MaterialTheme.colorScheme.scrim.copy(alpha = 0.32f)) so it adapts to light/dark.onToggle(i.e. dismisses the FAB) and does not propagate to the list below.Acceptance criteria
expanded == false.Scaffoldbody, below theColumncontaining the tabs/Pageris fine; placing it above the wholeScaffoldis not acceptable.Implementation notes (not prescriptive)
ExpandedFab(e.g. as anAnimatedVisibility { Box(Modifier.fillMaxSize().clickable(onClick = onToggle).background(...)) }rendered as a sibling of the existing column) and require the screen to renderExpandedFabin aBoxso it can stack above the list. The currentfloatingActionButtonslot in theScaffolddoes not stack a scrim above the body, so the call site (ExpenseListScreen) will need to be refactored to use aBoxcontaining both the list content and the FAB with its scrim — or the scrim is rendered inside theColumnbody and the body is wrapped in aBoxthat also contains the FAB. Coordinate the chosen approach with howScaffoldlays out the FAB slot (FAB is already a floating overlay).BackHandler(enabled = expanded) { onToggle() }inside the screen if going for it. Skip it for the first pass if it complicates the layout.