fix(#25,#26,#28): Expenses screen polish — scrim, tab badges, shared SearchToolbar #37

Merged
admin merged 4 commits from fix/25-26-28-expenses-screen-polish into main 2026-06-28 14:33:43 +00:00
Owner

Summary

  • Add a Material 3 scrim behind the open ExpandedFab on the Expenses screen, dismissable by tap or system back (#28)
  • Render the Expenses / Recurring tab labels with the shared TabText composable so each tab shows a badge with the post-filter list size (#25)
  • Replace the inline search field with the shared SearchToolbar; query is debounced via SEARCH_DEBOUNCE_MILLIS, shared across both tabs, and the recurring list is now filtered by query as well (#26)

Test plan

  • Open Expenses → tap the FAB → mini-FABs appear over a dimmed scrim; tap the scrim or press the system back button to dismiss
  • Add/delete expenses and toggle the date-range filter → the Expenses tab badge updates reactively
  • Add/delete recurring entries → the Recurring tab badge updates reactively
  • Tap the search icon in the top bar → the search field appears in the toolbar; type a query → both the Expenses and Recurring lists filter (case-insensitive substring against category name and note)
  • Switch tabs while a query is active → both lists are filtered, the query is preserved
  • Tap the close (X) icon → query clears, lists are restored, search mode exits
  • When the filtered list is empty, the "No results" empty state is shown instead of the per-tab "no data" copy
  • ./gradlew :app:assembleDebug :app:testDebugUnitTest passes

Closes #25 #26 #28

## Summary - Add a Material 3 scrim behind the open `ExpandedFab` on the Expenses screen, dismissable by tap or system back (#28) - Render the Expenses / Recurring tab labels with the shared `TabText` composable so each tab shows a badge with the post-filter list size (#25) - Replace the inline search field with the shared `SearchToolbar`; query is debounced via `SEARCH_DEBOUNCE_MILLIS`, shared across both tabs, and the recurring list is now filtered by query as well (#26) ## Test plan - [ ] Open Expenses → tap the FAB → mini-FABs appear over a dimmed scrim; tap the scrim or press the system back button to dismiss - [ ] Add/delete expenses and toggle the date-range filter → the Expenses tab badge updates reactively - [ ] Add/delete recurring entries → the Recurring tab badge updates reactively - [ ] Tap the search icon in the top bar → the search field appears in the toolbar; type a query → both the Expenses and Recurring lists filter (case-insensitive substring against category name and note) - [ ] Switch tabs while a query is active → both lists are filtered, the query is preserved - [ ] Tap the close (X) icon → query clears, lists are restored, search mode exits - [ ] When the filtered list is empty, the "No results" empty state is shown instead of the per-tab "no data" copy - [ ] `./gradlew :app:assembleDebug :app:testDebugUnitTest` passes Closes #25 #26 #28
admin added 3 commits 2026-06-28 14:23:36 +00:00
Add ExpandedFabScrim composable that renders a Material 3 scrim
overlay fading in/out in sync with the mini-FABs. Tapping the scrim
dismisses the FAB.

Move the ExpandedFab out of Scaffold's floatingActionButton slot and
into the body inside a Box, so the scrim can match the body size via
matchParentSize() and stack above the list but below the FAB. Add a
BackHandler that dismisses the FAB on system back while it is open.
Replace the plain Text inside PrimaryTabRow's Tab with the shared
TabText composable. Pass the current size of the expenses and
recurring state flows as badgeCount so each tab shows a small pill
with the (post-filter) list size. Counts update reactively as
items are added, deleted, or filtered by search/date.
Replace the inline OutlinedTextField inside ExpensesTabContent with
the shared SearchToolbar in the topBar. The query is shared across
both tabs; closing the toolbar (X / navigate-up) deactivates search
and clears the filter.

In ExpenseListScreenModel:
- searchQuery becomes StateFlow<String?> (null = inactive, "" = active
  empty, "foo" = active query)
- setSearchQuery now accepts String? to match SearchToolbar's
  onChangeSearchQuery signature
- expenses and recurring combine on
  _searchQuery.debounce(SEARCH_DEBOUNCE_MILLIS).distinctUntilChanged()
  so fast typing does not re-filter on every keystroke
- recurring is now filtered by query against category name and
  recurring note (case-insensitive substring)

In ExpenseListScreen:
- Remove the inline search field, the date-range-filter search hint
  label, and the now-unused OutlinedTextField / Icons.Outlined.Search
  imports
- Both ExpensesTabContent and RecurringTabContent now take a nullable
  searchQuery and show a generic 'No results' message when the active
  filter empties the list, or the per-tab empty copy otherwise
- Add the expense_list_no_results string
admin added 1 commit 2026-06-28 14:32:36 +00:00
Main moved ahead with the home-polish (#29/#32/#33), category HSV color
picker (#30), and category lock-icon fix (#31) PRs. The only conflicts
were in ExpenseListScreen.kt:

- Imports: main added AppBar + EmptyStateIllustration. The branch had
  already removed AppBar (replaced by SearchToolbar) and replaced the
  inline text empty state. Resolution: keep the branch's
  AppBarTitle/SearchToolbar/TabText set, drop AppBar (no longer used),
  add EmptyStateIllustration.
- ExpensesTabContent empty state: main replaced the Box+Text
  'No expenses yet' with EmptyStateIllustration. Resolution: use
  EmptyStateIllustration (consistent with main's new design) but keep
  the branch's three-way message selection (no results vs no data).

For visual consistency between the two tabs, also swap
RecurringTabContent's empty state to EmptyStateIllustration. No
behavioral change for the recurring case — same per-tab vs no-results
message selection, same strings, just rendered through the shared
component.

All other files (build.gradle.kts, libs.versions.toml, HomeScreen,
SettingsScreen, CategoryScreen, EmptyStateIllustration.kt, strings.xml)
auto-merged cleanly.
admin merged commit 7963ac55e2 into main 2026-06-28 14:33:43 +00:00
admin deleted branch fix/25-26-28-expenses-screen-polish 2026-06-28 15:01:14 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/ledgerr#37