-
Notifications
You must be signed in to change notification settings - Fork 963
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
Add blocking: true to JS.dispatch #3615
base: main
Are you sure you want to change the base?
Conversation
Given we already support In the long term we want to look at this holistically. Overall we have three distinct capabilities:
We already have It is also worth saying that, if you can block the whole UI with the |
Relates to #3615. Allowing beforeUpdate to cancel an update by returning false is **not** implemented, as this would require more complex internal changes.
Still todo: tests |
Relates to: #3516 When integrating external animation libraries like motion.dev, the existing JS functions are not sufficient. Instead, the third party library needs to be triggered via JS. This has the downside of not being able to block the DOM until the animation is complete, which prevents this from working when elements are removed using `phx-remove`. This commit introduces a new `blocking: true` option to `JS.dispatch/3`, which injects a `done` function into the event's `detail` object. Using this with motion could look like this: ```elixir def render(assigns) do ~H""" <div :if={@show} phx-remove={JS.dispatch("motion:rotate", blocking: true)}> ... </div> """ end ``` ```javascript const { animate } = Motion window.addEventListener("motion:rotate", (e) => { animate(e.target, { rotate: [0, 360] }, { duration: 1 }).then(() => { if (e.detail.done) { e.detail.done() } }) }) ``` It is still necessary to block the DOM while the remove animation is running, as the remove can happen because of a navigation, where the animation would otherwise not run as the whole LiveView is just replaced.
340efb6
to
55226c4
Compare
detail = detail || {} | ||
detail.dispatcher = sourceEl | ||
if(blocking){ | ||
const promise = new Promise((resolve, _reject) => { | ||
detail.done = resolve |
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.
Should we error if detail.done
already exists? Seems like something that could already be in use. That being said, since the user has to opt-in to blocking, it's not going to break for anyone upgrading LV.
Relates to: #3516
When integrating external animation libraries like motion.dev, the existing JS functions are not sufficient. Instead, the third party library needs to be triggered via JS. This has the downside of not being able to block the DOM until the animation is complete, which prevents this from working when elements are removed using
phx-remove
.This commit introduces a new
blocking: true
option toJS.dispatch/3
, which injects adone
function into the event'sdetail
object.Using this with motion could look like this:
It is still necessary to block the DOM while the remove animation is running, as the remove can happen because of a navigation, where the animation would otherwise not run as the whole LiveView is just replaced.