{"version":3,"file":"index.mjs","sources":["../../../src/govuk/common/index.mjs"],"sourcesContent":["/**\n * Common helpers which do not require polyfill.\n *\n * IMPORTANT: If a helper require a polyfill, please isolate it in its own module\n * so that the polyfill can be properly tree-shaken and does not burden\n * the components that do not need that helper\n */\n\n/**\n * Get GOV.UK Frontend breakpoint value from CSS custom property\n *\n * @private\n * @param {string} name - Breakpoint name\n * @returns {{ property: string, value?: string }} Breakpoint object\n */\nexport function getBreakpoint(name) {\n  const property = `--govuk-breakpoint-${name}`\n\n  // Get value from `<html>` with breakpoints on CSS :root\n  const value = window\n    .getComputedStyle(document.documentElement)\n    .getPropertyValue(property)\n\n  return {\n    property,\n    value: value || undefined\n  }\n}\n\n/**\n * Move focus to element\n *\n * Sets tabindex to -1 to make the element programmatically focusable,\n * but removes it on blur as the element doesn't need to be focused again.\n *\n * @private\n * @template {HTMLElement} FocusElement\n * @param {FocusElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: FocusElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: FocusElement): void} [options.onBlur] - Callback on blur\n */\nexport function setFocus($element, options = {}) {\n  const isFocusable = $element.getAttribute('tabindex')\n\n  if (!isFocusable) {\n    $element.setAttribute('tabindex', '-1')\n  }\n\n  /**\n   * Handle element focus\n   */\n  function onFocus() {\n    $element.addEventListener('blur', onBlur, { once: true })\n  }\n\n  /**\n   * Handle element blur\n   */\n  function onBlur() {\n    options.onBlur?.call($element)\n\n    if (!isFocusable) {\n      $element.removeAttribute('tabindex')\n    }\n  }\n\n  // Add listener to reset element on blur, after focus\n  $element.addEventListener('focus', onFocus, { once: true })\n\n  // Focus element\n  options.onBeforeFocus?.call($element)\n  $element.focus()\n}\n\n/**\n * Checks if component is already initialised\n *\n * @internal\n * @param {Element} $root - HTML element to be checked\n * @param {string} moduleName - name of component module\n * @returns {boolean} Whether component is already initialised\n */\nexport function isInitialised($root, moduleName) {\n  return (\n    $root instanceof HTMLElement &&\n    $root.hasAttribute(`data-${moduleName}-init`)\n  )\n}\n\n/**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * Some browsers will load and run our JavaScript but GOV.UK Frontend\n * won't be supported.\n *\n * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support\n * @returns {boolean} Whether GOV.UK Frontend is supported on this page\n */\nexport function isSupported($scope = document.body) {\n  if (!$scope) {\n    return false\n  }\n\n  return $scope.classList.contains('govuk-frontend-supported')\n}\n\n/**\n * Check for an array\n *\n * @internal\n * @param {unknown} option - Option to check\n * @returns {boolean} Whether the option is an array\n */\nfunction isArray(option) {\n  return Array.isArray(option)\n}\n\n/**\n * Check for an object\n *\n * @internal\n * @template {Partial<Record<keyof ObjectType, unknown>>} ObjectType\n * @param {unknown | ObjectType} option - Option to check\n * @returns {option is ObjectType} Whether the option is an object\n */\nexport function isObject(option) {\n  return !!option && typeof option === 'object' && !isArray(option)\n}\n\n/**\n * Check for valid scope\n *\n * @internal\n * @template {Element | Document} ScopeType\n * @param {unknown | ScopeType} $scope - Scope of the document to search within\n * @returns {$scope is ScopeType} Whether the scope can be queried\n */\nexport function isScope($scope) {\n  return !!$scope && ($scope instanceof Element || $scope instanceof Document)\n}\n\n/**\n * Format error message\n *\n * @internal\n * @param {ComponentWithModuleName} Component - Component that threw the error\n * @param {string} message - Error message\n * @returns {string} - Formatted error message\n */\nexport function formatErrorMessage(Component, message) {\n  return `${Component.moduleName}: ${message}`\n}\n\n/* eslint-disable jsdoc/valid-types --\n * `{new(...args: any[] ): object}` is not recognised as valid\n * https://github.com/gajus/eslint-plugin-jsdoc/issues/145#issuecomment-1308722878\n * https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/131\n **/\n\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n\n/* eslint-enable jsdoc/valid-types */\n"],"names":["getBreakpoint","name","property","value","window","getComputedStyle","document","documentElement","getPropertyValue","undefined","setFocus","$element","options","_options$onBeforeFocu","isFocusable","getAttribute","setAttribute","onFocus","addEventListener","onBlur","once","_options$onBlur","call","removeAttribute","onBeforeFocus","focus","isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","body","classList","contains","isArray","option","Array","isObject","isScope","Element","Document","formatErrorMessage","Component","message"],"mappings":"AAeO,SAASA,aAAaA,CAACC,IAAI,EAAE;AAClC,EAAA,MAAMC,QAAQ,GAAG,CAAA,mBAAA,EAAsBD,IAAI,CAAA,CAAE;AAG7C,EAAA,MAAME,KAAK,GAAGC,MAAM,CACjBC,gBAAgB,CAACC,QAAQ,CAACC,eAAe,CAAC,CAC1CC,gBAAgB,CAACN,QAAQ,CAAC;EAE7B,OAAO;IACLA,QAAQ;IACRC,KAAK,EAAEA,KAAK,IAAIM;GACjB;AACH;AAeO,SAASC,QAAQA,CAACC,QAAQ,EAAEC,OAAO,GAAG,EAAE,EAAE;AAAA,EAAA,IAAAC,qBAAA;AAC/C,EAAA,MAAMC,WAAW,GAAGH,QAAQ,CAACI,YAAY,CAAC,UAAU,CAAC;EAErD,IAAI,CAACD,WAAW,EAAE;AAChBH,IAAAA,QAAQ,CAACK,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;AACzC,EAAA;EAKA,SAASC,OAAOA,GAAG;AACjBN,IAAAA,QAAQ,CAACO,gBAAgB,CAAC,MAAM,EAAEC,MAAM,EAAE;AAAEC,MAAAA,IAAI,EAAE;AAAK,KAAC,CAAC;AAC3D,EAAA;EAKA,SAASD,MAAMA,GAAG;AAAA,IAAA,IAAAE,eAAA;IAChB,CAAAA,eAAA,GAAAT,OAAO,CAACO,MAAM,KAAA,IAAA,IAAdE,eAAA,CAAgBC,IAAI,CAACX,QAAQ,CAAC;IAE9B,IAAI,CAACG,WAAW,EAAE;AAChBH,MAAAA,QAAQ,CAACY,eAAe,CAAC,UAAU,CAAC;AACtC,IAAA;AACF,EAAA;AAGAZ,EAAAA,QAAQ,CAACO,gBAAgB,CAAC,OAAO,EAAED,OAAO,EAAE;AAAEG,IAAAA,IAAI,EAAE;AAAK,GAAC,CAAC;EAG3D,CAAAP,qBAAA,GAAAD,OAAO,CAACY,aAAa,KAAA,IAAA,IAArBX,qBAAA,CAAuBS,IAAI,CAACX,QAAQ,CAAC;EACrCA,QAAQ,CAACc,KAAK,EAAE;AAClB;AAUO,SAASC,aAAaA,CAACC,KAAK,EAAEC,UAAU,EAAE;EAC/C,OACED,KAAK,YAAYE,WAAW,IAC5BF,KAAK,CAACG,YAAY,CAAC,CAAA,KAAA,EAAQF,UAAU,CAAA,KAAA,CAAO,CAAC;AAEjD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,WAAWA,CAACC,MAAM,GAAG1B,QAAQ,CAAC2B,IAAI,EAAE;EAClD,IAAI,CAACD,MAAM,EAAE;AACX,IAAA,OAAO,KAAK;AACd,EAAA;AAEA,EAAA,OAAOA,MAAM,CAACE,SAAS,CAACC,QAAQ,CAAC,0BAA0B,CAAC;AAC9D;AASA,SAASC,OAAOA,CAACC,MAAM,EAAE;AACvB,EAAA,OAAOC,KAAK,CAACF,OAAO,CAACC,MAAM,CAAC;AAC9B;AAUO,SAASE,QAAQA,CAACF,MAAM,EAAE;AAC/B,EAAA,OAAO,CAAC,CAACA,MAAM,IAAI,OAAOA,MAAM,KAAK,QAAQ,IAAI,CAACD,OAAO,CAACC,MAAM,CAAC;AACnE;AAUO,SAASG,OAAOA,CAACR,MAAM,EAAE;EAC9B,OAAO,CAAC,CAACA,MAAM,KAAKA,MAAM,YAAYS,OAAO,IAAIT,MAAM,YAAYU,QAAQ,CAAC;AAC9E;AAUO,SAASC,kBAAkBA,CAACC,SAAS,EAAEC,OAAO,EAAE;AACrD,EAAA,OAAO,GAAGD,SAAS,CAAChB,UAAU,CAAA,EAAA,EAAKiB,OAAO,CAAA,CAAE;AAC9C;AAQA;AACA;AACA;AACA;;;;"}