stimulus-use
Advanced tools
Comparing version 0.51.3 to 0.52.0
1108
dist/index.js
@@ -5,3 +5,2 @@ /* | ||
import { Controller } from '@hotwired/stimulus'; | ||
import hotkeys from 'hotkeys-js'; | ||
@@ -52,257 +51,3 @@ const method = (controller, methodName) => { | ||
const defaultOptions$8 = { | ||
dispatchEvent: true, | ||
eventPrefix: true, | ||
visibleAttribute: 'isVisible' | ||
}; | ||
const useIntersection = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { dispatchEvent, eventPrefix, visibleAttribute } = Object.assign({}, defaultOptions$8, options); | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
if (!controller.intersectionElements) | ||
controller.intersectionElements = []; | ||
controller.intersectionElements.push(targetElement); | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
if (entry.isIntersecting) { | ||
dispatchAppear(entry); | ||
} | ||
else if (targetElement.hasAttribute(visibleAttribute)) { | ||
dispatchDisappear(entry); | ||
} | ||
}; | ||
const dispatchAppear = (entry) => { | ||
targetElement.setAttribute(visibleAttribute, 'true'); | ||
method(controller, 'appear').call(controller, entry); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('appear', controller, eventPrefix); | ||
const appearEvent = extendedEvent(eventName, null, { controller, entry }); | ||
targetElement.dispatchEvent(appearEvent); | ||
} | ||
}; | ||
const dispatchDisappear = (entry) => { | ||
targetElement.removeAttribute(visibleAttribute); | ||
method(controller, 'disappear').call(controller, entry); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('disappear', controller, eventPrefix); | ||
const disappearEvent = extendedEvent(eventName, null, { controller, entry }); | ||
targetElement.dispatchEvent(disappearEvent); | ||
} | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new IntersectionObserver(callback, options); | ||
const observe = () => { | ||
observer.observe(targetElement); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(targetElement); | ||
}; | ||
const noneVisible = () => { | ||
return controller.intersectionElements.filter(element => element.hasAttribute(visibleAttribute)).length === 0; | ||
}; | ||
const oneVisible = () => { | ||
return controller.intersectionElements.filter(element => element.hasAttribute(visibleAttribute)).length === 1; | ||
}; | ||
const atLeastOneVisible = () => { | ||
return controller.intersectionElements.some(element => element.hasAttribute(visibleAttribute)); | ||
}; | ||
const allVisible = () => { | ||
return controller.intersectionElements.every(element => element.hasAttribute(visibleAttribute)); | ||
}; | ||
const isVisible = allVisible; | ||
Object.assign(controller, { | ||
isVisible, | ||
noneVisible, | ||
oneVisible, | ||
atLeastOneVisible, | ||
allVisible, | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class IntersectionComposableController extends Controller { | ||
} | ||
class IntersectionController extends IntersectionComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useIntersection(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const useLazyLoad = (controller, options) => { | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
if (entry.isIntersecting && !controller.isLoaded) { | ||
handleAppear(); | ||
} | ||
}; | ||
const handleAppear = (entry) => { | ||
const src = controller.data.get('src'); | ||
if (!src) | ||
return; | ||
const imageElement = controller.element; | ||
controller.isLoading = true; | ||
method(controller, 'loading').call(controller, src); | ||
imageElement.onload = () => { | ||
handleLoaded(src); | ||
}; | ||
imageElement.src = src; | ||
}; | ||
const handleLoaded = (src) => { | ||
controller.isLoading = false; | ||
controller.isLoaded = true; | ||
method(controller, 'loaded').call(controller, src); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new IntersectionObserver(callback, options); | ||
const observe = () => { | ||
observer.observe(controller.element); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(controller.element); | ||
}; | ||
Object.assign(controller, { | ||
isVisible: false, | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class LazyLoadComposableController extends Controller { | ||
constructor() { | ||
super(...arguments); | ||
this.isLoading = false; | ||
this.isLoaded = false; | ||
} | ||
} | ||
class LazyLoadController extends LazyLoadComposableController { | ||
constructor(context) { | ||
super(context); | ||
this.options = { rootMargin: '10%' }; | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useLazyLoad(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const defaultOptions$7 = { | ||
dispatchEvent: true, | ||
eventPrefix: true | ||
}; | ||
const useResize = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$7, options); | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
method(controller, 'resize').call(controller, entry.contentRect); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('resize', controller, eventPrefix); | ||
const appearEvent = extendedEvent(eventName, null, { | ||
controller, | ||
entry | ||
}); | ||
targetElement.dispatchEvent(appearEvent); | ||
} | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new ResizeObserver(callback); | ||
const observe = () => { | ||
observer.observe(targetElement); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(targetElement); | ||
}; | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class ResizeComposableController extends Controller { | ||
} | ||
class ResizeController extends ResizeComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useResize(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const defaultOptions$6 = { | ||
events: ['click', 'touchend'], | ||
onlyVisible: true, | ||
dispatchEvent: true, | ||
eventPrefix: true | ||
}; | ||
const useClickOutside = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { onlyVisible, dispatchEvent, events, eventPrefix } = Object.assign({}, defaultOptions$6, options); | ||
const onEvent = (event) => { | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
if (targetElement.contains(event.target) || (!isElementInViewport(targetElement) && onlyVisible)) { | ||
return; | ||
} | ||
if (controller.clickOutside) { | ||
controller.clickOutside(event); | ||
} | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('click:outside', controller, eventPrefix); | ||
const clickOutsideEvent = extendedEvent(eventName, event, { controller }); | ||
targetElement.dispatchEvent(clickOutsideEvent); | ||
} | ||
}; | ||
const observe = () => { | ||
events === null || events === void 0 ? void 0 : events.forEach(event => { | ||
window.addEventListener(event, onEvent, false); | ||
}); | ||
}; | ||
const unobserve = () => { | ||
events === null || events === void 0 ? void 0 : events.forEach(event => { | ||
window.removeEventListener(event, onEvent, false); | ||
}); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class ClickOutsideComposableController extends Controller { | ||
} | ||
class ClickOutsideController extends ClickOutsideComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useClickOutside(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
/*! ***************************************************************************** | ||
/****************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
@@ -334,3 +79,3 @@ | ||
const defaultOptions$5 = { | ||
const defaultOptions$8 = { | ||
debug: false, | ||
@@ -391,8 +136,8 @@ logger: console, | ||
}; | ||
this.debug = (_b = (_a = options === null || options === void 0 ? void 0 : options.debug) !== null && _a !== void 0 ? _a : controller.application.stimulusUseDebug) !== null && _b !== void 0 ? _b : defaultOptions$5.debug; | ||
this.logger = (_c = options === null || options === void 0 ? void 0 : options.logger) !== null && _c !== void 0 ? _c : defaultOptions$5.logger; | ||
this.debug = (_b = (_a = options === null || options === void 0 ? void 0 : options.debug) !== null && _a !== void 0 ? _a : controller.application.stimulusUseDebug) !== null && _b !== void 0 ? _b : defaultOptions$8.debug; | ||
this.logger = (_c = options === null || options === void 0 ? void 0 : options.logger) !== null && _c !== void 0 ? _c : defaultOptions$8.logger; | ||
this.controller = controller; | ||
this.controllerId = controller.element.id || controller.element.dataset.id; | ||
this.targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
const { dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$5, options); | ||
const { dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$8, options); | ||
Object.assign(this, { dispatchEvent, eventPrefix }); | ||
@@ -405,3 +150,3 @@ this.controllerInitialize = controller.initialize.bind(controller); | ||
const defaultOptions$4 = { | ||
const defaultOptions$7 = { | ||
eventPrefix: true, | ||
@@ -430,5 +175,5 @@ bubbles: true, | ||
this.targetElement = (_a = options.element) !== null && _a !== void 0 ? _a : controller.element; | ||
this.eventPrefix = (_b = options.eventPrefix) !== null && _b !== void 0 ? _b : defaultOptions$4.eventPrefix; | ||
this.bubbles = (_c = options.bubbles) !== null && _c !== void 0 ? _c : defaultOptions$4.bubbles; | ||
this.cancelable = (_d = options.cancelable) !== null && _d !== void 0 ? _d : defaultOptions$4.cancelable; | ||
this.eventPrefix = (_b = options.eventPrefix) !== null && _b !== void 0 ? _b : defaultOptions$7.eventPrefix; | ||
this.bubbles = (_c = options.bubbles) !== null && _c !== void 0 ? _c : defaultOptions$7.bubbles; | ||
this.cancelable = (_d = options.cancelable) !== null && _d !== void 0 ? _d : defaultOptions$7.cancelable; | ||
this.enhanceController(); | ||
@@ -444,7 +189,7 @@ } | ||
const defaultOptions$3 = { | ||
const defaultOptions$6 = { | ||
overwriteDispatch: true | ||
}; | ||
const useApplication = (controller, options = {}) => { | ||
const { overwriteDispatch } = Object.assign({}, defaultOptions$3, options); | ||
const { overwriteDispatch } = Object.assign({}, defaultOptions$6, options); | ||
Object.defineProperty(controller, 'isPreview', { | ||
@@ -487,5 +232,149 @@ get() { | ||
const defaultOptions$5 = { | ||
events: ['click', 'touchend'], | ||
onlyVisible: true, | ||
dispatchEvent: true, | ||
eventPrefix: true | ||
}; | ||
const useClickOutside = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { onlyVisible, dispatchEvent, events, eventPrefix } = Object.assign({}, defaultOptions$5, options); | ||
const onEvent = (event) => { | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
if (targetElement.contains(event.target) || (!isElementInViewport(targetElement) && onlyVisible)) { | ||
return; | ||
} | ||
if (controller.clickOutside) { | ||
controller.clickOutside(event); | ||
} | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('click:outside', controller, eventPrefix); | ||
const clickOutsideEvent = extendedEvent(eventName, event, { controller }); | ||
targetElement.dispatchEvent(clickOutsideEvent); | ||
} | ||
}; | ||
const observe = () => { | ||
events === null || events === void 0 ? void 0 : events.forEach(event => { | ||
window.addEventListener(event, onEvent, true); | ||
}); | ||
}; | ||
const unobserve = () => { | ||
events === null || events === void 0 ? void 0 : events.forEach(event => { | ||
window.removeEventListener(event, onEvent, true); | ||
}); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class ClickOutsideComposableController extends Controller { | ||
} | ||
class ClickOutsideController extends ClickOutsideComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useClickOutside(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
class DebounceController extends Controller { | ||
} | ||
DebounceController.debounces = []; | ||
const defaultWait$1 = 200; | ||
const debounce = (fn, wait = defaultWait$1) => { | ||
let timeoutId = null; | ||
return function () { | ||
const args = Array.from(arguments); | ||
const context = this; | ||
const params = args.map(arg => arg.params); | ||
const callback = () => { | ||
args.forEach((arg, index) => (arg.params = params[index])); | ||
return fn.apply(context, args); | ||
}; | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
timeoutId = setTimeout(callback, wait); | ||
}; | ||
}; | ||
const useDebounce = (composableController, options) => { | ||
const controller = composableController; | ||
const constructor = controller.constructor; | ||
constructor.debounces.forEach((func) => { | ||
if (typeof func === 'string') { | ||
controller[func] = debounce(controller[func], options === null || options === void 0 ? void 0 : options.wait); | ||
} | ||
if (typeof func === 'object') { | ||
const { name, wait } = func; | ||
if (!name) | ||
return; | ||
controller[name] = debounce(controller[name], wait || (options === null || options === void 0 ? void 0 : options.wait)); | ||
} | ||
}); | ||
}; | ||
class UseHover extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
super(controller, options); | ||
this.observe = () => { | ||
this.targetElement.addEventListener('mouseenter', this.onEnter); | ||
this.targetElement.addEventListener('mouseleave', this.onLeave); | ||
}; | ||
this.unobserve = () => { | ||
this.targetElement.removeEventListener('mouseenter', this.onEnter); | ||
this.targetElement.removeEventListener('mouseleave', this.onLeave); | ||
}; | ||
this.onEnter = (event) => { | ||
this.call('mouseEnter', event); | ||
this.log('mouseEnter', { hover: true }); | ||
this.dispatch('mouseEnter', { hover: false }); | ||
}; | ||
this.onLeave = (event) => { | ||
this.call('mouseLeave', event); | ||
this.log('mouseLeave', { hover: false }); | ||
this.dispatch('mouseLeave', { hover: false }); | ||
}; | ||
this.controller = controller; | ||
this.enhanceController(); | ||
this.observe(); | ||
} | ||
enhanceController() { | ||
const controllerDisconnect = this.controller.disconnect.bind(this.controller); | ||
const disconnect = () => { | ||
this.unobserve(); | ||
controllerDisconnect(); | ||
}; | ||
Object.assign(this.controller, { disconnect }); | ||
} | ||
} | ||
const useHover = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const observer = new UseHover(controller, options); | ||
return [observer.observe, observer.unobserve]; | ||
}; | ||
class HoverComposableController extends Controller { | ||
} | ||
class HoverController extends HoverComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useHover(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const defaultEvents = ['mousemove', 'mousedown', 'resize', 'keydown', 'touchstart', 'wheel']; | ||
const oneMinute = 60e3; | ||
const defaultOptions$2 = { | ||
const defaultOptions$4 = { | ||
ms: oneMinute, | ||
@@ -499,3 +388,3 @@ initialState: false, | ||
const controller = composableController; | ||
const { ms, initialState, events, dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$2, options); | ||
const { ms, initialState, events, dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$4, options); | ||
let isIdle = initialState; | ||
@@ -584,63 +473,145 @@ let timeout = setTimeout(() => { | ||
class UseVisibility extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
super(controller, options); | ||
this.observe = () => { | ||
this.controller.isVisible = !document.hidden; | ||
document.addEventListener('visibilitychange', this.handleVisibilityChange); | ||
this.handleVisibilityChange(); | ||
}; | ||
this.unobserve = () => { | ||
document.removeEventListener('visibilitychange', this.handleVisibilityChange); | ||
}; | ||
this.becomesInvisible = (event) => { | ||
this.controller.isVisible = false; | ||
this.call('invisible', event); | ||
this.log('invisible', { isVisible: false }); | ||
this.dispatch('invisible', { event, isVisible: false }); | ||
}; | ||
this.becomesVisible = (event) => { | ||
this.controller.isVisible = true; | ||
this.call('visible', event); | ||
this.log('visible', { isVisible: true }); | ||
this.dispatch('visible', { event, isVisible: true }); | ||
}; | ||
this.handleVisibilityChange = (event) => { | ||
if (document.hidden) { | ||
this.becomesInvisible(event); | ||
} | ||
else { | ||
this.becomesVisible(event); | ||
} | ||
}; | ||
this.controller = controller; | ||
this.enhanceController(); | ||
this.observe(); | ||
} | ||
enhanceController() { | ||
const controllerDisconnect = this.controllerDisconnect; | ||
const disconnect = () => { | ||
this.unobserve(); | ||
const defaultOptions$3 = { | ||
dispatchEvent: true, | ||
eventPrefix: true, | ||
visibleAttribute: 'isVisible' | ||
}; | ||
const useIntersection = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { dispatchEvent, eventPrefix, visibleAttribute } = Object.assign({}, defaultOptions$3, options); | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
if (!controller.intersectionElements) | ||
controller.intersectionElements = []; | ||
controller.intersectionElements.push(targetElement); | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
if (entry.isIntersecting) { | ||
dispatchAppear(entry); | ||
} | ||
else if (targetElement.hasAttribute(visibleAttribute)) { | ||
dispatchDisappear(entry); | ||
} | ||
}; | ||
const dispatchAppear = (entry) => { | ||
targetElement.setAttribute(visibleAttribute, 'true'); | ||
method(controller, 'appear').call(controller, entry); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('appear', controller, eventPrefix); | ||
const appearEvent = extendedEvent(eventName, null, { controller, entry }); | ||
targetElement.dispatchEvent(appearEvent); | ||
} | ||
}; | ||
const dispatchDisappear = (entry) => { | ||
targetElement.removeAttribute(visibleAttribute); | ||
method(controller, 'disappear').call(controller, entry); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('disappear', controller, eventPrefix); | ||
const disappearEvent = extendedEvent(eventName, null, { controller, entry }); | ||
targetElement.dispatchEvent(disappearEvent); | ||
} | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new IntersectionObserver(callback, options); | ||
const observe = () => { | ||
observer.observe(targetElement); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(targetElement); | ||
}; | ||
const noneVisible = () => { | ||
return controller.intersectionElements.filter(element => element.hasAttribute(visibleAttribute)).length === 0; | ||
}; | ||
const oneVisible = () => { | ||
return controller.intersectionElements.filter(element => element.hasAttribute(visibleAttribute)).length === 1; | ||
}; | ||
const atLeastOneVisible = () => { | ||
return controller.intersectionElements.some(element => element.hasAttribute(visibleAttribute)); | ||
}; | ||
const allVisible = () => { | ||
return controller.intersectionElements.every(element => element.hasAttribute(visibleAttribute)); | ||
}; | ||
const isVisible = allVisible; | ||
Object.assign(controller, { | ||
isVisible, | ||
noneVisible, | ||
oneVisible, | ||
atLeastOneVisible, | ||
allVisible, | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
}; | ||
Object.assign(this.controller, { disconnect }); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class IntersectionComposableController extends Controller { | ||
} | ||
class IntersectionController extends IntersectionComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useIntersection(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const useVisibility = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const observer = new UseVisibility(controller, options); | ||
return [observer.observe, observer.unobserve]; | ||
const useLazyLoad = (controller, options) => { | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
if (entry.isIntersecting && !controller.isLoaded) { | ||
handleAppear(); | ||
} | ||
}; | ||
const handleAppear = (entry) => { | ||
const src = controller.data.get('src'); | ||
if (!src) | ||
return; | ||
const imageElement = controller.element; | ||
controller.isLoading = true; | ||
method(controller, 'loading').call(controller, src); | ||
imageElement.onload = () => { | ||
handleLoaded(src); | ||
}; | ||
imageElement.src = src; | ||
}; | ||
const handleLoaded = (src) => { | ||
controller.isLoading = false; | ||
controller.isLoaded = true; | ||
method(controller, 'loaded').call(controller, src); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new IntersectionObserver(callback, options); | ||
const observe = () => { | ||
observer.observe(controller.element); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(controller.element); | ||
}; | ||
Object.assign(controller, { | ||
isVisible: false, | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class VisibilityComposableController extends Controller { | ||
class LazyLoadComposableController extends Controller { | ||
constructor() { | ||
super(...arguments); | ||
this.isVisible = false; | ||
this.isLoading = false; | ||
this.isLoaded = false; | ||
} | ||
} | ||
class VisibilityController extends VisibilityComposableController { | ||
class LazyLoadController extends LazyLoadComposableController { | ||
constructor(context) { | ||
super(context); | ||
this.options = { rootMargin: '10%' }; | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useVisibility(this, this.options); | ||
const [observe, unobserve] = useLazyLoad(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
@@ -651,24 +622,57 @@ }); | ||
class UseHover extends StimulusUse { | ||
const defaultOptions$2 = { | ||
mediaQueries: {}, | ||
dispatchEvent: true, | ||
eventPrefix: true, | ||
debug: false | ||
}; | ||
class UseMatchMedia extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
var _a, _b, _c, _d; | ||
super(controller, options); | ||
this.matches = []; | ||
this.callback = (event) => { | ||
const name = Object.keys(this.mediaQueries).find(name => this.mediaQueries[name] === event.media); | ||
if (!name) | ||
return; | ||
const { media, matches } = event; | ||
this.changed({ name, media, matches, event }); | ||
}; | ||
this.changed = (payload) => { | ||
const { name } = payload; | ||
if (payload.event) { | ||
this.call(camelize(`${name}_changed`), payload); | ||
this.dispatch(`${name}:changed`, payload); | ||
this.log(`media query "${name}" changed`, payload); | ||
} | ||
if (payload.matches) { | ||
this.call(camelize(`is_${name}`), payload); | ||
this.dispatch(`is:${name}`, payload); | ||
} | ||
else { | ||
this.call(camelize(`not_${name}`), payload); | ||
this.dispatch(`not:${name}`, payload); | ||
} | ||
}; | ||
this.observe = () => { | ||
this.targetElement.addEventListener('mouseenter', this.onEnter); | ||
this.targetElement.addEventListener('mouseleave', this.onLeave); | ||
Object.keys(this.mediaQueries).forEach(name => { | ||
const media = this.mediaQueries[name]; | ||
const match = window.matchMedia(media); | ||
match.addListener(this.callback); | ||
this.matches.push(match); | ||
this.changed({ name, media, matches: match.matches }); | ||
}); | ||
}; | ||
this.unobserve = () => { | ||
this.targetElement.removeEventListener('mouseenter', this.onEnter); | ||
this.targetElement.removeEventListener('mouseleave', this.onLeave); | ||
this.matches.forEach(match => match.removeListener(this.callback)); | ||
}; | ||
this.onEnter = (event) => { | ||
this.call('mouseEnter', event); | ||
this.log('mouseEnter', { hover: true }); | ||
this.dispatch('mouseEnter', { hover: false }); | ||
}; | ||
this.onLeave = (event) => { | ||
this.call('mouseLeave', event); | ||
this.log('mouseLeave', { hover: false }); | ||
this.dispatch('mouseLeave', { hover: false }); | ||
}; | ||
this.controller = controller; | ||
this.mediaQueries = (_a = options.mediaQueries) !== null && _a !== void 0 ? _a : defaultOptions$2.mediaQueries; | ||
this.dispatchEvent = (_b = options.dispatchEvent) !== null && _b !== void 0 ? _b : defaultOptions$2.dispatchEvent; | ||
this.eventPrefix = (_c = options.eventPrefix) !== null && _c !== void 0 ? _c : defaultOptions$2.eventPrefix; | ||
this.debug = (_d = options.debug) !== null && _d !== void 0 ? _d : defaultOptions$2.debug; | ||
if (!window.matchMedia) { | ||
console.error('window.matchMedia() is not available'); | ||
return; | ||
} | ||
this.enhanceController(); | ||
@@ -686,19 +690,57 @@ this.observe(); | ||
} | ||
const useHover = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const observer = new UseHover(controller, options); | ||
const useMatchMedia = (controller, options = {}) => { | ||
const observer = new UseMatchMedia(controller, options); | ||
return [observer.observe, observer.unobserve]; | ||
}; | ||
class HoverComposableController extends Controller { | ||
const memoize = (controller, name, value) => { | ||
Object.defineProperty(controller, name, { value }); | ||
return value; | ||
}; | ||
const useMemo = (controller) => { | ||
var _a; | ||
(_a = controller.constructor.memos) === null || _a === void 0 ? void 0 : _a.forEach((getter) => { | ||
memoize(controller, getter, controller[getter]); | ||
}); | ||
}; | ||
const defineMetaGetter = (controller, metaName, suffix) => { | ||
const getterName = suffix ? `${camelize(metaName)}Meta` : camelize(metaName); | ||
Object.defineProperty(controller, getterName, { | ||
get() { | ||
return typeCast(metaValue(metaName)); | ||
} | ||
}); | ||
}; | ||
function metaValue(name) { | ||
const element = document.head.querySelector(`meta[name="${name}"]`); | ||
return element && element.getAttribute('content'); | ||
} | ||
class HoverController extends HoverComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useHover(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
function typeCast(value) { | ||
try { | ||
return JSON.parse(value); | ||
} | ||
catch (o_O) { | ||
return value; | ||
} | ||
} | ||
const useMeta = (controller, options = { suffix: true }) => { | ||
const metaNames = controller.constructor.metaNames; | ||
const suffix = options.suffix; | ||
metaNames === null || metaNames === void 0 ? void 0 : metaNames.forEach((metaName) => { | ||
defineMetaGetter(controller, metaName, suffix); | ||
}); | ||
Object.defineProperty(controller, 'metas', { | ||
get() { | ||
const result = {}; | ||
metaNames === null || metaNames === void 0 ? void 0 : metaNames.forEach((metaName) => { | ||
const value = typeCast(metaValue(metaName)); | ||
if (value !== undefined && value !== null) { | ||
result[camelize(metaName)] = value; | ||
} | ||
}); | ||
return result; | ||
} | ||
}); | ||
}; | ||
@@ -757,2 +799,52 @@ class UseMutation extends StimulusUse { | ||
const defaultOptions$1 = { | ||
dispatchEvent: true, | ||
eventPrefix: true | ||
}; | ||
const useResize = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$1, options); | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
method(controller, 'resize').call(controller, entry.contentRect); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('resize', controller, eventPrefix); | ||
const appearEvent = extendedEvent(eventName, null, { | ||
controller, | ||
entry | ||
}); | ||
targetElement.dispatchEvent(appearEvent); | ||
} | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new ResizeObserver(callback); | ||
const observe = () => { | ||
observer.observe(targetElement); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(targetElement); | ||
}; | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class ResizeComposableController extends Controller { | ||
} | ||
class ResizeController extends ResizeComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useResize(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
class UseTargetMutation extends StimulusUse { | ||
@@ -929,90 +1021,2 @@ constructor(controller, options = {}) { | ||
const useWindowResize = (composableController) => { | ||
const controller = composableController; | ||
const callback = (event) => { | ||
const { innerWidth, innerHeight } = window; | ||
const payload = { | ||
height: innerHeight || Infinity, | ||
width: innerWidth || Infinity, | ||
event | ||
}; | ||
method(controller, 'windowResize').call(controller, payload); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observe = () => { | ||
window.addEventListener('resize', callback); | ||
callback(); | ||
}; | ||
const unobserve = () => { | ||
window.removeEventListener('resize', callback); | ||
}; | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class WindowResizeComposableController extends Controller { | ||
} | ||
class WindowResizeController extends WindowResizeComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useWindowResize(this); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const memoize = (controller, name, value) => { | ||
Object.defineProperty(controller, name, { value }); | ||
return value; | ||
}; | ||
const useMemo = (controller) => { | ||
var _a; | ||
(_a = controller.constructor.memos) === null || _a === void 0 ? void 0 : _a.forEach((getter) => { | ||
memoize(controller, getter, controller[getter]); | ||
}); | ||
}; | ||
class DebounceController extends Controller { | ||
} | ||
DebounceController.debounces = []; | ||
const defaultWait$1 = 200; | ||
const debounce = (fn, wait = defaultWait$1) => { | ||
let timeoutId = null; | ||
return function () { | ||
const args = Array.from(arguments); | ||
const context = this; | ||
const params = args.map(arg => arg.params); | ||
const callback = () => { | ||
args.forEach((arg, index) => (arg.params = params[index])); | ||
return fn.apply(context, args); | ||
}; | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
timeoutId = setTimeout(callback, wait); | ||
}; | ||
}; | ||
const useDebounce = (composableController, options) => { | ||
const controller = composableController; | ||
const constructor = controller.constructor; | ||
constructor.debounces.forEach((func) => { | ||
if (typeof func === 'string') { | ||
controller[func] = debounce(controller[func], options === null || options === void 0 ? void 0 : options.wait); | ||
} | ||
if (typeof func === 'object') { | ||
const { name, wait } = func; | ||
if (!name) | ||
return; | ||
controller[name] = debounce(controller[name], wait || (options === null || options === void 0 ? void 0 : options.wait)); | ||
} | ||
}); | ||
}; | ||
class ThrottleController extends Controller { | ||
@@ -1051,42 +1055,2 @@ } | ||
const defineMetaGetter = (controller, metaName, suffix) => { | ||
const getterName = suffix ? `${camelize(metaName)}Meta` : camelize(metaName); | ||
Object.defineProperty(controller, getterName, { | ||
get() { | ||
return typeCast(metaValue(metaName)); | ||
} | ||
}); | ||
}; | ||
function metaValue(name) { | ||
const element = document.head.querySelector(`meta[name="${name}"]`); | ||
return element && element.getAttribute('content'); | ||
} | ||
function typeCast(value) { | ||
try { | ||
return JSON.parse(value); | ||
} | ||
catch (o_O) { | ||
return value; | ||
} | ||
} | ||
const useMeta = (controller, options = { suffix: true }) => { | ||
const metaNames = controller.constructor.metaNames; | ||
const suffix = options.suffix; | ||
metaNames === null || metaNames === void 0 ? void 0 : metaNames.forEach((metaName) => { | ||
defineMetaGetter(controller, metaName, suffix); | ||
}); | ||
Object.defineProperty(controller, 'metas', { | ||
get() { | ||
const result = {}; | ||
metaNames === null || metaNames === void 0 ? void 0 : metaNames.forEach((metaName) => { | ||
const value = typeCast(metaValue(metaName)); | ||
if (value !== undefined && value !== null) { | ||
result[camelize(metaName)] = value; | ||
} | ||
}); | ||
return result; | ||
} | ||
}); | ||
}; | ||
const alpineNames = { | ||
@@ -1100,3 +1064,3 @@ enterFromClass: 'enter', | ||
}; | ||
const defaultOptions$1 = { | ||
const defaultOptions = { | ||
transitioned: false, | ||
@@ -1120,3 +1084,3 @@ hiddenClass: 'hidden', | ||
const leaveAfter = parseInt(dataset.leaveAfter || '') || options.leaveAfter || 0; | ||
const { transitioned, hiddenClass, preserveOriginalClass, removeToClasses } = Object.assign({}, defaultOptions$1, options); | ||
const { transitioned, hiddenClass, preserveOriginalClass, removeToClasses } = Object.assign({}, defaultOptions, options); | ||
const controllerEnter = (_a = controller.enter) === null || _a === void 0 ? void 0 : _a.bind(controller); | ||
@@ -1262,116 +1226,34 @@ const controllerLeave = (_b = controller.leave) === null || _b === void 0 ? void 0 : _b.bind(controller); | ||
class UseHotkeys extends StimulusUse { | ||
constructor(controller, hotkeysOptions) { | ||
super(controller, hotkeysOptions); | ||
this.bind = () => { | ||
for (const [hotkey, definition] of Object.entries(this.hotkeysOptions.hotkeys)) { | ||
const handler = definition.handler.bind(this.controller); | ||
hotkeys(hotkey, definition.options, (e) => handler(e, e)); | ||
} | ||
class UseVisibility extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
super(controller, options); | ||
this.observe = () => { | ||
this.controller.isVisible = !document.hidden; | ||
document.addEventListener('visibilitychange', this.handleVisibilityChange); | ||
this.handleVisibilityChange(); | ||
}; | ||
this.unbind = () => { | ||
for (const hotkey in this.hotkeysOptions.hotkeys) { | ||
hotkeys.unbind(hotkey); | ||
} | ||
this.unobserve = () => { | ||
document.removeEventListener('visibilitychange', this.handleVisibilityChange); | ||
}; | ||
this.controller = controller; | ||
this.hotkeysOptions = hotkeysOptions; | ||
this.enhanceController(); | ||
this.bind(); | ||
} | ||
enhanceController() { | ||
if (this.hotkeysOptions.filter) { | ||
hotkeys.filter = this.hotkeysOptions.filter; | ||
} | ||
const controllerDisconnect = this.controller.disconnect.bind(this.controller); | ||
const disconnect = () => { | ||
this.unbind(); | ||
controllerDisconnect(); | ||
this.becomesInvisible = (event) => { | ||
this.controller.isVisible = false; | ||
this.call('invisible', event); | ||
this.log('invisible', { isVisible: false }); | ||
this.dispatch('invisible', { event, isVisible: false }); | ||
}; | ||
Object.assign(this.controller, { disconnect }); | ||
} | ||
} | ||
const convertSimpleHotkeyDefinition = (definition) => { | ||
return { | ||
handler: definition[0], | ||
options: { | ||
element: definition[1] | ||
} | ||
}; | ||
}; | ||
const coerceOptions = (options) => { | ||
if (!options.hotkeys) { | ||
const hotkeys = {}; | ||
Object.entries(options).forEach(([hotkey, definition]) => { | ||
Object.defineProperty(hotkeys, hotkey, { | ||
value: convertSimpleHotkeyDefinition(definition), | ||
writable: false, | ||
enumerable: true | ||
}); | ||
}); | ||
options = { | ||
hotkeys | ||
this.becomesVisible = (event) => { | ||
this.controller.isVisible = true; | ||
this.call('visible', event); | ||
this.log('visible', { isVisible: true }); | ||
this.dispatch('visible', { event, isVisible: true }); | ||
}; | ||
} | ||
return options; | ||
}; | ||
const useHotkeys = (controller, options) => { | ||
return new UseHotkeys(controller, coerceOptions(options)); | ||
}; | ||
const defaultOptions = { | ||
mediaQueries: {}, | ||
dispatchEvent: true, | ||
eventPrefix: true, | ||
debug: false | ||
}; | ||
class UseMatchMedia extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
var _a, _b, _c, _d; | ||
super(controller, options); | ||
this.matches = []; | ||
this.callback = (event) => { | ||
const name = Object.keys(this.mediaQueries).find(name => this.mediaQueries[name] === event.media); | ||
if (!name) | ||
return; | ||
const { media, matches } = event; | ||
this.changed({ name, media, matches, event }); | ||
}; | ||
this.changed = (payload) => { | ||
const { name } = payload; | ||
if (payload.event) { | ||
this.call(camelize(`${name}_changed`), payload); | ||
this.dispatch(`${name}:changed`, payload); | ||
this.log(`media query "${name}" changed`, payload); | ||
this.handleVisibilityChange = (event) => { | ||
if (document.hidden) { | ||
this.becomesInvisible(event); | ||
} | ||
if (payload.matches) { | ||
this.call(camelize(`is_${name}`), payload); | ||
this.dispatch(`is:${name}`, payload); | ||
} | ||
else { | ||
this.call(camelize(`not_${name}`), payload); | ||
this.dispatch(`not:${name}`, payload); | ||
this.becomesVisible(event); | ||
} | ||
}; | ||
this.observe = () => { | ||
Object.keys(this.mediaQueries).forEach(name => { | ||
const media = this.mediaQueries[name]; | ||
const match = window.matchMedia(media); | ||
match.addListener(this.callback); | ||
this.matches.push(match); | ||
this.changed({ name, media, matches: match.matches }); | ||
}); | ||
}; | ||
this.unobserve = () => { | ||
this.matches.forEach(match => match.removeListener(this.callback)); | ||
}; | ||
this.controller = controller; | ||
this.mediaQueries = (_a = options.mediaQueries) !== null && _a !== void 0 ? _a : defaultOptions.mediaQueries; | ||
this.dispatchEvent = (_b = options.dispatchEvent) !== null && _b !== void 0 ? _b : defaultOptions.dispatchEvent; | ||
this.eventPrefix = (_c = options.eventPrefix) !== null && _c !== void 0 ? _c : defaultOptions.eventPrefix; | ||
this.debug = (_d = options.debug) !== null && _d !== void 0 ? _d : defaultOptions.debug; | ||
if (!window.matchMedia) { | ||
console.error('window.matchMedia() is not available'); | ||
return; | ||
} | ||
this.enhanceController(); | ||
@@ -1381,3 +1263,3 @@ this.observe(); | ||
enhanceController() { | ||
const controllerDisconnect = this.controller.disconnect.bind(this.controller); | ||
const controllerDisconnect = this.controllerDisconnect; | ||
const disconnect = () => { | ||
@@ -1390,7 +1272,24 @@ this.unobserve(); | ||
} | ||
const useMatchMedia = (controller, options = {}) => { | ||
const observer = new UseMatchMedia(controller, options); | ||
const useVisibility = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const observer = new UseVisibility(controller, options); | ||
return [observer.observe, observer.unobserve]; | ||
}; | ||
class VisibilityComposableController extends Controller { | ||
constructor() { | ||
super(...arguments); | ||
this.isVisible = false; | ||
} | ||
} | ||
class VisibilityController extends VisibilityComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useVisibility(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
class UseWindowFocus extends StimulusUse { | ||
@@ -1469,2 +1368,47 @@ constructor(controller, options = {}) { | ||
export { ApplicationController, ClickOutsideController, HoverController, IdleController, IntersectionController, LazyLoadController, MutationController, ResizeController, TargetMutationController, TransitionController, UseHover, UseMutation, UseTargetMutation, UseVisibility, VisibilityController, WindowFocusController, WindowResizeController, useApplication, useClickOutside, useDebounce, useDispatch, useHotkeys, useHover, useIdle, useIntersection, useLazyLoad, useMatchMedia, useMemo, useMeta, useMutation, useResize, useTargetMutation, useThrottle, useTransition, useVisibility, useWindowFocus, useWindowResize }; | ||
const useWindowResize = (composableController) => { | ||
const controller = composableController; | ||
const callback = (event) => { | ||
const { innerWidth, innerHeight } = window; | ||
const payload = { | ||
height: innerHeight || Infinity, | ||
width: innerWidth || Infinity, | ||
event | ||
}; | ||
method(controller, 'windowResize').call(controller, payload); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observe = () => { | ||
window.addEventListener('resize', callback); | ||
callback(); | ||
}; | ||
const unobserve = () => { | ||
window.removeEventListener('resize', callback); | ||
}; | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class WindowResizeComposableController extends Controller { | ||
} | ||
class WindowResizeController extends WindowResizeComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useWindowResize(this); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
function useHotkeys() { | ||
throw '[stimulus-use] Notice: The import for `useHotkeys()` has been moved from `stimulus-use` to `stimulus-use/hotkeys`. \nPlease change the import accordingly and add `hotkey-js` as a dependency to your project. \n\nFor more information see: https://stimulus-use.github.io/stimulus-use/#/use-hotkeys?id=importing-the-behavior'; | ||
} | ||
export { ApplicationController, ClickOutsideController, HoverController, IdleController, IntersectionController, LazyLoadController, MutationController, ResizeController, TargetMutationController, TransitionController, UseHover, UseMutation, UseTargetMutation, UseVisibility, UseWindowFocus, VisibilityController, WindowFocusController, WindowResizeController, debounce, useApplication, useClickOutside, useDebounce, useDispatch, useHotkeys, useHover, useIdle, useIntersection, useLazyLoad, useMatchMedia, useMemo, useMeta, useMutation, useResize, useTargetMutation, useThrottle, useTransition, useVisibility, useWindowFocus, useWindowResize }; |
@@ -5,11 +5,7 @@ /* | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@hotwired/stimulus'), require('hotkeys-js')) : | ||
typeof define === 'function' && define.amd ? define(['exports', '@hotwired/stimulus', 'hotkeys-js'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.StimulusUse = {}, global.Stimulus, global.hotkeys)); | ||
})(this, (function (exports, stimulus, hotkeys) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@hotwired/stimulus')) : | ||
typeof define === 'function' && define.amd ? define(['exports', '@hotwired/stimulus'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.StimulusUse = {}, global.Stimulus)); | ||
})(this, (function (exports, stimulus) { 'use strict'; | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
var hotkeys__default = /*#__PURE__*/_interopDefaultLegacy(hotkeys); | ||
const method = (controller, methodName) => { | ||
@@ -59,257 +55,3 @@ const method = controller[methodName]; | ||
const defaultOptions$8 = { | ||
dispatchEvent: true, | ||
eventPrefix: true, | ||
visibleAttribute: 'isVisible' | ||
}; | ||
const useIntersection = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { dispatchEvent, eventPrefix, visibleAttribute } = Object.assign({}, defaultOptions$8, options); | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
if (!controller.intersectionElements) | ||
controller.intersectionElements = []; | ||
controller.intersectionElements.push(targetElement); | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
if (entry.isIntersecting) { | ||
dispatchAppear(entry); | ||
} | ||
else if (targetElement.hasAttribute(visibleAttribute)) { | ||
dispatchDisappear(entry); | ||
} | ||
}; | ||
const dispatchAppear = (entry) => { | ||
targetElement.setAttribute(visibleAttribute, 'true'); | ||
method(controller, 'appear').call(controller, entry); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('appear', controller, eventPrefix); | ||
const appearEvent = extendedEvent(eventName, null, { controller, entry }); | ||
targetElement.dispatchEvent(appearEvent); | ||
} | ||
}; | ||
const dispatchDisappear = (entry) => { | ||
targetElement.removeAttribute(visibleAttribute); | ||
method(controller, 'disappear').call(controller, entry); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('disappear', controller, eventPrefix); | ||
const disappearEvent = extendedEvent(eventName, null, { controller, entry }); | ||
targetElement.dispatchEvent(disappearEvent); | ||
} | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new IntersectionObserver(callback, options); | ||
const observe = () => { | ||
observer.observe(targetElement); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(targetElement); | ||
}; | ||
const noneVisible = () => { | ||
return controller.intersectionElements.filter(element => element.hasAttribute(visibleAttribute)).length === 0; | ||
}; | ||
const oneVisible = () => { | ||
return controller.intersectionElements.filter(element => element.hasAttribute(visibleAttribute)).length === 1; | ||
}; | ||
const atLeastOneVisible = () => { | ||
return controller.intersectionElements.some(element => element.hasAttribute(visibleAttribute)); | ||
}; | ||
const allVisible = () => { | ||
return controller.intersectionElements.every(element => element.hasAttribute(visibleAttribute)); | ||
}; | ||
const isVisible = allVisible; | ||
Object.assign(controller, { | ||
isVisible, | ||
noneVisible, | ||
oneVisible, | ||
atLeastOneVisible, | ||
allVisible, | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class IntersectionComposableController extends stimulus.Controller { | ||
} | ||
class IntersectionController extends IntersectionComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useIntersection(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const useLazyLoad = (controller, options) => { | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
if (entry.isIntersecting && !controller.isLoaded) { | ||
handleAppear(); | ||
} | ||
}; | ||
const handleAppear = (entry) => { | ||
const src = controller.data.get('src'); | ||
if (!src) | ||
return; | ||
const imageElement = controller.element; | ||
controller.isLoading = true; | ||
method(controller, 'loading').call(controller, src); | ||
imageElement.onload = () => { | ||
handleLoaded(src); | ||
}; | ||
imageElement.src = src; | ||
}; | ||
const handleLoaded = (src) => { | ||
controller.isLoading = false; | ||
controller.isLoaded = true; | ||
method(controller, 'loaded').call(controller, src); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new IntersectionObserver(callback, options); | ||
const observe = () => { | ||
observer.observe(controller.element); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(controller.element); | ||
}; | ||
Object.assign(controller, { | ||
isVisible: false, | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class LazyLoadComposableController extends stimulus.Controller { | ||
constructor() { | ||
super(...arguments); | ||
this.isLoading = false; | ||
this.isLoaded = false; | ||
} | ||
} | ||
class LazyLoadController extends LazyLoadComposableController { | ||
constructor(context) { | ||
super(context); | ||
this.options = { rootMargin: '10%' }; | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useLazyLoad(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const defaultOptions$7 = { | ||
dispatchEvent: true, | ||
eventPrefix: true | ||
}; | ||
const useResize = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$7, options); | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
method(controller, 'resize').call(controller, entry.contentRect); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('resize', controller, eventPrefix); | ||
const appearEvent = extendedEvent(eventName, null, { | ||
controller, | ||
entry | ||
}); | ||
targetElement.dispatchEvent(appearEvent); | ||
} | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new ResizeObserver(callback); | ||
const observe = () => { | ||
observer.observe(targetElement); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(targetElement); | ||
}; | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class ResizeComposableController extends stimulus.Controller { | ||
} | ||
class ResizeController extends ResizeComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useResize(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const defaultOptions$6 = { | ||
events: ['click', 'touchend'], | ||
onlyVisible: true, | ||
dispatchEvent: true, | ||
eventPrefix: true | ||
}; | ||
const useClickOutside = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { onlyVisible, dispatchEvent, events, eventPrefix } = Object.assign({}, defaultOptions$6, options); | ||
const onEvent = (event) => { | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
if (targetElement.contains(event.target) || (!isElementInViewport(targetElement) && onlyVisible)) { | ||
return; | ||
} | ||
if (controller.clickOutside) { | ||
controller.clickOutside(event); | ||
} | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('click:outside', controller, eventPrefix); | ||
const clickOutsideEvent = extendedEvent(eventName, event, { controller }); | ||
targetElement.dispatchEvent(clickOutsideEvent); | ||
} | ||
}; | ||
const observe = () => { | ||
events === null || events === void 0 ? void 0 : events.forEach(event => { | ||
window.addEventListener(event, onEvent, false); | ||
}); | ||
}; | ||
const unobserve = () => { | ||
events === null || events === void 0 ? void 0 : events.forEach(event => { | ||
window.removeEventListener(event, onEvent, false); | ||
}); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class ClickOutsideComposableController extends stimulus.Controller { | ||
} | ||
class ClickOutsideController extends ClickOutsideComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useClickOutside(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
/*! ***************************************************************************** | ||
/****************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
@@ -341,3 +83,3 @@ | ||
const defaultOptions$5 = { | ||
const defaultOptions$8 = { | ||
debug: false, | ||
@@ -398,8 +140,8 @@ logger: console, | ||
}; | ||
this.debug = (_b = (_a = options === null || options === void 0 ? void 0 : options.debug) !== null && _a !== void 0 ? _a : controller.application.stimulusUseDebug) !== null && _b !== void 0 ? _b : defaultOptions$5.debug; | ||
this.logger = (_c = options === null || options === void 0 ? void 0 : options.logger) !== null && _c !== void 0 ? _c : defaultOptions$5.logger; | ||
this.debug = (_b = (_a = options === null || options === void 0 ? void 0 : options.debug) !== null && _a !== void 0 ? _a : controller.application.stimulusUseDebug) !== null && _b !== void 0 ? _b : defaultOptions$8.debug; | ||
this.logger = (_c = options === null || options === void 0 ? void 0 : options.logger) !== null && _c !== void 0 ? _c : defaultOptions$8.logger; | ||
this.controller = controller; | ||
this.controllerId = controller.element.id || controller.element.dataset.id; | ||
this.targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
const { dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$5, options); | ||
const { dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$8, options); | ||
Object.assign(this, { dispatchEvent, eventPrefix }); | ||
@@ -412,3 +154,3 @@ this.controllerInitialize = controller.initialize.bind(controller); | ||
const defaultOptions$4 = { | ||
const defaultOptions$7 = { | ||
eventPrefix: true, | ||
@@ -437,5 +179,5 @@ bubbles: true, | ||
this.targetElement = (_a = options.element) !== null && _a !== void 0 ? _a : controller.element; | ||
this.eventPrefix = (_b = options.eventPrefix) !== null && _b !== void 0 ? _b : defaultOptions$4.eventPrefix; | ||
this.bubbles = (_c = options.bubbles) !== null && _c !== void 0 ? _c : defaultOptions$4.bubbles; | ||
this.cancelable = (_d = options.cancelable) !== null && _d !== void 0 ? _d : defaultOptions$4.cancelable; | ||
this.eventPrefix = (_b = options.eventPrefix) !== null && _b !== void 0 ? _b : defaultOptions$7.eventPrefix; | ||
this.bubbles = (_c = options.bubbles) !== null && _c !== void 0 ? _c : defaultOptions$7.bubbles; | ||
this.cancelable = (_d = options.cancelable) !== null && _d !== void 0 ? _d : defaultOptions$7.cancelable; | ||
this.enhanceController(); | ||
@@ -451,7 +193,7 @@ } | ||
const defaultOptions$3 = { | ||
const defaultOptions$6 = { | ||
overwriteDispatch: true | ||
}; | ||
const useApplication = (controller, options = {}) => { | ||
const { overwriteDispatch } = Object.assign({}, defaultOptions$3, options); | ||
const { overwriteDispatch } = Object.assign({}, defaultOptions$6, options); | ||
Object.defineProperty(controller, 'isPreview', { | ||
@@ -494,5 +236,149 @@ get() { | ||
const defaultOptions$5 = { | ||
events: ['click', 'touchend'], | ||
onlyVisible: true, | ||
dispatchEvent: true, | ||
eventPrefix: true | ||
}; | ||
const useClickOutside = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { onlyVisible, dispatchEvent, events, eventPrefix } = Object.assign({}, defaultOptions$5, options); | ||
const onEvent = (event) => { | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
if (targetElement.contains(event.target) || (!isElementInViewport(targetElement) && onlyVisible)) { | ||
return; | ||
} | ||
if (controller.clickOutside) { | ||
controller.clickOutside(event); | ||
} | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('click:outside', controller, eventPrefix); | ||
const clickOutsideEvent = extendedEvent(eventName, event, { controller }); | ||
targetElement.dispatchEvent(clickOutsideEvent); | ||
} | ||
}; | ||
const observe = () => { | ||
events === null || events === void 0 ? void 0 : events.forEach(event => { | ||
window.addEventListener(event, onEvent, true); | ||
}); | ||
}; | ||
const unobserve = () => { | ||
events === null || events === void 0 ? void 0 : events.forEach(event => { | ||
window.removeEventListener(event, onEvent, true); | ||
}); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class ClickOutsideComposableController extends stimulus.Controller { | ||
} | ||
class ClickOutsideController extends ClickOutsideComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useClickOutside(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
class DebounceController extends stimulus.Controller { | ||
} | ||
DebounceController.debounces = []; | ||
const defaultWait$1 = 200; | ||
const debounce = (fn, wait = defaultWait$1) => { | ||
let timeoutId = null; | ||
return function () { | ||
const args = Array.from(arguments); | ||
const context = this; | ||
const params = args.map(arg => arg.params); | ||
const callback = () => { | ||
args.forEach((arg, index) => (arg.params = params[index])); | ||
return fn.apply(context, args); | ||
}; | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
timeoutId = setTimeout(callback, wait); | ||
}; | ||
}; | ||
const useDebounce = (composableController, options) => { | ||
const controller = composableController; | ||
const constructor = controller.constructor; | ||
constructor.debounces.forEach((func) => { | ||
if (typeof func === 'string') { | ||
controller[func] = debounce(controller[func], options === null || options === void 0 ? void 0 : options.wait); | ||
} | ||
if (typeof func === 'object') { | ||
const { name, wait } = func; | ||
if (!name) | ||
return; | ||
controller[name] = debounce(controller[name], wait || (options === null || options === void 0 ? void 0 : options.wait)); | ||
} | ||
}); | ||
}; | ||
class UseHover extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
super(controller, options); | ||
this.observe = () => { | ||
this.targetElement.addEventListener('mouseenter', this.onEnter); | ||
this.targetElement.addEventListener('mouseleave', this.onLeave); | ||
}; | ||
this.unobserve = () => { | ||
this.targetElement.removeEventListener('mouseenter', this.onEnter); | ||
this.targetElement.removeEventListener('mouseleave', this.onLeave); | ||
}; | ||
this.onEnter = (event) => { | ||
this.call('mouseEnter', event); | ||
this.log('mouseEnter', { hover: true }); | ||
this.dispatch('mouseEnter', { hover: false }); | ||
}; | ||
this.onLeave = (event) => { | ||
this.call('mouseLeave', event); | ||
this.log('mouseLeave', { hover: false }); | ||
this.dispatch('mouseLeave', { hover: false }); | ||
}; | ||
this.controller = controller; | ||
this.enhanceController(); | ||
this.observe(); | ||
} | ||
enhanceController() { | ||
const controllerDisconnect = this.controller.disconnect.bind(this.controller); | ||
const disconnect = () => { | ||
this.unobserve(); | ||
controllerDisconnect(); | ||
}; | ||
Object.assign(this.controller, { disconnect }); | ||
} | ||
} | ||
const useHover = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const observer = new UseHover(controller, options); | ||
return [observer.observe, observer.unobserve]; | ||
}; | ||
class HoverComposableController extends stimulus.Controller { | ||
} | ||
class HoverController extends HoverComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useHover(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const defaultEvents = ['mousemove', 'mousedown', 'resize', 'keydown', 'touchstart', 'wheel']; | ||
const oneMinute = 60e3; | ||
const defaultOptions$2 = { | ||
const defaultOptions$4 = { | ||
ms: oneMinute, | ||
@@ -506,3 +392,3 @@ initialState: false, | ||
const controller = composableController; | ||
const { ms, initialState, events, dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$2, options); | ||
const { ms, initialState, events, dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$4, options); | ||
let isIdle = initialState; | ||
@@ -591,63 +477,145 @@ let timeout = setTimeout(() => { | ||
class UseVisibility extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
super(controller, options); | ||
this.observe = () => { | ||
this.controller.isVisible = !document.hidden; | ||
document.addEventListener('visibilitychange', this.handleVisibilityChange); | ||
this.handleVisibilityChange(); | ||
}; | ||
this.unobserve = () => { | ||
document.removeEventListener('visibilitychange', this.handleVisibilityChange); | ||
}; | ||
this.becomesInvisible = (event) => { | ||
this.controller.isVisible = false; | ||
this.call('invisible', event); | ||
this.log('invisible', { isVisible: false }); | ||
this.dispatch('invisible', { event, isVisible: false }); | ||
}; | ||
this.becomesVisible = (event) => { | ||
this.controller.isVisible = true; | ||
this.call('visible', event); | ||
this.log('visible', { isVisible: true }); | ||
this.dispatch('visible', { event, isVisible: true }); | ||
}; | ||
this.handleVisibilityChange = (event) => { | ||
if (document.hidden) { | ||
this.becomesInvisible(event); | ||
} | ||
else { | ||
this.becomesVisible(event); | ||
} | ||
}; | ||
this.controller = controller; | ||
this.enhanceController(); | ||
this.observe(); | ||
} | ||
enhanceController() { | ||
const controllerDisconnect = this.controllerDisconnect; | ||
const disconnect = () => { | ||
this.unobserve(); | ||
const defaultOptions$3 = { | ||
dispatchEvent: true, | ||
eventPrefix: true, | ||
visibleAttribute: 'isVisible' | ||
}; | ||
const useIntersection = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { dispatchEvent, eventPrefix, visibleAttribute } = Object.assign({}, defaultOptions$3, options); | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
if (!controller.intersectionElements) | ||
controller.intersectionElements = []; | ||
controller.intersectionElements.push(targetElement); | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
if (entry.isIntersecting) { | ||
dispatchAppear(entry); | ||
} | ||
else if (targetElement.hasAttribute(visibleAttribute)) { | ||
dispatchDisappear(entry); | ||
} | ||
}; | ||
const dispatchAppear = (entry) => { | ||
targetElement.setAttribute(visibleAttribute, 'true'); | ||
method(controller, 'appear').call(controller, entry); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('appear', controller, eventPrefix); | ||
const appearEvent = extendedEvent(eventName, null, { controller, entry }); | ||
targetElement.dispatchEvent(appearEvent); | ||
} | ||
}; | ||
const dispatchDisappear = (entry) => { | ||
targetElement.removeAttribute(visibleAttribute); | ||
method(controller, 'disappear').call(controller, entry); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('disappear', controller, eventPrefix); | ||
const disappearEvent = extendedEvent(eventName, null, { controller, entry }); | ||
targetElement.dispatchEvent(disappearEvent); | ||
} | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new IntersectionObserver(callback, options); | ||
const observe = () => { | ||
observer.observe(targetElement); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(targetElement); | ||
}; | ||
const noneVisible = () => { | ||
return controller.intersectionElements.filter(element => element.hasAttribute(visibleAttribute)).length === 0; | ||
}; | ||
const oneVisible = () => { | ||
return controller.intersectionElements.filter(element => element.hasAttribute(visibleAttribute)).length === 1; | ||
}; | ||
const atLeastOneVisible = () => { | ||
return controller.intersectionElements.some(element => element.hasAttribute(visibleAttribute)); | ||
}; | ||
const allVisible = () => { | ||
return controller.intersectionElements.every(element => element.hasAttribute(visibleAttribute)); | ||
}; | ||
const isVisible = allVisible; | ||
Object.assign(controller, { | ||
isVisible, | ||
noneVisible, | ||
oneVisible, | ||
atLeastOneVisible, | ||
allVisible, | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
}; | ||
Object.assign(this.controller, { disconnect }); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class IntersectionComposableController extends stimulus.Controller { | ||
} | ||
class IntersectionController extends IntersectionComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useIntersection(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const useVisibility = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const observer = new UseVisibility(controller, options); | ||
return [observer.observe, observer.unobserve]; | ||
const useLazyLoad = (controller, options) => { | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
if (entry.isIntersecting && !controller.isLoaded) { | ||
handleAppear(); | ||
} | ||
}; | ||
const handleAppear = (entry) => { | ||
const src = controller.data.get('src'); | ||
if (!src) | ||
return; | ||
const imageElement = controller.element; | ||
controller.isLoading = true; | ||
method(controller, 'loading').call(controller, src); | ||
imageElement.onload = () => { | ||
handleLoaded(src); | ||
}; | ||
imageElement.src = src; | ||
}; | ||
const handleLoaded = (src) => { | ||
controller.isLoading = false; | ||
controller.isLoaded = true; | ||
method(controller, 'loaded').call(controller, src); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new IntersectionObserver(callback, options); | ||
const observe = () => { | ||
observer.observe(controller.element); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(controller.element); | ||
}; | ||
Object.assign(controller, { | ||
isVisible: false, | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class VisibilityComposableController extends stimulus.Controller { | ||
class LazyLoadComposableController extends stimulus.Controller { | ||
constructor() { | ||
super(...arguments); | ||
this.isVisible = false; | ||
this.isLoading = false; | ||
this.isLoaded = false; | ||
} | ||
} | ||
class VisibilityController extends VisibilityComposableController { | ||
class LazyLoadController extends LazyLoadComposableController { | ||
constructor(context) { | ||
super(context); | ||
this.options = { rootMargin: '10%' }; | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useVisibility(this, this.options); | ||
const [observe, unobserve] = useLazyLoad(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
@@ -658,24 +626,57 @@ }); | ||
class UseHover extends StimulusUse { | ||
const defaultOptions$2 = { | ||
mediaQueries: {}, | ||
dispatchEvent: true, | ||
eventPrefix: true, | ||
debug: false | ||
}; | ||
class UseMatchMedia extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
var _a, _b, _c, _d; | ||
super(controller, options); | ||
this.matches = []; | ||
this.callback = (event) => { | ||
const name = Object.keys(this.mediaQueries).find(name => this.mediaQueries[name] === event.media); | ||
if (!name) | ||
return; | ||
const { media, matches } = event; | ||
this.changed({ name, media, matches, event }); | ||
}; | ||
this.changed = (payload) => { | ||
const { name } = payload; | ||
if (payload.event) { | ||
this.call(camelize(`${name}_changed`), payload); | ||
this.dispatch(`${name}:changed`, payload); | ||
this.log(`media query "${name}" changed`, payload); | ||
} | ||
if (payload.matches) { | ||
this.call(camelize(`is_${name}`), payload); | ||
this.dispatch(`is:${name}`, payload); | ||
} | ||
else { | ||
this.call(camelize(`not_${name}`), payload); | ||
this.dispatch(`not:${name}`, payload); | ||
} | ||
}; | ||
this.observe = () => { | ||
this.targetElement.addEventListener('mouseenter', this.onEnter); | ||
this.targetElement.addEventListener('mouseleave', this.onLeave); | ||
Object.keys(this.mediaQueries).forEach(name => { | ||
const media = this.mediaQueries[name]; | ||
const match = window.matchMedia(media); | ||
match.addListener(this.callback); | ||
this.matches.push(match); | ||
this.changed({ name, media, matches: match.matches }); | ||
}); | ||
}; | ||
this.unobserve = () => { | ||
this.targetElement.removeEventListener('mouseenter', this.onEnter); | ||
this.targetElement.removeEventListener('mouseleave', this.onLeave); | ||
this.matches.forEach(match => match.removeListener(this.callback)); | ||
}; | ||
this.onEnter = (event) => { | ||
this.call('mouseEnter', event); | ||
this.log('mouseEnter', { hover: true }); | ||
this.dispatch('mouseEnter', { hover: false }); | ||
}; | ||
this.onLeave = (event) => { | ||
this.call('mouseLeave', event); | ||
this.log('mouseLeave', { hover: false }); | ||
this.dispatch('mouseLeave', { hover: false }); | ||
}; | ||
this.controller = controller; | ||
this.mediaQueries = (_a = options.mediaQueries) !== null && _a !== void 0 ? _a : defaultOptions$2.mediaQueries; | ||
this.dispatchEvent = (_b = options.dispatchEvent) !== null && _b !== void 0 ? _b : defaultOptions$2.dispatchEvent; | ||
this.eventPrefix = (_c = options.eventPrefix) !== null && _c !== void 0 ? _c : defaultOptions$2.eventPrefix; | ||
this.debug = (_d = options.debug) !== null && _d !== void 0 ? _d : defaultOptions$2.debug; | ||
if (!window.matchMedia) { | ||
console.error('window.matchMedia() is not available'); | ||
return; | ||
} | ||
this.enhanceController(); | ||
@@ -693,19 +694,57 @@ this.observe(); | ||
} | ||
const useHover = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const observer = new UseHover(controller, options); | ||
const useMatchMedia = (controller, options = {}) => { | ||
const observer = new UseMatchMedia(controller, options); | ||
return [observer.observe, observer.unobserve]; | ||
}; | ||
class HoverComposableController extends stimulus.Controller { | ||
const memoize = (controller, name, value) => { | ||
Object.defineProperty(controller, name, { value }); | ||
return value; | ||
}; | ||
const useMemo = (controller) => { | ||
var _a; | ||
(_a = controller.constructor.memos) === null || _a === void 0 ? void 0 : _a.forEach((getter) => { | ||
memoize(controller, getter, controller[getter]); | ||
}); | ||
}; | ||
const defineMetaGetter = (controller, metaName, suffix) => { | ||
const getterName = suffix ? `${camelize(metaName)}Meta` : camelize(metaName); | ||
Object.defineProperty(controller, getterName, { | ||
get() { | ||
return typeCast(metaValue(metaName)); | ||
} | ||
}); | ||
}; | ||
function metaValue(name) { | ||
const element = document.head.querySelector(`meta[name="${name}"]`); | ||
return element && element.getAttribute('content'); | ||
} | ||
class HoverController extends HoverComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useHover(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
function typeCast(value) { | ||
try { | ||
return JSON.parse(value); | ||
} | ||
catch (o_O) { | ||
return value; | ||
} | ||
} | ||
const useMeta = (controller, options = { suffix: true }) => { | ||
const metaNames = controller.constructor.metaNames; | ||
const suffix = options.suffix; | ||
metaNames === null || metaNames === void 0 ? void 0 : metaNames.forEach((metaName) => { | ||
defineMetaGetter(controller, metaName, suffix); | ||
}); | ||
Object.defineProperty(controller, 'metas', { | ||
get() { | ||
const result = {}; | ||
metaNames === null || metaNames === void 0 ? void 0 : metaNames.forEach((metaName) => { | ||
const value = typeCast(metaValue(metaName)); | ||
if (value !== undefined && value !== null) { | ||
result[camelize(metaName)] = value; | ||
} | ||
}); | ||
return result; | ||
} | ||
}); | ||
}; | ||
@@ -764,2 +803,52 @@ class UseMutation extends StimulusUse { | ||
const defaultOptions$1 = { | ||
dispatchEvent: true, | ||
eventPrefix: true | ||
}; | ||
const useResize = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const { dispatchEvent, eventPrefix } = Object.assign({}, defaultOptions$1, options); | ||
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || controller.element; | ||
const callback = (entries) => { | ||
const [entry] = entries; | ||
method(controller, 'resize').call(controller, entry.contentRect); | ||
if (dispatchEvent) { | ||
const eventName = composeEventName('resize', controller, eventPrefix); | ||
const appearEvent = extendedEvent(eventName, null, { | ||
controller, | ||
entry | ||
}); | ||
targetElement.dispatchEvent(appearEvent); | ||
} | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observer = new ResizeObserver(callback); | ||
const observe = () => { | ||
observer.observe(targetElement); | ||
}; | ||
const unobserve = () => { | ||
observer.unobserve(targetElement); | ||
}; | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class ResizeComposableController extends stimulus.Controller { | ||
} | ||
class ResizeController extends ResizeComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useResize(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
class UseTargetMutation extends StimulusUse { | ||
@@ -936,90 +1025,2 @@ constructor(controller, options = {}) { | ||
const useWindowResize = (composableController) => { | ||
const controller = composableController; | ||
const callback = (event) => { | ||
const { innerWidth, innerHeight } = window; | ||
const payload = { | ||
height: innerHeight || Infinity, | ||
width: innerWidth || Infinity, | ||
event | ||
}; | ||
method(controller, 'windowResize').call(controller, payload); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observe = () => { | ||
window.addEventListener('resize', callback); | ||
callback(); | ||
}; | ||
const unobserve = () => { | ||
window.removeEventListener('resize', callback); | ||
}; | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class WindowResizeComposableController extends stimulus.Controller { | ||
} | ||
class WindowResizeController extends WindowResizeComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useWindowResize(this); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
const memoize = (controller, name, value) => { | ||
Object.defineProperty(controller, name, { value }); | ||
return value; | ||
}; | ||
const useMemo = (controller) => { | ||
var _a; | ||
(_a = controller.constructor.memos) === null || _a === void 0 ? void 0 : _a.forEach((getter) => { | ||
memoize(controller, getter, controller[getter]); | ||
}); | ||
}; | ||
class DebounceController extends stimulus.Controller { | ||
} | ||
DebounceController.debounces = []; | ||
const defaultWait$1 = 200; | ||
const debounce = (fn, wait = defaultWait$1) => { | ||
let timeoutId = null; | ||
return function () { | ||
const args = Array.from(arguments); | ||
const context = this; | ||
const params = args.map(arg => arg.params); | ||
const callback = () => { | ||
args.forEach((arg, index) => (arg.params = params[index])); | ||
return fn.apply(context, args); | ||
}; | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
timeoutId = setTimeout(callback, wait); | ||
}; | ||
}; | ||
const useDebounce = (composableController, options) => { | ||
const controller = composableController; | ||
const constructor = controller.constructor; | ||
constructor.debounces.forEach((func) => { | ||
if (typeof func === 'string') { | ||
controller[func] = debounce(controller[func], options === null || options === void 0 ? void 0 : options.wait); | ||
} | ||
if (typeof func === 'object') { | ||
const { name, wait } = func; | ||
if (!name) | ||
return; | ||
controller[name] = debounce(controller[name], wait || (options === null || options === void 0 ? void 0 : options.wait)); | ||
} | ||
}); | ||
}; | ||
class ThrottleController extends stimulus.Controller { | ||
@@ -1058,42 +1059,2 @@ } | ||
const defineMetaGetter = (controller, metaName, suffix) => { | ||
const getterName = suffix ? `${camelize(metaName)}Meta` : camelize(metaName); | ||
Object.defineProperty(controller, getterName, { | ||
get() { | ||
return typeCast(metaValue(metaName)); | ||
} | ||
}); | ||
}; | ||
function metaValue(name) { | ||
const element = document.head.querySelector(`meta[name="${name}"]`); | ||
return element && element.getAttribute('content'); | ||
} | ||
function typeCast(value) { | ||
try { | ||
return JSON.parse(value); | ||
} | ||
catch (o_O) { | ||
return value; | ||
} | ||
} | ||
const useMeta = (controller, options = { suffix: true }) => { | ||
const metaNames = controller.constructor.metaNames; | ||
const suffix = options.suffix; | ||
metaNames === null || metaNames === void 0 ? void 0 : metaNames.forEach((metaName) => { | ||
defineMetaGetter(controller, metaName, suffix); | ||
}); | ||
Object.defineProperty(controller, 'metas', { | ||
get() { | ||
const result = {}; | ||
metaNames === null || metaNames === void 0 ? void 0 : metaNames.forEach((metaName) => { | ||
const value = typeCast(metaValue(metaName)); | ||
if (value !== undefined && value !== null) { | ||
result[camelize(metaName)] = value; | ||
} | ||
}); | ||
return result; | ||
} | ||
}); | ||
}; | ||
const alpineNames = { | ||
@@ -1107,3 +1068,3 @@ enterFromClass: 'enter', | ||
}; | ||
const defaultOptions$1 = { | ||
const defaultOptions = { | ||
transitioned: false, | ||
@@ -1127,3 +1088,3 @@ hiddenClass: 'hidden', | ||
const leaveAfter = parseInt(dataset.leaveAfter || '') || options.leaveAfter || 0; | ||
const { transitioned, hiddenClass, preserveOriginalClass, removeToClasses } = Object.assign({}, defaultOptions$1, options); | ||
const { transitioned, hiddenClass, preserveOriginalClass, removeToClasses } = Object.assign({}, defaultOptions, options); | ||
const controllerEnter = (_a = controller.enter) === null || _a === void 0 ? void 0 : _a.bind(controller); | ||
@@ -1269,116 +1230,34 @@ const controllerLeave = (_b = controller.leave) === null || _b === void 0 ? void 0 : _b.bind(controller); | ||
class UseHotkeys extends StimulusUse { | ||
constructor(controller, hotkeysOptions) { | ||
super(controller, hotkeysOptions); | ||
this.bind = () => { | ||
for (const [hotkey, definition] of Object.entries(this.hotkeysOptions.hotkeys)) { | ||
const handler = definition.handler.bind(this.controller); | ||
hotkeys__default["default"](hotkey, definition.options, (e) => handler(e, e)); | ||
} | ||
class UseVisibility extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
super(controller, options); | ||
this.observe = () => { | ||
this.controller.isVisible = !document.hidden; | ||
document.addEventListener('visibilitychange', this.handleVisibilityChange); | ||
this.handleVisibilityChange(); | ||
}; | ||
this.unbind = () => { | ||
for (const hotkey in this.hotkeysOptions.hotkeys) { | ||
hotkeys__default["default"].unbind(hotkey); | ||
} | ||
this.unobserve = () => { | ||
document.removeEventListener('visibilitychange', this.handleVisibilityChange); | ||
}; | ||
this.controller = controller; | ||
this.hotkeysOptions = hotkeysOptions; | ||
this.enhanceController(); | ||
this.bind(); | ||
} | ||
enhanceController() { | ||
if (this.hotkeysOptions.filter) { | ||
hotkeys__default["default"].filter = this.hotkeysOptions.filter; | ||
} | ||
const controllerDisconnect = this.controller.disconnect.bind(this.controller); | ||
const disconnect = () => { | ||
this.unbind(); | ||
controllerDisconnect(); | ||
this.becomesInvisible = (event) => { | ||
this.controller.isVisible = false; | ||
this.call('invisible', event); | ||
this.log('invisible', { isVisible: false }); | ||
this.dispatch('invisible', { event, isVisible: false }); | ||
}; | ||
Object.assign(this.controller, { disconnect }); | ||
} | ||
} | ||
const convertSimpleHotkeyDefinition = (definition) => { | ||
return { | ||
handler: definition[0], | ||
options: { | ||
element: definition[1] | ||
} | ||
}; | ||
}; | ||
const coerceOptions = (options) => { | ||
if (!options.hotkeys) { | ||
const hotkeys = {}; | ||
Object.entries(options).forEach(([hotkey, definition]) => { | ||
Object.defineProperty(hotkeys, hotkey, { | ||
value: convertSimpleHotkeyDefinition(definition), | ||
writable: false, | ||
enumerable: true | ||
}); | ||
}); | ||
options = { | ||
hotkeys | ||
this.becomesVisible = (event) => { | ||
this.controller.isVisible = true; | ||
this.call('visible', event); | ||
this.log('visible', { isVisible: true }); | ||
this.dispatch('visible', { event, isVisible: true }); | ||
}; | ||
} | ||
return options; | ||
}; | ||
const useHotkeys = (controller, options) => { | ||
return new UseHotkeys(controller, coerceOptions(options)); | ||
}; | ||
const defaultOptions = { | ||
mediaQueries: {}, | ||
dispatchEvent: true, | ||
eventPrefix: true, | ||
debug: false | ||
}; | ||
class UseMatchMedia extends StimulusUse { | ||
constructor(controller, options = {}) { | ||
var _a, _b, _c, _d; | ||
super(controller, options); | ||
this.matches = []; | ||
this.callback = (event) => { | ||
const name = Object.keys(this.mediaQueries).find(name => this.mediaQueries[name] === event.media); | ||
if (!name) | ||
return; | ||
const { media, matches } = event; | ||
this.changed({ name, media, matches, event }); | ||
}; | ||
this.changed = (payload) => { | ||
const { name } = payload; | ||
if (payload.event) { | ||
this.call(camelize(`${name}_changed`), payload); | ||
this.dispatch(`${name}:changed`, payload); | ||
this.log(`media query "${name}" changed`, payload); | ||
this.handleVisibilityChange = (event) => { | ||
if (document.hidden) { | ||
this.becomesInvisible(event); | ||
} | ||
if (payload.matches) { | ||
this.call(camelize(`is_${name}`), payload); | ||
this.dispatch(`is:${name}`, payload); | ||
} | ||
else { | ||
this.call(camelize(`not_${name}`), payload); | ||
this.dispatch(`not:${name}`, payload); | ||
this.becomesVisible(event); | ||
} | ||
}; | ||
this.observe = () => { | ||
Object.keys(this.mediaQueries).forEach(name => { | ||
const media = this.mediaQueries[name]; | ||
const match = window.matchMedia(media); | ||
match.addListener(this.callback); | ||
this.matches.push(match); | ||
this.changed({ name, media, matches: match.matches }); | ||
}); | ||
}; | ||
this.unobserve = () => { | ||
this.matches.forEach(match => match.removeListener(this.callback)); | ||
}; | ||
this.controller = controller; | ||
this.mediaQueries = (_a = options.mediaQueries) !== null && _a !== void 0 ? _a : defaultOptions.mediaQueries; | ||
this.dispatchEvent = (_b = options.dispatchEvent) !== null && _b !== void 0 ? _b : defaultOptions.dispatchEvent; | ||
this.eventPrefix = (_c = options.eventPrefix) !== null && _c !== void 0 ? _c : defaultOptions.eventPrefix; | ||
this.debug = (_d = options.debug) !== null && _d !== void 0 ? _d : defaultOptions.debug; | ||
if (!window.matchMedia) { | ||
console.error('window.matchMedia() is not available'); | ||
return; | ||
} | ||
this.enhanceController(); | ||
@@ -1388,3 +1267,3 @@ this.observe(); | ||
enhanceController() { | ||
const controllerDisconnect = this.controller.disconnect.bind(this.controller); | ||
const controllerDisconnect = this.controllerDisconnect; | ||
const disconnect = () => { | ||
@@ -1397,7 +1276,24 @@ this.unobserve(); | ||
} | ||
const useMatchMedia = (controller, options = {}) => { | ||
const observer = new UseMatchMedia(controller, options); | ||
const useVisibility = (composableController, options = {}) => { | ||
const controller = composableController; | ||
const observer = new UseVisibility(controller, options); | ||
return [observer.observe, observer.unobserve]; | ||
}; | ||
class VisibilityComposableController extends stimulus.Controller { | ||
constructor() { | ||
super(...arguments); | ||
this.isVisible = false; | ||
} | ||
} | ||
class VisibilityController extends VisibilityComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useVisibility(this, this.options); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
class UseWindowFocus extends StimulusUse { | ||
@@ -1476,2 +1372,47 @@ constructor(controller, options = {}) { | ||
const useWindowResize = (composableController) => { | ||
const controller = composableController; | ||
const callback = (event) => { | ||
const { innerWidth, innerHeight } = window; | ||
const payload = { | ||
height: innerHeight || Infinity, | ||
width: innerWidth || Infinity, | ||
event | ||
}; | ||
method(controller, 'windowResize').call(controller, payload); | ||
}; | ||
const controllerDisconnect = controller.disconnect.bind(controller); | ||
const observe = () => { | ||
window.addEventListener('resize', callback); | ||
callback(); | ||
}; | ||
const unobserve = () => { | ||
window.removeEventListener('resize', callback); | ||
}; | ||
Object.assign(controller, { | ||
disconnect() { | ||
unobserve(); | ||
controllerDisconnect(); | ||
} | ||
}); | ||
observe(); | ||
return [observe, unobserve]; | ||
}; | ||
class WindowResizeComposableController extends stimulus.Controller { | ||
} | ||
class WindowResizeController extends WindowResizeComposableController { | ||
constructor(context) { | ||
super(context); | ||
requestAnimationFrame(() => { | ||
const [observe, unobserve] = useWindowResize(this); | ||
Object.assign(this, { observe, unobserve }); | ||
}); | ||
} | ||
} | ||
function useHotkeys() { | ||
throw '[stimulus-use] Notice: The import for `useHotkeys()` has been moved from `stimulus-use` to `stimulus-use/hotkeys`. \nPlease change the import accordingly and add `hotkey-js` as a dependency to your project. \n\nFor more information see: https://stimulus-use.github.io/stimulus-use/#/use-hotkeys?id=importing-the-behavior'; | ||
} | ||
exports.ApplicationController = ApplicationController; | ||
@@ -1491,5 +1432,7 @@ exports.ClickOutsideController = ClickOutsideController; | ||
exports.UseVisibility = UseVisibility; | ||
exports.UseWindowFocus = UseWindowFocus; | ||
exports.VisibilityController = VisibilityController; | ||
exports.WindowFocusController = WindowFocusController; | ||
exports.WindowResizeController = WindowResizeController; | ||
exports.debounce = debounce; | ||
exports.useApplication = useApplication; | ||
@@ -1496,0 +1439,0 @@ exports.useClickOutside = useClickOutside; |
@@ -1,20 +0,20 @@ | ||
export { useIntersection, IntersectionController } from './use-intersection'; | ||
export { useLazyLoad, LazyLoadController } from './use-lazy-load'; | ||
export { useResize, ResizeController } from './use-resize'; | ||
export { useClickOutside, ClickOutsideController } from './use-click-outside'; | ||
export { useApplication, ApplicationController } from './use-application'; | ||
export { useIdle, IdleController } from './use-idle'; | ||
export { useVisibility, UseVisibility, VisibilityController } from './use-visibility'; | ||
export { useHover, UseHover, HoverController } from './use-hover'; | ||
export { useMutation, UseMutation, MutationController } from './use-mutation'; | ||
export { useTargetMutation, UseTargetMutation, TargetMutationController } from './use-target-mutation'; | ||
export { useWindowResize, WindowResizeController } from './use-window-resize'; | ||
export { useMemo } from './use-memo'; | ||
export { useDebounce } from './use-debounce'; | ||
export { useThrottle } from './use-throttle'; | ||
export { useDispatch } from './use-dispatch'; | ||
export { useMeta } from './use-meta'; | ||
export { useTransition, TransitionOptions, TransitionController } from './use-transition'; | ||
export { useHotkeys } from './use-hotkeys'; | ||
export { useMatchMedia, MatchMediaOptions } from './use-match-media'; | ||
export { useWindowFocus, WindowFocusController } from './use-window-focus'; | ||
export * from './use-application'; | ||
export * from './use-click-outside'; | ||
export * from './use-debounce'; | ||
export * from './use-dispatch'; | ||
export * from './use-hover'; | ||
export * from './use-idle'; | ||
export * from './use-intersection'; | ||
export * from './use-lazy-load'; | ||
export * from './use-match-media'; | ||
export * from './use-memo'; | ||
export * from './use-meta'; | ||
export * from './use-mutation'; | ||
export * from './use-resize'; | ||
export * from './use-target-mutation'; | ||
export * from './use-throttle'; | ||
export * from './use-transition'; | ||
export * from './use-visibility'; | ||
export * from './use-window-focus'; | ||
export * from './use-window-resize'; | ||
export declare function useHotkeys(): void; |
import { Controller } from '@hotwired/stimulus'; | ||
import { DispatchOptions } from '../use-dispatch/index'; | ||
export declare type ApplicationOptions = DispatchOptions & { | ||
export type ApplicationOptions = DispatchOptions & { | ||
overwriteDispatch?: boolean; | ||
}; | ||
export declare const useApplication: (controller: Controller, options?: ApplicationOptions) => void; |
@@ -7,2 +7,2 @@ import { Controller } from '@hotwired/stimulus'; | ||
export declare const debounce: (fn: Function, wait?: number) => (this: any) => any; | ||
export declare const useDebounce: (composableController: Controller, options?: DebounceOptions | undefined) => void; | ||
export declare const useDebounce: (composableController: Controller, options?: DebounceOptions) => void; |
import { Controller } from '@hotwired/stimulus'; | ||
import { KeyHandler } from 'hotkeys-js'; | ||
import { StimulusUse, StimulusUseOptions } from '../stimulus-use'; | ||
declare type Options = { | ||
type Options = { | ||
scope?: string; | ||
@@ -11,7 +11,7 @@ element?: HTMLElement | null; | ||
}; | ||
declare type HotkeyDefinition = { | ||
type HotkeyDefinition = { | ||
handler: KeyHandler; | ||
options: Options; | ||
}; | ||
declare type SimpleHotkeyDefinition = (KeyHandler | HTMLElement)[]; | ||
type SimpleHotkeyDefinition = (KeyHandler | HTMLElement)[]; | ||
export interface HotkeyDefinitions { | ||
@@ -18,0 +18,0 @@ [hotkey: string]: HotkeyDefinition | SimpleHotkeyDefinition; |
import { LazyLoadComposableController } from './lazy-load-controller'; | ||
export declare const useLazyLoad: (controller: LazyLoadComposableController, options?: IntersectionObserverInit | undefined) => readonly [() => void, () => void]; | ||
export declare const useLazyLoad: (controller: LazyLoadComposableController, options?: IntersectionObserverInit) => readonly [() => void, () => void]; |
import { Controller } from '@hotwired/stimulus'; | ||
import { StimulusUse, StimulusUseOptions } from '../stimulus-use'; | ||
declare type MediaQueryDefinitions = Record<string, string>; | ||
type MediaQueryDefinitions = Record<string, string>; | ||
export interface MatchMediaPayload { | ||
@@ -5,0 +5,0 @@ name: string; |
{ | ||
"name": "stimulus-use", | ||
"version": "0.51.3", | ||
"version": "0.52.0", | ||
"description": "A collection of standard controllers and utilities for Stimulus", | ||
"repository": "https://github.com/stimulus-use/stimulus-use", | ||
"license": "MIT", | ||
"author": "Adrien Poly", | ||
"contributors": [ | ||
"Adrien Poly", | ||
"Marco Roth" | ||
], | ||
"sideEffects": false, | ||
"main": "dist/index.js", | ||
"module": "dist/index.js", | ||
"unpkg": "dist/index.umd.js", | ||
"types": "dist/types/index.d.ts", | ||
"amdName": "StimulusUse", | ||
"author": "@adrienpoly", | ||
"license": "MIT", | ||
"external": "@hotwired/stimulus", | ||
"main": "./dist/index.js", | ||
"module": "./dist/index.js", | ||
"unpkg": "./dist/index.umd.js", | ||
"types": "./dist/types/index.d.ts", | ||
"exports": { | ||
".": { | ||
"main": "./dist/index.umd.js", | ||
"browser": "./dist/index.js", | ||
"import": "./dist/index.js", | ||
"module": "./dist/index.js", | ||
"umd": "./dist/index.umd.js", | ||
"types": "./dist/types/index.d.ts" | ||
}, | ||
"./hotkeys": { | ||
"main": "./dist/hotkeys.umd.js", | ||
"browser": "./dist/hotkeys.js", | ||
"import": "./dist/hotkeys.js", | ||
"module": "./dist/hotkeys.js", | ||
"umd": "./dist/hotkeys.umd.js", | ||
"types": "./dist/types/hotkeys.d.ts" | ||
} | ||
}, | ||
"scripts": { | ||
@@ -38,4 +59,4 @@ "prestart": "cd playground && yarn install && cd -", | ||
"@hotwired/stimulus": ">=3", | ||
"@rollup/plugin-node-resolve": "^13.0.5", | ||
"@rollup/plugin-typescript": "^8.2.5", | ||
"@rollup/plugin-node-resolve": "^15.0.1", | ||
"@rollup/plugin-typescript": "^11.0.0", | ||
"agadoo": "^2.0.0", | ||
@@ -45,6 +66,7 @@ "babel-loader": "^8.1.0", | ||
"chai-dom": "^1.8.2", | ||
"cypress": "^9.6.1", | ||
"cypress": "^12.3.0", | ||
"docsify-cli": "^4.4.4", | ||
"hotkeys-js": "^3.10.1", | ||
"html2js": "^0.2.0", | ||
"intersection-observer": "^0.11.0", | ||
"intersection-observer": "^0.12.2", | ||
"karma": "^6.1.0", | ||
@@ -54,3 +76,3 @@ "karma-chai": "^0.1.0", | ||
"karma-coverage": "^2.0.3", | ||
"karma-firefox-launcher": "^1.3.0", | ||
"karma-firefox-launcher": "^2.1.2", | ||
"karma-fixture": "^0.2.6", | ||
@@ -63,3 +85,3 @@ "karma-html2js-preprocessor": "^1.1.0", | ||
"karma-sourcemap-loader": "^0.3.8", | ||
"karma-typescript": "^5.1.0", | ||
"karma-typescript": "^5.5.3", | ||
"karma-webpack": "^4.0.2", | ||
@@ -70,21 +92,15 @@ "kind-of": "^6.0.3", | ||
"prettier": "^2.3.1", | ||
"rimraf": "^3.0.2", | ||
"rimraf": "^4.1.1", | ||
"rollup": "^2.57.0", | ||
"rollup-plugin-filesize": "^9.1.1", | ||
"sinon": "^9.0.3", | ||
"sinon": "^15.0.1", | ||
"sinon-chai": "^3.5.0", | ||
"ts-loader": "^8.0.3", | ||
"typescript": "^3.9.7", | ||
"typescript": "^4.9.4", | ||
"webpack": "^4.44.1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/stimulus-use/stimulus-use" | ||
}, | ||
"peerDependencies": { | ||
"@hotwired/stimulus": ">= 3" | ||
}, | ||
"dependencies": { | ||
"hotkeys-js": ">=3" | ||
"@hotwired/stimulus": ">= 3", | ||
"hotkeys-js": ">= 3" | ||
} | ||
} |
@@ -220,2 +220,3 @@ <p align="center"> | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/daniel-rikowski"><img src="https://avatars.githubusercontent.com/u/1169363?v=4?s=80" width="80px;" alt="Daniel Rikowski"/><br /><sub><b>Daniel Rikowski</b></sub></a><br /><a href="https://github.com/stimulus-use/stimulus-use/issues?q=author%3Adaniel-rikowski" title="Bug reports">๐</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="http://twitter.com/marckohlbrugge"><img src="https://avatars.githubusercontent.com/u/93276?v=4?s=80" width="80px;" alt="Marc Kรถhlbrugge"/><br /><sub><b>Marc Kรถhlbrugge</b></sub></a><br /><a href="#ideas-marckohlbrugge" title="Ideas, Planning, & Feedback">๐ค</a></td> | ||
</tr> | ||
@@ -222,0 +223,0 @@ </tbody> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
176931
3596
238
42
66
1
- Removedhotkeys-js@>=3