Unverified Commit bff0ec47 authored by Daniel Edrisian's avatar Daniel Edrisian Committed by GitHub

Add footer to CupertinoFormSection and fix CupertinoFormSection margins. (#72046)

parent 781c9bcb
......@@ -10,7 +10,7 @@ import 'theme.dart';
// Content padding determined via SwiftUI's `Form` view in the iOS 14.2 SDK.
const EdgeInsetsGeometry _kDefaultPadding =
EdgeInsetsDirectional.fromSTEB(16.0, 6.0, 6.0, 6.0);
EdgeInsetsDirectional.fromSTEB(20.0, 6.0, 6.0, 6.0);
/// An iOS-style form row.
///
......@@ -149,22 +149,7 @@ class CupertinoFormRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final CupertinoThemeData themeData = CupertinoTheme.of(context);
final TextStyle textStyle = themeData.textTheme.textStyle;
final List<Widget> rowChildren = <Widget>[
if (prefix != null)
DefaultTextStyle(
style: textStyle,
child: prefix!,
),
Flexible(
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: child,
),
),
];
final TextStyle textStyle = CupertinoTheme.of(context).textTheme.textStyle;
return Padding(
padding: padding ?? _kDefaultPadding,
......@@ -172,7 +157,19 @@ class CupertinoFormRow extends StatelessWidget {
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: rowChildren,
children: <Widget>[
if (prefix != null)
DefaultTextStyle(
style: textStyle,
child: prefix!,
),
Flexible(
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: child,
),
),
],
),
if (helper != null)
Align(
......
......@@ -9,12 +9,16 @@ import 'colors.dart';
// Standard header margin, determined from SwiftUI's Forms in iOS 14.2 SDK.
const EdgeInsetsDirectional _kDefaultHeaderMargin =
EdgeInsetsDirectional.fromSTEB(16.5, 16.0, 16.5, 10.0);
EdgeInsetsDirectional.fromSTEB(20.0, 16.0, 20.0, 10.0);
// Standard footer margin, determined from SwiftUI's Forms in iOS 14.2 SDK.
const EdgeInsetsDirectional _kDefaultFooterMargin =
EdgeInsetsDirectional.fromSTEB(20.0, 0.0, 20.0, 10.0);
// Used for iOS "Inset Grouped" margin, determined from SwiftUI's Forms in
// iOS 14.2 SDK.
const EdgeInsetsDirectional _kDefaultInsetGroupedRowsMargin =
EdgeInsetsDirectional.fromSTEB(16.5, 0.0, 16.5, 16.5);
EdgeInsetsDirectional.fromSTEB(20.0, 0.0, 20.0, 10.0);
// Used for iOS "Inset Grouped" border radius, estimated from SwiftUI's Forms in
// iOS 14.2 SDK.
......@@ -39,6 +43,9 @@ enum _CupertinoFormSectionType { base, insetGrouped }
/// The [header] parameter sets the form section header. The section header lies
/// above the [children] rows, with margins that match the iOS style.
///
/// The [footer] parameter sets the form section footer. The section footer
/// lies below the [children] rows.
///
/// The [children] parameter is required and sets the list of rows shown in
/// the section. The [children] parameter takes a list, as opposed to a more
/// efficient builder function that lazy builds, because forms are intended to
......@@ -69,6 +76,9 @@ class CupertinoFormSection extends StatelessWidget {
/// The [header] parameter sets the form section header. The section header
/// lies above the [children] rows, with margins that match the iOS style.
///
/// The [footer] parameter sets the form section footer. The section footer
/// lies below the [children] rows.
///
/// The [children] parameter is required and sets the list of rows shown in
/// the section. The [children] parameter takes a list, as opposed to a more
/// efficient builder function that lazy builds, because forms are intended to
......@@ -93,6 +103,7 @@ class CupertinoFormSection extends StatelessWidget {
Key? key,
required this.children,
this.header,
this.footer,
this.margin = EdgeInsets.zero,
this.backgroundColor = CupertinoColors.systemGroupedBackground,
this.decoration,
......@@ -111,6 +122,9 @@ class CupertinoFormSection extends StatelessWidget {
/// The [header] parameter sets the form section header. The section header
/// lies above the [children] rows, with margins that match the iOS style.
///
/// The [footer] parameter sets the form section footer. The section footer
/// lies below the [children] rows.
///
/// The [children] parameter is required and sets the list of rows shown in
/// the section. The [children] parameter takes a list, as opposed to a more
/// efficient builder function that lazy builds, because forms are intended to
......@@ -136,6 +150,7 @@ class CupertinoFormSection extends StatelessWidget {
Key? key,
required this.children,
this.header,
this.footer,
this.margin = _kDefaultInsetGroupedRowsMargin,
this.backgroundColor = CupertinoColors.systemGroupedBackground,
this.decoration,
......@@ -150,6 +165,10 @@ class CupertinoFormSection extends StatelessWidget {
/// [children] rows.
final Widget? header;
/// Sets the form section footer. The section footer lies below the
/// [children] rows.
final Widget? footer;
/// Margin around the content area of the section encapsulating [children].
///
/// Defaults to zero padding if constructed with standard
......@@ -228,6 +247,16 @@ class CupertinoFormSection extends StatelessWidget {
childrenWithDividers.add(longDivider);
}
final BorderRadius childrenGroupBorderRadius;
switch (_type) {
case _CupertinoFormSectionType.insetGrouped:
childrenGroupBorderRadius = _kDefaultInsetGroupedBorderRadius;
break;
case _CupertinoFormSectionType.base:
childrenGroupBorderRadius = BorderRadius.zero;
break;
}
// Refactored the decorate children group in one place to avoid repeating it
// twice down bellow in the returned widget.
final DecoratedBox decoratedChildrenGroup = DecoratedBox(
......@@ -237,7 +266,7 @@ class CupertinoFormSection extends StatelessWidget {
decoration?.color ??
CupertinoColors.secondarySystemGroupedBackground,
context),
borderRadius: _kDefaultInsetGroupedBorderRadius,
borderRadius: childrenGroupBorderRadius,
),
child: Column(
children: childrenWithDividers,
......@@ -250,31 +279,43 @@ class CupertinoFormSection extends StatelessWidget {
),
child: Column(
children: <Widget>[
Align(
alignment: AlignmentDirectional.centerStart,
child: header == null
? null
: DefaultTextStyle(
style: TextStyle(
fontSize: 13.5,
color:
CupertinoColors.secondaryLabel.resolveFrom(context),
),
child: Padding(
padding: _kDefaultHeaderMargin,
child: header!,
),
),
),
if (header != null)
Align(
alignment: AlignmentDirectional.centerStart,
child: DefaultTextStyle(
style: TextStyle(
fontSize: 13.0,
color: CupertinoColors.secondaryLabel.resolveFrom(context),
),
child: Padding(
padding: _kDefaultHeaderMargin,
child: header!,
),
),
),
Padding(
padding: margin,
child: clipBehavior == Clip.none
? decoratedChildrenGroup
: ClipRRect(
borderRadius: _kDefaultInsetGroupedBorderRadius,
borderRadius: childrenGroupBorderRadius,
clipBehavior: clipBehavior,
child: decoratedChildrenGroup),
),
if (footer != null)
Align(
alignment: AlignmentDirectional.centerStart,
child: DefaultTextStyle(
style: TextStyle(
fontSize: 13.0,
color: CupertinoColors.secondaryLabel.resolveFrom(context),
),
child: Padding(
padding: _kDefaultFooterMargin,
child: footer!,
),
),
),
],
),
);
......
......@@ -8,20 +8,33 @@ import 'package:flutter/rendering.dart';
void main() {
testWidgets('Shows header', (WidgetTester tester) async {
const Widget header = Text('Enter Value');
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoFormSection(
header: const Text('Header'),
children: <Widget>[CupertinoTextFormFieldRow()],
),
),
),
);
expect(find.text('Header'), findsOneWidget);
});
testWidgets('Shows footer', (WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoFormSection(
header: header,
footer: const Text('Footer'),
children: <Widget>[CupertinoTextFormFieldRow()],
),
),
),
);
expect(header, tester.widget(find.byType(Text)));
expect(find.text('Footer'), findsOneWidget);
});
testWidgets('Shows long dividers in edge-to-edge section part 1',
......
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