Files
fizzy/app/javascript/controllers/dialog_controller.js
T
2025-08-14 14:59:50 -05:00

68 lines
1.5 KiB
JavaScript

import { Controller } from "@hotwired/stimulus"
const EDGE_THRESHOLD = 90
export default class extends Controller {
static targets = [ "dialog" ]
static values = {
modal: { type: Boolean, default: false }
}
connect() {
this.dialogTarget.setAttribute('aria-hidden', 'true')
}
open() {
const modal = this.modalValue
if (modal) {
this.dialogTarget.showModal()
} else {
this.dialogTarget.show()
}
this.#orient(this.dialogTarget)
this.dialogTarget.setAttribute('aria-hidden', 'false')
this.dispatch("show")
}
toggle() {
if (this.dialogTarget.open) {
this.close()
} else {
this.open()
}
}
close() {
this.dialogTarget.close()
this.dialogTarget.setAttribute('aria-hidden', 'true')
this.dialogTarget.blur()
}
closeOnClickOutside({ target }) {
if (!this.element.contains(target)) this.close()
}
#orient(element) {
element.classList.toggle("orient-left", this.#distanceToRight < EDGE_THRESHOLD)
element.classList.toggle("orient-right", this.#distanceToLeft < EDGE_THRESHOLD)
element.classList.toggle("orient-top", this.#distanceToBottom < EDGE_THRESHOLD)
}
get #distanceToLeft() {
return this.#boundingClientRect.left
}
get #distanceToRight() {
return window.innerWidth - this.#boundingClientRect.right
}
get #distanceToBottom() {
return window.innerHeight - this.#boundingClientRect.bottom
}
get #boundingClientRect() {
return this.dialogTarget.getBoundingClientRect()
}
}