WidgetStateInputBorder class abstract interface

Defines an InputBorder that is also a WidgetStateProperty.

This class exists to enable widgets with InputBorder valued properties to also accept WidgetStateProperty objects.

WidgetStateInputBorder should only be used with widgets that document their support, like InputDecoration.border.

A WidgetStateInputBorder can be created by:

  1. Creating a class that extends OutlineInputBorder or UnderlineInputBorder and implements WidgetStateInputBorder. The class would also need to override the resolve method.
  2. Using WidgetStateInputBorder.resolveWith with a callback that resolves the input border in the given states.
  3. Using WidgetStateInputBorder.fromMap to assign a border with a WidgetStateMap.

This example shows how to use WidgetStateInputBorder to create a TextField with an appearance that responds to user interaction.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [WidgetStateInputBorder].

void main() => runApp(const WidgetStateInputBorderExampleApp());

/// This extension isn't necessary when WidgetState properties are
/// configured using [WidgetStateMapper] objects.
///
/// But sometimes it makes sense to use a resolveWith() callback,
/// and these getters make those callbacks a bit more readable!
extension WidgetStateHelpers on Set<WidgetState> {
  bool get focused => contains(WidgetState.focused);
  bool get hovered => contains(WidgetState.hovered);
  bool get disabled => contains(WidgetState.disabled);
}

class WidgetStateInputBorderExampleApp extends StatelessWidget {
  const WidgetStateInputBorderExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('WidgetStateInputBorder Example')),
        body: const Center(child: PageContent()),
      ),
    );
  }
}

class PageContent extends StatefulWidget {
  const PageContent({super.key});

  @override
  State<PageContent> createState() => _PageContentState();
}

class _PageContentState extends State<PageContent> {
  bool enabled = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: .min,
      children: <Widget>[
        const Spacer(flex: 8),
        Focus(child: WidgetStateInputBorderExample(enabled: enabled)),
        const Spacer(),
        FilterChip(
          label: const Text('enable text field'),
          selected: enabled,
          onSelected: (bool selected) {
            setState(() {
              enabled = selected;
            });
          },
        ),
        const Spacer(flex: 8),
      ],
    );
  }
}

class WidgetStateInputBorderExample extends StatelessWidget {
  const WidgetStateInputBorderExample({super.key, required this.enabled});

  final bool enabled;

  /// A global or static function can be referenced in a `const` constructor,
  /// such as [WidgetStateInputBorder.resolveWith].
  ///
  /// Constant values can be useful for promoting accurate equality checks,
  /// such as when rebuilding a [Theme] widget.
  static UnderlineInputBorder veryCoolBorder(Set<WidgetState> states) {
    if (states.disabled) {
      return const UnderlineInputBorder(
        borderSide: BorderSide(color: Colors.grey),
      );
    }

    const Color dullViolet = Color(0xFF502080);

    return UnderlineInputBorder(
      borderSide: BorderSide(
        width: states.hovered ? 6 : (states.focused ? 3 : 1.5),
        color: states.focused ? Colors.deepPurpleAccent : dullViolet,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final InputDecoration decoration = InputDecoration(
      border: const WidgetStateInputBorder.resolveWith(veryCoolBorder),
      labelText: enabled
          ? 'Type something awesome…'
          : '(click below to enable)',
    );

    return AnimatedFractionallySizedBox(
      duration: Durations.medium1,
      curve: Curves.ease,
      widthFactor: Focus.of(context).hasFocus ? 0.9 : 0.6,
      child: TextField(decoration: decoration, enabled: enabled),
    );
  }
}
Implemented types

Properties

borderSide BorderSide
Defines the border line's color and weight.
finalinherited
dimensions EdgeInsetsGeometry
The widths of the sides of this border represented as an EdgeInsets.
no setterinherited
hashCode int
The hash code for this object.
no setterinherited
isOutline bool
True if this border will enclose the InputDecorator's container.
no setterinherited
preferPaintInterior bool
Reports whether paintInterior is implemented.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

add(ShapeBorder other, {bool reversed = false}) ShapeBorder?
Attempts to create a new object that represents the amalgamation of this border and the other border.
inherited
copyWith({BorderSide? borderSide}) InputBorder
Creates a copy of this input border with the specified borderSide.
inherited
getInnerPath(Rect rect, {TextDirection? textDirection}) Path
Create a Path that describes the inner edge of the border.
inherited
getOuterPath(Rect rect, {TextDirection? textDirection}) Path
Create a Path that describes the outer edge of the border.
inherited
lerpFrom(ShapeBorder? a, double t) ShapeBorder?
Linearly interpolates from another ShapeBorder (possibly of another class) to this.
inherited
lerpTo(ShapeBorder? b, double t) ShapeBorder?
Linearly interpolates from this to another ShapeBorder (possibly of another class).
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
paint(Canvas canvas, Rect rect, {double? gapStart, double gapExtent = 0.0, double gapPercentage = 0.0, TextDirection? textDirection}) → void
Paint this input border on canvas.
inherited
paintInterior(Canvas canvas, Rect rect, Paint paint, {TextDirection? textDirection}) → void
Paint a canvas with the appropriate shape.
inherited
resolve(Set<MaterialState> states) InputBorder
Returns a value of type T that depends on states.
inherited
scale(double t) ShapeBorder
Creates a copy of this border, scaled by the factor t.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator +(ShapeBorder other) ShapeBorder
Creates a new border consisting of the two borders on either side of the operator.
inherited
operator ==(Object other) bool
The equality operator.
inherited