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