Skip to content

[Animations] Add support for custom shadows to OpenContainer (#62475) - #11401

Merged
auto-submit[bot] merged 3 commits into
flutter:mainfrom
moepanda:fix_open_container_shadow
Apr 23, 2026
Merged

[Animations] Add support for custom shadows to OpenContainer (#62475)#11401
auto-submit[bot] merged 3 commits into
flutter:mainfrom
moepanda:fix_open_container_shadow

Conversation

@moepanda

Copy link
Copy Markdown
Contributor

Summary

This PR adds support for custom BoxShadow to the OpenContainer widget. This allows developers to specify closedShadows and openShadows to create more advanced and visually appealing transitions that go beyond the standard material elevation.

  • Fixes a legacy layout overflow issue in _ExampleSingleTile by replacing the fixed height with responsive constraints, ensuring the example remains stable across different system font sizes and shadow distributions.

Motivation

Currently, OpenContainer only supports a numeric elevation property, which limits modern UI designs requiring colored or multi-layered shadows. This PR also refactors the internal rendering hierarchy to move the shadow decoration outside the clipping surface, fixing a legacy issue where custom shadows were clipped by Material.

Issues

Fixesflutter/flutter#62475

Pre-Review Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [AI contribution guidelines] and understand my responsibilities.
  • I read the [Tree Hygiene] page, which explains my responsibilities.
  • I read and followed the [relevant style guides] and ran [the auto-formatter].
  • I signed the [CLA]. (Reminder: Please ensure you've signed it!)
  • The title of the PR starts with [animations]
  • I linked to at least one issue that this PR fixes in the description above.
  • I followed [the version and CHANGELOG instructions].
  • I updated/added any relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making.
  • All existing and new tests are passing.

@github-actionsgithub-actionsBot added p: animations triage-framework Should be looked at in framework triage labels Mar 31, 2026

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for custom closedShadows and openShadows to the OpenContainer widget, enabling custom shadow animations during transitions. It also fixes a layout overflow in the example app by transitioning from a fixed height to minimum height constraints and includes new tests to verify shadow behavior. A review comment suggests conditionally wrapping the Material widget with DecoratedBox only when custom shadows are provided to avoid unnecessary widgets in the tree.

Comment threadpackages/animations/lib/src/open_container.dart Outdated
@moepanda
moepandaforce-pushed the fix_open_container_shadow branch 4 times, most recently from 88d57a1 to f6d83d3CompareApril 1, 2026 06:15

@hannah-hyjhannah-hyj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you for fixing the layout overflow issue too!

@moepanda

Copy link
Copy Markdown
ContributorAuthor

LGTM, thank you for fixing the layout overflow issue too!

Thank you! Glad to help.

@stuartmorgan-g

Copy link
Copy Markdown
Collaborator

From triage: @hannah-hyj Please add a second reviewer familiar with the package, so this can get the secondary review for landing.

@QuncCcccccQuncCccccc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! Overall looks good! Just left one comment for adding an additional unit test.

final Widget material = Material(
clipBehavior: widget.clipBehavior,
color: widget.closedColor,
elevation: widget.closedShadows == null ? widget.closedElevation : 0.0,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for my learning, why do we need to set elevation to 0.0 when closedShadows is non-null.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We set elevation to 0.0 so the shadow comes from a single source when custom shadows are provided.
In this case the visual shadow is drawn by the wrapping DecoratedBox, so keeping Material.elevation would stack the framework shadow on top of the custom BoxShadows.
The same rule is applied in the fully-open state as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, it makes sense! Thanks for the explanation.

animationDuration: Duration.zero,
color: colorTween!.evaluate(animation),
shape: _shapeTween.evaluate(curvedAnimation),
elevation: _elevationTween.evaluate(curvedAnimation),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to check currentShadows here like above?

@moepandamoepandaApr 15, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional. The elevation tween already accounts for whether custom shadows are provided on either side, so mixed cases can smoothly transition between Material elevation and custom shadows. If we zeroed elevation whenever currentShadows is non-null, the transition would become abrupt in those mixed cases.

expect(dataClosed.rect, dataTransitionDone.rect);
});

testWidgets('Custom shadows work', (WidgetTester tester) async {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test case for when one of the shadow properties is null and the other is provided? This would ensure the fallback to elevation behavior is verified and doesn't break in the future.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I added mixed null/non-null shadow test coverage for both directions to lock in the elevation fallback behavior during the transition.

@QuncCcccccQuncCccccc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you!

final Widget material = Material(
clipBehavior: widget.clipBehavior,
color: widget.closedColor,
elevation: widget.closedShadows == null ? widget.closedElevation : 0.0,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, it makes sense! Thanks for the explanation.

@QuncCcccccQuncCccccc added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 22, 2026
@auto-submitauto-submitBot removed the autosubmit Merge PR when tree becomes green via auto submit App label Apr 22, 2026
@auto-submit

Copy link
Copy Markdown
Contributor

auto label is removed for flutter/packages/11401, Failed to merge flutter/packages/11401 with Pull request flutter/packages/11401 could not be merged: Required status check "ci.yaml validation" is expected..

Add coverage for null/non-null shadow combinations in OpenContainer.
This verifies the elevation fallback behavior during mixed shadow transitions.
@QuncCccccc
QuncCcccccforce-pushed the fix_open_container_shadow branch from cc8dea2 to 310d47cCompareApril 22, 2026 22:34
@QuncCcccccQuncCccccc added the CICD Run CI/CD label Apr 22, 2026
@QuncCccccc

Copy link
Copy Markdown
Contributor

Seems there are some format issues that need to fix.

Screenshot 2026-04-22 at 5 18 38 PM

@github-actionsgithub-actionsBot removed the CICD Run CI/CD label Apr 23, 2026
@moepanda

Copy link
Copy Markdown
ContributorAuthor

Seems there are some format issues that need to fix.

PTAL

@QuncCcccccQuncCccccc added the CICD Run CI/CD label Apr 23, 2026

@QuncCcccccQuncCccccc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@QuncCcccccQuncCccccc added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 23, 2026
@auto-submit
auto-submitBot merged commit 8400f71 into flutter:mainApr 23, 2026
82 checks passed
kjlubick pushed a commit to kjlubick/flutter that referenced this pull request Apr 24, 2026
…r#185536)
flutter/packages@4a2091d...8400f71
2026-04-23 14008334+moepanda@users.noreply.github.com [Animations] Add
support for custom shadows to OpenContainer (flutter#62475)
(flutter/packages#11401)
2026-04-23 engine-flutter-autoroll@skia.org Roll Flutter from
3d0e822 to 5e4f169 (24 revisions) (flutter/packages#11565)
2026-04-22 10687576+bparrishMines@users.noreply.github.com Revert
"[webview_flutter_wkwebview] Tear down ProxyAPIRegistrar in
`applicationWillTerminate`" (flutter/packages#11564)
If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC flutter-ecosystem@google.com on the revert to ensure that a
human
is aware of the problem.
To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose
To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622
Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
creatorpiyush pushed a commit to creatorpiyush/packages that referenced this pull request Jun 10, 2026
…flutter#11401)
## Summary
This PR adds support for custom `BoxShadow` to the `OpenContainer` widget. This allows developers to specify `closedShadows` and `openShadows` to create more advanced and visually appealing transitions that go beyond the standard material `elevation`.
* Fixes a legacy layout overflow issue in `_ExampleSingleTile` by replacing the fixed height with responsive constraints, ensuring the example remains stable across different system font sizes and shadow distributions.
## Motivation
Currently, `OpenContainer` only supports a numeric `elevation` property, which limits modern UI designs requiring colored or multi-layered shadows. This PR also refactors the internal rendering hierarchy to move the shadow decoration outside the clipping surface, fixing a legacy issue where custom shadows were clipped by `Material`.
## Issues
Fixesflutter/flutter#62475
## Pre-Review Checklist
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmitMerge PR when tree becomes green via auto submit AppCICDRun CI/CDp: animationstriage-frameworkShould be looked at in framework triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenContainer add customize shadow support

4 participants

@moepanda@stuartmorgan-g@QuncCccccc@hannah-hyj