UNPKG

uikit

Version:

UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.

281 lines (218 loc) • 6.64 kB
const { hasOwnProperty, toString } = Object.prototype; export function hasOwn(obj, key) { return hasOwnProperty.call(obj, key); } const hyphenateRe = /\B([A-Z])/g; export const hyphenate = memoize((str) => str.replace(hyphenateRe, '-$1').toLowerCase()); const camelizeRe = /-(\w)/g; export const camelize = memoize((str) => (str.charAt(0).toLowerCase() + str.slice(1)).replace(camelizeRe, (_, c) => c.toUpperCase()), ); export const ucfirst = memoize((str) => str.charAt(0).toUpperCase() + str.slice(1)); export function startsWith(str, search) { return str?.startsWith?.(search); } export function endsWith(str, search) { return str?.endsWith?.(search); } export function includes(obj, search) { return obj?.includes?.(search); } export function findIndex(array, predicate) { return array?.findIndex?.(predicate); } export const { isArray, from: toArray } = Array; export const { assign } = Object; export function isFunction(obj) { return typeof obj === 'function'; } export function isObject(obj) { return obj !== null && typeof obj === 'object'; } export function isPlainObject(obj) { return toString.call(obj) === '[object Object]'; } export function isWindow(obj) { return isObject(obj) && obj === obj.window; } export function isDocument(obj) { return nodeType(obj) === 9; } export function isNode(obj) { return nodeType(obj) >= 1; } export function isElement(obj) { return nodeType(obj) === 1; } function nodeType(obj) { return !isWindow(obj) && isObject(obj) && obj.nodeType; } export function isBoolean(value) { return typeof value === 'boolean'; } export function isString(value) { return typeof value === 'string'; } export function isNumber(value) { return typeof value === 'number'; } export function isNumeric(value) { return isNumber(value) || (isString(value) && !isNaN(value - parseFloat(value))); } export function isEmpty(obj) { return !(isArray(obj) ? obj.length : isObject(obj) ? Object.keys(obj).length : false); } export function isUndefined(value) { return value === void 0; } export function toBoolean(value) { return isBoolean(value) ? value : value === 'true' || value === '1' || value === '' ? true : value === 'false' || value === '0' ? false : value; } export function toNumber(value) { const number = Number(value); return isNaN(number) ? false : number; } export function toFloat(value) { return parseFloat(value) || 0; } export function toNode(element) { return element && toNodes(element)[0]; } export function toNodes(element) { return isNode(element) ? [element] : Array.from(element || []).filter(isNode); } export function toWindow(element) { if (isWindow(element)) { return element; } element = toNode(element); const document = isDocument(element) ? element : element?.ownerDocument; return document?.defaultView || window; } export function isEqual(value, other) { return ( value === other || (isObject(value) && isObject(other) && Object.keys(value).length === Object.keys(other).length && each(value, (val, key) => val === other[key])) ); } export function swap(value, a, b) { return value.replace(new RegExp(`${a}|${b}`, 'g'), (match) => (match === a ? b : a)); } export function last(array) { return array[array.length - 1]; } export function each(obj, cb) { for (const key in obj) { if (false === cb(obj[key], key)) { return false; } } return true; } export function sortBy(array, prop) { return array .slice() .sort(({ [prop]: propA = 0 }, { [prop]: propB = 0 }) => propA > propB ? 1 : propB > propA ? -1 : 0, ); } export function sumBy(array, iteratee) { return array.reduce( (sum, item) => sum + toFloat(isFunction(iteratee) ? iteratee(item) : item[iteratee]), 0, ); } export function uniqueBy(array, prop) { const seen = new Set(); return array.filter(({ [prop]: check }) => (seen.has(check) ? false : seen.add(check))); } export function pick(obj, props) { return props.reduce((res, prop) => ({ ...res, [prop]: obj[prop] }), {}); } export function clamp(number, min = 0, max = 1) { return Math.min(Math.max(toNumber(number) || 0, min), max); } export function noop() {} export function intersectRect(...rects) { return [ ['bottom', 'top'], ['right', 'left'], ].every( ([minProp, maxProp]) => Math.min(...rects.map(({ [minProp]: min }) => min)) - Math.max(...rects.map(({ [maxProp]: max }) => max)) > 0, ); } export function pointInRect(point, rect) { return ( point.x <= rect.right && point.x >= rect.left && point.y <= rect.bottom && point.y >= rect.top ); } function ratio(dimensions, prop, value) { const aProp = prop === 'width' ? 'height' : 'width'; return { [aProp]: dimensions[prop] ? Math.round((value * dimensions[aProp]) / dimensions[prop]) : dimensions[aProp], [prop]: value, }; } function contain(dimensions, maxDimensions) { dimensions = { ...dimensions }; for (const prop in dimensions) { dimensions = dimensions[prop] > maxDimensions[prop] ? ratio(dimensions, prop, maxDimensions[prop]) : dimensions; } return dimensions; } function cover(dimensions, maxDimensions) { dimensions = contain(dimensions, maxDimensions); for (const prop in dimensions) { dimensions = dimensions[prop] < maxDimensions[prop] ? ratio(dimensions, prop, maxDimensions[prop]) : dimensions; } return dimensions; } export const Dimensions = { ratio, contain, cover }; export function getIndex(i, elements, current = 0, finite = false) { elements = toNodes(elements); const { length } = elements; if (!length) { return -1; } i = isNumeric(i) ? toNumber(i) : i === 'next' ? current + 1 : i === 'previous' ? current - 1 : i === 'last' ? length - 1 : elements.indexOf(toNode(i)); if (finite) { return clamp(i, 0, length - 1); } i %= length; return i < 0 ? i + length : i; } export function memoize(fn) { const cache = Object.create(null); return (key, ...args) => cache[key] || (cache[key] = fn(key, ...args)); }