Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
219ff645
Unverified
Commit
219ff645
authored
Feb 24, 2023
by
Taha Tesser
Committed by
GitHub
Feb 24, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reland "Update ExpansionTile to support Material 3 & add an example" (#121212)
parent
cab761d1
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
230 additions
and
25 deletions
+230
-25
gen_defaults.dart
dev/tools/gen_defaults/bin/gen_defaults.dart
+2
-0
expansion_tile_template.dart
dev/tools/gen_defaults/lib/expansion_tile_template.dart
+34
-0
expansion_tile.0.dart
...les/api/lib/material/expansion_tile/expansion_tile.0.dart
+15
-15
expansion_tile.0_test.dart
...i/test/material/expansion_tile/expansion_tile.0_test.dart
+40
-0
expansion_tile.dart
packages/flutter/lib/src/material/expansion_tile.dart
+76
-10
expansion_tile_test.dart
packages/flutter/test/material/expansion_tile_test.dart
+63
-0
No files found.
dev/tools/gen_defaults/bin/gen_defaults.dart
View file @
219ff645
...
@@ -31,6 +31,7 @@ import 'package:gen_defaults/date_picker_template.dart';
...
@@ -31,6 +31,7 @@ import 'package:gen_defaults/date_picker_template.dart';
import
'package:gen_defaults/dialog_template.dart'
;
import
'package:gen_defaults/dialog_template.dart'
;
import
'package:gen_defaults/divider_template.dart'
;
import
'package:gen_defaults/divider_template.dart'
;
import
'package:gen_defaults/drawer_template.dart'
;
import
'package:gen_defaults/drawer_template.dart'
;
import
'package:gen_defaults/expansion_tile_template.dart'
;
import
'package:gen_defaults/fab_template.dart'
;
import
'package:gen_defaults/fab_template.dart'
;
import
'package:gen_defaults/filter_chip_template.dart'
;
import
'package:gen_defaults/filter_chip_template.dart'
;
import
'package:gen_defaults/icon_button_template.dart'
;
import
'package:gen_defaults/icon_button_template.dart'
;
...
@@ -153,6 +154,7 @@ Future<void> main(List<String> args) async {
...
@@ -153,6 +154,7 @@ Future<void> main(List<String> args) async {
DialogTemplate
(
'Dialog'
,
'
$materialLib
/dialog.dart'
,
tokens
).
updateFile
();
DialogTemplate
(
'Dialog'
,
'
$materialLib
/dialog.dart'
,
tokens
).
updateFile
();
DividerTemplate
(
'Divider'
,
'
$materialLib
/divider.dart'
,
tokens
).
updateFile
();
DividerTemplate
(
'Divider'
,
'
$materialLib
/divider.dart'
,
tokens
).
updateFile
();
DrawerTemplate
(
'Drawer'
,
'
$materialLib
/drawer.dart'
,
tokens
).
updateFile
();
DrawerTemplate
(
'Drawer'
,
'
$materialLib
/drawer.dart'
,
tokens
).
updateFile
();
ExpansionTileTemplate
(
'ExpansionTile'
,
'
$materialLib
/expansion_tile.dart'
,
tokens
).
updateFile
();
FABTemplate
(
'FAB'
,
'
$materialLib
/floating_action_button.dart'
,
tokens
).
updateFile
();
FABTemplate
(
'FAB'
,
'
$materialLib
/floating_action_button.dart'
,
tokens
).
updateFile
();
FilterChipTemplate
(
'ChoiceChip'
,
'
$materialLib
/choice_chip.dart'
,
tokens
).
updateFile
();
FilterChipTemplate
(
'ChoiceChip'
,
'
$materialLib
/choice_chip.dart'
,
tokens
).
updateFile
();
FilterChipTemplate
(
'FilterChip'
,
'
$materialLib
/filter_chip.dart'
,
tokens
).
updateFile
();
FilterChipTemplate
(
'FilterChip'
,
'
$materialLib
/filter_chip.dart'
,
tokens
).
updateFile
();
...
...
dev/tools/gen_defaults/lib/expansion_tile_template.dart
0 → 100644
View file @
219ff645
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'template.dart'
;
class
ExpansionTileTemplate
extends
TokenTemplate
{
const
ExpansionTileTemplate
(
super
.
blockName
,
super
.
fileName
,
super
.
tokens
,
{
super
.
colorSchemePrefix
=
'_colors.'
,
});
@override
String
generate
()
=>
'''
class _
${blockName}
DefaultsM3 extends ExpansionTileThemeData {
_
${blockName}
DefaultsM3(this.context);
final BuildContext context;
late final ThemeData _theme = Theme.of(context);
late final ColorScheme _colors = _theme.colorScheme;
@override
Color? get textColor =>
${componentColor('md.comp.list.list-item.label-text')}
;
@override
Color? get iconColor =>
${componentColor('md.comp.list.list-item.selected.trailing-icon')}
;
@override
Color? get collapsedTextColor =>
${componentColor('md.comp.list.list-item.label-text')}
;
@override
Color? get collapsedIconColor =>
${componentColor('md.comp.list.list-item.trailing-icon')}
;
}
'''
;
}
examples/api/lib/material/expansion_tile/expansion_tile.0.dart
View file @
219ff645
...
@@ -6,33 +6,31 @@
...
@@ -6,33 +6,31 @@
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
void
main
(
)
=>
runApp
(
const
My
App
());
void
main
(
)
=>
runApp
(
const
ExpansionTile
App
());
class
MyApp
extends
StatelessWidget
{
class
ExpansionTileApp
extends
StatelessWidget
{
const
MyApp
({
super
.
key
});
const
ExpansionTileApp
({
super
.
key
});
static
const
String
_title
=
'Flutter Code Sample'
;
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
MaterialApp
(
return
MaterialApp
(
t
itle:
_title
,
t
heme:
ThemeData
(
useMaterial3:
true
)
,
home:
Scaffold
(
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
_title
)),
appBar:
AppBar
(
title:
const
Text
(
'ExpansionTile Sample'
)),
body:
const
MyStatefulWidget
(),
body:
const
ExpansionTileExample
(),
),
),
);
);
}
}
}
}
class
MyStatefulWidget
extends
StatefulWidget
{
class
ExpansionTileExample
extends
StatefulWidget
{
const
MyStatefulWidget
({
super
.
key
});
const
ExpansionTileExample
({
super
.
key
});
@override
@override
State
<
MyStatefulWidget
>
createState
()
=>
_MyStatefulWidget
State
();
State
<
ExpansionTileExample
>
createState
()
=>
_ExpansionTileExample
State
();
}
}
class
_
MyStatefulWidgetState
extends
State
<
MyStatefulWidget
>
{
class
_
ExpansionTileExampleState
extends
State
<
ExpansionTileExample
>
{
bool
_customTileExpanded
=
false
;
bool
_customTileExpanded
=
false
;
@override
@override
...
@@ -51,14 +49,16 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> {
...
@@ -51,14 +49,16 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> {
subtitle:
const
Text
(
'Custom expansion arrow icon'
),
subtitle:
const
Text
(
'Custom expansion arrow icon'
),
trailing:
Icon
(
trailing:
Icon
(
_customTileExpanded
_customTileExpanded
?
Icons
.
arrow_drop_down_circle
?
Icons
.
arrow_drop_down_circle
:
Icons
.
arrow_drop_down
,
:
Icons
.
arrow_drop_down
,
),
),
children:
const
<
Widget
>[
children:
const
<
Widget
>[
ListTile
(
title:
Text
(
'This is tile number 2'
)),
ListTile
(
title:
Text
(
'This is tile number 2'
)),
],
],
onExpansionChanged:
(
bool
expanded
)
{
onExpansionChanged:
(
bool
expanded
)
{
setState
(()
=>
_customTileExpanded
=
expanded
);
setState
(()
{
_customTileExpanded
=
expanded
;
});
},
},
),
),
const
ExpansionTile
(
const
ExpansionTile
(
...
...
examples/api/test/material/expansion_tile/expansion_tile.0_test.dart
0 → 100644
View file @
219ff645
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter_api_samples/material/expansion_tile/expansion_tile.0.dart'
as
example
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'When expansion tiles are expanded tile numbers are revealed'
,
(
WidgetTester
tester
)
async
{
const
int
totalTiles
=
3
;
await
tester
.
pumpWidget
(
const
example
.
ExpansionTileApp
(),
);
expect
(
find
.
byType
(
ExpansionTile
),
findsNWidgets
(
totalTiles
));
const
String
tileOne
=
'This is tile number 1'
;
expect
(
find
.
text
(
tileOne
),
findsNothing
);
await
tester
.
tap
(
find
.
text
(
'ExpansionTile 1'
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
tileOne
),
findsOneWidget
);
const
String
tileTwo
=
'This is tile number 2'
;
expect
(
find
.
text
(
tileTwo
),
findsNothing
);
await
tester
.
tap
(
find
.
text
(
'ExpansionTile 2'
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
tileTwo
),
findsOneWidget
);
const
String
tileThree
=
'This is tile number 3'
;
expect
(
find
.
text
(
tileThree
),
findsNothing
);
await
tester
.
tap
(
find
.
text
(
'ExpansionTile 3'
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
tileThree
),
findsOneWidget
);
});
}
packages/flutter/lib/src/material/expansion_tile.dart
View file @
219ff645
...
@@ -34,7 +34,8 @@ const Duration _kExpand = Duration(milliseconds: 200);
...
@@ -34,7 +34,8 @@ const Duration _kExpand = Duration(milliseconds: 200);
/// to the [leading] and [trailing] properties of [ExpansionTile].
/// to the [leading] and [trailing] properties of [ExpansionTile].
///
///
/// {@tool dartpad}
/// {@tool dartpad}
/// This example demonstrates different configurations of ExpansionTile.
/// This example demonstrates how the [ExpansionTile] icon's location and appearance
/// can be customized.
///
///
/// ** See code in examples/api/lib/material/expansion_tile/expansion_tile.0.dart **
/// ** See code in examples/api/lib/material/expansion_tile/expansion_tile.0.dart **
/// {@end-tool}
/// {@end-tool}
...
@@ -218,7 +219,7 @@ class ExpansionTile extends StatefulWidget {
...
@@ -218,7 +219,7 @@ class ExpansionTile extends StatefulWidget {
/// Used to override to the [ListTileThemeData.iconColor].
/// Used to override to the [ListTileThemeData.iconColor].
///
///
/// If this property is null then [ExpansionTileThemeData.iconColor] is used. If that
/// If this property is null then [ExpansionTileThemeData.iconColor] is used. If that
/// is also null then the value of [
ListTileThemeData.iconColor
] is used.
/// is also null then the value of [
ColorScheme.primary
] is used.
///
///
/// See also:
/// See also:
///
///
...
@@ -229,6 +230,15 @@ class ExpansionTile extends StatefulWidget {
...
@@ -229,6 +230,15 @@ class ExpansionTile extends StatefulWidget {
/// The icon color of tile's expansion arrow icon when the sublist is collapsed.
/// The icon color of tile's expansion arrow icon when the sublist is collapsed.
///
///
/// Used to override to the [ListTileThemeData.iconColor].
/// Used to override to the [ListTileThemeData.iconColor].
///
/// If this property is null then [ExpansionTileThemeData.collapsedIconColor] is used. If that
/// is also null and [ThemeData.useMaterial3] is true, [ColorScheme.onSurface] is used. Otherwise,
/// defaults to [ThemeData.unselectedWidgetColor] color.
///
/// See also:
///
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
/// [ExpansionTileThemeData].
final
Color
?
collapsedIconColor
;
final
Color
?
collapsedIconColor
;
...
@@ -237,7 +247,8 @@ class ExpansionTile extends StatefulWidget {
...
@@ -237,7 +247,8 @@ class ExpansionTile extends StatefulWidget {
/// Used to override to the [ListTileThemeData.textColor].
/// Used to override to the [ListTileThemeData.textColor].
///
///
/// If this property is null then [ExpansionTileThemeData.textColor] is used. If that
/// If this property is null then [ExpansionTileThemeData.textColor] is used. If that
/// is also null then the value of [ListTileThemeData.textColor] is used.
/// is also null then and [ThemeData.useMaterial3] is true, color of the [TextTheme.bodyLarge]
/// will be used for the [title] and [subtitle]. Otherwise, defaults to [ColorScheme.primary] color.
///
///
/// See also:
/// See also:
///
///
...
@@ -249,8 +260,10 @@ class ExpansionTile extends StatefulWidget {
...
@@ -249,8 +260,10 @@ class ExpansionTile extends StatefulWidget {
///
///
/// Used to override to the [ListTileThemeData.textColor].
/// Used to override to the [ListTileThemeData.textColor].
///
///
/// If this property is null then [ExpansionTileThemeData.collapsedTextColor] is used. If that
/// If this property is null then [ExpansionTileThemeData.collapsedTextColor] is used.
/// is also null then the value of [ListTileThemeData.textColor] is used.
/// If that is also null and [ThemeData.useMaterial3] is true, color of the
/// [TextTheme.bodyLarge] will be used for the [title] and [subtitle]. Otherwise,
/// defaults to color of the [TextTheme.titleMedium].
///
///
/// See also:
/// See also:
///
///
...
@@ -443,7 +456,9 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
...
@@ -443,7 +456,9 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
void
didChangeDependencies
()
{
void
didChangeDependencies
()
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
ExpansionTileThemeData
expansionTileTheme
=
ExpansionTileTheme
.
of
(
context
);
final
ExpansionTileThemeData
expansionTileTheme
=
ExpansionTileTheme
.
of
(
context
);
final
ColorScheme
colorScheme
=
theme
.
colorScheme
;
final
ExpansionTileThemeData
defaults
=
theme
.
useMaterial3
?
_ExpansionTileDefaultsM3
(
context
)
:
_ExpansionTileDefaultsM2
(
context
);
_borderTween
_borderTween
..
begin
=
widget
.
collapsedShape
..
begin
=
widget
.
collapsedShape
??
expansionTileTheme
.
collapsedShape
??
expansionTileTheme
.
collapsedShape
...
@@ -460,13 +475,13 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
...
@@ -460,13 +475,13 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
_headerColorTween
_headerColorTween
..
begin
=
widget
.
collapsedTextColor
..
begin
=
widget
.
collapsedTextColor
??
expansionTileTheme
.
collapsedTextColor
??
expansionTileTheme
.
collapsedTextColor
??
theme
.
textTheme
.
titleMedium
!.
c
olor
??
defaults
.
collapsedTextC
olor
..
end
=
widget
.
textColor
??
expansionTileTheme
.
textColor
??
colorScheme
.
primary
;
..
end
=
widget
.
textColor
??
expansionTileTheme
.
textColor
??
defaults
.
textColor
;
_iconColorTween
_iconColorTween
..
begin
=
widget
.
collapsedIconColor
..
begin
=
widget
.
collapsedIconColor
??
expansionTileTheme
.
collapsedIconColor
??
expansionTileTheme
.
collapsedIconColor
??
theme
.
unselectedWidget
Color
??
defaults
.
collapsedIcon
Color
..
end
=
widget
.
iconColor
??
expansionTileTheme
.
iconColor
??
colorScheme
.
primary
;
..
end
=
widget
.
iconColor
??
expansionTileTheme
.
iconColor
??
defaults
.
iconColor
;
_backgroundColorTween
_backgroundColorTween
..
begin
=
widget
.
collapsedBackgroundColor
??
expansionTileTheme
.
collapsedBackgroundColor
..
begin
=
widget
.
collapsedBackgroundColor
??
expansionTileTheme
.
collapsedBackgroundColor
..
end
=
widget
.
backgroundColor
??
expansionTileTheme
.
backgroundColor
;
..
end
=
widget
.
backgroundColor
??
expansionTileTheme
.
backgroundColor
;
...
@@ -500,3 +515,54 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
...
@@ -500,3 +515,54 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
);
);
}
}
}
}
class
_ExpansionTileDefaultsM2
extends
ExpansionTileThemeData
{
_ExpansionTileDefaultsM2
(
this
.
context
);
final
BuildContext
context
;
late
final
ThemeData
_theme
=
Theme
.
of
(
context
);
late
final
ColorScheme
_colorScheme
=
_theme
.
colorScheme
;
@override
Color
?
get
textColor
=>
_colorScheme
.
primary
;
@override
Color
?
get
iconColor
=>
_colorScheme
.
primary
;
@override
Color
?
get
collapsedTextColor
=>
_theme
.
textTheme
.
titleMedium
!.
color
;
@override
Color
?
get
collapsedIconColor
=>
_theme
.
unselectedWidgetColor
;
}
// BEGIN GENERATED TOKEN PROPERTIES - ExpansionTile
// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
// dev/tools/gen_defaults/bin/gen_defaults.dart.
// Token database version: v0_158
class
_ExpansionTileDefaultsM3
extends
ExpansionTileThemeData
{
_ExpansionTileDefaultsM3
(
this
.
context
);
final
BuildContext
context
;
late
final
ThemeData
_theme
=
Theme
.
of
(
context
);
late
final
ColorScheme
_colors
=
_theme
.
colorScheme
;
@override
Color
?
get
textColor
=>
_colors
.
onSurface
;
@override
Color
?
get
iconColor
=>
_colors
.
primary
;
@override
Color
?
get
collapsedTextColor
=>
_colors
.
onSurface
;
@override
Color
?
get
collapsedIconColor
=>
_colors
.
onSurfaceVariant
;
}
// END GENERATED TOKEN PROPERTIES - ExpansionTile
packages/flutter/test/material/expansion_tile_test.dart
View file @
219ff645
...
@@ -522,6 +522,35 @@ void main() {
...
@@ -522,6 +522,35 @@ void main() {
expect
(
shapeDecoration
.
color
,
backgroundColor
);
expect
(
shapeDecoration
.
color
,
backgroundColor
);
});
});
testWidgets
(
'ExpansionTile default iconColor, textColor'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
theme
=
ThemeData
(
useMaterial3:
true
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
theme
,
home:
const
Material
(
child:
ExpansionTile
(
title:
TestText
(
'title'
),
trailing:
TestIcon
(),
children:
<
Widget
>[
SizedBox
(
height:
100
,
width:
100
),
],
),
),
));
Color
getIconColor
()
=>
tester
.
state
<
TestIconState
>(
find
.
byType
(
TestIcon
)).
iconTheme
.
color
!;
Color
getTextColor
()
=>
tester
.
state
<
TestTextState
>(
find
.
byType
(
TestText
)).
textStyle
.
color
!;
expect
(
getIconColor
(),
theme
.
colorScheme
.
onSurfaceVariant
);
expect
(
getTextColor
(),
theme
.
colorScheme
.
onSurface
);
await
tester
.
tap
(
find
.
text
(
'title'
));
await
tester
.
pumpAndSettle
();
expect
(
getIconColor
(),
theme
.
colorScheme
.
primary
);
expect
(
getTextColor
(),
theme
.
colorScheme
.
onSurface
);
});
testWidgets
(
'ExpansionTile iconColor, textColor'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'ExpansionTile iconColor, textColor'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/pull/78281
// Regression test for https://github.com/flutter/flutter/pull/78281
...
@@ -666,4 +695,38 @@ void main() {
...
@@ -666,4 +695,38 @@ void main() {
expect
(
listTile
.
leading
.
runtimeType
,
Icon
);
expect
(
listTile
.
leading
.
runtimeType
,
Icon
);
expect
(
listTile
.
trailing
,
isNull
);
expect
(
listTile
.
trailing
,
isNull
);
});
});
group
(
'Material 2'
,
()
{
// Tests that are only relevant for Material 2. Once ThemeData.useMaterial3
// is turned on by default, these tests can be removed.
testWidgets
(
'ExpansionTile default iconColor, textColor'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
theme
=
ThemeData
(
useMaterial3:
false
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
theme
,
home:
const
Material
(
child:
ExpansionTile
(
title:
TestText
(
'title'
),
trailing:
TestIcon
(),
children:
<
Widget
>[
SizedBox
(
height:
100
,
width:
100
),
],
),
),
));
Color
getIconColor
()
=>
tester
.
state
<
TestIconState
>(
find
.
byType
(
TestIcon
)).
iconTheme
.
color
!;
Color
getTextColor
()
=>
tester
.
state
<
TestTextState
>(
find
.
byType
(
TestText
)).
textStyle
.
color
!;
expect
(
getIconColor
(),
theme
.
unselectedWidgetColor
);
expect
(
getTextColor
(),
theme
.
textTheme
.
titleMedium
!.
color
);
await
tester
.
tap
(
find
.
text
(
'title'
));
await
tester
.
pumpAndSettle
();
expect
(
getIconColor
(),
theme
.
colorScheme
.
primary
);
expect
(
getTextColor
(),
theme
.
colorScheme
.
primary
);
});
});
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment