document.addEventListener('alpine:init', () => { Alpine.directive('hx-val', (el, { value, expression }, { evaluateLater, effect, cleanup, evaluate }) => { var config = function (evt) { evt.detail.parameters[value] = evaluate(expression); // add a new parameter into the request } el.addEventListener('htmx:configRequest', config); cleanup(() => { el.removeEventListener('htmx:configRequest', config); }) }) Alpine.directive('hx-header', (el, { value, expression }, { evaluateLater, effect, cleanup, evaluate }) => { var config = function (evt) { evt.detail.headers[value] = evaluate(expression); // add a new parameter into the request } el.addEventListener('htmx:configRequest', config); cleanup(() => { el.removeEventListener('htmx:configRequest', config); }) }) Alpine.directive('dispatch', (el, { value, expression }, { evaluateLater, effect, cleanup, evaluate }) => { let dependent_properties = evaluateLater(expression) effect(() => { dependent_properties(props => { el.dispatchEvent( new CustomEvent(value, { props, bubbles: true, // Allows events to pass the shadow DOM barrier. composed: true, cancelable: true, }) ) }) }) }) Alpine.directive( "destroy", (el, { expression }, { evaluateLater, cleanup }) => { const onDestroy = evaluateLater(expression); cleanup(onDestroy); } ); Alpine.data('popper', () => ({ show: false, popper: null, init() { this.$nextTick(() => this.popper = Popper.createPopper(this.$refs.source, this.$refs.tooltip, { placement: 'bottom', strategy: 'fixed', modifiers: [{ name: 'preventOverflow' }, { name: 'offset', options: { offset: [0, 10] } }] })) let reveal = () => { if (!this.show) { this.show = true; } }; let hide = () => this.show = false; this.$refs.source.addEventListener('mouseover', reveal) this.$refs.source.addEventListener('mouseout', hide) }, destroy() { this.popper.destroy() }, tooltip: { [':class']() { return { 'opacity-0': !this.show, 'opacity-100': this.show, 'pointer-events-none': !this.show, 'transition': true } }, ["x-ref"]: 'tooltip', ['x-transition']: true } })); Alpine.store('darkMode', { on: false, toggle() { this.on = ! this.on } }) }) function addQueryParam(url, k, v) { let z = new URL(url, window.location.origin); z.searchParams.append(k, v); return z }