Unverified Commit 677f218e authored by Hans Muller's avatar Hans Muller Committed by GitHub

Added InputDecorationTheme (#14177)

parent 38ce59f0
...@@ -28,6 +28,13 @@ import 'package:flutter/widgets.dart'; ...@@ -28,6 +28,13 @@ import 'package:flutter/widgets.dart';
/// rounded rectangle around the input decorator's container. /// rounded rectangle around the input decorator's container.
/// * [InputDecoration], which is used to configure an [InputDecorator]. /// * [InputDecoration], which is used to configure an [InputDecorator].
abstract class InputBorder extends ShapeBorder { abstract class InputBorder extends ShapeBorder {
/// No input border.
///
/// Use this value with [InputDecoration.border] to specify that no border
/// should be drawn. The [InputDecoration.collapsed] constructor sets
/// its border to this value.
static const InputBorder none = const _NoInputBorder();
/// Creates a border for an [InputDecorator]. /// Creates a border for an [InputDecorator].
/// ///
/// The [borderSide] parameter must not be null. Applications typically do /// The [borderSide] parameter must not be null. Applications typically do
...@@ -72,6 +79,43 @@ abstract class InputBorder extends ShapeBorder { ...@@ -72,6 +79,43 @@ abstract class InputBorder extends ShapeBorder {
}); });
} }
// Used to create the InputBorder.none singleton.
class _NoInputBorder extends InputBorder {
const _NoInputBorder() : super(borderSide: BorderSide.none);
@override
_NoInputBorder copyWith({ BorderSide borderSide }) => const _NoInputBorder();
@override
bool get isOutline => false;
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
@override
_NoInputBorder scale(double t) => const _NoInputBorder();
@override
Path getInnerPath(Rect rect, { TextDirection textDirection }) {
return new Path()..addRect(rect);
}
@override
Path getOuterPath(Rect rect, { TextDirection textDirection }) {
return new Path()..addRect(rect);
}
@override
void paint(Canvas canvas, Rect rect, {
double gapStart,
double gapExtent: 0.0,
double gapPercentage: 0.0,
TextDirection textDirection,
}) {
// Do not paint.
}
}
/// Draws a horizontal line at the bottom of an [InputDecorator]'s container. /// Draws a horizontal line at the bottom of an [InputDecorator]'s container.
/// ///
/// The input decorator's "container" is the optionally filled area above the /// The input decorator's "container" is the optionally filled area above the
......
...@@ -296,10 +296,12 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi ...@@ -296,10 +296,12 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
&& widget.decoration.counterText == null; && widget.decoration.counterText == null;
InputDecoration _getEffectiveDecoration() { InputDecoration _getEffectiveDecoration() {
final InputDecoration effectiveDecoration = (widget.decoration ?? const InputDecoration())
.applyDefaults(Theme.of(context).inputDecorationTheme);
if (!needsCounter) if (!needsCounter)
return widget.decoration; return effectiveDecoration;
final InputDecoration effectiveDecoration = widget?.decoration ?? const InputDecoration();
final String counterText = '${_effectiveController.value.text.runes.length} / ${widget.maxLength}'; final String counterText = '${_effectiveController.value.text.runes.length} / ${widget.maxLength}';
if (_effectiveController.value.text.runes.length > widget.maxLength) { if (_effectiveController.value.text.runes.length > widget.maxLength) {
final ThemeData themeData = Theme.of(context); final ThemeData themeData = Theme.of(context);
......
...@@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart'; ...@@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart';
import 'input_decorator.dart'; import 'input_decorator.dart';
import 'text_field.dart'; import 'text_field.dart';
import 'theme.dart';
/// A [FormField] that contains a [TextField]. /// A [FormField] that contains a [TextField].
/// ///
...@@ -71,10 +72,12 @@ class TextFormField extends FormField<String> { ...@@ -71,10 +72,12 @@ class TextFormField extends FormField<String> {
validator: validator, validator: validator,
builder: (FormFieldState<String> field) { builder: (FormFieldState<String> field) {
final _TextFormFieldState state = field; final _TextFormFieldState state = field;
final InputDecoration effectiveDecoration = (decoration ?? const InputDecoration())
.applyDefaults(Theme.of(field.context).inputDecorationTheme);
return new TextField( return new TextField(
controller: state._effectiveController, controller: state._effectiveController,
focusNode: focusNode, focusNode: focusNode,
decoration: decoration.copyWith(errorText: field.errorText), decoration: effectiveDecoration.copyWith(errorText: field.errorText),
keyboardType: keyboardType, keyboardType: keyboardType,
style: style, style: style,
textAlign: textAlign, textAlign: textAlign,
......
...@@ -10,6 +10,7 @@ import 'package:flutter/widgets.dart'; ...@@ -10,6 +10,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart'; import 'colors.dart';
import 'ink_splash.dart'; import 'ink_splash.dart';
import 'ink_well.dart' show InteractiveInkFeatureFactory; import 'ink_well.dart' show InteractiveInkFeatureFactory;
import 'input_decorator.dart';
import 'typography.dart'; import 'typography.dart';
/// Describes the contrast needs of a color. /// Describes the contrast needs of a color.
...@@ -101,6 +102,7 @@ class ThemeData { ...@@ -101,6 +102,7 @@ class ThemeData {
TextTheme textTheme, TextTheme textTheme,
TextTheme primaryTextTheme, TextTheme primaryTextTheme,
TextTheme accentTextTheme, TextTheme accentTextTheme,
InputDecorationTheme inputDecorationTheme,
IconThemeData iconTheme, IconThemeData iconTheme,
IconThemeData primaryIconTheme, IconThemeData primaryIconTheme,
IconThemeData accentIconTheme, IconThemeData accentIconTheme,
...@@ -135,6 +137,7 @@ class ThemeData { ...@@ -135,6 +137,7 @@ class ThemeData {
indicatorColor ??= accentColor == primaryColor ? Colors.white : accentColor; indicatorColor ??= accentColor == primaryColor ? Colors.white : accentColor;
hintColor ??= isDark ? const Color(0x42FFFFFF) : const Color(0x4C000000); hintColor ??= isDark ? const Color(0x42FFFFFF) : const Color(0x4C000000);
errorColor ??= Colors.red[700]; errorColor ??= Colors.red[700];
inputDecorationTheme ??= const InputDecorationTheme();
iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black); iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black); primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
accentIconTheme ??= accentIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black); accentIconTheme ??= accentIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
...@@ -176,6 +179,7 @@ class ThemeData { ...@@ -176,6 +179,7 @@ class ThemeData {
textTheme: textTheme, textTheme: textTheme,
primaryTextTheme: primaryTextTheme, primaryTextTheme: primaryTextTheme,
accentTextTheme: accentTextTheme, accentTextTheme: accentTextTheme,
inputDecorationTheme: inputDecorationTheme,
iconTheme: iconTheme, iconTheme: iconTheme,
primaryIconTheme: primaryIconTheme, primaryIconTheme: primaryIconTheme,
accentIconTheme: accentIconTheme, accentIconTheme: accentIconTheme,
...@@ -217,6 +221,7 @@ class ThemeData { ...@@ -217,6 +221,7 @@ class ThemeData {
@required this.textTheme, @required this.textTheme,
@required this.primaryTextTheme, @required this.primaryTextTheme,
@required this.accentTextTheme, @required this.accentTextTheme,
@required this.inputDecorationTheme,
@required this.iconTheme, @required this.iconTheme,
@required this.primaryIconTheme, @required this.primaryIconTheme,
@required this.accentIconTheme, @required this.accentIconTheme,
...@@ -248,6 +253,7 @@ class ThemeData { ...@@ -248,6 +253,7 @@ class ThemeData {
assert(textTheme != null), assert(textTheme != null),
assert(primaryTextTheme != null), assert(primaryTextTheme != null),
assert(accentTextTheme != null), assert(accentTextTheme != null),
assert(inputDecorationTheme != null),
assert(iconTheme != null), assert(iconTheme != null),
assert(primaryIconTheme != null), assert(primaryIconTheme != null),
assert(accentIconTheme != null), assert(accentIconTheme != null),
...@@ -388,6 +394,12 @@ class ThemeData { ...@@ -388,6 +394,12 @@ class ThemeData {
/// A text theme that contrasts with the accent color. /// A text theme that contrasts with the accent color.
final TextTheme accentTextTheme; final TextTheme accentTextTheme;
/// The default [InputDecoration] values for [InputDecorator], [TextField],
/// and [TextFormField] are based on this theme.
///
/// See [InputDecoration.applyDefaults].
final InputDecorationTheme inputDecorationTheme;
/// An icon theme that contrasts with the card and canvas colors. /// An icon theme that contrasts with the card and canvas colors.
final IconThemeData iconTheme; final IconThemeData iconTheme;
...@@ -431,6 +443,7 @@ class ThemeData { ...@@ -431,6 +443,7 @@ class ThemeData {
TextTheme textTheme, TextTheme textTheme,
TextTheme primaryTextTheme, TextTheme primaryTextTheme,
TextTheme accentTextTheme, TextTheme accentTextTheme,
InputDecorationTheme inputDecorationTheme,
IconThemeData iconTheme, IconThemeData iconTheme,
IconThemeData primaryIconTheme, IconThemeData primaryIconTheme,
IconThemeData accentIconTheme, IconThemeData accentIconTheme,
...@@ -464,6 +477,7 @@ class ThemeData { ...@@ -464,6 +477,7 @@ class ThemeData {
textTheme: textTheme ?? this.textTheme, textTheme: textTheme ?? this.textTheme,
primaryTextTheme: primaryTextTheme ?? this.primaryTextTheme, primaryTextTheme: primaryTextTheme ?? this.primaryTextTheme,
accentTextTheme: accentTextTheme ?? this.accentTextTheme, accentTextTheme: accentTextTheme ?? this.accentTextTheme,
inputDecorationTheme: inputDecorationTheme ?? this.inputDecorationTheme,
iconTheme: iconTheme ?? this.iconTheme, iconTheme: iconTheme ?? this.iconTheme,
primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme, primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme,
accentIconTheme: accentIconTheme ?? this.accentIconTheme, accentIconTheme: accentIconTheme ?? this.accentIconTheme,
...@@ -582,6 +596,7 @@ class ThemeData { ...@@ -582,6 +596,7 @@ class ThemeData {
textTheme: TextTheme.lerp(a.textTheme, b.textTheme, t), textTheme: TextTheme.lerp(a.textTheme, b.textTheme, t),
primaryTextTheme: TextTheme.lerp(a.primaryTextTheme, b.primaryTextTheme, t), primaryTextTheme: TextTheme.lerp(a.primaryTextTheme, b.primaryTextTheme, t),
accentTextTheme: TextTheme.lerp(a.accentTextTheme, b.accentTextTheme, t), accentTextTheme: TextTheme.lerp(a.accentTextTheme, b.accentTextTheme, t),
inputDecorationTheme: t < 0.5 ? a.inputDecorationTheme : b.inputDecorationTheme,
iconTheme: IconThemeData.lerp(a.iconTheme, b.iconTheme, t), iconTheme: IconThemeData.lerp(a.iconTheme, b.iconTheme, t),
primaryIconTheme: IconThemeData.lerp(a.primaryIconTheme, b.primaryIconTheme, t), primaryIconTheme: IconThemeData.lerp(a.primaryIconTheme, b.primaryIconTheme, t),
accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t), accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t),
...@@ -621,6 +636,7 @@ class ThemeData { ...@@ -621,6 +636,7 @@ class ThemeData {
(otherData.textTheme == textTheme) && (otherData.textTheme == textTheme) &&
(otherData.primaryTextTheme == primaryTextTheme) && (otherData.primaryTextTheme == primaryTextTheme) &&
(otherData.accentTextTheme == accentTextTheme) && (otherData.accentTextTheme == accentTextTheme) &&
(otherData.inputDecorationTheme == inputDecorationTheme) &&
(otherData.iconTheme == iconTheme) && (otherData.iconTheme == iconTheme) &&
(otherData.primaryIconTheme == primaryIconTheme) && (otherData.primaryIconTheme == primaryIconTheme) &&
(otherData.accentIconTheme == accentIconTheme) && (otherData.accentIconTheme == accentIconTheme) &&
...@@ -659,6 +675,7 @@ class ThemeData { ...@@ -659,6 +675,7 @@ class ThemeData {
primaryTextTheme, primaryTextTheme,
accentTextTheme, accentTextTheme,
iconTheme, iconTheme,
inputDecorationTheme,
primaryIconTheme, primaryIconTheme,
accentIconTheme, accentIconTheme,
platform, platform,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment