igniteui-webcomponents
Version:
Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.
381 lines • 11.7 kB
JavaScript
import { html, isServer, nothing } from 'lit';
export const asPercent = (part, whole) => (part / whole) * 100;
export const clamp = (number, min, max) => Math.max(min, Math.min(number, max));
export function numberOfDecimals(number) {
const [_, decimals] = number.toString().split('.');
return decimals ? decimals.length : 0;
}
export function roundPrecise(number, magnitude = 1) {
const factor = 10 ** magnitude;
return Math.round(number * factor) / factor;
}
export function numberInRangeInclusive(value, min, max) {
return value >= min && value <= max;
}
export function createCounter() {
let i = 0;
return () => {
i++;
return i;
};
}
export function isLTR(element) {
return element.matches(':dir(ltr)');
}
export function formatString(template, ...params) {
const length = params.length;
return template.replace(/{(\d+)}/g, (match, index) => index >= length ? match : `${params[index]}`);
}
export function asNumber(value, fallback = 0) {
const parsed = Number.parseFloat(value);
return Number.isNaN(parsed) ? fallback : parsed;
}
export function wrap(min, max, value) {
if (value < min) {
return max;
}
if (value > max) {
return min;
}
return value;
}
export function isDefined(value) {
return value !== undefined;
}
function createNodeFilter(predicate) {
return {
acceptNode: (node) => !predicate || predicate(node)
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_SKIP,
};
}
export function* iterNodes(root, options) {
if (!isDefined(globalThis.document)) {
return;
}
const whatToShow = options?.show
? NodeFilter[options.show]
: NodeFilter.SHOW_ALL;
const nodeFilter = options?.filter
? createNodeFilter(options.filter)
: undefined;
const treeWalker = document.createTreeWalker(root, whatToShow, nodeFilter);
while (treeWalker.nextNode()) {
yield treeWalker.currentNode;
}
}
export function getRoot(element, options) {
return element.getRootNode(options);
}
export function getElementByIdFromRoot(root, id) {
return getRoot(root).getElementById(id);
}
export function isElement(node) {
return node instanceof Node && node.nodeType === Node.ELEMENT_NODE;
}
export function getElementsFromEventPath(event) {
return event.composedPath().filter((item) => isElement(item));
}
export function findElementFromEventPath(predicate, event) {
const func = isString(predicate)
? (e) => e.matches(predicate)
: (e) => predicate(e);
return getElementsFromEventPath(event).find(func);
}
export function first(arr) {
return arr.at(0);
}
export function last(arr) {
return arr.at(-1);
}
export function modulo(n, d) {
return ((n % d) + d) % d;
}
export function take(iterable, n) {
const result = [];
let i = 0;
let current = iterable.next();
while (i < n && !current.done) {
result.push(current.value);
current = iterable.next();
i++;
}
return result;
}
export function* chunk(arr, size) {
if (size < 1) {
throw new Error('size must be an integer >= 1');
}
for (let i = 0; i < arr.length; i += size) {
yield arr.slice(i, i + size);
}
}
export function splitToWords(text) {
const input = text.replaceAll(/[^a-zA-Z0-9\s-_]/g, '');
if (/[\s-_]+/.test(input))
return input.split(/[\s-_]+/);
return input.split(/(?=[A-Z])+/);
}
export function toKebabCase(text) {
const input = text.trim();
return splitToWords(input).join('-').toLocaleLowerCase();
}
export function isFunction(value) {
return typeof value === 'function';
}
export function isString(value) {
return typeof value === 'string';
}
export function isObject(value) {
return value != null && typeof value === 'object';
}
export function isPlainObject(value) {
if (!isObject(value)) {
return false;
}
const proto = Object.getPrototypeOf(value);
const hasObjectPrototype = proto === null ||
proto === Object.prototype ||
Object.getPrototypeOf(proto) === null;
return hasObjectPrototype
? Object.prototype.toString.call(value) === '[object Object]'
: false;
}
function isUnsafeProperty(key) {
return key === '__proto__' || key === 'constructor' || key === 'prototype';
}
export function isEventListenerObject(x) {
return isObject(x) && 'handleEvent' in x;
}
export function addWeakEventListener(element, event, listener, options) {
const weakRef = new WeakRef(listener);
const wrapped = (evt) => {
const handler = weakRef.deref();
return isEventListenerObject(handler)
? handler.handleEvent(evt)
: handler?.(evt);
};
element.addEventListener(event, wrapped, options);
}
export function addSafeEventListener(target, eventName, handler, options) {
if (isServer) {
return;
}
const boundHandler = (event) => handler.call(target, event);
target.addEventListener(eventName, boundHandler, options);
}
export function isEmpty(x) {
return 'length' in x ? x.length < 1 : x.size < 1;
}
export function asArray(value) {
if (!isDefined(value))
return [];
return Array.isArray(value) ? value : [value];
}
export function partition(array, isTruthy) {
const truthy = [];
const falsy = [];
for (const item of array) {
(isTruthy(item) ? truthy : falsy).push(item);
}
return [truthy, falsy];
}
export function getCenterPoint(element) {
const { left, top, width, height } = element.getBoundingClientRect();
return {
x: left + width * 0.5,
y: top + height * 0.5,
};
}
export function getScaleFactor(element) {
const { offsetWidth, offsetHeight } = element;
const { width, height } = element.getBoundingClientRect();
return { x: offsetWidth / width || 1, y: offsetHeight / height || 1 };
}
export function roundByDPR(value) {
const dpr = globalThis.devicePixelRatio || 1;
return Math.round(value * dpr) / dpr;
}
export function scrollIntoView(element, config) {
if (!element) {
return;
}
element.scrollIntoView(Object.assign({
behavior: 'auto',
block: 'nearest',
inline: 'nearest',
}, config));
}
export function isRegExp(value) {
return value != null && value.constructor === RegExp;
}
export function equal(a, b, visited = new WeakSet()) {
if (Object.is(a, b)) {
return true;
}
if (isObject(a) && isObject(b)) {
if (a.constructor !== b.constructor) {
return false;
}
if (visited.has(a) && visited.has(b)) {
return true;
}
visited.add(a);
visited.add(b);
if (isRegExp(a) && isRegExp(b)) {
return a.source === b.source && a.flags === b.flags;
}
if (a instanceof Map && b instanceof Map) {
if (a.size !== b.size) {
return false;
}
for (const [keyA, valueA] of a.entries()) {
let found = false;
for (const [keyB, valueB] of b.entries()) {
if (equal(keyA, keyB, visited) && equal(valueA, valueB, visited)) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
if (a instanceof Set && b instanceof Set) {
if (a.size !== b.size) {
return false;
}
for (const valueA of a) {
let found = false;
for (const valueB of b) {
if (equal(valueA, valueB, visited)) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
if (Array.isArray(a) && Array.isArray(b)) {
const length = a.length;
if (length !== b.length) {
return false;
}
for (let i = 0; i < length; i++) {
if (!equal(a[i], b[i], visited)) {
return false;
}
}
return true;
}
if (a.valueOf !== Object.prototype.valueOf) {
return a.valueOf() === b.valueOf();
}
if (a.toString !== Object.prototype.toString) {
return a.toString() === b.toString();
}
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
if (aKeys.length !== bKeys.length) {
return false;
}
for (const key of aKeys) {
if (!Object.hasOwn(b, key)) {
return false;
}
}
for (const key of aKeys) {
if (!equal(a[key], b[key], visited)) {
return false;
}
}
visited.delete(a);
visited.delete(b);
return true;
}
return false;
}
export function setStyles(element, styles) {
merge(element.style, styles);
}
export function merge(target, source) {
const sourceKeys = Object.keys(source);
const length = sourceKeys.length;
for (let i = 0; i < length; i++) {
const key = sourceKeys[i];
if (isUnsafeProperty(key)) {
continue;
}
const sourceValue = source[key];
const targetValue = target[key];
if (Array.isArray(sourceValue)) {
if (Array.isArray(targetValue)) {
target[key] = merge(targetValue, sourceValue);
}
else {
target[key] = merge([], sourceValue);
}
}
else if (isPlainObject(sourceValue)) {
if (isPlainObject(targetValue)) {
target[key] = merge(targetValue, sourceValue);
}
else {
target[key] = merge({}, sourceValue);
}
}
else if (targetValue === undefined || sourceValue !== undefined) {
target[key] = sourceValue;
}
}
return target;
}
export function toMerged(target, source) {
return merge(structuredClone(target), source);
}
export function bindIf(assertion, value) {
return assertion
? (value ?? nothing)
: nothing;
}
let pool;
let poolOffset;
const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
function fillPool(bytes) {
if (!pool || pool.length < bytes) {
pool = new Uint8Array(new ArrayBuffer(bytes * 128));
crypto.getRandomValues(pool);
poolOffset = 0;
}
else if (poolOffset + bytes > pool.length) {
crypto.getRandomValues(pool);
poolOffset = 0;
}
poolOffset += bytes;
}
export function nanoid(size = 21) {
const bytes = size | 0;
fillPool(bytes);
let id = '';
for (let i = poolOffset - bytes; i < poolOffset; i++) {
id += urlAlphabet[pool[i] & 63];
}
return id;
}
export function hasFiles(input) {
return input.files != null && input.files.length > 0;
}
const trimmedCache = new WeakMap();
export function trimmedHtml(strings, ...values) {
if (!trimmedCache.has(strings)) {
const trimmedStrings = strings.map((s) => s.trim().replaceAll('\n', ''));
trimmedCache.set(strings, Object.assign([...trimmedStrings], { raw: [...strings.raw] }));
}
return html(trimmedCache.get(strings), ...values);
}
//# sourceMappingURL=util.js.map