field-editors icon indicating copy to clipboard operation
field-editors copied to clipboard

Multi-reference editor 'Create new entry and link' dropdown won't work in an app

Open kamsar opened this issue 5 years ago • 7 comments

To reproduce this:

  1. Clone https://github.com/kamsar/ctfl-multi-reference-embed-bug (specific repro code location)
  2. npm run start
  3. In Contentful, add a private app pointed at http://localhost:1338, with a Entry field editor for Entry reference, list
  4. Assign the app's field editor to any Entry reference, list field. Ensure that more than one content type is allowed to be linked.
  5. Edit an entry with the custom editor. It will render correctly and work as a duplicate of the default multiple reference editor until you click Create new entry and link. Then the dropdown for content type selection becomes hidden and can't be clicked.

image

The same view, but with sdk.window.startAutoResizer() replaced with sdk.window.updateHeight(800) to force a very tall iframe:

image

There are two issues here (and they're probably closely related):

  1. The extension SDK's autoResizer is not picking up the opening of the dropdown and resizing the iframe
  2. This seems to be because the technique used to open the dropdown is also not updating any of the usual browser height detection properties, such as document.body.scrollHeight or document.documentElement.getBoundingClientRect() all of which remain constant within the iframe whether the dropdown is open or not.

kamsar avatar Sep 25 '20 14:09 kamsar

@kamsar, I encountered this same issue. It is because the dropdown containers use fixed positioning. Subsequently the iframe height calculations do not take the dropdown dimensions into account.

position-fixed

It is related to #188 and also impacts the action menu dropdown, which leverages the same container and positioning. The bottom dropdown, (or otherwise long actions menus), will always get cut off by the iframe.

actions-dropdown

Specifically regarding the Create new entry and link action, I was able to produce a quick and dirty workaround by overriding the styles to force the container to be static positioned:

.DropdownContainer__DropdownContainer___3WlJM[data-test-id="add-entry-menu-container"] {
  position: static !important;
  display: inline-block !important;
  margin-top: 5px !important;
}

This results in: position-static

Unfortunately it isn't an applicable workaround for the actions menu dropdown on the individual entry cards.

knupska avatar Sep 28 '20 08:09 knupska

Experiencing the same issue.

The above fix solves it for me.

matt-koevort avatar Oct 01 '20 10:10 matt-koevort

@kamsar @knupska @matt-koevort We're working on the fix for this issue. We're about to release a new version of field-editors with the latest Forma36 under the hook that should resolve the issue.

suevalov avatar Oct 27 '20 10:10 suevalov

This fix makes the dropdown at least usable without a hack but it's not particularly nice of an experience. The popper dropdown is absolutely positioned using transform: translate(0px, iframeHeightpx), which still does not affect the document height calculations.

Before click: image

After click - now you get scrollbars, but the menu is not visible without scrolling - to a non-technical user, that's not very obvious especially since the text does not indicate a menu is open via icon change, etc: image

After scrolling down within the iframe, you can use the menu: image

User-experience wise the hack we were using with the old menu was actually a lot better, as autoresizer worked with it.

For anyone looking for an updated hack that works with the new version, this does the trick when we negate the transform:

.DropdownContainer__DropdownContainer___3WlJM[data-test-id="add-entry-menu-container"] {
  position: static !important;
  display: inline-block !important;
  margin-top: 5px !important;
  transform: none !important;
}

kamsar avatar Oct 28 '20 17:10 kamsar

"@contentful/forma-36-react-components": "^3.100.2",:

image

adrian-skybaker avatar Nov 30 '21 01:11 adrian-skybaker

The way I worked around this on one of our apps was as follows. However, it's only useful in certain situations (see caveats):

  1. Create a ref on the absolute-positioned element which overflows the iframe (caveat: this is only possible if the component lets you pass a ref obviously, such as using a Forma 36 <DropdownList>)
  2. Create an event handler for any event which causes the overflowing element to appear (caveat: again, this is only possible if you have control over when the element is displayed - for example, you can't add a callback to get notified when the user opens the dropdown on an AssetCard as far as I know)
  3. In the event handler above, grab the element reference (the ref added in point 1) and call getBoundingClientRect() on it - you now have the dimensions of the absolute-positioned element
  4. From there it's simply a case of turning off the window auto-resizer and calling updateHeight() with the bounding box height, plus any offsets / padding / whatever you need to make it fit
  5. When the element is hidden again, make sure to restart the window auto-resizer

https://user-images.githubusercontent.com/273311/144236000-d9085360-4948-464c-8983-d77de861e22f.mov

The results still aren't perfect - obviously the dropdown is causing the whole iframe to grow, rather than just appearing over the field below it, but there are limits to what HTML can do 😄 This was good enough for our use case - to be able to dynamically adjust the height of the iframe to encompass the (variable-length) dropdown items without clipping/scrolling.

chrisfrancis27 avatar Dec 01 '21 12:12 chrisfrancis27

Marking issue as stale since there was no activity for 30 days

github-actions[bot] avatar Sep 21 '22 07:09 github-actions[bot]