{"version":3,"file":"index.cjs","sources":["../hash.js","../env.js","../constants.js","../strings.js","../props.js","../svg.js","../focus.js"],"sourcesContent":["/**\n * generates a random hash using Math.random()\n *\n * @returns {String}\n */\nexport const randomHash = () => `${Math.random().toString(36).substring(2, 15)}`\n\n/**\n * creates hex string of the ArrayBuffer\n *\n * takes an ArrayBuffer and then converts it into Uint8Array\n * converts each element of Uint8Array and converts the value into Hex\n * pads the hex value with 0 to make it 2 character strings\n * returns the joined Array\n *\n * @param {ArrayBuffer} buffer\n * @returns {String}\n */\nexport const paddedHexString = (buffer) => {\n  const byteArray = new Uint8Array(buffer)\n\n  const hexCodes = Array.from(byteArray).map((value) =>\n    value.toString(16).padStart(2, \"0\")\n  )\n\n  return hexCodes.join(\"\")\n}\n\n/**\n * creates a sha256 of the given string\n *\n * based on the runtime environment, creates a sha256 hash of the string\n * before converting to hex\n *\n * @param {String} input\n * @returns {Promise}\n */\nexport const sha256 = async (input) => {\n  if (process.browser) {\n    if (!window.crypto.subtle) {\n      return Promise.reject(\n        new Error(\"`crypto` only works in secure contexts.\")\n      )\n    }\n    const buffer = await window.crypto.subtle.digest(\"SHA-256\", input)\n    return paddedHexString(buffer)\n    /* eslint-disable-next-line no-else-return */\n  } else {\n    // this kind of `process.browser` diversification is added because\n    // node doesn't support the WebCrypto API yet. node 16 has experimental\n    // support for the WebCrypto API.\n    // once support is mature, it would be wise & safe to remove `process.browser`\n    // also would need to update the rollup config & package metadata accordingly\n    /**\n     * @see https://nodejs.org/dist/latest-v16.x/docs/api/webcrypto.html\n     */\n    const { createHash } = require(\"crypto\")\n    const hash = createHash(\"sha256\")\n    hash.update(input)\n    return hash.digest(\"hex\")\n  }\n}\n\n/**\n * creates a sha256 of the given string\n *\n * creates a sha256 hash as hex value in browser or node\n *\n * @param {String} data\n * @returns {Promise}\n */\nexport const hash = (data) => {\n  const encoder = new TextEncoder(\"utf-8\")\n  return sha256(encoder.encode(data))\n}\n","/**\n * checks if environment is node or not\n *\n * @returns boolean\n */\nexport const isNode = () => typeof process !== \"undefined\"\n","export const INFO = \"info\"\nexport const SUCCESS = \"success\"\nexport const WARNING = \"warning\"\nexport const DANGER = \"danger\"\nexport const NEUTRAL = \"neutral\"\nexport const INVALID = \"invalid\"\nexport const BRAND = \"brand\"\n\nexport const KEYCODES = Object.freeze({\n  TAB: 9,\n  RETURN: 13,\n  ESC: 27,\n  SPACE: 32,\n  PAGEUP: 33,\n  PAGEDOWN: 34,\n  END: 35,\n  HOME: 36,\n  LEFT: 37,\n  UP: 38,\n  RIGHT: 39,\n  DOWN: 40,\n})\n\nexport const ID_PREFIX = \"sphlt-\"\n","import { ID_PREFIX } from \"./constants\"\n\n/**\n * Prepends a constant prefix to an ID\n *\n * @param {string} id ID of an element\n * @returns {string}\n */\nexport const getPrefixedId = (id) => (id ? `${ID_PREFIX}${id}` : \"\")\n\n/**\n * Converts the first character of `string` to upper case and the remaining to lower case\n *\n * @param {string} word The string to capitalize\n * @returns {string} Returns the capitalized string\n */\nexport const capitalise = (word = \"\") =>\n  word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase()\n\n/**\n * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).\n *\n * @param  {...string} words Strings to convert\n * @returns {string} Returns the camel cased string.\n */\nexport const camelCase = (...words) => {\n  return words.reduce((result, word, index) => {\n    word = word.toLowerCase()\n    return result + (index ? capitalise(word) : word)\n  }, \"\")\n}\n","import { camelCase } from \"./strings\"\n\n/**\n * validate custom size prop\n *\n * @param {Array} sizeArr array of sizes which the component accepts\n * @param {String} size size of component\n */\nexport const validateSize = (sizeArr, size) => {\n  return sizeArr.includes(size)\n}\n\n/**\n * validates that specific props occur only once\n *\n * takes an Enum of props to be validated and returns a function\n * the returned function then accepts props and checks that the\n * props which are in the Enum occur only once.\n *\n * @param {Enumerator} propsEnum Enum of props to be validated\n *\n * @returns {Function}\n */\nexport const createPropOccurValidator = (propsEnum) => (props) => {\n  const incomingProps = Object.keys(props).filter((key) => Boolean(props[key]))\n  return propsEnum.filter((prop) => incomingProps.includes(prop)).length <= 1\n}\n\n/**\n * Checks and resolves colliding props if present.\n * Returns defaultProp in case of collision otherwise return the prop.\n *\n * @param {Object} propsObj values of the props\n * @param {String} defaultProp fallback prop\n * @returns {{collision: boolean, value: string}} value with singleOccur information\n */\nexport const resolvePropCollision = (propsObj, defaultProp) => {\n  const validateProp = createPropOccurValidator(Object.keys(propsObj))\n\n  const singleOccur = validateProp({ ...propsObj })\n\n  if (!singleOccur) {\n    return { collision: true, value: defaultProp }\n  }\n\n  const truthyProp = Object.keys(propsObj).find((prop) => propsObj[prop])\n\n  return { collision: false, value: truthyProp ? truthyProp : defaultProp }\n}\n\n/**\n * returns function to determine support type\n *\n * @param {String} defaultType default support type\n *\n * @returns {Function}\n */\nexport const getSupportType = (defaultType) => (typeProps) => {\n  /**\n   * determines support type for component\n   *\n   * example:\n   * let's say `danger` is the default support type\n   * _case 1_: pass `info` in prop, returns `info`\n   * _case 2_: pass `info` and `danger`, returns `info`\n   * _case 3_: pass `info`, `success` and `danger`, returns `danger`\n   *\n   * @param {Object} typeProps object of support types\n   *\n   * @return {string}\n   */\n  const { [defaultType]: removedProp, ...restProps } = typeProps\n  const supportKeys = Object.keys(restProps)\n  const doPropsConflict = !createPropOccurValidator(supportKeys)(restProps)\n  if (doPropsConflict) {\n    return defaultType\n  }\n  return supportKeys.find((key) => Boolean(restProps[key])) || defaultType\n}\n\n/**\n * Returns a function to merge refs\n *\n * @param  {...any} refs React Ref to merge\n * @returns {Function}\n */\nexport const mergeRefs =\n  (...refs) =>\n  (node) => {\n    /**\n     * Points all the refs to one element\n     *\n     * @param {Object} node element to which all refs will point\n     */\n    refs.forEach((ref) => {\n      if (typeof ref === \"function\") {\n        ref(node)\n      } else if (ref !== null) {\n        ref.current = node\n      }\n    })\n  }\n\n/**\n * Returns properties with desired prefix from an object\n * @private\n *\n * @param {object} obj Object to filter from\n * @param {string} prefix prefix of properties to return\n *\n * @return object\n */\nconst yieldPropsWithPrefix = (obj, prefix) =>\n  Object.keys(obj).reduce(\n    (prefixedProps, key) => ({\n      ...prefixedProps,\n      ...(key.startsWith(prefix) && { [key]: obj[key] }),\n    }),\n    {}\n  )\n\n/**\n * Filters out properties with undesired prefix from an object\n * @private\n *\n * @param {object} obj Object to filter from\n * @param {string} prefix prefix of properties to filter\n *\n * @return object\n */\nconst filterPropsWithPrefix = (obj, prefix) =>\n  Object.keys(obj).reduce(\n    (prefixedProps, key) => ({\n      ...prefixedProps,\n      ...(!key.startsWith(prefix) && { [key]: obj[key] }),\n    }),\n    {}\n  )\n\n/**\n * Returns properties with `data-` prefix from an object\n *\n * @param {object} obj Object to filter from\n * @returns {object}\n */\nexport const yieldDataAttrs = (obj) => yieldPropsWithPrefix(obj, \"data-\")\n\n/**\n * Excludes properties with `data-` prefix from on object\n *\n * @param {object} obj Object to filter from\n * @returns {object}\n */\nexport const excludeDataAttrs = (obj) => filterPropsWithPrefix(obj, \"data-\")\n\n/**\n * Returns properties with `aria-` prefix from an object\n *\n * @param {object} obj Object to filter from\n * @returns {object}\n */\nexport const yieldAriaAttrs = (obj) => yieldPropsWithPrefix(obj, \"aria-\")\n\n/**\n * Excludes properties with `aria-` prefix from on object\n *\n * @param {object} obj Object to filter from\n * @returns {object}\n */\nexport const excludeAriaAttrs = (obj) => filterPropsWithPrefix(obj, \"aria-\")\n\nexport const concatClasses = (...words) => camelCase(...words)\n","/**\n * Checks if the value is of the type SVG\n *\n * @param {*} val\n * @returns {Boolean}\n */\n\nconst isTypeSVG = (val) => {\n  const type = typeof val === \"function\" ? val().type : val\n  return type === \"svg\"\n}\n\n/**\n * Checks if the the input is a SVG\n *\n * @param {Object} icon\n * @returns {Boolean}\n */\n\nexport const isSVG = (icon) => {\n  if (!icon) return false\n  const type = (icon.props && icon.props.originalType) || icon.type\n\n  return isTypeSVG(type)\n}\n","import { tabbable } from \"tabbable\"\n\n/**\n * Finds all focusable elements in the target element and returns the first, last and total focusable elements\n *\n * @param {Object} element - element in which you need to find focusable elements\n * @returns {Object}\n */\nconst firstAndlastFocusEls = (element) => {\n  const focusEls = tabbable(element)\n\n  const total = focusEls.length\n  return {\n    firstEl: focusEls[0],\n    lastEl: focusEls[total - 1],\n    total,\n  }\n}\n\n/**\n * Implements focus trap inside an element\n *\n * @param {Object} element element in which focus trap needs to be implemented\n * @param {Object} event React.syntheticEvent\n */\nexport const focusTrap = (element, event) => {\n  const { firstEl, lastEl } = firstAndlastFocusEls(element)\n\n  /**\n   * if `shift` key is pressed\n   * and the activeElement is first focusable element\n   * loop to the last foccussable element and set focus to it\n   */\n  if (event.shiftKey && document.activeElement === firstEl) {\n    lastEl.focus()\n    event.preventDefault()\n  }\n\n  if (!event.shiftKey && document.activeElement === lastEl) {\n    /**\n     * if the activeElement is the last focusable element\n     * loop to the first focusable element and set focus to it\n     */\n    firstEl.focus()\n    event.preventDefault()\n  }\n}\n"],"names":["randomHash","Math","random","toString","substring","paddedHexString","buffer","byteArray","Uint8Array","hexCodes","Array","from","map","value","padStart","join","sha256","input","createHash","require","hash","update","digest","data","encoder","TextEncoder","encode","isNode","process","INFO","SUCCESS","WARNING","DANGER","NEUTRAL","INVALID","BRAND","KEYCODES","Object","freeze","TAB","RETURN","ESC","SPACE","PAGEUP","PAGEDOWN","END","HOME","LEFT","UP","RIGHT","DOWN","ID_PREFIX","getPrefixedId","id","capitalise","word","toUpperCase","toLowerCase","camelCase","words","reduce","result","index","validateSize","sizeArr","size","includes","createPropOccurValidator","propsEnum","props","incomingProps","keys","filter","key","Boolean","prop","length","resolvePropCollision","propsObj","defaultProp","validateProp","singleOccur","collision","truthyProp","find","getSupportType","defaultType","typeProps","removedProp","restProps","supportKeys","doPropsConflict","mergeRefs","refs","node","forEach","ref","current","yieldPropsWithPrefix","obj","prefix","prefixedProps","startsWith","filterPropsWithPrefix","yieldDataAttrs","excludeDataAttrs","yieldAriaAttrs","excludeAriaAttrs","concatClasses","isTypeSVG","val","type","isSVG","icon","originalType","firstAndlastFocusEls","element","focusEls","tabbable","total","firstEl","lastEl","focusTrap","event","shiftKey","document","activeElement","focus","preventDefault"],"mappings":"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"}