Skip to content

fix(limitShift): always apply offset regardless of the axis and the side#1868

Closed
ciampo wants to merge 2 commits intofloating-ui:masterfrom
ciampo:fix/limit-shift-main-axis-offset
Closed

fix(limitShift): always apply offset regardless of the axis and the side#1868
ciampo wants to merge 2 commits intofloating-ui:masterfrom
ciampo:fix/limit-shift-main-axis-offset

Conversation

@ciampo
Copy link
Copy Markdown

@ciampo ciampo commented Aug 24, 2022

Fixes #1859

This PR changes the limitShift function from the shift middleware so that it always applies the middlewareData.offset when computing mix/max limits for both the main and the cross axis, regardless of the side (origin or not).

See #1859 and WordPress/gutenberg#42950 for extra context

@rollingversions
Copy link
Copy Markdown

rollingversions bot commented Aug 24, 2022

@floating-ui/core (1.0.1 → 1.0.2)

Bug Fixes

  • fix(limitShift): always apply offset regardless of the axis and the side

Packages With No Changes

The following packages have no user facing changes, so won't be released:

  • @floating-ui/dom
  • @floating-ui/react-dom
  • @floating-ui/react-dom-interactions
  • @floating-ui/react-native

Edit changelogs

@netlify
Copy link
Copy Markdown

netlify bot commented Aug 24, 2022

Deploy Preview for vibrant-gates-22c214 canceled.

Name Link
🔨 Latest commit c3caeba
🔍 Latest deploy log https://app.netlify.com/sites/vibrant-gates-22c214/deploys/630664aa3041820008feb99f

@ciampo ciampo changed the title limitShift: take offset middleware into account when limiting the shift on the main axis fix(limitShift): take offset into account also for the main axis Aug 24, 2022
@ciampo ciampo changed the title fix(limitShift): take offset into account also for the main axis fix(limitShift): always apply offset regardless of the axis and the side Aug 24, 2022
Comment on lines -200 to -205
(isOriginSide ? middlewareData.offset?.[crossAxis] ?? 0 : 0) +
(middlewareData.offset?.[crossAxis] ?? 0) +
(isOriginSide ? 0 : computedOffset.crossAxis);
const limitMax =
rects.reference[crossAxis] +
rects.reference[len] +
(isOriginSide ? 0 : middlewareData.offset?.[crossAxis] ?? 0) -
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I don't really understand the current approach on master where middlewareData.offset is added depending on isOriginSide

@ciampo
Copy link
Copy Markdown
Author

ciampo commented Aug 25, 2022

For my case, I'm getting away by writing a custom limitShift function.

Although I'd still be curious to understand why the offset from the offset middleware is applied arbitrarily:

  • only on the cross axis
  • depending on whether the side is an "origin" side or not

@atomiks
Copy link
Copy Markdown
Collaborator

atomiks commented Aug 25, 2022

The current logic ensures that the offset does not impact the goal to stop shifting once the opposite edges of the reference and floating elements are aligned. With this change, the shifting stops based on the offset, not whether their edges are aligned.

@ciampo
Copy link
Copy Markdown
Author

ciampo commented Aug 25, 2022

Thank you for the explanation, @atomiks !

I'll explain my use-case a bit more in depth:

In the Gutenberg editor, there are situations in which the reference element is inside an iframe, while the floating element is rendered outside of the iframe.

The iframe has an offset with respect to the document's viewport, which floating-ui doesn't seem to apply correctly to the floating element — and therefore, we've been adding the iframe offset ourselves via the offset middleware.

This causes problems with the limitShift function, since it applies the offset from the offset middleware arbitrarily.
We also tried to use the offset property of the limitShift function, but that also doesn't work (since the limitShift function adds/subtracts the offset for the min/max values).

We're now experimenting with adding the iframe offset via a separate custom middleware, and also using a custom version of the limitShift function which always adds that iframe offset to the min/max values.

We're still testing that solution, but it seems to work for us — although I'm wondering if there's a better way around it. Do you have any thoughts?

Probably the ideal case scenario would be that floating-ui adds better support for when the reference is in a different ownerDocument than the floating?

@atomiks
Copy link
Copy Markdown
Collaborator

atomiks commented Aug 26, 2022

I think better handling of cross-document elements is likely required to get it working properly.

Interestingly the future CSS anchor positioning proposal says it will forbid this:

Security
[...] elements cannot be anchored to each other across document boundaries.

Alternatively, a flag option in the limitShift function to ignore offset (or something else) might work

@ciampo
Copy link
Copy Markdown
Author

ciampo commented Aug 26, 2022

I think better handling of cross-document elements is likely required to get it working properly.

I think so too — is that on the roadmap for @flaoting-ui ?

It would be quite useful to the Gutenberg project too, so in that case it may be interesting to see if we can help move this feature forward.

Interestingly the future CSS anchor positioning proposal says it will forbid this:

That is something I wasn't aware of — it looks interesting, though! (and good point about document boundaries). I guess it would be great if there was an explicit way to remove those boundaries if both frames specially state it in some ways (maybe via CSP or something?)

Alternatively, a flag option in the limitShift function to ignore offset (or something else) might work

That would be the quickest short-term solution — an additional flag that allows to pass an arbitrary offset value that always gets added to min/max limits. Would that be possible? Happy to open a PR to help get things moving!

@atomiks
Copy link
Copy Markdown
Collaborator

atomiks commented Aug 26, 2022

I probably won't work on it myself soon, but you're welcome to create a PR to better support cross-document elements for the dom package

@ciampo
Copy link
Copy Markdown
Author

ciampo commented Aug 26, 2022

I'm going to close this PR and the related issue, and instead I opened two new issues:

It would be great if we could continue the conversation in those two issues.

@ciampo ciampo closed this Aug 26, 2022
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.

limitShift(): take middlewareData.offset into account when limiting the mainAxis

2 participants