@hakuna-matata-ui/utils
Version:
Common utilties and types for Chakra UI
1,802 lines (1,524 loc) • 50.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var cssBoxModel = require('css-box-model');
var lodash_mergewith = require('lodash.mergewith');
var sync = require('framesync');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var lodash_mergewith__default = /*#__PURE__*/_interopDefault(lodash_mergewith);
var sync__default = /*#__PURE__*/_interopDefault(sync);
function getFirstItem(array) {
return array != null && array.length ? array[0] : undefined;
}
function getLastItem(array) {
var length = array == null ? 0 : array.length;
return length ? array[length - 1] : undefined;
}
function getPrevItem(index, array, loop) {
if (loop === void 0) {
loop = true;
}
var prevIndex = getPrevIndex(index, array.length, loop);
return array[prevIndex];
}
function getNextItem(index, array, loop) {
if (loop === void 0) {
loop = true;
}
var nextIndex = getNextIndex(index, array.length, 1, loop);
return array[nextIndex];
}
function removeIndex(array, index) {
return array.filter(function (_, idx) {
return idx !== index;
});
}
function addItem(array, item) {
return [].concat(array, [item]);
}
function removeItem(array, item) {
return array.filter(function (eachItem) {
return eachItem !== item;
});
}
/**
* Get the next index based on the current index and step.
*
* @param currentIndex the current index
* @param length the total length or count of items
* @param step the number of steps
* @param loop whether to circle back once `currentIndex` is at the start/end
*/
function getNextIndex(currentIndex, length, step, loop) {
if (step === void 0) {
step = 1;
}
if (loop === void 0) {
loop = true;
}
var lastIndex = length - 1;
if (currentIndex === -1) {
return step > 0 ? 0 : lastIndex;
}
var nextIndex = currentIndex + step;
if (nextIndex < 0) {
return loop ? lastIndex : 0;
}
if (nextIndex >= length) {
if (loop) return 0;
return currentIndex > length ? length : currentIndex;
}
return nextIndex;
}
/**
* Get's the previous index based on the current index.
* Mostly used for keyboard navigation.
*
* @param index - the current index
* @param count - the length or total count of items in the array
* @param loop - whether we should circle back to the
* first/last once `currentIndex` is at the start/end
*/
function getPrevIndex(index, count, loop) {
if (loop === void 0) {
loop = true;
}
return getNextIndex(index, count, -1, loop);
}
/**
* Converts an array into smaller chunks or groups.
*
* @param array the array to chunk into group
* @param size the length of each chunk
*/
function chunk(array, size) {
return array.reduce(function (rows, currentValue, index) {
if (index % size === 0) {
rows.push([currentValue]);
} else {
rows[rows.length - 1].push(currentValue);
}
return rows;
}, []);
}
/**
* Gets the next item based on a search string
*
* @param items array of items
* @param searchString the search string
* @param itemToString resolves an item to string
* @param currentItem the current selected item
*/
function getNextItemFromSearch(items, searchString, itemToString, currentItem) {
if (searchString == null) {
return currentItem;
} // If current item doesn't exist, find the item that matches the search string
if (!currentItem) {
var foundItem = items.find(function (item) {
return itemToString(item).toLowerCase().startsWith(searchString.toLowerCase());
});
return foundItem;
} // Filter items for ones that match the search string (case insensitive)
var matchingItems = items.filter(function (item) {
return itemToString(item).toLowerCase().startsWith(searchString.toLowerCase());
}); // If there's a match, let's get the next item to select
if (matchingItems.length > 0) {
var nextIndex; // If the currentItem is in the available items, we move to the next available option
if (matchingItems.includes(currentItem)) {
var currentIndex = matchingItems.indexOf(currentItem);
nextIndex = currentIndex + 1;
if (nextIndex === matchingItems.length) {
nextIndex = 0;
}
return matchingItems[nextIndex];
} // Else, we pick the first item in the available items
nextIndex = items.indexOf(matchingItems[0]);
return items[nextIndex];
} // a decent fallback to the currentItem
return currentItem;
}
// Number assertions
function isNumber(value) {
return typeof value === "number";
}
function isNotNumber(value) {
return typeof value !== "number" || Number.isNaN(value) || !Number.isFinite(value);
}
function isNumeric(value) {
return value != null && value - parseFloat(value) + 1 >= 0;
} // Array assertions
function isArray(value) {
return Array.isArray(value);
}
function isEmptyArray(value) {
return isArray(value) && value.length === 0;
} // Function assertions
function isFunction(value) {
return typeof value === "function";
} // Generic assertions
function isDefined(value) {
return typeof value !== "undefined" && value !== undefined;
}
function isUndefined(value) {
return typeof value === "undefined" || value === undefined;
} // Object assertions
function isObject(value) {
var type = typeof value;
return value != null && (type === "object" || type === "function") && !isArray(value);
}
function isEmptyObject(value) {
return isObject(value) && Object.keys(value).length === 0;
}
function isNotEmptyObject(value) {
return value && !isEmptyObject(value);
}
function isNull(value) {
return value == null;
} // String assertions
function isString(value) {
return Object.prototype.toString.call(value) === "[object String]";
}
function isCssVar(value) {
return /^var\(--.+\)$/.test(value);
} // Empty assertions
function isEmpty(value) {
if (isArray(value)) return isEmptyArray(value);
if (isObject(value)) return isEmptyObject(value);
if (value == null || value === "") return true;
return false;
}
var __DEV__ = "production" !== "production";
var __TEST__ = "production" === "test";
function isRefObject(val) {
return "current" in val;
}
function isInputEvent(value) {
return value && isObject(value) && isObject(value.target);
}
function omit(object, keys) {
var result = {};
Object.keys(object).forEach(function (key) {
if (keys.includes(key)) return;
result[key] = object[key];
});
return result;
}
function pick(object, keys) {
var result = {};
keys.forEach(function (key) {
if (key in object) {
result[key] = object[key];
}
});
return result;
}
function split(object, keys) {
var picked = {};
var omitted = {};
Object.keys(object).forEach(function (key) {
if (keys.includes(key)) {
picked[key] = object[key];
} else {
omitted[key] = object[key];
}
});
return [picked, omitted];
}
/**
* Get value from a deeply nested object using a string path.
* Memoizes the value.
* @param obj - the object
* @param path - the string path
* @param def - the fallback value
*/
function get(obj, path, fallback, index) {
var key = typeof path === "string" ? path.split(".") : [path];
for (index = 0; index < key.length; index += 1) {
if (!obj) break;
obj = obj[key[index]];
}
return obj === undefined ? fallback : obj;
}
var memoize = function memoize(fn) {
var cache = new WeakMap();
var memoizedFn = function memoizedFn(obj, path, fallback, index) {
if (typeof obj === "undefined") {
return fn(obj, path, fallback);
}
if (!cache.has(obj)) {
cache.set(obj, new Map());
}
var map = cache.get(obj);
if (map.has(path)) {
return map.get(path);
}
var value = fn(obj, path, fallback, index);
map.set(path, value);
return value;
};
return memoizedFn;
};
var memoizedGet = memoize(get);
/**
* Get value from deeply nested object, based on path
* It returns the path value if not found in object
*
* @param path - the string path or value
* @param scale - the string path or value
*/
function getWithDefault(path, scale) {
return memoizedGet(scale, path, path);
}
/**
* Returns the items of an object that meet the condition specified in a callback function.
*
* @param object the object to loop through
* @param fn The filter function
*/
function objectFilter(object, fn) {
var result = {};
Object.keys(object).forEach(function (key) {
var value = object[key];
var shouldPass = fn(value, key, object);
if (shouldPass) {
result[key] = value;
}
});
return result;
}
var filterUndefined = function filterUndefined(object) {
return objectFilter(object, function (val) {
return val !== null && val !== undefined;
});
};
var objectKeys = function objectKeys(obj) {
return Object.keys(obj);
};
/**
* Object.entries polyfill for Nodev10 compatibility
*/
var fromEntries = function fromEntries(entries) {
return entries.reduce(function (carry, _ref) {
var key = _ref[0],
value = _ref[1];
carry[key] = value;
return carry;
}, {});
};
/**
* Get the CSS variable ref stored in the theme
*/
var getCSSVar = function getCSSVar(theme, scale, value) {
var _theme$__cssMap$$varR, _theme$__cssMap$;
return (_theme$__cssMap$$varR = (_theme$__cssMap$ = theme.__cssMap[scale + "." + value]) == null ? void 0 : _theme$__cssMap$.varRef) != null ? _theme$__cssMap$$varR : value;
};
function analyzeCSSValue(value) {
var num = parseFloat(value.toString());
var unit = value.toString().replace(String(num), "");
return {
unitless: !unit,
value: num,
unit: unit
};
}
function px(value) {
if (value == null) return value;
var _analyzeCSSValue = analyzeCSSValue(value),
unitless = _analyzeCSSValue.unitless;
return unitless || isNumber(value) ? value + "px" : value;
}
var sortByBreakpointValue = function sortByBreakpointValue(a, b) {
return parseInt(a[1], 10) > parseInt(b[1], 10) ? 1 : -1;
};
var sortBps = function sortBps(breakpoints) {
return fromEntries(Object.entries(breakpoints).sort(sortByBreakpointValue));
};
function normalize(breakpoints) {
var sorted = sortBps(breakpoints);
return Object.assign(Object.values(sorted), sorted);
}
function keys(breakpoints) {
var value = Object.keys(sortBps(breakpoints));
return new Set(value);
}
function subtract(value) {
var _px;
if (!value) return value;
value = (_px = px(value)) != null ? _px : value;
var factor = value.endsWith("px") ? -1 : // the equivalent of 1px in em using a 16px base
-0.0635;
return isNumber(value) ? "" + (value + factor) : value.replace(/([0-9]+\.?[0-9]*)/, function (m) {
return "" + (parseFloat(m) + factor);
});
}
function queryString(min, max) {
var query = [];
if (min) query.push("@media screen and (min-width: " + px(min) + ")");
if (query.length > 0 && max) query.push("and");
if (max) query.push("@media screen and (max-width: " + px(max) + ")");
return query.join(" ");
}
function analyzeBreakpoints(breakpoints) {
var _breakpoints$base;
if (!breakpoints) return null;
breakpoints.base = (_breakpoints$base = breakpoints.base) != null ? _breakpoints$base : "0px";
var normalized = normalize(breakpoints);
var queries = Object.entries(breakpoints).sort(sortByBreakpointValue).map(function (_ref, index, entry) {
var _entry;
var breakpoint = _ref[0],
minW = _ref[1];
var _ref2 = (_entry = entry[index + 1]) != null ? _entry : [],
maxW = _ref2[1];
maxW = parseFloat(maxW) > 0 ? subtract(maxW) : undefined;
return {
breakpoint: breakpoint,
minW: minW,
maxW: maxW,
maxWQuery: queryString(null, maxW),
minWQuery: queryString(minW),
minMaxQuery: queryString(minW, maxW)
};
});
var _keys = keys(breakpoints);
var _keysArr = Array.from(_keys.values());
return {
keys: _keys,
normalized: normalized,
isResponsive: function isResponsive(test) {
var keys = Object.keys(test);
return keys.length > 0 && keys.every(function (key) {
return _keys.has(key);
});
},
asObject: sortBps(breakpoints),
asArray: normalize(breakpoints),
details: queries,
media: [null].concat(normalized.map(function (minW) {
return queryString(minW);
}).slice(1)),
toArrayValue: function toArrayValue(test) {
if (!isObject(test)) {
throw new Error("toArrayValue: value must be an object");
}
var result = _keysArr.map(function (bp) {
var _test$bp;
return (_test$bp = test[bp]) != null ? _test$bp : null;
});
while (getLastItem(result) === null) {
result.pop();
}
return result;
},
toObjectValue: function toObjectValue(test) {
if (!Array.isArray(test)) {
throw new Error("toObjectValue: value must be an array");
}
return test.reduce(function (acc, value, index) {
var key = _keysArr[index];
if (key != null && value != null) acc[key] = value;
return acc;
}, {});
}
};
}
function isElement(el) {
return el != null && typeof el == "object" && "nodeType" in el && el.nodeType === Node.ELEMENT_NODE;
}
function isHTMLElement(el) {
var _el$ownerDocument$def;
if (!isElement(el)) {
return false;
}
var win = (_el$ownerDocument$def = el.ownerDocument.defaultView) != null ? _el$ownerDocument$def : window;
return el instanceof win.HTMLElement;
}
function getOwnerWindow(node) {
var _getOwnerDocument$def, _getOwnerDocument;
return isElement(node) ? (_getOwnerDocument$def = (_getOwnerDocument = getOwnerDocument(node)) == null ? void 0 : _getOwnerDocument.defaultView) != null ? _getOwnerDocument$def : window : window;
}
function getOwnerDocument(node) {
var _node$ownerDocument;
return isElement(node) ? (_node$ownerDocument = node.ownerDocument) != null ? _node$ownerDocument : document : document;
}
function getEventWindow(event) {
var _view;
return (_view = event.view) != null ? _view : window;
}
function canUseDOM() {
return !!(typeof window !== "undefined" && window.document && window.document.createElement);
}
var isBrowser = canUseDOM();
var dataAttr = function dataAttr(condition) {
return condition ? "" : undefined;
};
var ariaAttr = function ariaAttr(condition) {
return condition ? true : undefined;
};
var cx = function cx() {
for (var _len = arguments.length, classNames = new Array(_len), _key = 0; _key < _len; _key++) {
classNames[_key] = arguments[_key];
}
return classNames.filter(Boolean).join(" ");
};
function getActiveElement(node) {
var doc = getOwnerDocument(node);
return doc == null ? void 0 : doc.activeElement;
}
function contains(parent, child) {
if (!parent) return false;
return parent === child || parent.contains(child);
}
function addDomEvent(target, eventName, handler, options) {
target.addEventListener(eventName, handler, options);
return function () {
target.removeEventListener(eventName, handler, options);
};
}
/**
* Get the normalized event key across all browsers
* @param event keyboard event
*/
function normalizeEventKey(event) {
var key = event.key,
keyCode = event.keyCode;
var isArrowKey = keyCode >= 37 && keyCode <= 40 && key.indexOf("Arrow") !== 0;
var eventKey = isArrowKey ? "Arrow" + key : key;
return eventKey;
}
function getRelatedTarget(event) {
var _event$target, _event$relatedTarget;
var target = (_event$target = event.target) != null ? _event$target : event.currentTarget;
var activeElement = getActiveElement(target);
return (_event$relatedTarget = event.relatedTarget) != null ? _event$relatedTarget : activeElement;
}
function isRightClick(event) {
return event.button !== 0;
}
// Really great work done by Diego Haz on this one
var hasDisplayNone = function hasDisplayNone(element) {
return window.getComputedStyle(element).display === "none";
};
var hasTabIndex = function hasTabIndex(element) {
return element.hasAttribute("tabindex");
};
var hasNegativeTabIndex = function hasNegativeTabIndex(element) {
return hasTabIndex(element) && element.tabIndex === -1;
};
function isDisabled(element) {
return Boolean(element.getAttribute("disabled")) === true || Boolean(element.getAttribute("aria-disabled")) === true;
}
function isInputElement(element) {
return isHTMLElement(element) && element.tagName.toLowerCase() === "input" && "select" in element;
}
function isActiveElement(element) {
var doc = isHTMLElement(element) ? getOwnerDocument(element) : document;
return doc.activeElement === element;
}
function hasFocusWithin(element) {
if (!document.activeElement) return false;
return element.contains(document.activeElement);
}
function isHidden(element) {
if (element.parentElement && isHidden(element.parentElement)) return true;
return element.hidden;
}
function isContentEditable(element) {
var value = element.getAttribute("contenteditable");
return value !== "false" && value != null;
}
function isFocusable(element) {
if (!isHTMLElement(element) || isHidden(element) || isDisabled(element)) {
return false;
}
var localName = element.localName;
var focusableTags = ["input", "select", "textarea", "button"];
if (focusableTags.indexOf(localName) >= 0) return true;
var others = {
a: function a() {
return element.hasAttribute("href");
},
audio: function audio() {
return element.hasAttribute("controls");
},
video: function video() {
return element.hasAttribute("controls");
}
};
if (localName in others) {
return others[localName]();
}
if (isContentEditable(element)) return true;
return hasTabIndex(element);
}
function isTabbable(element) {
if (!element) return false;
return isHTMLElement(element) && isFocusable(element) && !hasNegativeTabIndex(element);
}
var focusableElList = ["input:not([disabled])", "select:not([disabled])", "textarea:not([disabled])", "embed", "iframe", "object", "a[href]", "area[href]", "button:not([disabled])", "[tabindex]", "audio[controls]", "video[controls]", "*[tabindex]:not([aria-disabled])", "*[contenteditable]"];
var focusableElSelector = focusableElList.join();
function getAllFocusable(container) {
var focusableEls = Array.from(container.querySelectorAll(focusableElSelector));
focusableEls.unshift(container);
return focusableEls.filter(isFocusable).filter(function (el) {
return window.getComputedStyle(el).display !== "none";
});
}
function getFirstFocusable(container) {
var allFocusable = getAllFocusable(container);
return allFocusable.length ? allFocusable[0] : null;
}
function getAllTabbable(container, fallbackToFocusable) {
var allFocusable = Array.from(container.querySelectorAll(focusableElSelector));
var allTabbable = allFocusable.filter(isTabbable);
if (isTabbable(container)) {
allTabbable.unshift(container);
}
if (!allTabbable.length && fallbackToFocusable) {
return allFocusable;
}
return allTabbable;
}
function getFirstTabbableIn(container, fallbackToFocusable) {
var _getAllTabbable = getAllTabbable(container, fallbackToFocusable),
first = _getAllTabbable[0];
return first || null;
}
function getLastTabbableIn(container, fallbackToFocusable) {
var allTabbable = getAllTabbable(container, fallbackToFocusable);
return allTabbable[allTabbable.length - 1] || null;
}
function getNextTabbable(container, fallbackToFocusable) {
var allFocusable = getAllFocusable(container);
var index = allFocusable.indexOf(document.activeElement);
var slice = allFocusable.slice(index + 1);
return slice.find(isTabbable) || allFocusable.find(isTabbable) || (fallbackToFocusable ? slice[0] : null);
}
function getPreviousTabbable(container, fallbackToFocusable) {
var allFocusable = getAllFocusable(container).reverse();
var index = allFocusable.indexOf(document.activeElement);
var slice = allFocusable.slice(index + 1);
return slice.find(isTabbable) || allFocusable.find(isTabbable) || (fallbackToFocusable ? slice[0] : null);
}
function focusNextTabbable(container, fallbackToFocusable) {
var nextTabbable = getNextTabbable(container, fallbackToFocusable);
if (nextTabbable && isHTMLElement(nextTabbable)) {
nextTabbable.focus();
}
}
function focusPreviousTabbable(container, fallbackToFocusable) {
var previousTabbable = getPreviousTabbable(container, fallbackToFocusable);
if (previousTabbable && isHTMLElement(previousTabbable)) {
previousTabbable.focus();
}
}
function matches(element, selectors) {
if ("matches" in element) return element.matches(selectors);
if ("msMatchesSelector" in element) return element.msMatchesSelector(selectors);
return element.webkitMatchesSelector(selectors);
}
function closest(element, selectors) {
if ("closest" in element) return element.closest(selectors);
do {
if (matches(element, selectors)) return element;
element = element.parentElement || element.parentNode;
} while (element !== null && element.nodeType === 1);
return null;
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
if (it) return (it = it.call(o)).next.bind(it);
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
/* eslint-disable no-nested-ternary */
function runIfFn(valueOrFn) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return isFunction(valueOrFn) ? valueOrFn.apply(void 0, args) : valueOrFn;
}
function callAllHandlers() {
for (var _len2 = arguments.length, fns = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
fns[_key2] = arguments[_key2];
}
return function func(event) {
fns.some(function (fn) {
fn == null ? void 0 : fn(event);
return event == null ? void 0 : event.defaultPrevented;
});
};
}
function callAll() {
for (var _len3 = arguments.length, fns = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
fns[_key3] = arguments[_key3];
}
return function mergedFn(arg) {
fns.forEach(function (fn) {
fn == null ? void 0 : fn(arg);
});
};
}
var compose = function compose(fn1) {
for (var _len4 = arguments.length, fns = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
fns[_key4 - 1] = arguments[_key4];
}
return fns.reduce(function (f1, f2) {
return function () {
return f1(f2.apply(void 0, arguments));
};
}, fn1);
};
function once(fn) {
var result;
return function func() {
if (fn) {
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
args[_key5] = arguments[_key5];
}
result = fn.apply(this, args);
fn = null;
}
return result;
};
}
var noop = function noop() {};
var warn = once(function (options) {
return function () {
var condition = options.condition,
message = options.message;
if (condition && __DEV__) {
console.warn(message);
}
};
});
var error = once(function (options) {
return function () {
var condition = options.condition,
message = options.message;
if (condition && __DEV__) {
console.error(message);
}
};
});
var pipe = function pipe() {
for (var _len6 = arguments.length, fns = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
fns[_key6] = arguments[_key6];
}
return function (v) {
return fns.reduce(function (a, b) {
return b(a);
}, v);
};
};
var distance1D = function distance1D(a, b) {
return Math.abs(a - b);
};
var isPoint = function isPoint(point) {
return "x" in point && "y" in point;
};
function distance(a, b) {
if (isNumber(a) && isNumber(b)) {
return distance1D(a, b);
}
if (isPoint(a) && isPoint(b)) {
var xDelta = distance1D(a.x, b.x);
var yDelta = distance1D(a.y, b.y);
return Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2));
}
return 0;
}
function focus(element, options) {
if (options === void 0) {
options = {};
}
var _options = options,
_options$isActive = _options.isActive,
isActive = _options$isActive === void 0 ? isActiveElement : _options$isActive,
nextTick = _options.nextTick,
_options$preventScrol = _options.preventScroll,
preventScroll = _options$preventScrol === void 0 ? true : _options$preventScrol,
_options$selectTextIf = _options.selectTextIfInput,
selectTextIfInput = _options$selectTextIf === void 0 ? true : _options$selectTextIf;
if (!element || isActive(element)) return -1;
function triggerFocus() {
if (!element) {
warn({
condition: true,
message: "[chakra-ui]: can't call focus() on `null` or `undefined` element"
});
return;
}
if (supportsPreventScroll()) {
element.focus({
preventScroll: preventScroll
});
} else {
element.focus();
if (preventScroll) {
var scrollableElements = getScrollableElements(element);
restoreScrollPosition(scrollableElements);
}
}
if (isInputElement(element) && selectTextIfInput) {
element.select();
}
}
if (nextTick) {
return requestAnimationFrame(triggerFocus);
}
triggerFocus();
return -1;
}
var supportsPreventScrollCached = null;
function supportsPreventScroll() {
if (supportsPreventScrollCached == null) {
supportsPreventScrollCached = false;
try {
var div = document.createElement("div");
div.focus({
get preventScroll() {
supportsPreventScrollCached = true;
return true;
}
});
} catch (e) {// Ignore
}
}
return supportsPreventScrollCached;
}
function getScrollableElements(element) {
var _doc$defaultView;
var doc = getOwnerDocument(element);
var win = (_doc$defaultView = doc.defaultView) != null ? _doc$defaultView : window;
var parent = element.parentNode;
var scrollableElements = [];
var rootScrollingElement = doc.scrollingElement || doc.documentElement;
while (parent instanceof win.HTMLElement && parent !== rootScrollingElement) {
if (parent.offsetHeight < parent.scrollHeight || parent.offsetWidth < parent.scrollWidth) {
scrollableElements.push({
element: parent,
scrollTop: parent.scrollTop,
scrollLeft: parent.scrollLeft
});
}
parent = parent.parentNode;
}
if (rootScrollingElement instanceof win.HTMLElement) {
scrollableElements.push({
element: rootScrollingElement,
scrollTop: rootScrollingElement.scrollTop,
scrollLeft: rootScrollingElement.scrollLeft
});
}
return scrollableElements;
}
function restoreScrollPosition(scrollableElements) {
for (var _iterator = _createForOfIteratorHelperLoose(scrollableElements), _step; !(_step = _iterator()).done;) {
var _step$value = _step.value,
element = _step$value.element,
scrollTop = _step$value.scrollTop,
scrollLeft = _step$value.scrollLeft;
element.scrollTop = scrollTop;
element.scrollLeft = scrollLeft;
}
}
/**
* Determines whether the children of a disclosure widget
* should be rendered or not, depending on the lazy behavior.
*
* Used in accordion, tabs, popover, menu and other disclosure
* widgets.
*/
function determineLazyBehavior(options) {
var hasBeenSelected = options.hasBeenSelected,
isLazy = options.isLazy,
isSelected = options.isSelected,
_options$lazyBehavior = options.lazyBehavior,
lazyBehavior = _options$lazyBehavior === void 0 ? "unmount" : _options$lazyBehavior; // if not lazy, always render the disclosure's content
if (!isLazy) return true; // if the diclosure is selected, render the disclosure's content
if (isSelected) return true; // if the disclosure was selected but not active, keep its content active
if (lazyBehavior === "keepMounted" && hasBeenSelected) return true;
return false;
}
var minSafeInteger = Number.MIN_SAFE_INTEGER || -9007199254740991;
var maxSafeInteger = Number.MAX_SAFE_INTEGER || 9007199254740991;
function toNumber(value) {
var num = parseFloat(value);
return isNotNumber(num) ? 0 : num;
}
/**
* Converts a value to a specific precision (or decimal points).
*
* Returns a string representing a number in fixed-point notation.
*
* @param value the value to convert
* @param precision the precision or decimal points
*/
function toPrecision(value, precision) {
var nextValue = toNumber(value);
var scaleFactor = Math.pow(10, precision != null ? precision : 10);
nextValue = Math.round(nextValue * scaleFactor) / scaleFactor;
return precision ? nextValue.toFixed(precision) : nextValue.toString();
}
/**
* Counts the number of decimal places a number has
*
* @param value the decimal value to count
*/
function countDecimalPlaces(value) {
if (!Number.isFinite(value)) return 0;
var e = 1;
var p = 0;
while (Math.round(value * e) / e !== value) {
e *= 10;
p += 1;
}
return p;
}
/**
* Convert a value to percentage based on lower and upper bound values
*
* @param value the value in number
* @param min the minimum value
* @param max the maximum value
*/
function valueToPercent(value, min, max) {
return (value - min) * 100 / (max - min);
}
/**
* Calculate the value based on percentage, lower and upper bound values
*
* @param percent the percent value in decimals (e.g 0.6, 0.3)
* @param min the minimum value
* @param max the maximum value
*/
function percentToValue(percent, min, max) {
return (max - min) * percent + min;
}
/**
* Rounds a specific value to the next or previous step
*
* @param value the value to round
* @param from the number that stepping started from
* @param step the specified step
*/
function roundValueToStep(value, from, step) {
var nextValue = Math.round((value - from) / step) * step + from;
var precision = countDecimalPlaces(step);
return toPrecision(nextValue, precision);
}
/**
* Clamps a value to ensure it stays within the min and max range.
*
* @param value the value to clamp
* @param min the minimum value
* @param max the maximum value
*/
function clampValue(value, min, max) {
if (value == null) return value;
warn({
condition: max < min,
message: "clamp: max cannot be less than min"
});
return Math.min(Math.max(value, min), max);
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
/**
* Credit goes to `framer-motion` of this useful utilities.
* License can be found here: https://github.com/framer/motion
*/
function isMouseEvent(event) {
var win = getEventWindow(event); // PointerEvent inherits from MouseEvent so we can't use a straight instanceof check.
if (typeof win.PointerEvent !== "undefined" && event instanceof win.PointerEvent) {
return !!(event.pointerType === "mouse");
}
return event instanceof win.MouseEvent;
}
function isTouchEvent(event) {
var hasTouches = !!event.touches;
return hasTouches;
}
/**
* Filters out events not attached to the primary pointer (currently left mouse button)
* @param eventHandler
*/
function filterPrimaryPointer(eventHandler) {
return function (event) {
var win = getEventWindow(event);
var isMouseEvent = event instanceof win.MouseEvent;
var isPrimaryPointer = !isMouseEvent || isMouseEvent && event.button === 0;
if (isPrimaryPointer) {
eventHandler(event);
}
};
}
var defaultPagePoint = {
pageX: 0,
pageY: 0
};
function pointFromTouch(e, pointType) {
if (pointType === void 0) {
pointType = "page";
}
var primaryTouch = e.touches[0] || e.changedTouches[0];
var point = primaryTouch || defaultPagePoint;
return {
x: point[pointType + "X"],
y: point[pointType + "Y"]
};
}
function pointFromMouse(point, pointType) {
if (pointType === void 0) {
pointType = "page";
}
return {
x: point[pointType + "X"],
y: point[pointType + "Y"]
};
}
function extractEventInfo(event, pointType) {
if (pointType === void 0) {
pointType = "page";
}
return {
point: isTouchEvent(event) ? pointFromTouch(event, pointType) : pointFromMouse(event, pointType)
};
}
function getViewportPointFromEvent(event) {
return extractEventInfo(event, "client");
}
var wrapPointerEventHandler = function wrapPointerEventHandler(handler, shouldFilterPrimaryPointer) {
if (shouldFilterPrimaryPointer === void 0) {
shouldFilterPrimaryPointer = false;
}
var listener = function listener(event) {
return handler(event, extractEventInfo(event));
};
return shouldFilterPrimaryPointer ? filterPrimaryPointer(listener) : listener;
}; // We check for event support via functions in case they've been mocked by a testing suite.
var supportsPointerEvents = function supportsPointerEvents() {
return isBrowser && window.onpointerdown === null;
};
var supportsTouchEvents = function supportsTouchEvents() {
return isBrowser && window.ontouchstart === null;
};
var supportsMouseEvents = function supportsMouseEvents() {
return isBrowser && window.onmousedown === null;
};
var mouseEventNames = {
pointerdown: "mousedown",
pointermove: "mousemove",
pointerup: "mouseup",
pointercancel: "mousecancel",
pointerover: "mouseover",
pointerout: "mouseout",
pointerenter: "mouseenter",
pointerleave: "mouseleave"
};
var touchEventNames = {
pointerdown: "touchstart",
pointermove: "touchmove",
pointerup: "touchend",
pointercancel: "touchcancel"
};
function getPointerEventName(name) {
if (supportsPointerEvents()) {
return name;
}
if (supportsTouchEvents()) {
return touchEventNames[name];
}
if (supportsMouseEvents()) {
return mouseEventNames[name];
}
return name;
}
function addPointerEvent(target, eventName, handler, options) {
return addDomEvent(target, getPointerEventName(eventName), wrapPointerEventHandler(handler, eventName === "pointerdown"), options);
}
function isMultiTouchEvent(event) {
return isTouchEvent(event) && event.touches.length > 1;
}
/**
* The event information passed to pan event handlers like `onPan`, `onPanStart`.
*
* It contains information about the current state of the tap gesture such as its
* `point`, `delta`, and `offset`
*/
/**
* @internal
*
* A Pan Session is recognized when the pointer is down
* and moved in the allowed direction.
*/
var PanSession = /*#__PURE__*/function () {
/**
* We use this to keep track of the `x` and `y` pan session history
* as the pan event happens. It helps to calculate the `offset` and `delta`
*/
// The pointer event that started the pan session
// The current pointer event for the pan session
// The current pointer event info for the pan session
/**
* Minimal pan distance required before recognizing the pan.
* @default "3px"
*/
function PanSession(_event, handlers, threshold) {
var _this = this;
this.history = [];
this.startEvent = null;
this.lastEvent = null;
this.lastEventInfo = null;
this.handlers = {};
this.removeListeners = noop;
this.threshold = 3;
this.win = void 0;
this.updatePoint = function () {
if (!(_this.lastEvent && _this.lastEventInfo)) return;
var info = getPanInfo(_this.lastEventInfo, _this.history);
var isPanStarted = _this.startEvent !== null;
var isDistancePastThreshold = distance(info.offset, {
x: 0,
y: 0
}) >= _this.threshold;
if (!isPanStarted && !isDistancePastThreshold) return;
var _getFrameData = sync.getFrameData(),
timestamp = _getFrameData.timestamp;
_this.history.push(_extends({}, info.point, {
timestamp: timestamp
}));
var _this$handlers = _this.handlers,
onStart = _this$handlers.onStart,
onMove = _this$handlers.onMove;
if (!isPanStarted) {
onStart == null ? void 0 : onStart(_this.lastEvent, info);
_this.startEvent = _this.lastEvent;
}
onMove == null ? void 0 : onMove(_this.lastEvent, info);
};
this.onPointerMove = function (event, info) {
_this.lastEvent = event;
_this.lastEventInfo = info; // Because Safari doesn't trigger mouseup events when it's above a `<select>`
if (isMouseEvent(event) && event.buttons === 0) {
_this.onPointerUp(event, info);
return;
} // Throttle mouse move event to once per frame
sync__default["default"].update(_this.updatePoint, true);
};
this.onPointerUp = function (event, info) {
// notify pan session ended
var panInfo = getPanInfo(info, _this.history);
var _this$handlers2 = _this.handlers,
onEnd = _this$handlers2.onEnd,
onSessionEnd = _this$handlers2.onSessionEnd;
onSessionEnd == null ? void 0 : onSessionEnd(event, panInfo);
_this.end(); // if panning never started, no need to call `onEnd`
// panning requires a pointermove of at least 3px
if (!onEnd || !_this.startEvent) return;
onEnd == null ? void 0 : onEnd(event, panInfo);
};
this.win = getEventWindow(_event); // If we have more than one touch, don't start detecting this gesture
if (isMultiTouchEvent(_event)) return;
this.handlers = handlers;
if (threshold) {
this.threshold = threshold;
} // stop default browser behavior
_event.stopPropagation();
_event.preventDefault(); // get and save the `pointerdown` event info in history
// we'll use it to compute the `offset`
var _info = extractEventInfo(_event);
var _getFrameData2 = sync.getFrameData(),
_timestamp = _getFrameData2.timestamp;
this.history = [_extends({}, _info.point, {
timestamp: _timestamp
})]; // notify pan session start
var onSessionStart = handlers.onSessionStart;
onSessionStart == null ? void 0 : onSessionStart(_event, getPanInfo(_info, this.history)); // attach event listeners and return a single function to remove them all
this.removeListeners = pipe(addPointerEvent(this.win, "pointermove", this.onPointerMove), addPointerEvent(this.win, "pointerup", this.onPointerUp), addPointerEvent(this.win, "pointercancel", this.onPointerUp));
}
var _proto = PanSession.prototype;
_proto.updateHandlers = function updateHandlers(handlers) {
this.handlers = handlers;
};
_proto.end = function end() {
var _this$removeListeners;
(_this$removeListeners = this.removeListeners) == null ? void 0 : _this$removeListeners.call(this);
sync.cancelSync.update(this.updatePoint);
};
return PanSession;
}();
function subtractPoint(a, b) {
return {
x: a.x - b.x,
y: a.y - b.y
};
}
function startPanPoint(history) {
return history[0];
}
function lastPanPoint(history) {
return history[history.length - 1];
}
function getPanInfo(info, history) {
return {
point: info.point,
delta: subtractPoint(info.point, lastPanPoint(history)),
offset: subtractPoint(info.point, startPanPoint(history)),
velocity: getVelocity(history, 0.1)
};
}
function lastDevicePoint(history) {
return history[history.length - 1];
}
var toMilliseconds = function toMilliseconds(seconds) {
return seconds * 1000;
};
function getVelocity(history, timeDelta) {
if (history.length < 2) {
return {
x: 0,
y: 0
};
}
var i = history.length - 1;
var timestampedPoint = null;
var lastPoint = lastDevicePoint(history);
while (i >= 0) {
timestampedPoint = history[i];
if (lastPoint.timestamp - timestampedPoint.timestamp > toMilliseconds(timeDelta)) {
break;
}
i--;
}
if (!timestampedPoint) {
return {
x: 0,
y: 0
};
}
var time = (lastPoint.timestamp - timestampedPoint.timestamp) / 1000;
if (time === 0) {
return {
x: 0,
y: 0
};
}
var currentVelocity = {
x: (lastPoint.x - timestampedPoint.x) / time,
y: (lastPoint.y - timestampedPoint.y) / time
};
if (currentVelocity.x === Infinity) {
currentVelocity.x = 0;
}
if (currentVelocity.y === Infinity) {
currentVelocity.y = 0;
}
return currentVelocity;
}
var breakpoints = Object.freeze(["base", "sm", "md", "lg", "xl", "2xl"]);
function mapResponsive(prop, mapper) {
if (isArray(prop)) {
return prop.map(function (item) {
if (item === null) {
return null;
}
return mapper(item);
});
}
if (isObject(prop)) {
return objectKeys(prop).reduce(function (result, key) {
result[key] = mapper(prop[key]);
return result;
}, {});
}
if (prop != null) {
return mapper(prop);
}
return null;
}
function objectToArrayNotation(obj, bps) {
if (bps === void 0) {
bps = breakpoints;
}
var result = bps.map(function (br) {
var _obj$br;
return (_obj$br = obj[br]) != null ? _obj$br : null;
});
while (getLastItem(result) === null) {
result.pop();
}
return result;
}
function arrayToObjectNotation(values, bps) {
if (bps === void 0) {
bps = breakpoints;
}
var result = {};
values.forEach(function (value, index) {
var key = bps[index];
if (value == null) return;
result[key] = value;
});
return result;
}
function isResponsiveObjectLike(obj, bps) {
if (bps === void 0) {
bps = breakpoints;
}
var keys = Object.keys(obj);
return keys.length > 0 && keys.every(function (key) {
return bps.includes(key);
});
}
/**
* since breakpoints are defined as custom properties on an array, you may
* `Object.keys(theme.breakpoints)` to retrieve both regular numeric indices
* and custom breakpoints as string.
*
* This function returns true given a custom array property.
*/
var isCustomBreakpoint = function isCustomBreakpoint(maybeBreakpoint) {
return Number.isNaN(Number(maybeBreakpoint));
};
function getUserAgentBrowser(navigator) {
var ua = navigator.userAgent,
vendor = navigator.vendor;
var android = /(android)/i.test(ua);
switch (true) {
case /CriOS/.test(ua):
return "Chrome for iOS";
case /Edg\//.test(ua):
return "Edge";
case android && /Silk\//.test(ua):
return "Silk";
case /Chrome/.test(ua) && /Google Inc/.test(vendor):
return "Chrome";
case /Firefox\/\d+\.\d+$/.test(ua):
return "Firefox";
case android:
return "AOSP";
case /MSIE|Trident/.test(ua):
return "IE";
case /Safari/.test(navigator.userAgent) && /Apple Computer/.test(ua):
return "Safari";
case /AppleWebKit/.test(ua):
return "WebKit";
default:
return null;
}
}
function getUserAgentOS(navigator) {
var ua = navigator.userAgent,
platform = navigator.platform;
switch (true) {
case /Android/.test(ua):
return "Android";
case /iPhone|iPad|iPod/.test(platform):
return "iOS";
case /Win/.test(platform):
return "Windows";
case /Mac/.test(platform):
return "Mac";
case /CrOS/.test(ua):
return "Chrome OS";
case /Firefox/.test(ua):
return "Firefox OS";
default:
return null;
}
}
function detectDeviceType(navigator) {
var ua = navigator.userAgent;
if (/(tablet)|(iPad)|(Nexus 9)/i.test(ua)) return "tablet";
if (/(mobi)/i.test(ua)) return "phone";
return "desktop";
}
function detectOS(os) {
if (!isBrowser) return false;
return getUserAgentOS(window.navigator) === os;
}
function detectBrowser(browser) {
if (!isBrowser) return false;
return getUserAgentBrowser(window.navigator) === browser;
}
function detectTouch() {
if (!isBrowser) return false;
return window.ontouchstart === null && window.ontouchmove === null && window.ontouchend === null;
}
function walkObject(target, predicate) {
function inner(value, path) {
if (path === void 0) {
path = [];
}
if (isArray(value)) {
return value.map(function (item, index) {
return inner(item, [].concat(path, [String(index)]));
});
}
if (isObject(value)) {
return fromEntries(Object.entries(value).map(function (_ref) {
var key = _ref[0],
child = _ref[1];
return [key, inner(child, [].concat(path, [key]))];
}));
}
return predicate(value, path);
}
return inner(target);
}
Object.defineProperty(exports, 'mergeWith', {
enumerable: true,
get: function () { return lodash_mergewith__default["default"]; }
});
exports.PanSession = PanSession;
exports.__DEV__ = __DEV__;
exports.__TEST__ = __TEST__;
exports.addDomEvent = addDomEvent;
exports.addItem = addItem;
exports.addPointerEvent = addPointerEvent;
exports.analyzeBreakpoints = analyzeBreakpoints;
exports.ariaAttr = ariaAttr;
exports.arrayToObjectNotation = arrayToObjectNotation;
exports.breakpoints = breakpoints;
exports.callAll = callAll;
exports.callAllHandlers = callAllHandlers;
exports.canUseDOM = canUseDOM;
exports.chunk = chunk;
exports.clampValue = clampValue;
exports.closest = closest;
exports.compose = compose;
exports.contains = contains;
exports.countDecimalPlaces = countDecimalPlaces;
exports.cx = cx;
exports.dataAttr = dataAttr;
exports.detectBrowser = detectBrowser;
exports.detectDeviceType = detectDeviceType;
exports.detectOS = detectOS;
exports.detectTouch = detectTouch;
exports.determineLazyBehavior = determineLazyBehavior;
exports.distance = distance;
exports.error = error;
exports.extractEventInfo = extractEventInfo;
exports.filterUndefined = filterUndefined;
exports.focus = focus;
exports.focusNextTabbable = focusNextTabbable;
exports.focusPreviousTabbable = focusPreviousTabbable;
exports.fromEntries = fromEntries;
exports.get = get;
exports.getActiveElement = getActiveElement;
exports.getAllFocusable = getAllFocusable;
exports.getAllTabbable = getAllTabbable;
exports.getCSSVar = getCSSVar;
exports.getEventWindow = getEventWindow;
exports.getFirstFocusable = getFirstFocusable;
exports.getFirstItem = getFirstItem;
exports.getFirstTabbableIn = getFirstTabbableIn;
exports.getLastItem = getLastItem;
exports.getLastTabbableIn = getLastTabbableIn;
exports.getNextIndex = getNextIndex;
exports.getNextItem = getNextItem;
exports.getNextItemFromSearch = getNextItemFromSearch;
exports.getNextTabbable = getNextTabbable;
exports.getOwnerDocument = getOwnerDocument;
exports.getOwnerWindow = getOwnerWindow;
exports.getPointerEventName = getPointerEventName;
exports.getPrevIndex = getPrevIndex;
exports.getPrevItem = getPrevItem;
exports.getPreviousTabbable = getPreviousTabbable;
exports.getRelatedTarget = getRelatedTarget;
exports.getViewportPointFromEvent = getViewportPointFromEvent;
exports.getWithDefault = getWithDefault;
exports.hasDisplayNone = hasDisplayNone;
exports.hasFocusWithin = hasFocusWithin;
exports.hasNegativeTabIndex = hasNegativeTabIndex;
exports.hasTabIndex = hasTabIndex;
exports.isActiveElement = isActiveElement;
exports.isArray = isArray;
exports.isBrowser = isBrowser;
exports.isContentEditable = isContentEditable;
exports.isCssVar = isCssVar;
exports.isCustomBreakpoint = isCustomBreakpoint;
exports.isDefined = isDefined;
exports.isDisabled = isDisabled;
exports.isElement = isElement;
exports.isEmpty = isEmpty;
exports.isEmptyArray = isEmptyArray;
exports.isEmptyObject = isEmptyObject;
exports.isFocusable = isFocusable;
exports.isFunction = isFunction;
exports.isHTMLElement = isHTMLElement;
exports.isHidden = isHidden;
exports.isInputElement = isInputElement;
exports.isInputEvent = isInputEvent;
exports.isMouseEvent = isMouseEvent;
exports.isMultiTouchEvent = isMultiTouchEvent;
exports.isNotEmptyObject = isNotEmptyObject;
exports.isNotNumber = isNotNumber;
exports.isNull = isNull;
exports.isNumber = isNumber;
exports.isNumeric = isNumeric;
exports.isObject = isObject;
exports.isRefObject = isRefObject;
exports.isResponsiveObjectLike = isResponsiveObjectLike;
exports.isRightClick = isRightClick;
exports.isString = isString;
exports.isTabbable = isTabbable;
exports.isTouchEvent = isTouchEvent;
exports.isUndefined = isUndefined;
exports.mapResponsive = mapResponsive;
exports.maxSafeInteger = maxSafeInteger;
exports.memoize = memoize;
exports.memoizedGet = memoizedGet;
exports.minSafeInteger = minSafeInteger;
exports.noop = noop;
exports.normalizeEventKey = normalizeEventKey;
exports.objectFilter = objectFilter;
exports.objectKeys = objectKeys;
exports.objectToArrayNotation = objectToArrayNotation;
exports.omit = omit;
exports.once = once;
exports.percentToValue = percentToValue;
exports.pick = pick;
exports.pipe = pipe;
exports.px = px;
exports.removeIndex = removeIndex;
exports.removeItem = removeItem;
exports.roundValueToStep = roundValueToStep;
exports.runIfF