separate editor FAB and panel for cleaner animation
All checks were successful
deploy / deploy (push) Successful in 1m32s
All checks were successful
deploy / deploy (push) Successful in 1m32s
Split the editor sheet into two distinct elements: - .editor-fab: floating action button, always a pill in the corner - .editor-panel: sliding panel that animates in/out independently This enables proper CSS keyframe animations (slide-up/down on mobile, slide-in/out on desktop) with a closing class for exit transitions. Simplified the JS hook to only handle close behaviour. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -679,28 +679,25 @@ const DirtyGuard = {
|
||||
}
|
||||
}
|
||||
|
||||
// EditorSheet: simple open/collapse sheet for page editing
|
||||
// Positioning is handled by CSS - JS just handles click-outside and Escape
|
||||
// EditorSheet: handles click-outside and Escape for the editor panel
|
||||
const EditorSheet = {
|
||||
mounted() {
|
||||
// Click outside to collapse (works in any mode for preview)
|
||||
// Use mousedown instead of click to avoid race with LiveView re-renders
|
||||
this._onDocMousedown = (e) => {
|
||||
if (!this.el.contains(e.target) && this._getState() !== "collapsed") {
|
||||
this._setState("collapsed")
|
||||
}
|
||||
if (this._getState() !== "open") return
|
||||
const fab = document.querySelector(".editor-fab")
|
||||
if (this.el.contains(e.target)) return
|
||||
if (fab && fab.contains(e.target)) return
|
||||
this._close()
|
||||
}
|
||||
document.addEventListener("mousedown", this._onDocMousedown)
|
||||
|
||||
// Escape key to collapse
|
||||
this._onKeydown = (e) => {
|
||||
if (e.key === "Escape" && this._getState() !== "collapsed") {
|
||||
if (e.key === "Escape" && this._getState() === "open") {
|
||||
e.preventDefault()
|
||||
this._setState("collapsed")
|
||||
this._close()
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", this._onKeydown)
|
||||
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
@@ -712,11 +709,22 @@ const EditorSheet = {
|
||||
return this.el.dataset.state || "collapsed"
|
||||
},
|
||||
|
||||
_setState(state) {
|
||||
this.el.dataset.state = state
|
||||
this.el.setAttribute("aria-expanded", state !== "collapsed")
|
||||
this.pushEvent("editor_set_sheet_state", { state })
|
||||
this._announce(state === "collapsed" ? "Editor collapsed" : "Editor expanded")
|
||||
_close() {
|
||||
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
||||
if (prefersReducedMotion) {
|
||||
this.el.setAttribute("aria-hidden", "true")
|
||||
this.pushEvent("editor_set_sheet_state", { state: "collapsed" })
|
||||
this._announce("Editor collapsed")
|
||||
return
|
||||
}
|
||||
|
||||
this.el.classList.add("closing")
|
||||
this.el.addEventListener("animationend", () => {
|
||||
this.el.classList.remove("closing")
|
||||
this.el.setAttribute("aria-hidden", "true")
|
||||
this.pushEvent("editor_set_sheet_state", { state: "collapsed" })
|
||||
this._announce("Editor collapsed")
|
||||
}, { once: true })
|
||||
},
|
||||
|
||||
_announce(message) {
|
||||
|
||||
Reference in New Issue
Block a user