@oruga-ui/oruga-next
Version:
UI components for Vue.js and CSS framework agnostic
1 lines • 16.6 kB
Source Map (JSON)
{"version":3,"file":"helpers.cjs","sources":["../../src/utils/helpers.ts"],"sourcesContent":["import { Comment, Fragment, Text } from \"vue\";\nimport type { DeepKeys, DeepType } from \"@/types\";\n\n/**\n * +/- function to native math sign\n */\nfunction signPoly(value: number): number {\n if (value < 0) return -1;\n return value > 0 ? 1 : 0;\n}\nexport const sign = Math.sign || signPoly;\n\n/**\n * Native modulo bug with negative numbers\n * @param n\n * @param mod\n * @returns {number}\n */\nexport const mod = (n: number, mod: number): number => ((n % mod) + mod) % mod;\n\n/** add a prefix `0` to a 1 digit number */\nexport const pad = (value: number): string => (value < 10 ? \"0\" : \"\") + value;\n\n/**\n * Asserts a value is beetween min and max\n * @param val\n * @param min\n * @param max\n * @returns {number}\n */\nexport function bound(val: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, val));\n}\n\n/**\n * checks if the value is of type object\n */\nexport const isObject = (value: unknown): value is object =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\n\n/**\n * checks if the value is of type date\n */\nexport const isDate = (value: unknown): value is Date =>\n !!value && value instanceof Date && !isNaN(value.getTime());\n\n/**\n * checks if the value is not null or undefined\n */\nexport const isDefined = <T>(value: T | undefined | null): value is T =>\n value !== null && typeof value !== \"undefined\";\n\n/**\n * Determines if the value of a prop that is either present (true) or not\n * present (undefined). For example, the prop disabled should disable\n * by just existing, but what if it is set to the string \"false\" — then it\n * should not be disabled.\n *\n * @param value - Value to check for undefined.\n * @returns boolean\n */\nexport const isTrueish = (value: unknown): boolean =>\n isDefined(value) && value !== \"false\" && value !== false;\n\nexport const blankIfUndefined = (value: string | null | undefined): string =>\n isDefined(value) ? value : \"\";\n\nexport const defaultIfUndefined = <T>(\n value: T | undefined,\n defaultValue: T,\n): T => (isDefined(value) ? value : defaultValue);\n\nexport const toCssDimension = (\n width: string | number | undefined,\n dimension: string = \"px\",\n): string | undefined =>\n !isDefined(width)\n ? undefined\n : isNaN(width as number)\n ? String(width)\n : String(width) + dimension;\n\n/**\n * Sort an array by key without mutating original data.\n * Call the user sort function if it was passed.\n */\nexport function sortBy<T extends object>(\n array: T[],\n key: DeepKeys<T>,\n fn?: (a: T, b: T, asc: boolean) => number,\n isAsc: boolean = false,\n mutate: boolean = false,\n): T[] {\n // Sorting without mutating original data\n if (fn && typeof fn === \"function\") {\n return (mutate ? array : [...array]).sort((a, b) => fn(a, b, isAsc));\n } else {\n return (mutate ? array : [...array]).sort((a, b) => {\n // Get nested values from objects\n let newA: any = isObject(a) ? getValueByPath(a, key) : a;\n let newB: any = isObject(b) ? getValueByPath(b, key) : b;\n\n // sort boolean type\n if (typeof newA === \"boolean\" && typeof newB === \"boolean\") {\n return isAsc ? (newA > newB ? 1 : -1) : newA > newB ? -1 : 1;\n }\n\n if (!newA && newA !== 0) return 1;\n if (!newB && newB !== 0) return -1;\n if (newA === newB) return 0;\n\n newA = typeof newA === \"string\" ? newA.toUpperCase() : newA;\n newB = typeof newB === \"string\" ? newB.toUpperCase() : newB;\n\n return isAsc ? (newA > newB ? 1 : -1) : newA > newB ? -1 : 1;\n });\n }\n}\n\n/**\n * Deeply check if two values are equal\n */\nexport function isEqual(valueA: unknown, valueB: unknown): boolean {\n // Check if only one value is empty.\n if ((!valueA && !!valueB) || (!!valueA && !valueB)) return false;\n\n // If both objects are identical, return true.\n if (valueA === valueB) return true;\n\n // Check if both values are objecs.\n if (isObject(valueA) && isObject(valueB)) {\n // Get the keys of both objects.\n const keys1 = Object.keys(valueA);\n const keys2 = Object.keys(valueB);\n\n // Check if the number of keys is the same.\n if (keys1.length !== keys2.length) return false;\n\n // Iterate through the keys and compare their values recursively.\n for (const key of keys1) {\n const val1 = valueA[key];\n const val2 = valueB[key];\n const areObjects = isObject(val1) && isObject(val2);\n if (\n (areObjects && !isEqual(val1, val2)) ||\n (!areObjects && val1 !== val2)\n )\n return false;\n }\n // If all checks pass, the objects are deep equal.\n return true;\n }\n\n // Check if both values are arrays.\n if (Array.isArray(valueA) && Array.isArray(valueB)) {\n // Check if the number of keys is the same.\n if (valueA.length !== valueB.length) return false;\n // Check if each value of the array is the same.\n if (!valueA.every((val, index) => val === valueB[index])) return false;\n // If all checks pass, the arrays are deep equal.\n return true;\n }\n\n return false;\n}\n\n/**\n * @deprecated not used\n * Returns true if it is a DOM element\n * @source https://stackoverflow.com/questions/384286/how-do-you-check-if-a-javascript-object-is-a-dom-object\n */\nexport function isElement(el: any): el is Element {\n return typeof HTMLElement === \"object\"\n ? el instanceof HTMLElement //DOM2\n : el &&\n typeof el === \"object\" &&\n el !== null &&\n el.nodeType === 1 &&\n typeof el.nodeName === \"string\";\n}\n\n/**\n * Merge function to replace Object.assign with deep merging possibility\n */\nexport function merge(target: any, source: any, deep = false): any {\n if (!isObject(target) || !isObject(source)) return source;\n if (!deep) return Object.assign(target, source);\n else return mergeDeep(target, source);\n}\n\n/**\n * Performs a deep merge of `source` into `target`.\n * Mutates `target` only but not its objects and arrays.\n *\n * @author inspired by [jhildenbiddle](https://stackoverflow.com/a/48218209).\n */\nexport function mergeDeep(target: any, source: any): any {\n if (!isObject(target) || !isObject(source)) return source;\n\n Object.getOwnPropertyNames(source).forEach((key) => {\n const targetValue = target[key];\n const sourceValue = source[key];\n\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n target[key] = targetValue.concat(sourceValue);\n } else if (isObject(targetValue) && isObject(sourceValue)) {\n target[key] = mergeDeep(\n Object.assign({}, targetValue),\n sourceValue,\n );\n } else {\n target[key] = sourceValue;\n }\n });\n\n return target;\n}\n\n/**\n * Return display text for an option.\n * If option is an object, get the property from path based on given field, or else just the property.\n * Apply a formatter function to the property if given.\n * Return the display label.\n *\n * @param obj Object to get the label for\n * @param field Property path of the object to use as display text\n * @param formatter Function to format the property to a string\n */\nexport function getPropertyValue<\n O,\n K extends DeepKeys<O>,\n D extends DeepType<O, K>,\n>(obj: O, field?: K, formatter?: (value: D, option: O) => string): string {\n if (!obj) return \"\";\n\n const property = (field ? getValueByPath<O, K, D>(obj, field) : obj) as D;\n\n const label =\n typeof formatter === \"function\" ? formatter(property, obj) : property;\n\n return String(label || \"\");\n}\n\n/**\n * Get a value of an object property/path even if it's nested\n */\nexport function getValueByPath<\n O,\n K extends DeepKeys<O>,\n D extends DeepType<O, K>,\n>(obj: O, path: K | (string & {})): D | undefined;\nexport function getValueByPath<\n O,\n K extends DeepKeys<O>,\n D extends DeepType<O, K>,\n>(obj: O, path: K | (string & {}), defaultValue: D): D;\nexport function getValueByPath<\n O,\n K extends DeepKeys<O>,\n D extends DeepType<O, K>,\n>(obj: O, path: K | (string & {}), defaultValue?: D): D | undefined;\nexport function getValueByPath<\n O,\n K extends DeepKeys<O>,\n D extends DeepType<O, K>,\n>(obj: O, path: K | (string & {}), defaultValue?: D): D | undefined {\n if (!obj || typeof obj !== \"object\" || typeof path !== \"string\")\n return defaultValue;\n\n const value: any = path\n .split(\".\")\n .reduce((o, i) => (typeof o !== \"undefined\" ? o[i] : undefined), obj);\n\n return typeof value !== \"undefined\" ? value : defaultValue;\n}\n\n/**\n * Set a value of an object property/path even if it's nested\n */\nexport function setValueByPath<O, K extends DeepKeys<O>>(\n obj: O,\n path: K,\n value: DeepType<O, K>,\n): void {\n if (typeof path !== \"string\") return;\n\n const p = path.split(\".\");\n if (p.length === 1) {\n obj[p[0]] = value;\n return;\n }\n const field = p[0];\n if (typeof obj[field] === \"undefined\") obj[field] = {};\n return setValueByPath(obj[field], p.slice(1).join(\".\"), value);\n}\n\nexport function removeElement(el: Element): void {\n if (typeof el.remove !== \"undefined\") {\n el.remove();\n } else if (typeof el.parentNode !== \"undefined\" && el.parentNode !== null) {\n el.parentNode.removeChild(el);\n }\n}\n\n/**\n * Escape regex characters\n * http://stackoverflow.com/a/6969486\n */\nexport function escapeRegExpChars(value: string): string {\n if (!value) return value;\n\n return value.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\");\n}\n\n/**\n * Remove accents/diacritics in a string\n * https://stackoverflow.com/a/37511463\n */\nexport function removeDiacriticsFromString(value: string): string {\n if (!value) return value;\n return value.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\n}\n\n/** checks if a vue vnode is empty */\nexport function isVNodeEmpty(vnode): boolean {\n if (!vnode) return true;\n if (vnode.type === Comment) return true;\n if (vnode.type === Text && !vnode.children.trim()) return true;\n if (vnode.type === Fragment && isVNodeEmpty(vnode.children)) return true;\n return false;\n}\n\n/**\n * Mobile detection\n * https://www.abeautifulsite.net/detecting-mobile-devices-with-javascript\n */\nexport const isMobileAgent = {\n Android: (): boolean =>\n typeof window !== \"undefined\" &&\n !!window.navigator.userAgent.match(/Android/i),\n BlackBerry: (): boolean =>\n typeof window !== \"undefined\" &&\n !!window.navigator.userAgent.match(/BlackBerry/i),\n iOS: (): boolean =>\n typeof window !== \"undefined\" &&\n !!window.navigator.userAgent.match(/iPhone|iPad|iPod/i),\n Opera: (): boolean =>\n typeof window !== \"undefined\" &&\n !!window.navigator.userAgent.match(/Opera Mini/i),\n Windows: (): boolean =>\n typeof window !== \"undefined\" &&\n !!window.navigator.userAgent.match(/IEMobile/i),\n any: (): boolean =>\n isMobileAgent.Android() ||\n isMobileAgent.BlackBerry() ||\n isMobileAgent.iOS() ||\n isMobileAgent.Opera() ||\n isMobileAgent.Windows(),\n};\n"],"names":["mod","Comment","Text","Fragment"],"mappings":"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"}