-
Notifications
You must be signed in to change notification settings - Fork 1k
Fix drop container transform #6097
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 drop container transform #6097
Conversation
…esPharmacies/grommet into fix-drop-container-transform
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Hi @ericsoderberghp, Any news about this PR ? Yours faithfully, |
I think I at least partly understand what's going on here. We are skipping over parents that have some sort of CSS transformation so that we can adjust the drop position by the appropriate offset of the transformation. Two thoughts:
|
Thank you for your reply. To answer your two thoughts:
Yours faithfully, |
Hello, Someone available to merge this PR ? Best regards, |
Hi, Can you tell if changes are needed please ? Best regards, |
Hello :) I have been testing this PR today, thank you to @JrDuComptoirDesPharmacies for your work on this! These changes did help us solve a particular use case where we have a Drop being positioned incorrectly when I have some suggestions which fixes our issues entirely and hopefully you'll see them as useful additions to this PR.
Imagine this scenario:
In container.style.left = `${left - viewportOffsetLeft + (containingBlock?.scrollLeft ?? 0);
// ...
if (top !== '') {
container.style.top = `${top - viewportOffsetTop +
(containingBlock?.scrollTop ?? 0)}px`;
}
if (bottom !== '') {
container.style.bottom = `${viewportOffsetBottom - bottom -
(containingBlock?.scrollTop ?? 0)}px`;
}
In let scrollParents;
+ let scrollParentsHorizontal;
const addScrollListeners = () => {
scrollParents = findScrollParents(dropTarget);
+ scrollParentsHorizontal = findScrollParents(dropTarget, true);
scrollParents.forEach((scrollParent) =>
scrollParent.addEventListener('scroll', place),
);
+ scrollParentsHorizontal.forEach((scrollParent) =>
+ scrollParent.addEventListener('scroll', place),
+ );
}; I tested these changes with both Let me know if you have any feedback, would love to see this merged
|
Hi @jonscottclark, Thank you for this additional use case, it seems logic to realign the drop when the horizontal scroll is changing too. I tried to modify the CodeSandbox to represent your use case without success. Once done, we will compare the behavior with and without your fix and we will add your changes to the Pull Request. Thanks in advance ! |
@AntoineDuComptoirDesPharmacies Good idea, I'll attempt to make a minimum reproduction of the situation I'm describing. |
@AntoineDuComptoirDesPharmacies Here's the simplified scenario: https://codesandbox.io/s/grommet-v2-template-forked-fqhfx5?file=/index.js We have a very wide Box with items in it - scroll horizontally to see all of the items. After clicking a button the incorrect "top" positioning is as expected - the currently broken positioning that your PR already fixes. Now try clicking on "Open Drop 1", then start scrolling vertically and horizontally. You will see the necessity of checking for If you change |
@jonscottclark Thank you for this perfect reproducer, we can notice that the bug you outlined is resolved with your suggested modifications. We have just added your modifications to the current PR. Yours faithfully, |
@AntoineDuComptoirDesPharmacies test snapshot looks like it can be safely updated The Chromatic step is failing due to the appId not being recognized:
|
Thank you for the ping @jonscottclark. We merged the current master branch in the PR so tests pass now. Yours faithfully, |
Hey @ericsoderberghp , friendly ping to see if you have time to look at this again. Thank you in advance :) |
@AntoineDuComptoirDesPharmacies nvm - cloning your fork instead :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this locally by cloning the LDCP fork, rebasing against the grommet
main branch (only conflicts were package.json), running a local build and then linking the /dist
output locally to our project. I found that one change was needed to make this PR work perfectly for some real-world use cases 🎉
See here that we reference dropTarget
, (the prop): https://github.com/grommet/grommet/pull/6097/files#diff-a8c7783b048816fb6a81c4d4d49839bb165a273f34164cc9fa580226391aa51eR294-R295
We need to instead first check if dropTarget?.current
is defined, like we do in the place()
function: https://github.com/grommet/grommet/pull/6097/files#diff-a8c7783b048816fb6a81c4d4d49839bb165a273f34164cc9fa580226391aa51eR146
If we move L146 out of place()
and put it at L96, then rename dropTarget
to target
in addScrollListeners()
, everything works 🙌
This works with inline: true
and inline: false
.
This is with { drop: { checkContainerBlock: true }}
. With this option off, the positioning is okay with inline: false
, but with inline: true
there's erroneous positioning due to the omission of the containing block's position - for the reasons I list here: #6097 (comment)
So it seems this work actually contains two things:
- A fix to the scroll listeners not always sending a valid element to
findScrollParents
- The opt-in behaviour to calculate drop positioning based on possible containing blocks.
For what it's worth, and to continue my rambling, we will 100% be opting in to this behaviour (and hopefully it becomes a default), and also using inline: true
for all of our Drop instances (so that we can tell rendered Drop content to layer beneath some ancestor sticky elements - with inline: false
the Drop content will always go overtop of everything)
Thank you, LDCP folks for the initial PR and continued attention, and Grommet folks for the work you do 🤝
@GeryDuComptoirDesPharmacies I should clarify that I approved the PR (instead of saying Request Changes) because it works for me assuming this comment is implemented:
Just didn't want that point to get lost in the text :) Thanks |
@jonscottclark We will implement what you ask for. Thanks for your time. |
Hi @jonscottclark, We have included your remarks and rebase the branch on last master's commit. Yours faithfully, |
Hi, Review is done, let's merge it this time please 🙏🏾 @ericsoderberghp @jonscottclark @jcfilben Thanks. |
Hi @GeryDuComptoirDesPharmacies I am still seeing issues with the drop positioning behavior. Aug-23-2023.12-58-33.mp4Since the primary issue this PR is trying to solve is the containing block issue I would be okay moving forward with only the containing block code and removing the |
@jcfilben is the issue you mention the seemingly slow updating of the drop position? |
Yes, in addition I would expect the drop container to scroll out of view when the target is out of view |
@jcfilben Okay - I see there's a lot of stuff happening in the I'm okay with removing the If you agree, then perhaps we can get a check from @ericsoderberghp once it's removed since everything else is looking great in this PR. |
Yes, I'm supportive of removing the |
…R as it requires more work to be smooth See: grommet#6097 (comment)
@jcfilben @jonscottclark Yours faithfully, |
Hi everyone, Everything is fine now. Can we merge please ? |
const portalContext = useContext(PortalContext); | ||
const portalId = useMemo(() => portalContext.length, [portalContext]); | ||
const nextPortalContext = useMemo( | ||
() => [...portalContext, portalId], | ||
[portalContext, portalId], | ||
); | ||
const dropRef = useForwardedRef(ref); | ||
const target = dropTarget?.current || dropTarget; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to be defined outside of the useEffect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It do not need to be defined outside.
I followed the recommendations of @jonscottclark here : #6097 (review)
I just moved it into the useEffect to save some computation.
Yours faithfully,
LCDP
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Looks like there are some merge conflicts that need to be resolved before merging |
…transform # Conflicts: # src/js/components/Drop/DropContainer.js
@jcfilben conflict have been resolved |
🥳 |
What does this PR do?
Fixes the drop container position when it inlude in a transformed parent position (fixed position is not computed according viewport)
Before the fix: https://codesandbox.io/s/adoring-currying-ztj374
After the fix: https://codesandbox.io/s/grommet-v2-template-forked-vojosq
Where should the reviewer start?
See in
src/js/components/Drop/DropContainer.js
in place methodWhat testing has been done on this PR?
Maual testing through firefox/chrome using codesandbox from issue #5954
How should this be manually tested?
Click on the Fancy Selector and control the drop position
Do Jest tests follow these best practices?
screen
is used for querying.userEvent
is used in place offireEvent
.asFragment()
is used for snapshot testing.Any background context you want to provide?
Description of the fixed position according to transformed parent:
https://developer.mozilla.org/fr/docs/Web/CSS/position#fixed
Description of way to find the containing block used for fixed element position computation :
https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
Similar to this issue: floating-ui/floating-ui#1577
Grommet solution inspired of this code: https://github.com/floating-ui/floating-ui/blob/a3299dc9c56a7c95183dfb3463f0542db4e945e2/packages/dom/src/utils/getOffsetParent.ts#L22
What are the relevant issues?
See #5954
Screenshots (if appropriate)
Before:

After:

Do the grommet docs need to be updated?
No
Should this PR be mentioned in the release notes?
Yes
Is this change backwards compatible or is it a breaking change?
Backwards compatible