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): use Popper.js for a proper positioning #597

Merged
merged 2 commits into from
Oct 26, 2020

Conversation

denkristoffer
Copy link
Collaborator

@denkristoffer denkristoffer commented Oct 20, 2020

Purpose of PR

This PR refactors the Dropdown component to use Popper.js instead of the current, custom positioning calculation.

Resolves #361

Todo

  • Dynamic content
  • Don't re-open when toggling on the toggleElement
  • What to do about the isAutoalignmentEnabled prop? It doesn't serve much of a purpose with Popper doing the positioning automatically. Is it considered a breaking change to remove it?

PR Checklist

  • I have read the relevant readme.md file(s)
  • All commits follow our Git commit message convention
  • Tests are added/updated/not required
  • Tests are passing
  • Storybook stories are added/updated/not required
  • Usage notes are added/updated/not required
  • Has been tested based on Contentful's browser support
  • Doesn't contain any sensitive information

@netlify
Copy link

netlify bot commented Oct 20, 2020

Deploy preview for forma-36-react-components ready!

Built with commit 20880fb

https://deploy-preview-597--forma-36-react-components.netlify.app

@netlify
Copy link

netlify bot commented Oct 20, 2020

Deploy preview for forma-36-react-components ready!

Built with commit 4651b47

https://deploy-preview-597--forma-36-react-components.netlify.app

@m10l
Copy link
Contributor

m10l commented Oct 21, 2020

Awesome 😻, looks like there are some issues with the react-timepicker package though due to React mismatch?

lerna ERR! yarn run test exited 1 in '@contentful/[secure]-react-timepicker'
lerna ERR! yarn run test stdout:
$ tsdx test --env=jsdom
  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Uncaught [Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
    1. You might have mismatching versions of React and the renderer (such as React DOM)
    2. You might be breaking the Rules of Hooks
    3. You might have more than one copy of React in the same app
    See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.]

@denkristoffer

This comment has been minimized.

@denkristoffer denkristoffer force-pushed the dropdown-popper branch 2 times, most recently from 4dd2a37 to f31379e Compare October 21, 2020 14:02
@giotiskl giotiskl requested a review from m10l October 21, 2020 14:31
Copy link
Contributor

@m10l m10l left a comment

Choose a reason for hiding this comment

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

Awesome work

Copy link
Contributor

@gui-santos gui-santos left a comment

Choose a reason for hiding this comment

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

🚀

styles[`DropdownContainer__container-position--${this.state.position}`],
);
return () => {
document.body.removeChild(portalTarget.current);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should refactor the Tooltip to use Portals as well. But In another PR of course 😄

@@ -18,7 +18,6 @@ function DefaultStory() {
onClose={() => setOpen(false)}
isFullWidth={boolean('isFullWidth', false)}
key={Date.now()} // Force Reinit
isAutoalignmentEnabled={boolean('isAutoalignmentEnabled', true)}
Copy link
Contributor

Choose a reason for hiding this comment

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

We might want to refactor it to the new format, but we can totally do it later.

Copy link
Contributor

@burakukula burakukula left a comment

Choose a reason for hiding this comment

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

🎉 Great work!
As you are removing isAutoalignmentEnabled would this mean minor change in the API?
On a separate PR we could do refactor to the story to new storybook format and add README for the component. But we can totally do it later.
Overall great! 🙌

Copy link
Contributor

@DanweDE DanweDE left a comment

Choose a reason for hiding this comment

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

As you are removing isAutoalignmentEnabled would this mean minor change in the API?

This is kind of a breaking change in the sense that previously you could disable auto-alignment explicitly via isAutoalignmentEnabled={false}. If you rely on this behavior for some reason it's breaking for you.

@denkristoffer Searching for "isAutoalignmentEnabled" I noticed that we're relying on this in the web app in two places. If you really want to remove this prop, please make sure it's not strictly necessary there and that the UI around it still works fine without it.

@burakukula
Copy link
Contributor

@denkristoffer if this means breaking change, I think we should w8 and group this with other changes to release bigger major version. We have couple of things - We could move some of the alpha components to main build I think and I'm sure that we have couple of more things that might do into the next major release. Maybe a catch up regarding this topic would be a good thing to do? WDYT?

@denkristoffer

This comment has been minimized.

@denkristoffer
Copy link
Collaborator Author

@burakukula @DanweDE I think I managed to replicate disabling positioning with the isAutoAlignmentEnabled prop. I have un-deprecated it, so we can get this in without breaking changes. I think it's ready.

const { submenu, className, width, testId } = this.props;
useEffect(() => {
if (isOpen) {
document.body.appendChild(portalTarget.current);
Copy link
Collaborator

Choose a reason for hiding this comment

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

@denkristoffer if you can find a way to not to use portal it would be awesome. the problem with portal is keyboard focus order; upon open the dropdown content is at the end of the document, onClose the next keyboard element to be focused is the first element in the document. I hope that makes any sense, let's talk about it if not :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@mshaaban0 I agree, the portal should be removed by default. I think we should handle this separately in #601 though, also to make sure this PR doesn't break any existing uses of the dropdown. Is that okay with you?

@denkristoffer denkristoffer force-pushed the dropdown-popper branch 2 times, most recently from 6db8d89 to 77e3f65 Compare October 26, 2020 09:03
@burakukula
Copy link
Contributor

burakukula commented Oct 26, 2020

@denkristoffer ok, cool. 😎
Sorry, maybe it's a silly question. I think the prop isAutoalignmentEnabled is still removed from the API in the PR? Or I am missing something? It's very possible that I am missing something. Hope you don't mind me asking. 🙃
I'm thinking about potential usage of the API outside of the webapp. if someone rely on this, it will still be breaking change?

@denkristoffer
Copy link
Collaborator Author

@burakukula Of course not 🙂 The prop is being used in the Dropdown component where Popper is used, instead of the DropdownContainer where it was used before: https://github.com/contentful/forma-36/blob/dropdown-popper/packages/forma-36-react-components/src/components/Dropdown/Dropdown.tsx#L149-L164

I've also added it back to the story.

@burakukula
Copy link
Contributor

@denkristoffer super, thx! (the file was folded from me 😑 and I didn't see this change. sorry for confusion)

testId: 'cf-ui-dropdown-portal',
position: 'bottom-left',
submenu: false,
isAutoalignmentEnabled: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

@denkristoffer Since you made the prop work again, I think you'd want to keep the default value of true for this prop and also add it back to the DropdownContainerProps interface above, no?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The functionality has been moved to Dropdown.tsx, so you shouldn't ever want/have to pass it to DropdownContainer.

@suevalov suevalov changed the title refactor(dropdown): Use Popper.js for positioning feat(dropdown): use Popper.js for a proper positioning Oct 26, 2020
@suevalov suevalov merged commit 67ec949 into master Oct 26, 2020
@denkristoffer denkristoffer deleted the dropdown-popper branch October 27, 2020 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: Use tether.io for attaching absolutely positioned elements to a target
7 participants