@furo/util
Version:
165 lines (152 loc) • 3.73 kB
JavaScript
import {LitElement, css} from 'lit';
import {FBP} from '@furo/fbp';
/**
* The Debounce technique allow us to “group” multiple sequential calls in a single one.
*
* [Read more about debouncing here](https://css-tricks.com/debouncing-throttling-explained-examples/)
*
*
*
* ```html
* <furo-de-bounce
* fn-trigger="--searchStringEntered" at-debounced="--debouncedSrch"
* ></furo-de-bounce>
* ```
*
* @fires {*} debounced - Fired after N milliseconds. If `immediate`is set to TRUE, it fires on the leading edge.
* @fires {*} out - deprecated, use debounced instead.
*
* // TODO: remove @out and fn-input-wire in q2 2022
* @summary event de bouncer
* @customElement
* @appliesMixin FBP
*/
export class FuroDeBounce extends FBP(LitElement) {
/**
* flow is ready lifecycle method
* @private
*/
_FBPReady() {
super._FBPReady();
// this._FBPTraceWires();
}
static get properties() {
return {
/**
* Debounce time in milliseconds
* Default value: 250
* @type Number
*/
wait: {type: Number, attribute: 'wait'},
/**
* If true, input-wire is triggered immediatley (leading edge instead of trailing)
* Default value: false
*
* @type Boolean
*/
immediate: {type: Boolean, attribute: 'immediate'},
};
}
constructor() {
super();
/**
* as taken from Underscore.js
* @param func
* @param wait
* @param immediate
* @return {(function(): void)|*}
* @private
*/
this._debounce = function debounce(func, wait, immediate) {
let timeout;
return function debouncer() {
const context = this;
// eslint-disable-next-line prefer-rest-params
const args = arguments;
const later = function applyLater() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
/**
*
* @type {boolean}
* @private
*/
this._immediate = false;
/**
*
* @type {number}
* @private
*/
this._wait = 250;
this._createHandler(this._wait, this._immediate);
}
set immediate(i) {
this._immediate = i;
this._createHandler(this._wait ? this._wait : 250, i);
}
set wait(w) {
this._wait = w;
this._createHandler(w, this._immediate ? this._immediate : false);
}
/**
* Internal create of debounce handler function
* @param wait
* @param immediate
* @private
*/
_createHandler(wait, immediate) {
this.handler = this._debounce(
wire => {
this.dispatchEvent(
new CustomEvent('out', {
detail: wire,
bubbles: true,
composed: true,
})
);
this.dispatchEvent(
new CustomEvent('debounced', {
detail: wire,
bubbles: true,
composed: true,
})
);
},
wait,
immediate,
);
}
/**
* Trigger the debounce
* @param {*} data - Any data, will be dispatched on the `debounced` event.
*/
trigger(data) {
this.handler(data);
}
/**
* Debounce function
* @param wire
* @private
* @deprecated - Use trigger() instead
*/
inputWire(wire) {
this.handler(wire);
console.warn("input-wire is deprecated, use the trigger method instead", this)
}
static get styles() {
// language=CSS
return css`
:host {
display: none;
}
`;
}
}
window.customElements.define('furo-de-bounce', FuroDeBounce);