@umbraco-ui/uui-base
Version:
This is a base dependency for Umbraco UI components. It contains mixins, animations, abstract base classes, UUIEvent base class, and universal types for properties shared by different components
131 lines (124 loc) • 3.9 kB
JavaScript
class Timer {
constructor(_callback, duration) {
this._callback = _callback;
this._timerId = null;
this._remaining = null;
this._onComplete = () => {
this._remaining = null;
this._callback();
};
this.setDuration(duration);
}
setDuration(duration) {
this._duration = duration;
if (this._timerId !== null) {
this.restart();
}
}
/** starts the timer */
start() {
if (this._timerId === null) {
this.resume();
}
}
/** restarts the timer by setting remaining time to duration. */
restart() {
this._remaining = this._duration;
this.resume();
}
pause() {
if (this._timerId !== null) {
window.clearTimeout(this._timerId);
this._timerId = null;
if (this._remaining !== null) {
this._remaining -= Date.now() - this._startTime;
}
}
}
resume() {
if (this._timerId !== null) {
window.clearTimeout(this._timerId);
}
if (this._remaining === null) {
this._remaining = this._duration;
}
this._startTime = Date.now();
this._timerId = window.setTimeout(this._onComplete, this._remaining);
}
destroy() {
this.pause();
}
}
const demandCustomElement = (requester, elementName, message = `This element has to be present for ${requester.nodeName} to work appropriate.`) => {
if (!customElements.get(elementName)) {
console.warn(
`%c ${requester.nodeName} requires ${elementName} element to be registered!`,
"font-weight: bold;",
message,
requester
);
}
};
const drag = (container, options) => {
function move(event) {
const dims = container.getBoundingClientRect();
const defaultView = container.ownerDocument.defaultView;
const offsetX = dims.left + defaultView.scrollX;
const offsetY = dims.top + defaultView.scrollY;
let pointerEvent;
if ("TouchEvent" in window && event instanceof TouchEvent) {
pointerEvent = event.touches[0];
} else if (event instanceof PointerEvent) {
pointerEvent = event;
} else {
return;
}
const x = pointerEvent.pageX - offsetX;
const y = pointerEvent.pageY - offsetY;
if (options?.onMove) {
options.onMove(x, y);
}
}
function stop() {
document.removeEventListener("pointermove", move);
document.removeEventListener("pointerup", stop);
if (options?.onStop) {
options.onStop();
}
}
document.addEventListener("pointermove", move, { passive: true });
document.addEventListener("pointerup", stop);
if (options?.initialEvent) {
move(options.initialEvent);
}
};
const clamp = (value, min, max) => {
return Math.min(Math.max(value, min), max);
};
const reverseNumberInRange = (num, min, max) => {
return max + min - num;
};
const toHex = (value) => {
const hex = Math.round(value).toString(16);
return hex.length === 1 ? `0${hex}` : hex;
};
const findAncestorByAttributeValue = (startNode, attributeName, attributeValue) => {
let currentNode = startNode;
while (currentNode !== null) {
const elementHasAttribute = currentNode instanceof HTMLElement && currentNode.hasAttribute(attributeName) && currentNode.getAttribute(attributeName) === attributeValue;
const elementContainsAttribute = currentNode.querySelector(`[${attributeName}="${attributeValue}"]`) !== null;
if (elementHasAttribute) {
return currentNode;
} else if (elementContainsAttribute) {
return currentNode.querySelector(
`[${attributeName}="${attributeValue}"]`
);
}
currentNode = currentNode.parentElement || currentNode.parentNode || currentNode.host || null;
}
return null;
};
function slotHasContent(target) {
return target ? target.assignedNodes({ flatten: true }).length > 0 : false;
}
export { Timer, clamp, demandCustomElement, drag, findAncestorByAttributeValue, reverseNumberInRange, slotHasContent, toHex };