Open laterdayi opened 8 months ago
Hi @laterdayi,
Interesting find 👍🏻 Yes indeed if I make a larger padding, like this:
final ThemeData lightTheme = FlexThemeData.light(
scheme: FlexScheme.indigoM3,
subThemesData: const FlexSubThemesData(
useM2StyleDividerInM3: true,
inputDecoratorRadius: 12.0,
popupMenuRadius: 10.0,
menuRadius: 12.0,
menuPadding: EdgeInsetsDirectional.fromSTEB(10, 20, 10, 16),
menuIndicatorRadius: 8.0,
),
keyColors: const FlexKeyColors(),
tones: FlexTones.chroma(Brightness.light),
useMaterial3: true,
);
and this
final InputDecorationTheme inputDecorationThemeLight =
lightTheme.inputDecorationTheme.copyWith(
isDense: false,
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 30),
);
and in MaterialApp
set light theme to:
theme: lightTheme.copyWith(
inputDecorationTheme: inputDecorationThemeLight,
),
Then if I use:
final InputDecorationTheme inputDecorationThemeLight =
lightTheme.inputDecorationTheme.copyWith(
isDense: true,
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 30),
);
or
final InputDecorationTheme inputDecorationThemeLight =
lightTheme.inputDecorationTheme.copyWith(
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 30),
);
The result is identical.
However, you are right if I use:
final InputDecorationTheme inputDecorationThemeLight =
lightTheme.inputDecorationTheme.copyWith(
isDense: true,
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
);
I get this:
But if I use:
final InputDecorationTheme inputDecorationThemeLight =
lightTheme.inputDecorationTheme.copyWith(
isDense: false,
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
);
or
final InputDecorationTheme inputDecorationThemeLight =
lightTheme.inputDecorationTheme.copyWith(
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
);
The result is this:
It appears the contentPadding
will grow but not shrink beyond a certain limit, if isDense
is not set to true.
Let's check the docs:
/// Whether the input decorator's child is part of a dense form (i.e., uses
/// less vertical space).
///
/// Defaults to false.
final bool isDense;
/// The padding for the input decoration's container.
///
/// The decoration's container is the area which is filled if
/// [InputDecoration.filled] is true and bordered per the [border].
/// It's the area adjacent to [InputDecoration.icon] and above the
/// [InputDecoration.icon] and above the widgets that contain
/// [InputDecoration.helperText], [InputDecoration.errorText], and
/// [InputDecoration.counterText].
///
/// By default the [contentPadding] reflects [isDense] and the type of the
/// [border]. If [isCollapsed] is true then [contentPadding] is
/// [EdgeInsets.zero].
final EdgeInsetsGeometry? contentPadding;
No clue there why this is so. Let's check the relevant Flutter code:
// The _Decoration widget and _RenderDecoration assume that contentPadding
// has been resolved to EdgeInsets.
final TextDirection textDirection = Directionality.of(context);
final EdgeInsets? decorationContentPadding = decoration.contentPadding?.resolve(textDirection);
final EdgeInsets contentPadding;
final double floatingLabelHeight;
if (decoration.isCollapsed) {
floatingLabelHeight = 0.0;
contentPadding = decorationContentPadding ?? EdgeInsets.zero;
} else if (!border.isOutline) {
// 4.0: the vertical gap between the inline elements and the floating label.
floatingLabelHeight = (4.0 + 0.75 * labelStyle.fontSize!) * MediaQuery.textScaleFactorOf(context);
if (decoration.filled ?? false) {
contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0)
: const EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0));
} else {
// Not left or right padding for underline borders that aren't filled
// is a small concession to backwards compatibility. This eliminates
// the most noticeable layout change introduced by #13734.
contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0)
: const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 12.0));
}
} else {
floatingLabelHeight = 0.0;
contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 20.0, 12.0, 12.0)
: const EdgeInsets.fromLTRB(12.0, 24.0, 12.0, 16.0));
}
Gotta say it looks like it with the outline border, it should be hitting that last else, that is what I originally thought and thus we should get whatever content padding value is defined as padding, regardless of the isDense
setting, BUT we do not, it does not shrink as much as it is set to.
However, if you do something like this:
final InputDecorationTheme inputDecorationThemeLight =
lightTheme.inputDecorationTheme.copyWith(
isDense: false,
constraints: BoxConstraints.tight(const Size(double.infinity, 20)),
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 0),
);
The isDense
won't matter, and you get this:
You can make it super slim, so slim it becomes useless. With content padding only you cannot do that, so you cannot shoot yourself in the foot with it.
Of course none of these things are related to FlexColorScheme, this is just vanilla Flutter SDK behavior with these properties, but certainly an interesting find. From FCS point of view, it does whatever the props in Flutter do, even if they area bit odd 😄
Later I might dig into why it actually behaves like this by debugging it further. It could be some default min constraints, but at quick glance I did not find where it would set that to be tighter when using isDense
true, but it might be in there somewhere, or it might be something else.
EDIT:
I will add this find to the property docs in FlexColorScheme for version 7.4.0 though, as it is useful info that the Flutter docs do not mention anywhere.
I am also confused about this part, it is not clear why flutter is designed this way, if only set the constraints: BoxConstraints.tight(const Size(double-infinity, 60)) without setting the contentPadding then the input box will be very small and the cursor will be very short
While this is technically not a FlexColorScheme issue, I'm keeping this issue open to remind myself to dig a bit deeper into why this works the way it does. Maybe it is as intended in Flutter too, maybe not. If not, I might open an issue about it in Flutter SDK. I already updated the doc for the properties in FCS docs for next version a bit.
Good find! 👍🏻 😄
When set to CustomTextFormFieldSize. Small, contentPadding cannot change, you must specify isDense will only take effect, when CustomTextFormFieldSize. Large when it is normal