Files
3dealer/resources/js/stimulus/dropdown-controller.js
T

28 lines
1.2 KiB
JavaScript

import { Controller } from '@hotwired/stimulus'
// Positions the popover panel directly under its trigger.
//
// A [popover] renders in the top layer, so its containing block is the
// viewport, not the .dropdown wrapper — CSS alone can't tie it to the trigger
// without anchor positioning, which isn't in every browser yet. So on each
// open we measure the trigger and write the geometry to CSS custom properties
// that .dropdown-panel consumes (top / left / min-width). The open/close
// animation stays entirely in CSS; the controller only feeds it three numbers.
export default class extends Controller {
static targets = ['trigger', 'panel']
// Wired to `click->dropdown#position` on the trigger, which also fires for
// keyboard activation (Enter/Space on a <button>), so this runs before the
// native popover toggle paints the panel.
position() {
const rect = this.triggerTarget.getBoundingClientRect()
const style = this.panelTarget.style
style.setProperty('--dropdown-top', `${rect.bottom + window.scrollY}px`)
style.setProperty('--dropdown-left', `${rect.left + window.scrollX}px`)
style.setProperty('--dropdown-width', `${rect.width}px`)
}
}