Merge branch 'main' into unique-notifications

This commit is contained in:
Jason Zimdars
2025-11-12 10:06:47 -06:00
236 changed files with 1873 additions and 1260 deletions
@@ -6,6 +6,10 @@ export default class extends Controller {
async click() {
await nextFrame()
this.clickableTarget.click()
this.#clickable.click()
}
get #clickable() {
return this.hasClickableTarget ? this.clickableTarget : this.element
}
}
@@ -2,8 +2,8 @@ import { Controller } from "@hotwired/stimulus"
import { nextFrame, debounce } from "helpers/timing_helpers";
export default class extends Controller {
static classes = [ "collapsed", "noTransitions" ]
static targets = [ "column", "button" ]
static classes = [ "collapsed", "noTransitions", "titleNotVisible" ]
static targets = [ "column", "button", "title" ]
static values = {
board: String
}
@@ -14,6 +14,14 @@ export default class extends Controller {
async connect() {
await this.#restoreColumnsDisablingTransitions()
this.#setupIntersectionObserver()
}
disconnect() {
if (this._intersectionObserver) {
this._intersectionObserver.disconnect()
this._intersectionObserver = null
}
}
toggle({ target }) {
@@ -106,4 +114,23 @@ export default class extends Controller {
#localStorageKeyFor(column) {
return `expand-${this.boardValue}-${column.getAttribute("id")}`
}
#setupIntersectionObserver() {
if (typeof IntersectionObserver === "undefined") return
if (this._intersectionObserver) this._intersectionObserver.disconnect()
this._intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
const title = entry.target
const column = title.closest(".cards")
if (!column) return
const offscreen = entry.intersectionRatio === 0
column.classList.toggle(this.titleNotVisibleClass, offscreen)
})
}, { threshold: [0] })
this.titleTargets.forEach(title => this._intersectionObserver.observe(title))
}
}
@@ -24,6 +24,7 @@ export default class extends Controller {
limitHeightToViewport(this.dialogTarget, true)
this.#loadLazyFrames()
this.dialogTarget.setAttribute("aria-hidden", "false")
this.dispatch("show")
}
@@ -54,4 +55,8 @@ export default class extends Controller {
event.stopPropagation()
}
}
#loadLazyFrames() {
Array.from(this.dialogTarget.querySelectorAll("turbo-frame")).forEach(frame => { frame.loading = "eager" })
}
}
@@ -0,0 +1,24 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
this.element.addEventListener("dialog:show", this.handleDialogShow.bind(this))
}
disconnect() {
this.element.removeEventListener("dialog:show", this.handleDialogShow.bind(this))
}
handleDialogShow(event) {
this.#dialogControllers.forEach(dialogController => {
if (dialogController !== event.target) {
const dialog = dialogController.querySelector("dialog")
dialog.removeAttribute("open")
}
})
}
get #dialogControllers() {
return this.element.querySelectorAll('[data-controller~="dialog"]')
}
}
@@ -80,6 +80,10 @@ export default class extends Controller {
selectedItem.setAttribute(this.selectionAttributeValue, "true")
this.currentItem = selectedItem
await nextFrame()
try {
this.currentItem.scrollIntoView({ block: "nearest", inline: "nearest" })
} catch (e) {}
if (this.focusOnSelectionValue) { this.currentItem.focus() }
if (this.hasInputTarget && id) {
this.inputTarget.setAttribute("aria-activedescendant", id)