Skip to content

Paint scaffold persistent bottom sheet background color behind the keyboard - #186365

Closed
victorsanni wants to merge 18 commits into
flutter:masterfrom
victorsanni:persistent-sheets-backdrop
Closed

victorsanni wants to merge 18 commits into
flutter:masterfrom
victorsanni:persistent-sheets-backdrop

Conversation

@victorsanni

@victorsanni victorsanni commented May 11, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the framework-owned part of #179482.

Problem

With a persistent bottom sheet (Scaffold.bottomSheet or ScaffoldState.showBottomSheet) and resizeToAvoidBottomInset: true, the sheet is lifted above the keyboard and the Scaffold's own Material (Scaffold.backgroundColor) is what sits behind the keyboard. On iOS 26 the keyboard is translucent, so the scaffold color shows through under the sheet instead of the sheet's color.

Fix

Lay the sheet out all the way to the bottom and pad its content, instead of lying about its size:

  • _ScaffoldLayout extends the persistent sheet's slot by the part of the keyboard inset that is not already covered by the bottom bars (bottomSheetKeyboardInset), and keeps reporting the content-only height so FAB and SnackBar geometry are unchanged. The inset reaches the pre-built sheet widgets through _BottomSheetBoxConstraints + a LayoutBuilder, the same pattern as _BodyBoxConstraints / _BodyBuilder.
  • New BottomSheet.bottomInset (default 0): a Padding inside the sheet's Material, so the surface (color, surface tint, elevation, shape) continues behind the keyboard while _childHeight, the drag/fling dismissal thresholds and constraints are still measured against the content. The Padding is always present so the content's element tree and focus survive the inset changing.

Because the sheet is laid out within its slot, a Scaffold shorter than the keyboard keeps the sheet inside its bounds without any clipping.

Behavior notes

  • Only the sheet's own Material color extends (showBottomSheet(backgroundColor:), BottomSheetThemeData.backgroundColor, or the default surface color). A child's Container(color:) does not.
  • With the keyboard up, the sheet slides behind the keyboard glass on open/close rather than emerging from above it.
  • The extended Material absorbs taps below the content, which is what the Scaffold's Material did there before. Only a docked keyboard produces an inset.
  • The sheet's semantics container rect now includes the extension; child rects are unchanged.
  • resizeToAvoidBottomInset: false, showModalBottomSheet, and a BottomSheet passed directly as Scaffold.bottomSheet behave as before.

Tests

No new test file. persistent_bottom_sheet_test.dart gains a keyboard inset group (11 tests): extension with and without a keyboard, resizeToAvoidBottomInset: false, bottom navigation bar, docked FAB, focus preserved while the keyboard appears, fling and slow-drag dismissal thresholds, constraints, taps in the extension, a Scaffold shorter than the keyboard, and a nested BottomSheet not being extended twice.

bottom_sheet_test.dart gains a BottomSheet.bottomInset group (5 tests) that exercises the new API on a standalone BottomSheet: layout (plus the default value and the non-negative assert), constraints (min and max) bounding the content rather than the inset, the drag-to-dismiss threshold measured against the content through a real AnimationController, state and focus preserved across inset changes, and showModalBottomSheet not setting it.

Pre-launch Checklist

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 11, 2026
@github-actions github-actions Bot added framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages and removed CICD Run CI/CD labels May 11, 2026
@victorsanni victorsanni added the CICD Run CI/CD label May 11, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 11, 2026
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 11, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 11, 2026
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 12, 2026
@victorsanni victorsanni added CICD Run CI/CD and removed CICD Run CI/CD labels May 12, 2026
@fluttergithubbot

Copy link
Copy Markdown
Contributor

An existing Git SHA, 22dd4ecdf63849a4b879efadd533835f57e1233d, was detected, and no actions were taken.

To re-trigger presubmits after closing or re-opeing a PR, or pushing a HEAD commit (i.e. with --force) that already was pushed before, push a blank commit (git commit --allow-empty -m "Trigger Build") or rebase to continue.

@Piinks

Piinks commented May 27, 2026

Copy link
Copy Markdown
Contributor

In the before/after image, the padding around the text field is gone. Is that intentional?

@victorsanni

Copy link
Copy Markdown
Contributor Author

In the before/after image, the padding around the text field is gone. Is that intentional?

Oops... thanks for catching that. I mistakenly used images from two different APIs in my repro app, one with padding and one without. Fixed.

@Piinks Piinks added the Decoupling: Not ready to port yet Instructions will be provided when this is ready to move to flutter/packages. label Jun 24, 2026
@Piinks

Piinks commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

I've marked this PR as not ready to port to flutter/packages yet.
We'll provide instructions to move this change over to material_ui/cupertino_ui once ready to receive PRs. Thank you!

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

This pull request contains changes to Material or Cupertino, which are currently frozen in this repository.

Changes should be made in material_ui and/or cupertino_ui in the flutter/packages repository.

Please refer to #188444 for instructions.

@victorsanni victorsanni added CICD Run CI/CD and removed CICD Run CI/CD labels Sep 8, 2026
…a size-lying render object

Replaces _RenderBottomSheetSurface, _BottomSheetContentClip, _BottomSheetClipper,
_BottomSheetSemanticsClip, _BottomSheetContentMaterial and the adoption of a
user-supplied BottomSheet with the approach from 70dac41:

- _ScaffoldLayout lays the persistent bottom sheet's slot out to the bottom
  edge available to it (contentBottom + the keyboard inset not already covered
  by the bottom bars) and reports the content-only height to keep FAB and
  snackbar geometry unchanged. The inset travels to the pre-built sheets via
  _BottomSheetBoxConstraints + a LayoutBuilder, the same pattern as
  _BodyBoxConstraints / _BodyBuilder.
- BottomSheet.bottomInset pads the content inside the sheet's Material, so
  the surface (color, tint, elevation, shape) continues behind the keyboard
  while _childHeight and `constraints` are measured against the content.
  The Padding is always present so the content's element tree and focus
  survive the inset changing.

Because the sheet is laid out within its slot, no clipping is needed: a
Scaffold shorter than the keyboard keeps the sheet inside its bounds.

Tests move to scaffold_bottom_sheet_keyboard_test.dart (13 tests): extension
with/without keyboard, resize opt-out, bottom navigation bar, docked FAB,
focus preservation, fling and slow-drag dismissal thresholds, constraints,
standalone bottomInset, taps in the extension, a Scaffold shorter than the
keyboard, modal sheets unaffected, and a nested BottomSheet not being
extended twice.

Lifecycle hardening of removeCurrentBottomSheet and forwarding of a
user-supplied BottomSheet's properties are left for separate changes.
No new test file: the Scaffold-level tests join the other persistent bottom
sheet tests in persistent_bottom_sheet_test.dart (group 'keyboard inset'),
and bottom_sheet_test.dart gains a 'BottomSheet.bottomInset' group that
exercises the new API on a standalone BottomSheet:

- extends the Material below the content (plus the default and the
  non-negative assert)
- constraints bound the content, not the inset (minHeight and maxHeight)
- drag-to-dismiss threshold is measured against the content, driven
  through a real AnimationController
- changing bottomInset preserves the content state and focus
- showModalBottomSheet does not set bottomInset
…omSheet.bottomInset

_StandardBottomSheet now pads its content by the keyboard inset inside the
BottomSheet's Material and grows the sheet's constraints by the same amount,
so BottomSheet and its API are unchanged.

The whole sheet now follows the finger while the keyboard is up. Before,
drag progress was measured against the content alone while the reveal
animated the full sheet, so the sheet ran ahead of the finger. A slow drag
now closes the sheet past half of its full height, including the part
behind the keyboard, like a modal sheet that pads its content by the
keyboard height.
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Nov 5, 2026
… behind the keyboard (#13242)

Ports flutter/flutter#186365 to `material_ui` (design: https://flutter.dev/go/ios-26-keyboard-bleed).

With a persistent bottom sheet (`Scaffold.bottomSheet` or `ScaffoldState.showBottomSheet`) and `resizeToAvoidBottomInset: true`, the sheet is lifted above the keyboard and the `Scaffold`'s own `Material` is what sits behind the keyboard. On iOS 26 the keyboard is translucent, so the scaffold color shows through under the sheet instead of the sheet's color.

`_ScaffoldLayout` now extends the persistent sheet's slot by the part of the keyboard inset not already covered by the bottom bars, while still reporting the content-only height so FAB and `SnackBar` geometry are unchanged. `_StandardBottomSheet` pads its content inside the `BottomSheet`'s `Material` by that amount (growing the sheet's constraints to match), so the sheet's surface continues behind the keyboard. `resizeToAvoidBottomInset: false`, `showModalBottomSheet`, and `BottomSheet`'s public API are unchanged.

Fixes the framework-owned part of flutter/flutter#179482.

## Before

<img width="368" height="405" alt="before" src="https://github.com/user-attachments/assets/d60ec5b8-60e7-4ea5-881e-d1fe80fa2e4f" />

## After

<img width="368" height="405" alt="after" src="https://github.com/user-attachments/assets/0f8ae510-40bc-497f-b9a8-9545b5a42e43" />

## Pre-Review Checklist

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD Decoupling: Not ready to port yet Instructions will be provided when this is ready to move to flutter/packages. framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants