Skip to content

feat(appbar): rework LdAppBar with wrapper-based composition (Issue #91)#98

Merged
ElectricCookie merged 11 commits into
devfrom
feature/issue-91-rework-ldappbar-wrapper-composition
May 15, 2026
Merged

feat(appbar): rework LdAppBar with wrapper-based composition (Issue #91)#98
ElectricCookie merged 11 commits into
devfrom
feature/issue-91-rework-ldappbar-wrapper-composition

Conversation

@ElectricCookie
Copy link
Copy Markdown
Collaborator

Summary

  • Replace AppBarRegistry/injection pattern with wrapper-based LdAppBar and LdTabNavigation composition
  • Bar height, visibility, and scroll-under state published via InheritedWidget to descendants
  • Remove AppBarRegistry, LdAppBarRegistryEntry, and addPostFrameCallback relay pipeline
  • LdScaffold.appBars deprecated; body padding now derived from context-provided bar metrics
  • Fix consumedInsets double-counting: edgeMargin now subtracted (not added) from visible height
  • Move MeasureSize outside AnimatedContainer so height is measured after layout
  • Update all call sites, regenerate golden tests, and add regression test for nested bar padding

Test plan

  • Run melos run analyze — no analysis errors
  • Run melos run test — all tests pass including new nested-bar padding regression test
  • Verify example app: drawer, chemical screen, code dialog show correct layout
  • Check nested bars (modal over scaffold) have no extra empty gap at top/bottom

Fixes #91


Generated with Claude Code

ElectricCookie and others added 11 commits April 20, 2026 09:05
…Tree API

- Use buildMonkeyRouteTree/MonkeyRouteNode for nested project/file routes
- Update repositoryBuilder signatures to accept (context, state)
- Remove manual Provider/ShellRoute nesting in AppRouter
- Add MonkeyRouteScope and MonkeyRouteTree helpers
- Update monkey tests and example app patterns
…(Stage 1)

- Create LdAppBarMetrics immutable value object with position, barHeight,
  edgeMargin, hideOffset, isScrolledUnder, level fields
- Add consumedInsets computed getter for 4-directional EdgeInsets
- Re-export LdAppBarPosition from appbar_state.dart via index.dart
- Add unit tests for value equality, consumedInsets, and copyWith

Part of issue #91 — Stage 1 (#92)
- Add wrappedChild and scrollBehavior params to AppBarFrame
- Stack-mode: wraps child in Stack with Positioned bar surface,
  Transform.translate for scroll-hide, NotificationListener for
  scroll tracking
- Provides LdAppBarMetrics via Provider.value to wrapped subtree
- Patches MediaQuery.padding additively with consumedInsets
- Resolves level from nearest ancestor LdAppBarMetrics context
- Legacy-mode preserved for backward compat until Stage 3
- Add 9 widget tests in appbar_frame_test.dart

Part of issue #91 — Stage 2 (#93)
…ge 3)

- Add child: Widget? parameter to LdAppBar, LdTabNavigation (stack-mode)
- Deprecate order parameter (kept as no-op for backward compat)
- Remove LdAppBarRegistryEntry and LdAppBarScrollWrapper from stack-mode path
- Delegate to AppBarFrame(wrappedChild: child) when child is provided
- Add insideDecorationBuilder/outsideDecorationBuilder to AppBarFrame
  for reactive scroll-under decoration
- closeModalButton uses LdAppBarMetrics from context in stack-mode
- Legacy-mode (no child) preserved for backward compat until Stage 4
- Update appbar_test.dart and tab_navigation_test.dart to new API
- 22/22 appbar tests, 14/14 tab_navigation tests pass

Part of issue #91 — Stage 3 (#94)
…ars (Stage 4)

- Remove AppBarRegistry widget and bodyPadding ValueListenableBuilder from build()
- Remove Stack with appBars.reversed children; body now rendered directly
- Remove appbar_registry.dart import from scaffold.dart
- Deprecate appBars param (kept as no-op for ~60 call sites awaiting Stage 6)
- Body bars now use wrapper pattern: LdAppBar(child: body)
- Update scaffold_test.dart: migrate 3 tests to wrapper API, add 3 new tests
- 17/17 scaffold tests pass

Part of issue #91 — Stage 4 (#95)
…and drawer buttons (Stage 5)

- Delete appbar_registry.dart, appbar_scroll_wrapper.dart, scaffold_layout_state.dart
- ScrolledUnderBuilder simplified to StatelessWidget reading LdAppBarMetrics? from context
- OpenDrawerButton and CloseDrawerButton use LdAppBarMetrics for level/position check
- Remove LdDrawerLayout widget-type ancestor check (LdDrawerSlot provider is sufficient)
- Remove remaining legacy-mode registry/scroll_wrapper code from appbar.dart and tab_navigation.dart
- Export appbar_scroll_behavior.dart from index.dart
- 27/27 appbar tests pass, 0 analysis errors

Part of issue #91 — Stage 5 (#96)
…ldens (Stage 6)

- Migrate LdMonkeyAppBar to accept child parameter, forward to LdAppBar
- Migrate all internal library files to wrapper pattern:
  - exception_dialog.dart, time_picker.dart, date_picker.dart
  - choose/choose.dart, modal/utils.dart (both usages)
  - devtools extension main.dart
- Migrate all example app files (agent partial work from prior run)
- Rewrite appbar_golden_test.dart, scaffold_golden_test.dart,
  tab_navigation_golden_test.dart, modal_golden_test.dart to new API
- Migrate modal_test.dart to new wrapper pattern
- Regenerate all golden images with new Stack-based layout
- Zero analysis errors; pre-existing test failures (list_test, repository_test,
  time_picker_test) are unrelated to this change

Completes issue #91 — Stage 6 (#97)
…ample formatting

- consumedInsets now subtracts edgeMargin from the visible height instead of
  adding it, so nested bars no longer double-count ancestor insets
- Move MeasureSize outside AnimatedContainer so bar height is measured after
  layout, preventing spurious padding in stacked bars
- Update appbar_state_test.dart expectations to match corrected formula
- Add regression test: nested same-position bars should not add an extra gap
- Fix LdOrb dispose order (super.dispose() before controller.dispose())
- Reformat example files (chemical_screen, component_well, demo_code_dialog,
  drawer) to correct indentation after LdScaffoldBody child extraction
- Remove unused flutter/services and liquid/main.dart imports from drawer.dart
@ElectricCookie ElectricCookie merged commit f3ebc89 into dev May 15, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant