Conversation
|
@SteffenDE I haven't tried this but isn't the I think my original issue was about the |
|
fwiw, one thing we've been looking into with LVN is state preservation of certain elements that get restored by certain actions. We are packing these into the history API state object (we re-implemented history API in our headless browser). It's been working well as there are certain UI states that make sense to only do client-side, like dialog open/close, that don't make sense to capture server side. But you may want to restore when backbutton'ing |
I'm not sure if I understand your question correctly, but since for details and dialog the open state is based on the open attribute, this PR works by ensuring that the attribute is kept across patches. This is basically the same as #2349 (comment), just without needing a global option.
Do you have an example where this might make sense for a LiveView app? Usually, when changing the history, a round trip to the server is necessary too, so I'm not sure when this would be beneficial, for example when thinking about client side only dialogs. |
An example may be if you have a scrollable section of a page, if you navigate away, then back button to it whatever the scroll position of that section would be lost without state restoration. This is a common pattern in native that web doesn't really have too much expectations around. But I do think it adds to the user experience |
|
LiveView does restore the global scroll position, but for individual containers it is not done automatically. There’s a separate issue for that: #2107 :) |
|
I'll review that issue but our implementation may provide some guidance here. The state restoration is opt-in for each view. So it can apply to more than just scroll but any client-specific state that isn't be tracked server-side and is blown away due to navigation. We have unique IDs for each node in the view tree that our parser injects as a |
Sometimes it is useful to ignore updates to specific attributes. One
famous example is the "new"-ish HTML `dialog` element that relies on
an `open` attribute to determine if it is open or closed. The same
applies to `details` elements. Importantly, when opened by a user, the
browser sets this attribute by itself and LiveView should not overwrite
it on patches, otherwise it would accidentally close it again.
Previously, the recommended way to handle such cases was to add a function
to the `onBeforeElUpdated` dom option of the `liveSocket`. This is
cumbersome though and especially for libraries leads to more friction, as
more steps are necessary to install them.
Now, one can use `JS.ignore_attributes` in instead, for example:
```heex
<details phx-mounted={JS.ignore_attributes(["open"])}>
<summary>...</summary>
...
</details>
````
And then the details element will always retain the previous open state,
regardless of what the server does.
Relates to: #3741
Relates to: #2349
Relates to: #3574
1ad5532 to
f77438e
Compare
Sometimes it is useful to ignore updates to specific attributes. One famous example is the "new"-ish HTML
dialogelement that relies on anopenattribute to determine if it is open or closed. The same applies todetailselements. Importantly, when opened by a user, the browser sets this attribute by itself and LiveView should not overwrite it on patches, otherwise it would accidentally close it again.Previously, the recommended way to handle such cases was to add a function to the
onBeforeElUpdateddom option of theliveSocket. This is cumbersome though and especially for libraries leads to more friction, as more steps are necessary to install them.Now, one can use
JS.ignore_attributesin instead, for example:And then the details element will always retain the previous open state, regardless of what the server does.
Relates to: #3741
Relates to: #2349
Relates to: #3574