Skip to content

Commit ce24dd6

Browse files
authored
Add WidgetStateBorderSide example and tests for it. (flutter#155559)
Fixes flutter#155557 ### Description - Adds example for `WidgetStateBorderSide` - Adds tests for `examples/api/lib/widgets/widget_state/widget_state_border_side.0.dart`
1 parent 4d1f086 commit ce24dd6

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
7+
/// Flutter code sample for [WidgetStateBorderSide].
8+
9+
void main() {
10+
runApp(const WidgetStateBorderSideExampleApp());
11+
}
12+
13+
class WidgetStateBorderSideExampleApp extends StatelessWidget {
14+
const WidgetStateBorderSideExampleApp({super.key});
15+
16+
@override
17+
Widget build(BuildContext context) {
18+
return MaterialApp(
19+
home: Scaffold(
20+
appBar: AppBar(title: const Text('WidgetStateBorderSide Sample')),
21+
body: const Center(
22+
child: WidgetStateBorderSideExample(),
23+
),
24+
),
25+
);
26+
}
27+
}
28+
29+
class WidgetStateBorderSideExample extends StatefulWidget {
30+
const WidgetStateBorderSideExample({super.key});
31+
32+
@override
33+
State<WidgetStateBorderSideExample> createState() => _WidgetStateBorderSideExampleState();
34+
}
35+
36+
class _WidgetStateBorderSideExampleState extends State<WidgetStateBorderSideExample> {
37+
bool _isSelected = true;
38+
39+
@override
40+
Widget build(BuildContext context) {
41+
return FilterChip(
42+
label: const Text('Select chip'),
43+
selected: _isSelected,
44+
onSelected: (bool value) {
45+
setState(() {
46+
_isSelected = value;
47+
});
48+
},
49+
side: const WidgetStateBorderSide.fromMap(
50+
<WidgetStatesConstraint, BorderSide?>{
51+
WidgetState.pressed: BorderSide(color: Colors.green),
52+
WidgetState.hovered: BorderSide(color: Colors.blue),
53+
WidgetState.selected: BorderSide(color: Colors.red),
54+
// Resolves to null if no keys match, deferring to the default value
55+
// of the theme or widget.
56+
},
57+
),
58+
);
59+
}
60+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:ui';
6+
7+
import 'package:flutter/material.dart';
8+
import 'package:flutter_api_samples/widgets/widget_state/widget_state_border_side.0.dart'
9+
as example;
10+
import 'package:flutter_test/flutter_test.dart';
11+
12+
void main() {
13+
Finder findByBorderColor(Color color) {
14+
return find.byWidgetPredicate((Widget widget) {
15+
if (widget is! Material) {
16+
return false;
17+
}
18+
19+
final ShapeBorder? shape = widget.shape;
20+
return shape is OutlinedBorder && shape.side.color == color;
21+
});
22+
}
23+
24+
testWidgets('FilterChip displays the blue colored border when hovered', (WidgetTester tester) async {
25+
await tester.pumpWidget(
26+
const example.WidgetStateBorderSideExampleApp(),
27+
);
28+
29+
// Hover over the FilterChip.
30+
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
31+
await gesture.moveTo(tester.getCenter(find.byType(FilterChip)));
32+
33+
await tester.pumpAndSettle();
34+
35+
expect(findByBorderColor(Colors.blue), findsOneWidget);
36+
});
37+
38+
testWidgets('FilterChip displays the green colored border when pressed', (WidgetTester tester) async {
39+
await tester.pumpWidget(
40+
const example.WidgetStateBorderSideExampleApp(),
41+
);
42+
43+
// Press on the FilterChip.
44+
final TestGesture gesture = await tester.createGesture();
45+
await gesture.down(tester.getCenter(find.byType(FilterChip)));
46+
47+
await tester.pumpAndSettle();
48+
49+
expect(findByBorderColor(Colors.green), findsOneWidget);
50+
});
51+
52+
testWidgets('FilterChip displays the red colored border when selected', (WidgetTester tester) async {
53+
await tester.pumpWidget(
54+
const example.WidgetStateBorderSideExampleApp(),
55+
);
56+
57+
expect(findByBorderColor(Colors.red), findsOneWidget);
58+
});
59+
60+
testWidgets('FilterChip displays the correct border color when not selected', (WidgetTester tester) async {
61+
await tester.pumpWidget(
62+
const example.WidgetStateBorderSideExampleApp(),
63+
);
64+
65+
await tester.tap(find.byType(FilterChip));
66+
await tester.pumpAndSettle();
67+
68+
final ThemeData theme = Theme.of(tester.element(find.byType(FilterChip)));
69+
70+
// FilterChip's border color defaults to ColorScheme.outlineVariant.
71+
expect(
72+
findByBorderColor(theme.colorScheme.outlineVariant),
73+
findsOneWidget,
74+
);
75+
});
76+
}

packages/flutter/lib/src/widgets/widget_state.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,13 @@ class _EnabledAndDisabledMouseCursor extends WidgetStateMouseCursor {
480480
/// property values. [WidgetStateBorderSide] should only be used with widgets that document
481481
/// their support, like [ActionChip.side].
482482
///
483+
/// {@tool dartpad}
484+
/// This example defines a [WidgetStateBorderSide] which resolves to different
485+
/// border colors depending on how the user interacts with it.
486+
///
487+
/// ** See code in examples/api/lib/widgets/widget_state/widget_state_border_side.0.dart **
488+
/// {@end-tool}
489+
///
483490
/// This class should only be used for parameters which are documented to take
484491
/// [WidgetStateBorderSide], otherwise only the default state will be used.
485492
///

0 commit comments

Comments
 (0)