@csedl/stimulus-dropdown
Version:
Dropdown and Tooltip with stimulus and floating-ui
63 lines (54 loc) • 2.3 kB
JavaScript
import {Controller} from "@hotwired/stimulus"
import {positionPanelByButton} from "./floating-ui-functions.js";
import {debugLog, onPanelOpen} from "./utils.js";
export default class extends Controller {
opening_timer_id = null
connect() {
const panel_id = this.element.getAttribute('data-panel-id')
if (!panel_id) {
console.error(`Attribute data-panel-id missing`, this.element)
}
const delay_sec = parseFloat(this.element.getAttribute('data-delay'))
if (!delay_sec) {
console.error('missing required attribute: data-delay', this.element)
}
this.element.addEventListener('mouseenter', (e) => this.start_opening(e, panel_id, delay_sec * 1000))
this.element.addEventListener('mouseleave', (e) => this.close(e, panel_id))
if (window.StimulusDropdown.persistTooltipOnClick) {
this.element.addEventListener('click', (e) => this.toggleByClick(e, panel_id))
}
}
start_opening(e, panel_id, delay_ms) {
if (this.element.hasAttribute('data-tooltip-click')) { return; }
this.opening_timer_id = setTimeout(() => this.open(e, panel_id), delay_ms)
}
toggleByClick(e, panel_id) {
const stat = this.element.getAttribute('data-tooltip-click')
if (stat === 'open') {
debugLog('closing by click')
this.element.removeAttribute('data-tooltip-click')
this.close(e, panel_id)
} else {
debugLog('opening by click')
this.open(e, panel_id)
this.element.setAttribute('data-tooltip-click', 'open')
}
}
open(e, panel_id) {
this.element.classList.add('tooltip-is-visible')
onPanelOpen(e, this.element)
this.opening_timer_id = null
let panel = document.getElementById(panel_id)
panel.style.display = 'block';
positionPanelByButton(this.element)
}
close(e, panel_id) {
if (this.element.hasAttribute('data-tooltip-click')) { return; }
this.element.classList.remove('tooltip-is-visible')
if (this.opening_timer_id) {
clearTimeout(this.opening_timer_id)
}
let panel = document.getElementById(panel_id)
panel.style.display = 'none';
}
}