Skip to content

Commit 9d2b6da

Browse files
authored
feat(Tooltip): replace the height parameter with constraints (#163314)
Introduce a new `constraints` parameter, which constrains the size of the tooltip's message and deprecate the now obsolete `height` parameter. Do the same for the theme data, while also making some minor changes to the docs to clear up some misconceptions about which properties apply to the tooltip's message and which to the tooltip's child. To make the transition from `height` to `constraints` as easy as possible for our users, introduce fix data to do this replacement automatically in the IDE. Closes: #163313 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent 51bf72a commit 9d2b6da

File tree

11 files changed

+421
-14
lines changed

11 files changed

+421
-14
lines changed

examples/api/lib/material/tooltip/tooltip.1.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class TooltipSample extends StatelessWidget {
3434
borderRadius: BorderRadius.circular(25),
3535
gradient: const LinearGradient(colors: <Color>[Colors.amber, Colors.red]),
3636
),
37-
height: 50,
37+
constraints: const BoxConstraints(minWidth: 250),
3838
padding: const EdgeInsets.all(8.0),
3939
preferBelow: true,
4040
textStyle: const TextStyle(fontSize: 24),
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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+
# For details regarding the *Flutter Fix* feature, see https://flutter.dev/to/flutter-fix
6+
7+
# Please add new fixes to the top of the file, separated by one blank line
8+
# from other fixes. In a comment, include a link to the PR where the change
9+
# requiring the fix was made.
10+
11+
# Every fix must be tested. See the flutter/packages/flutter/test_fixes/README.md
12+
# file for instructions on testing these data driven fixes.
13+
14+
# For documentation about this file format, see https://dart.dev/go/data-driven-fixes.
15+
16+
# * Fixes in this file are for the Tooltip widget from the Material library. *
17+
18+
version: 1
19+
transforms:
20+
# Changes made in https://github.com/flutter/flutter/pull/163314
21+
- title: "Migrate to 'constraints'"
22+
date: 2025-02-14
23+
element:
24+
uris: ["package:flutter/material.dart"]
25+
constructor: ""
26+
inClass: "Tooltip"
27+
oneOf:
28+
- if: "height == 'null'"
29+
changes:
30+
- kind: "removeParameter"
31+
name: "height"
32+
- if: "constraints == '' && height != ''"
33+
changes:
34+
- kind: "addParameter"
35+
index: 2
36+
name: "constraints"
37+
style: "optional_named"
38+
argumentValue:
39+
expression: "{% BoxConstraints %}(minHeight: {% height %})"
40+
requiredIf: "height != '' && height != 'null'"
41+
- kind: "removeParameter"
42+
name: "height"
43+
- if: "constraints == 'null' && height != ''"
44+
changes:
45+
- kind: "removeParameter"
46+
name: "constraints"
47+
- kind: "addParameter"
48+
index: 2
49+
name: "constraints"
50+
style: "optional_named"
51+
argumentValue:
52+
expression: "{% BoxConstraints %}(minHeight: {% height %})"
53+
requiredIf: "height != '' && height != 'null'"
54+
- kind: "removeParameter"
55+
name: "height"
56+
- if: "constraints != '' && height != ''"
57+
changes:
58+
- kind: "removeParameter"
59+
name: "height"
60+
variables:
61+
constraints:
62+
kind: "fragment"
63+
value: "arguments[constraints]"
64+
height:
65+
kind: "fragment"
66+
value: "arguments[height]"
67+
BoxConstraints:
68+
kind: "import"
69+
uris: ["package:flutter/rendering.dart"]
70+
name: "BoxConstraints"
71+
72+
# Changes made in https://github.com/flutter/flutter/pull/163314
73+
- title: "Migrate to 'constraints'"
74+
date: 2025-02-14
75+
element:
76+
uris: ["package:flutter/material.dart"]
77+
getter: "height"
78+
inClass: "Tooltip"
79+
changes:
80+
- kind: "rename"
81+
newName: "constraints?.minHeight"
82+
83+
# Before adding a new fix: read instructions at the top of this file.
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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+
# For details regarding the *Flutter Fix* feature, see https://flutter.dev/to/flutter-fix
6+
7+
# Please add new fixes to the top of the file, separated by one blank line
8+
# from other fixes. In a comment, include a link to the PR where the change
9+
# requiring the fix was made.
10+
11+
# Every fix must be tested. See the flutter/packages/flutter/test_fixes/README.md
12+
# file for instructions on testing these data driven fixes.
13+
14+
# For documentation about this file format, see https://dart.dev/go/data-driven-fixes.
15+
16+
# * Fixes in this file are for the TooltipThemeData class from the Material library. *
17+
18+
version: 1
19+
transforms:
20+
# Changes made in https://github.com/flutter/flutter/pull/163314
21+
- title: "Migrate to 'constraints'"
22+
date: 2025-02-14
23+
element:
24+
uris: ["package:flutter/material.dart"]
25+
constructor: ""
26+
inClass: "TooltipThemeData"
27+
oneOf:
28+
- if: "height == 'null'"
29+
changes:
30+
- kind: "removeParameter"
31+
name: "height"
32+
- if: "constraints == '' && height != ''"
33+
changes:
34+
- kind: "addParameter"
35+
index: 0
36+
name: "constraints"
37+
style: "optional_named"
38+
argumentValue:
39+
expression: "{% BoxConstraints %}(minHeight: {% height %})"
40+
requiredIf: "height != '' && height != 'null'"
41+
- kind: "removeParameter"
42+
name: "height"
43+
- if: "constraints == 'null' && height != ''"
44+
changes:
45+
- kind: "removeParameter"
46+
name: "constraints"
47+
- kind: "addParameter"
48+
index: 0
49+
name: "constraints"
50+
style: "optional_named"
51+
argumentValue:
52+
expression: "{% BoxConstraints %}(minHeight: {% height %})"
53+
requiredIf: "height != '' && height != 'null'"
54+
- kind: "removeParameter"
55+
name: "height"
56+
- if: "constraints != '' && height != ''"
57+
changes:
58+
- kind: "removeParameter"
59+
name: "height"
60+
variables:
61+
constraints:
62+
kind: "fragment"
63+
value: "arguments[constraints]"
64+
height:
65+
kind: "fragment"
66+
value: "arguments[height]"
67+
BoxConstraints:
68+
kind: "import"
69+
uris: ["package:flutter/rendering.dart"]
70+
name: "BoxConstraints"
71+
72+
# Changes made in https://github.com/flutter/flutter/pull/163314
73+
- title: "Migrate to 'constraints'"
74+
date: 2025-02-14
75+
element:
76+
uris: ["package:flutter/material.dart"]
77+
getter: "height"
78+
inClass: "TooltipThemeData"
79+
changes:
80+
- kind: "rename"
81+
newName: "constraints?.minHeight"
82+
83+
# Changes made in https://github.com/flutter/flutter/pull/163314
84+
- title: "Migrate to 'constraints'"
85+
date: 2025-02-14
86+
element:
87+
uris: ["package:flutter/material.dart"]
88+
method: "copyWith"
89+
inClass: "TooltipThemeData"
90+
oneOf:
91+
- if: "height == 'null'"
92+
changes:
93+
- kind: "removeParameter"
94+
name: "height"
95+
- if: "constraints == '' && height != ''"
96+
changes:
97+
- kind: "addParameter"
98+
index: 0
99+
name: "constraints"
100+
style: "optional_named"
101+
argumentValue:
102+
expression: "{% BoxConstraints %}(minHeight: {% height %})"
103+
requiredIf: "height != '' && height != 'null'"
104+
- kind: "removeParameter"
105+
name: "height"
106+
- if: "constraints == 'null' && height != ''"
107+
changes:
108+
- kind: "removeParameter"
109+
name: "constraints"
110+
- kind: "addParameter"
111+
index: 0
112+
name: "constraints"
113+
style: "optional_named"
114+
argumentValue:
115+
expression: "{% BoxConstraints %}(minHeight: {% height %})"
116+
requiredIf: "height != '' && height != 'null'"
117+
- kind: "removeParameter"
118+
name: "height"
119+
- if: "constraints != '' && height != ''"
120+
changes:
121+
- kind: "removeParameter"
122+
name: "height"
123+
variables:
124+
constraints:
125+
kind: "fragment"
126+
value: "arguments[constraints]"
127+
height:
128+
kind: "fragment"
129+
value: "arguments[height]"
130+
BoxConstraints:
131+
kind: "import"
132+
uris: ["package:flutter/rendering.dart"]
133+
name: "BoxConstraints"
134+
135+
# Before adding a new fix: read instructions at the top of this file.

packages/flutter/lib/src/material/tooltip.dart

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class _RenderExclusiveMouseRegion extends RenderMouseRegion {
118118
/// {@tool dartpad}
119119
/// This example covers most of the attributes available in Tooltip.
120120
/// `decoration` has been used to give a gradient and borderRadius to Tooltip.
121-
/// `height` has been used to set a specific height of the Tooltip.
121+
/// `constraints` has been used to set the minimum width of the Tooltip.
122122
/// `preferBelow` is true; the tooltip will prefer showing below [Tooltip]'s child widget.
123123
/// However, it may show the tooltip above if there's not enough space
124124
/// below the widget.
@@ -169,7 +169,12 @@ class Tooltip extends StatefulWidget {
169169
super.key,
170170
this.message,
171171
this.richMessage,
172+
@Deprecated(
173+
'Use Tooltip.constraints instead. '
174+
'This feature was deprecated after v3.30.0-0.1.pre.',
175+
)
172176
this.height,
177+
this.constraints,
173178
this.padding,
174179
this.margin,
175180
this.verticalOffset,
@@ -191,6 +196,10 @@ class Tooltip extends StatefulWidget {
191196
}) : assert(
192197
(message == null) != (richMessage == null),
193198
'Either `message` or `richMessage` must be specified',
199+
),
200+
assert(
201+
height == null || constraints == null,
202+
'Only one of `height` and `constraints` may be specified.',
194203
);
195204

196205
/// The text to display in the tooltip.
@@ -203,12 +212,22 @@ class Tooltip extends StatefulWidget {
203212
/// Only one of [message] and [richMessage] may be non-null.
204213
final InlineSpan? richMessage;
205214

206-
/// The height of the tooltip's [child].
207-
///
208-
/// If the [child] is null, then this is the tooltip's intrinsic height.
215+
/// The minimum height of the [Tooltip]'s message.
216+
@Deprecated(
217+
'Use Tooltip.constraints instead. '
218+
'This feature was deprecated after v3.30.0-0.1.pre.',
219+
)
209220
final double? height;
210221

211-
/// The amount of space by which to inset the tooltip's [child].
222+
/// Constrains the size of the [Tooltip]'s message.
223+
///
224+
/// If null, then the [TooltipThemeData.constraints] of the ambient [ThemeData.tooltipTheme]
225+
/// will be used. If that is also null, then a default value will be picked based on the current
226+
/// platform. For desktop platforms, the default value is `BoxConstraints(minHeight: 24.0)`,
227+
/// while for mobile platforms the default value is `BoxConstraints(minHeight: 32.0)`.
228+
final BoxConstraints? constraints;
229+
230+
/// The amount of space by which to inset the [Tooltip]'s message.
212231
///
213232
/// On mobile, defaults to 16.0 logical pixels horizontally and 4.0 vertically.
214233
/// On desktop, defaults to 8.0 logical pixels horizontally and 4.0 vertically.
@@ -225,6 +244,10 @@ class Tooltip extends StatefulWidget {
225244
/// If this property is null, then [TooltipThemeData.margin] is used.
226245
/// If [TooltipThemeData.margin] is also null, the default margin is
227246
/// 0.0 logical pixels on all sides.
247+
///
248+
/// See also:
249+
///
250+
/// * [constraints], which allow setting an explicit size for the tooltip.
228251
final EdgeInsetsGeometry? margin;
229252

230253
/// The vertical gap between the widget and the displayed tooltip.
@@ -412,6 +435,9 @@ class Tooltip extends StatefulWidget {
412435
),
413436
);
414437
properties.add(DoubleProperty('height', height, defaultValue: null));
438+
properties.add(
439+
DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null),
440+
);
415441
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
416442
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('margin', margin, defaultValue: null));
417443
properties.add(DoubleProperty('vertical offset', verticalOffset, defaultValue: null));
@@ -837,9 +863,12 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
837863
};
838864

839865
final TooltipThemeData tooltipTheme = _tooltipTheme;
866+
final BoxConstraints defaultConstraints = BoxConstraints(
867+
minHeight: widget.height ?? tooltipTheme.height ?? _getDefaultTooltipHeight(),
868+
);
840869
final _TooltipOverlay overlayChild = _TooltipOverlay(
841870
richMessage: widget.richMessage ?? TextSpan(text: widget.message),
842-
height: widget.height ?? tooltipTheme.height ?? _getDefaultTooltipHeight(),
871+
constraints: widget.constraints ?? tooltipTheme.constraints ?? defaultConstraints,
843872
padding: widget.padding ?? tooltipTheme.padding ?? _getDefaultPadding(),
844873
margin: widget.margin ?? tooltipTheme.margin ?? _defaultMargin,
845874
onEnter: _handleMouseEnter,
@@ -967,8 +996,8 @@ class _TooltipPositionDelegate extends SingleChildLayoutDelegate {
967996

968997
class _TooltipOverlay extends StatelessWidget {
969998
const _TooltipOverlay({
970-
required this.height,
971999
required this.richMessage,
1000+
required this.constraints,
9721001
this.padding,
9731002
this.margin,
9741003
this.decoration,
@@ -984,7 +1013,7 @@ class _TooltipOverlay extends StatelessWidget {
9841013
});
9851014

9861015
final InlineSpan richMessage;
987-
final double height;
1016+
final BoxConstraints constraints;
9881017
final EdgeInsetsGeometry? padding;
9891018
final EdgeInsetsGeometry? margin;
9901019
final Decoration? decoration;
@@ -1003,7 +1032,7 @@ class _TooltipOverlay extends StatelessWidget {
10031032
Widget result = FadeTransition(
10041033
opacity: animation,
10051034
child: ConstrainedBox(
1006-
constraints: BoxConstraints(minHeight: height),
1035+
constraints: constraints,
10071036
child: DefaultTextStyle(
10081037
style: textStyle,
10091038
textAlign: textAlign,

0 commit comments

Comments
 (0)