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

fix: Align popover inside dropdown #789

Closed

Conversation

parostatkiem-zz
Copy link
Contributor

@parostatkiem-zz parostatkiem-zz commented Nov 5, 2019

This is a temporary solution.

The whole problem requires a major refactoring on popovers, as @jbadan said on Slack (100% agree).
This is just a "patch" to make Popover working with Dropdown or any other element.
⚠️ It does not introduce any backwards-incompatible changes.

Description

  • Add ability to align Popover left and right edge with its parent control element edges.
  • Add ability to set Popover right edge to be not-further-left or not-further-right than parent control right edge.

It works well with Dropdown as well as any other type. Sadly, the solution requires creating a reference on the client side.

Before:

image

After:

image

fixes #788

@netlify
Copy link

netlify bot commented Nov 5, 2019

@jbadan jbadan requested a review from a team November 5, 2019 19:53
@jbadan jbadan changed the title Align popover inside dropdown fix: Align popover inside dropdown Nov 5, 2019
};

Popover.propDescriptions = {
body: 'Node(s) to render in the overlay.',
control: 'Node to render as the reference element (that the `body` will be placed in relation to).',
disableEdgeDetection: 'Set to **true** to render popover without edge detection so popover will not flip from top to bottom with scroll.',
noArrow: 'Set to **true** to render a popover without an arrow.',
parentElement: 'A reference (useRef) to an element of which the Popover will be positioned and sized relatively. Leave it empty to let it be done automatically.',
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we call this parentRef to be even more explicit?

And if we're going to mention useRef(), can we clarify the function itself shouldn't be passed in, but rather the return object from calling it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, the description seems to imply ("let it be done") that positioning and sizing relative to its parent can happen automatically if left empty. Is that the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sadly, it's not. If it was, this PR wouldn't need to exist at all ;)
I had no idea how to let the developer know he should put useRef's result there... Your idea of parentRef seems reasonable.

I tried to put some comments into the code displayed in the documentation website but it's impossible :(

@@ -94,6 +95,11 @@ class Popper extends React.Component {
if (!show) {
return null;
}
const currentParentElement = parentElement && parentElement.current;
Copy link
Contributor

Choose a reason for hiding this comment

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

Regarding my other comment, parentRef would be slightly clearer here that we could access a property .current.

@bcullman
Copy link
Contributor

bcullman commented Nov 5, 2019

@parostatkiem - can you add before and after screen caps?

@parostatkiem-zz
Copy link
Contributor Author

@bcullman you can clearly see it live on the deployed preview.
https://deploy-preview-789--fundamental-react.netlify.com/dropdown

Open the Width limited to parent's dropdown, then open any other one. You'll see the difference :)

Copy link
Contributor

@jbadan jbadan left a comment

Choose a reason for hiding this comment

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

This needs some unit tests added and screenshots - while I understand we can currently see it with the deploy preview, for history's sake if we need to look back it's better to have some screenshots in the description.

@parostatkiem-zz
Copy link
Contributor Author

parostatkiem-zz commented Nov 7, 2019

@jbadan ✅done
I couldn't come up with any more tests scenarios...

@bcullman
Copy link
Contributor

bcullman commented Nov 14, 2019

@parostatkiem - I could imagine a better long term fix would be to address this here by adding a opt-in prop for `widthSizingType' here:

https://github.com/SAP/fundamental-react/blob/master/src/utils/_Popper.js

that accepted the following

    ‘none’,
   ‘matchTarget’,
   ‘minTarget’,
   ‘maxTarget’

it would fix this component, and be flexible enough to handle all other circumstances, including other copmponets relying on _popper.js

@parostatkiem-zz
Copy link
Contributor Author

parostatkiem-zz commented Nov 15, 2019

@bcullman - where it would take the target's width from? The problem is Popper has no "idea" of his parent. That's why I introduced parentRef which has an obvious disadvantage of being defined on the client side.

... or do you mean adding widthSizingType on top of my solution? If yes, that would mean if widthSizingType has any other value than none, parentRef would have to be defined.

@greg-a-smith
Copy link
Contributor

@parostatkiem The _Popper.js component has a prop called referenceComponent, which is the element to be sized in relation to.

@parostatkiem-zz
Copy link
Contributor Author

parostatkiem-zz commented Nov 20, 2019

@greg-a-smith it was the first place I tried to find a solution at but I couldn't get the real DOM node of the referenceComponent, so I abandoned the idea and did it the other way.
However, today you inspired me to give it another chance and... here it is 🍾
Thank you for the inspiration!

@bcullman I implemented your idea in an unchanged form. I finally got rid of a ref on the client side :)

Copy link
Contributor

@greg-a-smith greg-a-smith left a comment

Choose a reason for hiding this comment

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

There appears to be some display issues with the popover examples using the Menu component, but I think that's another issue altogether. Not sure why Menu is a display type of table, but it is. 🤔 This is part of the reason why new Select and List components were built in fundamental-styles. The down side is they haven't been created in fundamental-react yet. 😞 Let's go forward with these changes for now and revisit if and when necessary. 🚢

@jbadan
Copy link
Contributor

jbadan commented Nov 22, 2019

@parostatkiem I tried to resolve some conflicts for you here, but I can't push to your branch to fix the failing test. Ping the team when the tests pass and we will merge :)

@parostatkiem-zz
Copy link
Contributor Author

@jbadan I added you to collaborators, you should receive an invitation email.
I'm quite busy this night (it's midnight right now) and will be able to fix the tests on Monday at the earliest.

@jbadan
Copy link
Contributor

jbadan commented Nov 26, 2019

closing for #804

@jbadan jbadan closed this Nov 26, 2019
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.

Popover is always stretched to the right edge of the viewport
5 participants