Skip to content
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

feat(Dropdown): open to side with most space left #720 #2817

Merged

Conversation

mihai-dinculescu
Copy link
Member

@mihai-dinculescu mihai-dinculescu commented May 21, 2018

#720

I have added a new prop, "keepInViewPort", so dropdown is consistent to Popup. However, this one is false by default, so the current behavior doesn't change.

Please let me know your thoughts.

@codecov-io
Copy link

codecov-io commented May 21, 2018

Codecov Report

Merging #2817 into master will increase coverage by 0.07%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2817      +/-   ##
==========================================
+ Coverage   99.66%   99.74%   +0.07%     
==========================================
  Files         161      160       -1     
  Lines        2722     2785      +63     
==========================================
+ Hits         2713     2778      +65     
+ Misses          9        7       -2
Impacted Files Coverage Δ
src/modules/Dropdown/Dropdown.js 100% <100%> (ø) ⬆️
src/modules/Search/Search.js 99.46% <0%> (-0.01%) ⬇️
src/modules/Tab/TabPane.js 100% <0%> (ø) ⬆️
src/elements/Segment/Segment.js 100% <0%> (ø) ⬆️
src/elements/Header/HeaderSubheader.js 100% <0%> (ø) ⬆️
src/elements/Button/ButtonOr.js 100% <0%> (ø) ⬆️
src/addons/Pagination/Pagination.js 100% <0%> (ø) ⬆️
src/views/Card/CardHeader.js 100% <0%> (ø) ⬆️
src/elements/Image/ImageGroup.js 100% <0%> (ø) ⬆️
src/elements/Label/LabelGroup.js 100% <0%> (ø) ⬆️
... and 146 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ecd238e...1e45dfd. Read the comment docs.

@levithomason
Copy link
Member

Let's make this the default behavior and remove the prop. The current behavior is a bug so it is OK to "break" it.

} else {
this.setState({ shouldOpenUpward: false })
}
}
Copy link
Member

Choose a reason for hiding this comment

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

An if/else which results in true/false statements can be simplified to using the condition as the value:

this.setState({ 
  shouldOpenUpward: spaceAtTheBottom < 0 && spaceAtTheTop > 0,
})

Copy link
Member

Choose a reason for hiding this comment

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

In the case that both top and bottom are blocked, perhaps we should open to the side with the most available space. I think this math is wrong, but something like:

this.setState({ shouldOpenUpward: spaceAtTheBottom > spaceAtTheTop })

if (!menu) return

const dropdownRect = this.ref.getBoundingClientRect()
const itemsHeight = menu.clientHeight
Copy link
Member

Choose a reason for hiding this comment

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

nit: Let's keep the naming consistent and use menuHeight.

@@ -1273,7 +1338,7 @@ export default class Dropdown extends Component {
useKeyOnly(selection, 'selection'),
useKeyOnly(simple, 'simple'),
useKeyOnly(scrolling, 'scrolling'),
useKeyOnly(upward, 'upward'),
useKeyOnly(upward || shouldOpenUpward, 'upward'),
Copy link
Member

Choose a reason for hiding this comment

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

When we have props that need to be controlled, we move to them to being autoControlledProps. See Dropdown.js around line 346.

  • add upward to static autoControlledProps = []
  • add defaultUpward as a propType (since it is now stateful, we accept a default value for it)
  • move all usages of upward from this.props.upward to this.state.upward
  • to change the value of upward use this.trySetState({ upward: <new value> })
  • remove shouldOpenUpward as it is no longer needed.

Auto controlled props automatically defer to the user's prop value, if any. Also, this.trySetState() will not update the state value if the user is using that prop.

@levithomason
Copy link
Member

Looking great! I've added some feedback for you here. Thanks much for tackling this one.

@mihai-dinculescu
Copy link
Member Author

mihai-dinculescu commented May 22, 2018

Thank you for the feedback. I've done the changes that you've requested.

However, there is one unit test failing now: "filters the items based on custom search function"

It fails because the search function is now called two times instead of once. I suspect that it's called the first time when the dropdown opens, and a second time after the direction is set.

This also points another issue. I don't like the fact that the dropdown needs to rerender after the direction is set. I'm not sure how to get around this though. The content needs to be rendered before we can calculate it's height.

I could use some help.

@samboylett
Copy link

I've been looking at this too. I think if it doesn't change direction, it should only render once, so the search function will only be called once. Otherwise it will have to render twice (there's not really any way around this) so the search function will be called twice too.

@mihai-dinculescu mihai-dinculescu force-pushed the dropdown_keep_in_viewport branch from bf7475e to 3265024 Compare May 24, 2018 10:59
@mihai-dinculescu
Copy link
Member Author

Thank you for your input, @samboylett.

I've optimized the code so it updates the state only when there is a relevant change.

@levithomason
Copy link
Member

This looks great, thanks! The last thing we need here is a test. The test would resize the browser window and assert the dropdown opened upward. We can merge after this update.

@levithomason
Copy link
Member

Superb 👍 I've merged master. We can merge this PR once tests pass.

@levithomason
Copy link
Member

levithomason commented Jun 1, 2018

@mihai-dinculescu You've contributed here before and you've shown care and initiative for ensuring SUIR becomes better. We appreciate this and want to enable you to do more. I've added you as a collaborator. You're now able to manage issues and PRs as well as create branches here in the main repo. You no longer need to work from a fork. Merging to master is the only reserved permission.

We are very select about who we add and when, so know that we trust your abilities and your judgment. Please feel free to weigh in on any issues and PRs that you have an opinion about. You have a share of ownership and say here now.

Once you accept the invite (see your email), you might want to show the Semantic Org badge publicly on your profile. To do that, navigate to the "people" page and change the "private" dropdown to "public" for your user in the table. Here's a direct link to your user in the table.

/cc
@Semantic-Org/react-collaborators
@Semantic-Org/react-maintainers

Please welcome @mihai-dinculescu to our ranks 😄 🎉

@levithomason levithomason merged commit 5ebeedf into Semantic-Org:master Jun 1, 2018
@mihai-dinculescu
Copy link
Member Author

Thank you @levithomason. I'll do my best to be helpful.

@levithomason
Copy link
Member

Released in [email protected].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants