- Issue created by @luke.leber
- 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
AFAICT this is in direct conflict with @lauriii's product requirement
3. Real-time page preview
:[…] Custom component code should not have to be aware that it may be rendered in the page builder.
- 🇺🇸United States luke.leber Pennsylvania
I suppose that an alternative approach might be to allow certain rendered elements receive input events, but that seems like it'd be quite the technical lift to accomplish.
- 🇺🇸United States effulgentsia
allow certain rendered elements receive input events
That should already work with ✨ Initial support for allowing interaction with the preview Active . Not sure if state is retained when exiting preview though, or if the whole canvas gets re-rendered and therefore the accordion reverts to collapsed.
Even when the accordion is collapsed, are you able to move a component into a hidden slot via the Layers panel (left sidebar)? That's certainly not enough of a solution, but I'm curious if that at least works in the meantime.
- 🇺🇸United States luke.leber Pennsylvania
Even when the accordion is collapsed, are you able to move a component into a hidden slot via the Layers panel (left sidebar)?
Yep. That works.
That should already work with #3486785: Initial support for allowing interaction with the preview. Not sure if state is retained when exiting preview though, or if the whole canvas gets re-rendered and therefore the accordion reverts to collapsed.
Yep, the preview mode works perfectly -- things are able to be interacted with just fine in there. It's just the non-preview mode where it's impossible to use the mouse and/or keyboard to expand/collapse interactive things.
While this can be worked around for accordions (through adding an "expand by default" prop and temporarily adjust that while adding content), I don't think it'll be quite as easy for other interactive UI patterns, like multiple tabs. For completeness, this is how we've set up our Tabs implementation in Layout Builder (dragging a block over a tab activator will actually activate the tab in the LB editor):
- 🇺🇸United States effulgentsia
It's just the non-preview mode where it's impossible to use the mouse and/or keyboard to expand/collapse interactive things.
But why do you need to? What's wrong with whenever you want to interact with the component to go into preview mode, interact, then exit preview mode? Is the problem that when you exit preview mode the canvas is re-rendered in a way that resets any interaction that you did while in preview mode? If so, I think that's an issue that we should open and fix.
- 🇺🇸United States luke.leber Pennsylvania
Here's a gif of the behavior (described in previous comment).
- 🇬🇧United Kingdom jessebaker
I actually snuck into 0.x a very work-in-progress/hacky (and totally untested by anyone except me) feature where you can press and hold the 'V' key and it will hide the overlay UI and allow you to interact with the page inside the iFrame. *
I use it for debugging and I have some vague intentions to build it out into a full feature in the fullness of time, but I'm curious if it is enough to work around your problem (and as such would be a good use case for us to consider more fully fleshing out that feature).
As for your request, when I was building Visual Page Builder for Site Studio we had to add in a variable/property to let Site Studio interactive components know they were being rendered in the VPB for very similar reasons to the ones you are facing. I think one of the main reasons was a gallery slider that would auto-transition to the next slide every few seconds which was very undesirable when trying edit the slides!
* if you get stuck in the Visual mode, make sure you focus outside the iFrame and press 'v' again a few times and it will unstick you. The issue is the keyup event when you let go of V sometimes gets swallowed by the iFrame. Like I said, very work-in-progress!
- 🇺🇸United States luke.leber Pennsylvania
That's pretty neat, @jessebaker. It definitely *helps*, but the editing UX still seems off as the accordion seems to re-flip back to closed every time it's re-rendered.
Strangely enough, the newly added component seems to be selected by default even after re-paint and it's hidden.
- 🇬🇧United Kingdom jessebaker
Hmm, that's a really difficult challenge.
There are actually 2 iframe elements one on top of the other. Each time any data changes, the hidden iframe is updated with the new preview and once it has loaded, the iframes are swapped so you can see the changes.
Because the page is re-rendered server side whenever there are any changes, the iframe swapping has to be done to hide the document loading and stop any FOUC issues/flickering.
As a result of that implementation though, no front end state on the page is maintained between data updates.
Off the top of my head I don't have an immediate thought of how to even begin addressing that.
- 🇺🇸United States luke.leber Pennsylvania
It's actually pretty simple to resolve if the component knows if it's being observed in Experience Builder.
A custom twig extension...
class XBExtension extends AbstractExtension { public function getFunctions() { return parent::getFunctions() + [ new TwigFunction('is_xb_editing', [ $this, 'isXbEditing', ]), ]; } public function isXbEditing() { return \Drupal::routeMatch()->getRouteName() === 'experience_builder.api.preview'; } }
...and using it in the SDC template:
{% set expanded = is_xb_editing() %} {# <-- "in_preview" variable-like-thing #} {% include '@my-upstream-components/accordion.twig' %}
That said, I wouldn't recommend writing this off as a niche problem. I can't think of any interactive / progressive disclosure elements from *any* design systems that wouldn't need a mechanism like this. I think it's more along the lines of not having any example components available in XB to have stepped on this yet. It'd be really unfortunate for each design system to have to roll their own "in_preview"-like feature.
- 🇺🇸United States luke.leber Pennsylvania
Added copy/paste example to I.S. w/o any external dependencies :-).
- 🇫🇮Finland lauriii Finland
I agree with the premise from #2 that the proposal to add
in_preview
variable is in conflict with the idea that the components shouldn't have to be aware that they are being rendered in XB. That said, think we will eventually have to add in_preview as a tool to help working around the limitations of the editor in the complex use cases.There's an alternative approach to this, which is to add a new property that allows toggling the accordion. This would essentially allow setting the default value for the open/closed state, but would also allow opening the accordion item in XB.
- 🇬🇧United Kingdom jessebaker
I'm not sure your alternative approach in #16 @lauriii would be enough to handle the scenario of disabling an auto-playing image slider for instance.
Maybe it's just semantics but "Custom component code should not have to be aware..." - suggests that components must work without being aware they are in the editor but doesn't say that they can't be told they are in the editor if that allows for someone to improve the DX when building them out.
I think we have work arounds planned to mean that any/all components will work and be useable (e.g. falling back to using the layers panel) which fulfils that requirement but we shouldn't intentionally hamper more advanced use cases just to meet that requirement.
- 🇫🇮Finland lauriii Finland
To clarify my comment from #16, I'm +1 to adding the
in_preview
(or similar variable). At the same time, I think that we should continue improving our tools to better facilitate an seamless integration of components for common use cases, even if they come with some interaction.