UNPKG

@publidata/utils-core

Version:
450 lines (376 loc) 13.8 kB
// Transform my-text to My-Text const capitalize = (string = "") => string .replace(/\b\w/g, l => l.toUpperCase()) .replace(/([à-ùÀ-Ù])\b\w/g, l => l.toLowerCase()); exports.capitalize = capitalize; // Transform my-text to myText const toCamelCase = (string = "") => string.replace(/(-|_)([a-z])/g, g => g[1].toUpperCase()); exports.toCamelCase = toCamelCase; const toSnakeCase = string => string .replace(/[\w]([A-Z])/g, juncture => `${juncture[0]}_${juncture[1]}`) .toLowerCase(); exports.toSnakeCase = toSnakeCase; const toPascalCase = string => string .match(/[a-z]+/gi) .map(word => word.charAt(0).toUpperCase() + word.substr(1).toLowerCase()) .join(""); exports.toPascalCase = toPascalCase; // Remove all "-" or "_" in a string const removeHyphen = (string, replaceBy = "") => string.replace(/-|_/g, replaceBy); exports.removeHyphen = removeHyphen; // Remove all HTML tags such as <span> and so from a string const removeHTML = string => (string || "") .replace(/<\/p>\s*<p[^>]*>/g, " ") .replace(/<(?:.|\n)*?>/gm, "") .replace(/&nbsp;/gm, " "); exports.removeHTML = removeHTML; // Transform my-text to MyText exports.classify = (string = "") => removeHyphen(capitalize(toCamelCase(string))); const capitalizeFirstLetter = string => string && string.length && string.charAt(0).toUpperCase() + string.slice(1); exports.capitalizeFirstLetter = capitalizeFirstLetter; // Adds a leading 0 to a time in Int when it's < 10 const addLeadingZeroToNumber = number => `${number < 10 ? `0${number}` : number}`; exports.addLeadingZeroToNumber = addLeadingZeroToNumber; /* global window */ // Return IE version - null if not IE or below v6 const isIe = () => { if (typeof window !== "undefined") { const win = window; const doc = win.document; const input = doc.createElement("input"); // "!win.ActiveXObject" is evaluated to true in IE11 if (win.ActiveXObject === undefined) return null; if (!win.XMLHttpRequest) return 6; if (!doc.querySelector) return 7; if (!doc.addEventListener) return 8; if (!win.atob) return 9; // "!doc.body.dataset" is faster but the body is null when the DOM is not // ready. Anyway, an input tag needs to be created to check if IE is being // emulated if (!input.dataset) return 10; return 11; } return null; }; exports.isIe = isIe; /* global document */ const canUseWebP = () => { const elem = document.createElement("canvas"); if (elem.getContext && elem.getContext("2d")) { // was able or not to get WebP representation return elem.toDataURL("image/webp").indexOf("data:image/webp") === 0; } // very old browser like IE 8, canvas not supported return false; }; exports.canUseWebP = canUseWebP; // Syntax shortcut for JSON.parse const parse = json => { if (typeof json === "object") return json; if (json && json !== "") return JSON.parse(json); return {}; }; exports.parse = parse; function strAttr(name, value, depth) { return `${"\t".repeat(depth)}${name}: ${value};\n`; } exports.strAttr = strAttr; const toCSS = (node, depth = 0, breaks = false) => { let cssString = ""; if (node.attributes) { node.attributes.forEach((attribute, i) => { if (attribute instanceof Array) { for (let j = 0; j < attribute.length; j++) { cssString += strAttr(i, attribute[j], depth); } } else { cssString += strAttr(i, attribute, depth); } }); } if (node.children) { let first = true; node.children.forEach((child, i) => { if (breaks && !first) { cssString += "\n"; } else { first = false; } cssString += strNode(i, child, depth); // eslint-disable-line }); } return cssString; }; exports.toCSS = toCSS; function strNode(name, value, depth) { let cssString = `${"\t".repeat(depth)}${name} {\n`; cssString += toCSS(value, depth + 1); cssString += `${"\t".repeat(depth)}}\n`; return cssString; } // Transform json css data to react compliant css properties exports.css = json => { if (!json) return ""; return toCSS(parse(json)); }; // // Loop all property following this JSON structure : https://github.com/aramk/CSSJSON // function formatJSONCss(css) { // for (let key in css) { // if (key === "attributes") { // let attributes = css["attributes"] // if (attributes) attributes = setAttributeKeyToCamelCase(attributes) // } else { // css[key] = formatJSONCss(css[key]) // } // } // return css // } // // // Change every background-color to backgroundColor // function setAttributeKeyToCamelCase(attributes) { // let newAttributes = {} // for (let key in attributes) { // newAttributes[toCamelCase(key)] = attributes[key] // } // return newAttributes // } const hashCode = string => { let hash = 0; let i; let chr; if (string.length === 0) return hash; for (i = 0; i < string.length; i++) { chr = string.charCodeAt(i); hash = (hash << 5) - hash + chr; // eslint-disable-line no-bitwise hash |= 0; // eslint-disable-line no-bitwise } return hash; }; /* Generate react item key from array of items * array : array of whatever you want * @return : array[{ * value: item, * key: randomkey * }] */ const keygen = array => { if (!array) return []; return array.map((item, index) => { const newObject = { value: item, key: "" }; if (typeof item === "object") { if (item.props !== undefined) newObject.key = hashCode(`${JSON.stringify(item.props)}`); else newObject.key = hashCode(`${JSON.stringify(item)}`); } else newObject.key = hashCode(`${JSON.stringify(item)}`); newObject.key = `${newObject.key}${index}`; return newObject; }); }; exports.keygen = keygen; /* eslint-disable */ function isComputer() { if(typeof window === "undefined") return true; let check = true; (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = false;})(navigator.userAgent||navigator.vendor||window.opera); return check; } function isWide() { if(typeof window === "undefined") return false; if (window.innerWidth >= 1200 && isComputer()) return true; return false; } exports.isWide = isWide; function isMobile() { if(typeof window === "undefined") return false; // if (window.innerWidth <= 480) return true; return !isComputer(); } exports.isMobile = isMobile; function isMobileAndTablet() { if(typeof window === "undefined") return false; // if (window.innerWidth <= 768) return true; return !isComputer(); } exports.isMobileAndTablet = isMobileAndTablet; function isTablet() { if(isMobileAndTablet() && !isMobile()) return true; return false; } exports.isTablet = isTablet; function pluralize(object, string) { if(object.length > 1) return `${string}s`; // Plural case else if(object.length === 0) return `${string}s`; return string; } exports.pluralize = pluralize; /** * Return value of CSS variable from a type or a variable string * @param { String } str type (Ex: "facility" --> var(--facility)) */ function getColorVar(str) { return `var(--${str})`; } exports.getColorVar = getColorVar; /** * Return array of unique objects * @param { Array<Object> } myArr Array you want to check * @param { String } prop Property you want to be unique */ function removeDuplicates(myArr, prop) { return myArr.filter((obj, pos, arr) => arr.map(item => item[prop]).indexOf(obj[prop]) === pos); } exports.removeDuplicates = removeDuplicates; /** * Return simple unique ID * @return { String } ID */ function getUniqueID() { return `id-${Math.random().toString(36).substr(2, 16)}`; } exports.getUniqueID = getUniqueID; /** * * @param {Object} object * @param {String} oldKey * @param {String} newKey */ function renameObjectKey(object, oldKey, newKey) { if (oldKey !== newKey) { delete Object.assign(object, {[newKey]: object[oldKey]})[oldKey]; } } exports.renameObjectKey = renameObjectKey; /* * Instead of imbricate functions, pipe them. * Usage : method3(method2(method1(string))) becomes pipe(method1, method2, method3)(string) */ const pipe = (...functions) => variable => functions.reduce( (resultOfPreviousChange, currentFunction) => currentFunction(resultOfPreviousChange), variable ); exports.pipe = pipe; /* * Returns a function, that, as long as it continues to be invoked, will not * be triggered. The function will be called after it stops being called for * 'delay' milliseconds. */ const debounce = (callback, context, delay) => { let timeout; return function() { const args = arguments; const later = function() { timeout = null; callback.apply(context, args); }; clearTimeout(timeout); timeout = setTimeout(later, delay) } } exports.debounce = debounce; /* Create a unique identifier * @return {String} - uuid */ function createUuid(){ var dt = new Date().getTime(); var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = (dt + Math.random()*16)%16 | 0; dt = Math.floor(dt/16); return (c=='x' ? r :(r&0x3|0x8)).toString(16); }); return uuid; } exports.createUuid = createUuid; /* Escape special characters from a string to be used as a pattern in a RegExp * these characters : \ ^ $ * + ? . ( ) | { } [ ] * should be escaped : \\ \^ \$ \* \+ \? \. \( \) \| \{ \} \[ \] */ const escapeRegExp = string => { if (typeof string !== "string") return ""; return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string } exports.escapeRegExp = escapeRegExp; /** * Removes duplicates objects from an array. * @param {Array} array Array to be processed. * @param {String} [key] Base key to be used to check for duplicates. "id" by default. * @return {Array} Return the array without duplicates. */ const arrayOfUniqsObject = (array, key = "id") => { if (!array) return null; const uniqueArray = []; array.forEach(item => { if ( !uniqueArray.some(objectToCompare => objectToCompare[key] === item[key]) ) { uniqueArray.push(item); } }); return uniqueArray; }; exports.arrayOfUniqsObject = arrayOfUniqsObject; /** * Truncate a string if it exceeds a maximum length * * @param {string} str Text to truncate * @param {number} maxLength Maximum length of the truncated text (excluding suffix length) * @param {string} suffix Suffix to append to the truncated text (default: "...") * @returns {string} * * @example * * ```js * truncate("Lorem ipsum dolor sit amet", 10); // => "Lorem ipsu..." * truncate("Lorem ipsum dolor sit amet", 10, "... 🏁"); // => "Lorem ipsu... 🏁" * ``` */ function truncate(str, maxLength, suffix = "...") { if (str.length > maxLength) { return str.slice(0, maxLength) + suffix; } return str; }; exports.truncate = truncate; /** * Fully decode a URI component * @param {String} param The URI component to decode * @returns {String} The decoded URI component */ const fullyDecodeComponent = param => { let decodedParam = param; let iterationCount = 0; const MAX_ITERATIONS = 10; try { while ( decodedParam !== decodeURIComponent(decodedParam) && iterationCount < MAX_ITERATIONS ) { decodedParam = decodeURIComponent(decodedParam); iterationCount++; } } catch (error) { console.error("Error decoding URI component:", error); return param; // Return the original param if decoding fails } if (iterationCount === MAX_ITERATIONS) { // eslint-disable-next-line no-console console.warn( "Maximum iteration limit reached while decoding URI component." ); } return decodedParam; }; exports.fullyDecodeComponent = fullyDecodeComponent;