// A Turbo Stream `remove` action deletes its target right away. Pause that until // the element's CSS animation has finished, so a revoked device row can fade out // instead of vanishing. const REMOVE_ANIMATION_CLASS = "animate-remove" const REMOVE_ANIMATION_TIMEOUT = 1000 document.addEventListener("turbo:before-stream-render", (event) => { const renderDefault = event.detail.render event.detail.render = (streamElement) => { const target = streamElement.action === "remove" ? document.getElementById(streamElement.target) : null if (!target) return renderDefault(streamElement) let rendered = false const render = () => { if (rendered) return rendered = true renderDefault(streamElement) } target.addEventListener("animationend", render, { once: true }) target.classList.add(REMOVE_ANIMATION_CLASS) // Don't leave the element behind if the animation cannot run at all. setTimeout(render, REMOVE_ANIMATION_TIMEOUT) } })