Skip to content

Added OverflowBar widget #62350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 29, 2020
Merged

Conversation

HansMuller
Copy link
Contributor

@HansMuller HansMuller commented Jul 27, 2020

This widget provides most of the same features as ButtonBar, without being tangled up with the Material ButtonTheme.

DartPad demo of OverflowBar: https://dartpad.dev/4791c69a962dd9da97b7b9748ac2983c

@fluttergithubbot fluttergithubbot added the framework flutter/packages/flutter repository. See also f: labels. label Jul 27, 2020
Copy link
Contributor

@rami-a rami-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

/// color: Colors.white,
/// elevation: 24,
/// shape: RoundedRectangleBorder(
/// borderRadius: BorderRadius.all(Radius.circular(4.0))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Demo code should either consistently use or omit the .0 on doubles

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

/// [OverflowBarAlignment.start], and with the left edge of the
/// available space for [OverflowBarAlignment.end]. For
/// [OverflowBarAlignment.center] each child is horizontally
/// centered with the available space.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// centered with the available space.
/// centered within the available space.

maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

/// of the children within the vertical "overflow" layout.
final VerticalDirection overflowDirection;

/// Determines the order that the [children] appear in for the default
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is null, then it uses the inherited text direction right? Probably worth mentioning that in the documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DoubleProperty('spacing', spacing, defaultValue: 0));
properties.add(DoubleProperty('overflowSpacing', overflowSpacing));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To match the other lines

Suggested change
properties.add(DoubleProperty('overflowSpacing', overflowSpacing));
properties.add(DoubleProperty('overflowSpacing', overflowSpacing, defaultValue: 0));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

child = childAfter(child);
}

final bool rtl = textDirection == TextDirection.rtl;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
final bool rtl = textDirection == TextDirection.rtl;
final bool isRtl = textDirection == TextDirection.rtl;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had it this way originally but I suffer from a personal loathing for logically capitalizing acronyms, so rtl.

} else {
// Default horizontal layout
child = rtl ? lastChild : firstChild;
RenderBox nextChild() => textDirection == TextDirection.rtl ? childBefore(child) : childAfter(child);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RenderBox nextChild() => textDirection == TextDirection.rtl ? childBefore(child) : childAfter(child);
RenderBox nextChild() => rtl ? childBefore(child) : childAfter(child);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

expect(bar.children, const <Widget>[]);
});

testWidgets('EmptyOverflowBar', (WidgetTester tester) async {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit/Suggestion:

Suggested change
testWidgets('EmptyOverflowBar', (WidgetTester tester) async {
testWidgets('Empty OverflowBar', (WidgetTester tester) async {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// Children are vertically centered, start at x=0
await tester.pumpWidget(buildFrame(spacing: 10, textDirection: TextDirection.ltr));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(0, 8, 48, 56));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(10.0 + 48, 0, 10.0 + 112, 64));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Should probably be consistent with keeping/omitting the .0 for doubles.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find that omitting the .0 makes code easier to read however it was necessary to introduce one in these expressions so that they eval to doubles instead of ints. I realize that it's inconsistent but I've tried to be consistent about that.

expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(100.0/2.0 - 48/2, 0, 100.0/2.0 + 48/2, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(100.0/2.0 - 64/2, 48, 100.0/2.0 + 64/2, 112));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(100.0/2.0 - 32/2, 112, 100.0/2.0 + 32/2, 144));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Unnecessary new line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@darrenaustin darrenaustin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! LGTM, just a question about defaults.

/// used instead.
///
/// Defaults to 0.0.
final double spacing;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should make this default match the material spec for button spacing? Or is that assuming too much? It would just be nice to just wrap an array of buttons with an OverflowBar with no params and have it match the old ButtonBar layout by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a dialog you'd also need to end-align the OverflowBar and somewhere you need to ensure that the OverflowBar can be scrolled into view.

Using 0 for the spacing seemed appropriate for the widgets library since it's probably the wrong place to have an opinion about spacing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I missed that it was part of the widgets library 😄. Totally makes sense for it to be there and that the default should be 0.

///
/// This example defines a simple approximation of a dialog
/// layout, where the layout of the dialog's action buttons are
/// defined by an [OverflowBar]. The content is wrapped in a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: double space

/// layout, where the layout of the dialog's action buttons are
/// defined by an [OverflowBar]. The content is wrapped in a
/// [SingleChildScrollView], so that if overflow occurs, the
/// action buttons will be still be accessible by scrolling,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... will be still be ... ?

class OverflowBar extends MultiChildRenderObjectWidget {
/// Constructs an OverflowBar.
///
/// The [spacing], [overflowSpacing], [overflowAlignment],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe children of an MultiChildRenderObjectWidget also cannot be null. Mention that in the docs and add an assert?


@override
double computeMinIntrinsicHeight(double width) {
RenderBox child = firstChild;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this calculation correct? I'd assumed that if width is big enough everything gets layed out in a row and then the hight would not be the sum of the children heights, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are correct, this method is incorrect. The min intrinsic height should be: if the sum of child intrinsic widths fit, then the max child height, otherwise the sum of the child heights.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed this however I still need to add some tests for min/max intrinsic height.

@fluttergithubbot fluttergithubbot merged commit 6139708 into flutter:master Jul 29, 2020
Pragya007 pushed a commit to Pragya007/flutter that referenced this pull request Aug 11, 2020
mingwandroid pushed a commit to mingwandroid/flutter that referenced this pull request Sep 6, 2020
@HansMuller HansMuller deleted the overflow_bar branch June 26, 2021 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants