Fix WidgetStateProperty documentation (#154298)

Changes:
- Remove 2<sup>nd</sup> person language from docs ([relevant style guideline](https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md#use-the-passive-voice-recommend-do-not-require-never-say-things-are-simple))
- Update a bunch of spots to be more explicit about `WidgetStateMouseCursor`.
- `WidgetStateFoo` constructors now accurately describe what happens when used incorrectly.
- Gave `WidgetStateProperty` a little section about equality checks.
This commit is contained in:
Nate Wilson 2024-11-04 15:35:13 -07:00 committed by GitHub
parent 97a4db9396
commit 43bd9482d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 74 additions and 109 deletions

View File

@ -377,18 +377,12 @@ class BottomNavigationBar extends StatefulWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// items.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.selected].
/// If [mouseCursor] is a [WidgetStateMouseCursor], its `resolve` method
/// can define the appearance of the cursor depending on whether
/// [WidgetState.selected] is active.
///
/// If null, then the value of [BottomNavigationBarThemeData.mouseCursor] is used. If
/// that is also null, then [WidgetStateMouseCursor.clickable] is used.
///
/// See also:
///
/// * [WidgetStateMouseCursor], which can be used to create a [MouseCursor]
/// that is also a [WidgetStateProperty<MouseCursor>].
final MouseCursor? mouseCursor;
/// Whether detected gestures should provide acoustic and/or haptic feedback.

View File

@ -115,7 +115,7 @@ class RawMaterialButton extends StatefulWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// button.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.pressed].

View File

@ -197,12 +197,6 @@ class Checkbox extends StatefulWidget {
///
/// If null, then the value of [CheckboxThemeData.mouseCursor] is used. If
/// that is also null, then [WidgetStateMouseCursor.clickable] is used.
///
/// See also:
///
/// * [WidgetStateMouseCursor], a [MouseCursor] that implements
/// [WidgetStateProperty] which is used in APIs that need to accept
/// either a [MouseCursor] or a [WidgetStateProperty].
final MouseCursor? mouseCursor;
/// The color to use when this checkbox is checked.

View File

@ -291,7 +291,7 @@ class CheckboxListTile extends StatelessWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.selected].

View File

@ -403,7 +403,7 @@ class InkResponse extends StatelessWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.hovered].

View File

@ -621,7 +621,7 @@ class ListTile extends StatelessWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.selected].
@ -630,11 +630,6 @@ class ListTile extends StatelessWidget {
///
/// If null, then the value of [ListTileThemeData.mouseCursor] is used. If
/// that is also null, then [WidgetStateMouseCursor.clickable] is used.
///
/// See also:
///
/// * [WidgetStateMouseCursor], which can be used to create a [MouseCursor]
/// that is also a [WidgetStateProperty<MouseCursor>].
final MouseCursor? mouseCursor;
/// If this tile is also [enabled] then icons and text are rendered with the same color.

View File

@ -289,7 +289,7 @@ class PopupMenuItem<T> extends PopupMenuEntry<T> {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.hovered].

View File

@ -183,7 +183,7 @@ class Radio<T> extends StatefulWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.selected].
@ -194,12 +194,6 @@ class Radio<T> extends StatefulWidget {
///
/// If null, then the value of [RadioThemeData.mouseCursor] is used.
/// If that is also null, then [WidgetStateMouseCursor.clickable] is used.
///
/// See also:
///
/// * [WidgetStateMouseCursor], a [MouseCursor] that implements
/// `WidgetStateProperty` which is used in APIs that need to accept
/// either a [MouseCursor] or a [WidgetStateProperty<MouseCursor>].
final MouseCursor? mouseCursor;
/// Set to true if this radio button is allowed to be returned to an

View File

@ -288,7 +288,7 @@ class RadioListTile<T> extends StatelessWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.selected].

View File

@ -486,7 +486,7 @@ class Slider extends StatefulWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.dragged].
@ -497,11 +497,6 @@ class Slider extends StatefulWidget {
///
/// If null, then the value of [SliderThemeData.mouseCursor] is used. If that
/// is also null, then [WidgetStateMouseCursor.clickable] is used.
///
/// See also:
///
/// * [WidgetStateMouseCursor], which can be used to create a [MouseCursor]
/// that is also a [WidgetStateProperty<MouseCursor>].
final MouseCursor? mouseCursor;
/// The callback used to create a semantic value from a slider value.

View File

@ -485,7 +485,7 @@ class Switch extends StatelessWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.selected].
@ -496,12 +496,6 @@ class Switch extends StatelessWidget {
///
/// If null, then the value of [SwitchThemeData.mouseCursor] is used. If that
/// is also null, then [WidgetStateMouseCursor.clickable] is used.
///
/// See also:
///
/// * [WidgetStateMouseCursor], a [MouseCursor] that implements
/// `WidgetStateProperty` which is used in APIs that need to accept
/// either a [MouseCursor] or a [WidgetStateProperty<MouseCursor>].
final MouseCursor? mouseCursor;
/// The color for the button's [Material] when it has the input focus.

View File

@ -401,7 +401,7 @@ class SwitchListTile extends StatelessWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.selected].

View File

@ -1192,7 +1192,7 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// individual tab widgets.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.selected].
@ -1200,11 +1200,6 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
///
/// If null, then the value of [TabBarThemeData.mouseCursor] is used. If
/// that is also null, then [WidgetStateMouseCursor.clickable] is used.
///
/// See also:
///
/// * [WidgetStateMouseCursor], which can be used to create a [MouseCursor]
/// that is also a [WidgetStateProperty<MouseCursor>].
final MouseCursor? mouseCursor;
/// Whether detected gestures should provide acoustic and/or haptic feedback.

View File

@ -714,7 +714,7 @@ class TextField extends StatefulWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If [mouseCursor] is a [WidgetStateProperty<MouseCursor>],
/// If [mouseCursor] is a [WidgetStateMouseCursor],
/// [WidgetStateProperty.resolve] is used for the following [WidgetState]s:
///
/// * [WidgetState.error].

View File

@ -154,7 +154,7 @@ class _AnyWidgetStates implements WidgetStatesConstraint {
/// Interactive states that some of the widgets can take on when receiving input
/// from the user.
///
/// States are defined by https://material.io/design/interaction/states.html#usage,
/// States are defined by https://m3.material.io/foundations/interaction/states,
/// but are not limited to the Material design system or library.
///
/// Some widgets track their current state in a `Set<WidgetState>`.
@ -260,21 +260,12 @@ typedef WidgetPropertyResolver<T> = T Function(Set<WidgetState> states);
/// [WidgetStateColor] should only be used with widgets that document
/// their support, like [TimePickerThemeData.dayPeriodColor].
///
/// To use a [WidgetStateColor], you can either:
/// A [WidgetStateColor] can be created in one of the following ways:
/// 1. Create a subclass of [WidgetStateColor] and implement the abstract `resolve` method.
/// 2. Use [WidgetStateColor.resolveWith] and pass in a callback that
/// will be used to resolve the color in the given states.
/// 3. Use [WidgetStateColor.fromMap] to assign a value using a [WidgetStateMap].
///
/// If a [WidgetStateColor] is used for a property or a parameter that doesn't
/// support resolving [WidgetStateProperty<Color>]s, then its default color
/// value will be used for all states.
///
/// To define a `const` [WidgetStateColor], you'll need to extend
/// [WidgetStateColor] and override its [resolve] method. You'll also need
/// to provide a `defaultValue` to the super constructor, so that we can know
/// at compile-time what its default color is.
///
/// {@tool snippet}
///
/// This example defines a [WidgetStateColor] with a const constructor.
@ -318,9 +309,8 @@ abstract class WidgetStateColor extends Color implements WidgetStateProperty<Col
/// Creates a [WidgetStateColor] from a [WidgetStateMap<Color>].
///
/// {@macro flutter.widgets.WidgetStateProperty.fromMap}
///
/// If used as a regular color, the first key that matches an empty
/// [Set] of [WidgetState]s will be selected.
/// It should only be used with widgets that document support for
/// [WidgetStateColor] (throws an error if used as a normal [Color]).
///
/// {@macro flutter.widgets.WidgetState.any}
const factory WidgetStateColor.fromMap(WidgetStateMap<Color> map) = _WidgetStateColorMapper;
@ -352,7 +342,6 @@ class _WidgetStateColorTransparent extends WidgetStateColor {
Color resolve(Set<WidgetState> states) => const Color(0x00000000);
}
@immutable
class _WidgetStateColorMapper extends WidgetStateMapper<Color> implements WidgetStateColor {
const _WidgetStateColorMapper(super.map);
}
@ -368,8 +357,15 @@ class _WidgetStateColorMapper extends WidgetStateMapper<Color> implements Widget
/// is a [WidgetStateMouseCursor.clickable], which resolves to
/// [SystemMouseCursors.basic] when the button is disabled.
///
/// To use a [WidgetStateMouseCursor], you should create a subclass of
/// [WidgetStateMouseCursor] and implement the abstract `resolve` method.
/// This class should only be used for parameters that document their support
/// for [WidgetStateMouseCursor].
///
/// A [WidgetStateMouseCursor] can be created in one of the following ways:
/// 1. Create a subclass of [WidgetStateMouseCursor] and implement
/// the abstract `resolve` method.
/// 2. Use [WidgetStateMouseCursor.resolveWith] and pass in a callback that
/// will be used to resolve the color in the given states.
/// 3. Use [WidgetStateMouseCursor.fromMap] to assign a value using a [WidgetStateMap].
///
/// {@tool dartpad}
/// This example defines a mouse cursor that resolves to
@ -378,9 +374,6 @@ class _WidgetStateColorMapper extends WidgetStateMapper<Color> implements Widget
/// ** See code in examples/api/lib/widgets/widget_state/widget_state_mouse_cursor.0.dart **
/// {@end-tool}
///
/// This class should only be used for parameters which are documented to take
/// [WidgetStateMouseCursor], otherwise only the default state will be used.
///
/// See also:
///
/// * [MaterialStateMouseCursor], the Material specific version of
@ -409,7 +402,8 @@ abstract class WidgetStateMouseCursor extends MouseCursor implements WidgetState
///
/// {@macro flutter.widgets.WidgetStateProperty.fromMap}
/// It should only be used with classes that document support for
/// [WidgetStateMouseCursor], such as [ButtonStyle.mouseCursor].
/// [WidgetStateMouseCursor] (throws an error if used as a regular
/// [MouseCursor].)
const factory WidgetStateMouseCursor.fromMap(
WidgetStateMap<MouseCursor> map,
) = _WidgetMouseCursorMapper;
@ -482,13 +476,16 @@ class _WidgetMouseCursorMapper extends WidgetStateMapper<MouseCursor> implements
/// Defines a [BorderSide] whose value depends on a set of [WidgetState]s
/// which represent the interactive state of a component.
///
/// To use a [WidgetStateBorderSide], you should create a subclass of a
/// [WidgetStateBorderSide] and override the abstract `resolve` method.
///
/// This class enables existing widget implementations with [BorderSide]
/// properties to be extended to also effectively support `WidgetStateProperty<BorderSide>`
/// property values. [WidgetStateBorderSide] should only be used with widgets that document
/// their support, like [ActionChip.side].
/// property values. It should only be used for parameters that document support
/// for [WidgetStateBorderSide] objects.
///
/// A [WidgetStateBorderSide] can be created in one of the following ways:
/// 1. Create a subclass of [WidgetStateBorderSide] and implement the abstract `resolve` method.
/// 2. Use [WidgetStateBorderSide.resolveWith] and pass in a callback that
/// will be used to resolve the color in the given states.
/// 3. Use [WidgetStateBorderSide.fromMap] to assign a value using a [WidgetStateMap].
///
/// {@tool dartpad}
/// This example defines a [WidgetStateBorderSide] which resolves to different
@ -497,9 +494,6 @@ class _WidgetMouseCursorMapper extends WidgetStateMapper<MouseCursor> implements
/// ** See code in examples/api/lib/widgets/widget_state/widget_state_border_side.0.dart **
/// {@end-tool}
///
/// This class should only be used for parameters which are documented to take
/// [WidgetStateBorderSide], otherwise only the default state will be used.
///
/// See also:
///
/// * [MaterialStateBorderSide], the Material specific version of
@ -512,8 +506,8 @@ abstract class WidgetStateBorderSide extends BorderSide implements WidgetStatePr
/// Creates a [WidgetStateBorderSide] from a
/// [WidgetPropertyResolver<BorderSide?>] callback function.
///
/// If used as a regular [BorderSide], the border resolved in the default state
/// (the empty set of states) will be used.
/// If used as a regular [BorderSide], its behavior matches an empty
/// `BorderSide()` constructor.
///
/// Usage:
///
@ -551,9 +545,9 @@ abstract class WidgetStateBorderSide extends BorderSide implements WidgetStatePr
/// Creates a [WidgetStateBorderSide] from a [WidgetStateMap].
///
/// {@macro flutter.widgets.WidgetStateProperty.fromMap}
///
/// If used as a regular [BorderSide], the first key that matches an empty
/// [Set] of [WidgetState]s will be selected.
/// It should only be used with widgets that document support for
/// [WidgetStateBorderSide] objects (throws an error if used as a
/// regular [BorderSide].)
///
/// Example:
///
@ -630,9 +624,11 @@ class _WidgetBorderSideMapper extends WidgetStateMapper<BorderSide?> implements
/// Defines an [OutlinedBorder] whose value depends on a set of [WidgetState]s
/// which represent the interactive state of a component.
///
/// To use a [WidgetStateOutlinedBorder], you should create a subclass of an
/// [OutlinedBorder] and implement [WidgetStateOutlinedBorder]'s abstract
/// `resolve` method.
/// A [WidgetStateOutlinedBorder] can be created in one of the following ways:
/// 1. Create a subclass of [WidgetStateOutlinedBorder] and implement the abstract `resolve` method.
/// 2. Use [WidgetStateOutlinedBorder.resolveWith] and pass in a callback that
/// will be used to resolve the color in the given states.
/// 3. Use [WidgetStateOutlinedBorder.fromMap] to assign a value using a [WidgetStateMap].
///
/// {@tool dartpad}
/// This example defines a subclass of [RoundedRectangleBorder] and an
@ -672,7 +668,9 @@ abstract class WidgetStateOutlinedBorder extends OutlinedBorder implements Widge
/// It should only be used with widgets that support
/// [WidgetStateOutlinedBorder], such as [ChipThemeData.shape]
/// (throws an error if used as a regular [OutlinedBorder]).
/// {@macro flutter.widgets.WidgetState.any}
///
/// Resolves to `null` if no keys match, deferring to the default value
/// of the widget or theme.
const factory WidgetStateOutlinedBorder.fromMap(
WidgetStateMap<OutlinedBorder?> map,
) = _WidgetOutlinedBorderMapper;
@ -709,18 +707,12 @@ class _WidgetOutlinedBorderMapper extends WidgetStateMapper<OutlinedBorder?> imp
/// [WidgetStateTextStyle] should only be used with widgets that document
/// their support, like [InputDecoration.labelStyle].
///
/// To use a [WidgetStateTextStyle], you can either:
/// A [WidgetStateTextStyle] can be created in one of the following ways:
/// 1. Create a subclass of [WidgetStateTextStyle] and implement the abstract `resolve` method.
/// 2. Use [WidgetStateTextStyle.resolveWith] and pass in a callback that
/// will be used to resolve the text style in the given states.
/// 3. Use [WidgetStateTextStyle.fromMap] to assign a style using a [WidgetStateMap].
///
/// If a [WidgetStateTextStyle] is used for a property or a parameter that doesn't
/// support resolving [WidgetStateProperty<TextStyle>]s, then its default text style
/// value will be used for all states.
///
/// To define a `const` [WidgetStateTextStyle], you'll need to extend
/// [WidgetStateTextStyle] and override its [resolve] method.
/// See also:
///
/// * [MaterialStateTextStyle], the Material specific version of
@ -733,8 +725,8 @@ abstract class WidgetStateTextStyle extends TextStyle implements WidgetStateProp
/// Creates a [WidgetStateTextStyle] from a [WidgetPropertyResolver<TextStyle>]
/// callback function.
///
/// If used as a regular text style, the style resolved in the default state (the
/// empty set of states) will be used.
/// Behaves like an empty `TextStyle()` constructor if used as a
/// regular [TextStyle].
///
/// The given callback parameter must return a non-null text style in the default
/// state.
@ -743,9 +735,9 @@ abstract class WidgetStateTextStyle extends TextStyle implements WidgetStateProp
/// Creates a [WidgetStateTextStyle] from a [WidgetStateMap].
///
/// {@macro flutter.widgets.WidgetStateProperty.fromMap}
///
/// If used as a regular text style, the first key that matches an empty
/// [Set] of [WidgetState]s will be selected.
/// It should only be used with widgets that document support for
/// [WidgetStateTextStyle] objects (throws an error if used as a regular
/// [TextStyle]).
///
/// {@macro flutter.widgets.WidgetState.any}
const factory WidgetStateTextStyle.fromMap(WidgetStateMap<TextStyle> map) = _WidgetTextStyleMapper;
@ -791,12 +783,24 @@ class _WidgetTextStyleMapper extends WidgetStateMapper<TextStyle> implements Wid
/// This example shows how the default text and icon color
/// (the "foreground color") of a [TextButton] can be overridden with a
/// [WidgetStateProperty]. In this example, the button's text color will be
/// `Colors.blue` when the button is being pressed, hovered, or focused.
/// Otherwise, the text color will be `Colors.red`.
/// colored differently depending on whether the button is pressed, hovered,
/// or focused.
///
/// ** See code in examples/api/lib/widgets/widget_state/widget_state_property.0.dart **
/// {@end-tool}
///
/// ## Performance Consideration
///
/// In order for constructed [WidgetStateProperty] objects to be recognized as
/// equivalent, they need to either be `const` objects, or have overrides for
/// [operator==] and [hashCode].
///
/// This comes into play when, for instance, two [ThemeData] objects are being
/// compared for equality.
///
/// For a concrete `WidgetStateProperty` object that supports stable
/// equality checks, consider using [WidgetStateMapper].
///
/// See also:
///
/// * [MaterialStateProperty], the Material specific version of
@ -816,9 +820,8 @@ abstract class WidgetStateProperty<T> {
/// key is satisfied by the set of states, and returns its associated value.
/// {@endtemplate}
///
/// Returns `null` if no keys match, or if [T] is non-nullable,
/// Resolves to `null` if no keys match, or if [T] is non-nullable,
/// the method throws an [ArgumentError].
///
/// {@macro flutter.widgets.WidgetState.any}
///
/// {@macro flutter.widgets.WidgetStateMap}
@ -845,7 +848,8 @@ abstract class WidgetStateProperty<T> {
/// Convenience method for creating a [WidgetStateProperty] that resolves
/// to a single value for all states.
///
/// If you need a const value, use [WidgetStatePropertyAll] directly.
/// Prefer using [WidgetStatePropertyAll] directly, which allows for creating
/// `const` values.
///
// TODO(darrenaustin): Deprecate this when we have the ability to create
// a dart fix that will replace this with WidgetStatePropertyAll: