Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
4515563
Introduce the Expansible widget
victorsanni Feb 25, 2025
36dbab5
Merge branch 'master' into raw-expansible
victorsanni Feb 25, 2025
d0527c1
Add semantics fix
victorsanni Feb 25, 2025
1a6a90e
Add addHeaderTap
victorsanni Feb 25, 2025
c4cbf05
Merge branch 'master' into raw-expansible
victorsanni Feb 25, 2025
500201b
Add documentation and name refactor
victorsanni Feb 25, 2025
dbc2e96
Merge branch 'master' into raw-expansible
victorsanni Feb 25, 2025
9e755b2
Apply some review suggestions
victorsanni Mar 1, 2025
04f3928
Merge branch 'master' into raw-expansible
victorsanni Mar 1, 2025
aa24688
Duplicate animation controller managed by material/cupertino
victorsanni Mar 3, 2025
f70d377
Merge branch 'master' into raw-expansible
victorsanni Mar 3, 2025
cf82ae4
Expose animation controller via builder callbacks
victorsanni Mar 6, 2025
072f7cf
Merge branch 'master' into raw-expansible
victorsanni Mar 6, 2025
a106bd0
Apply review suggestions
victorsanni Mar 7, 2025
9815196
Merge branch 'master' into raw-expansible
victorsanni Mar 7, 2025
6b33827
Dispose ExpansibleController
victorsanni Mar 7, 2025
6a48570
Merge branch 'master' into raw-expansible
victorsanni Mar 7, 2025
9001f0b
Dispose controllers
victorsanni Mar 7, 2025
6d5b352
Merge branch 'master' into raw-expansible
victorsanni Mar 7, 2025
0d10702
Remove excludeHeaderGestures flag
victorsanni Mar 7, 2025
2b05738
Merge branch 'master' into raw-expansible
victorsanni Mar 7, 2025
32154b3
Apply review suggestions
victorsanni Mar 8, 2025
b630359
More review suggestions
victorsanni Mar 8, 2025
9d69c15
Merge branch 'master' into raw-expansible
victorsanni Mar 8, 2025
956d14a
Apply review suggestions
victorsanni Mar 11, 2025
05ed134
Merge branch 'master' into raw-expansible
victorsanni Mar 11, 2025
a74f611
Call out duplicate APIs in docs
victorsanni Mar 12, 2025
431b6f9
Merge branch 'master' into raw-expansible
victorsanni Mar 12, 2025
9c32116
Apply review suggestions
victorsanni Mar 12, 2025
7821a52
Merge branch 'master' into raw-expansible
victorsanni Mar 12, 2025
e5924cb
More review suggestions
victorsanni Mar 12, 2025
d99c26d
Merge branch 'master' into raw-expansible
victorsanni Mar 12, 2025
797743d
Add comment for setState
victorsanni Mar 12, 2025
fc64396
State lifecycle tweaks
victorsanni Mar 13, 2025
62dd9ae
Merge branch 'master' into raw-expansible
victorsanni Mar 13, 2025
d29ba13
Merge branch 'master' into raw-expansible
victorsanni Mar 17, 2025
e539679
Merge branch 'master' into raw-expansible
victorsanni Mar 17, 2025
69aac62
Merge branch 'master' into raw-expansible
victorsanni Mar 18, 2025
1c3507f
Merge branch 'master' into raw-expansible
victorsanni Mar 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Apply some review suggestions
  • Loading branch information
victorsanni committed Mar 1, 2025
commit 9e755b2142c499fc47456326907c10bf945ab82b
75 changes: 45 additions & 30 deletions packages/flutter/lib/src/widgets/expansible.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,26 @@ import 'transitions.dart';

/// The type of the callback that returns the header or body of an [Expansible].
///
/// The `isExpanded` property allows for a different header or body depending on
/// whether the [Expansible] is currently expanded or collapsed.
///
/// See also:
///
/// * [Expansible.headerBuilder], which is of this type.
/// * [Expansible.bodyBuilder], which is also of this type.
typedef ExpansibleComponentBuilder = Widget Function(BuildContext context, bool isExpanded);

/// The type of the callback that uses the header and body of an [Expansible]
/// widget to layout that widget.
/// widget to build the widget.
///
/// The `header` property is the header returned by [Expansible.headerBuilder]
/// wrapped in a [GestureDetector] to toggle the expansion when tapped.
///
/// The `body` property is the body returned by [Expansible.bodyBuilder] wrapped
/// in an [Offstage] to hide the body when the [Expansible] is collapsed.
///
/// The `isExpanded` property allows for a different return value depending on
/// whether the [Expansible] is currently expanded or collapsed.
///
/// See also:
///
Expand Down Expand Up @@ -98,8 +110,8 @@ class ExpansibleController {
///
/// See also:
///
/// * [expand], which expands the tile.
/// * [isExpanded] to check whether the tile is expanded.
/// * [expand], which expands the [Expansible].
/// * [isExpanded] to check whether the [Expansible] is expanded.
void collapse() {
assert(_state != null);
if (isExpanded) {
Expand Down Expand Up @@ -133,33 +145,36 @@ class ExpansibleController {
/// within the `build` method of a descendant of an [Expansible].
static ExpansibleController of(BuildContext context) {
final ExpansibleState? result = context.findAncestorStateOfType<ExpansibleState>();
if (result != null) {
return result.widget.controller;
}
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary(
'ExpansibleController.of() called with a context that does not contain a Expansible.',
),
ErrorDescription(
'No Expansible ancestor could be found starting from the context that was passed to ExpansibleController.of(). '
'This usually happens when the context provided is from the same StatefulWidget as that '
'whose build function actually creates the Expansible widget being sought.',
),
ErrorHint(
'There are several ways to avoid this problem. The simplest is to use a Builder to get a '
'context that is "under" the Expansible. ',
),
ErrorHint(
'A more efficient solution is to split your build function into several widgets. This '
'introduces a new context from which you can obtain the Expansible. In this solution, '
'you would have an outer widget that creates the Expansible populated by instances of '
'your new inner widgets, and then in these inner widgets you would use ExpansibleController.of().\n'
'An other solution is assign a GlobalKey to the Expansible, '
'then use the key.currentState property to obtain the Expansible rather than '
'using the ExpansibleController.of() function.',
),
context.describeElement('The context used was'),
]);
assert(() {
if (result == null) {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary(
'ExpansibleController.of() called with a context that does not contain a Expansible.',
),
ErrorDescription(
'No Expansible ancestor could be found starting from the context that was passed to ExpansibleController.of(). '
'This usually happens when the context provided is from the same StatefulWidget as that '
'whose build function actually creates the Expansible widget being sought.',
),
ErrorHint(
'There are several ways to avoid this problem. The simplest is to use a Builder to get a '
'context that is "under" the Expansible. ',
),
ErrorHint(
'A more efficient solution is to split your build function into several widgets. This '
'introduces a new context from which you can obtain the Expansible. In this solution, '
'you would have an outer widget that creates the Expansible populated by instances of '
'your new inner widgets, and then in these inner widgets you would use ExpansibleController.of().\n'
'An other solution is assign a GlobalKey to the Expansible, '
'then use the key.currentState property to obtain the Expansible rather than '
'using the ExpansibleController.of() function.',
),
context.describeElement('The context used was'),
]);
}
return true;
}());
return result!.widget.controller;
}

/// Finds the [Expansible] from the closest instance of this class that
Expand Down