{"version":3,"file":"init.mjs","sources":["../../src/govuk/init.mjs"],"sourcesContent":["import { normaliseOptions } from './common/configuration.mjs'\nimport { isObject, isSupported } from './common/index.mjs'\nimport { Accordion } from './components/accordion/accordion.mjs'\nimport { Button } from './components/button/button.mjs'\nimport { CharacterCount } from './components/character-count/character-count.mjs'\nimport { Checkboxes } from './components/checkboxes/checkboxes.mjs'\nimport { ErrorSummary } from './components/error-summary/error-summary.mjs'\nimport { ExitThisPage } from './components/exit-this-page/exit-this-page.mjs'\nimport { FileUpload } from './components/file-upload/file-upload.mjs'\nimport { NotificationBanner } from './components/notification-banner/notification-banner.mjs'\nimport { PasswordInput } from './components/password-input/password-input.mjs'\nimport { Radios } from './components/radios/radios.mjs'\nimport { ServiceNavigation } from './components/service-navigation/service-navigation.mjs'\nimport { SkipLink } from './components/skip-link/skip-link.mjs'\nimport { Tabs } from './components/tabs/tabs.mjs'\nimport { ElementError, SupportError } from './errors/index.mjs'\n\n/**\n * Initialise all components\n *\n * Use the `data-module` attributes to find, instantiate and init all of the\n * components provided as part of GOV.UK Frontend.\n *\n * @param {Config | Element | Document | null} [scopeOrConfig] - Scope of the document to search within or config for all components (with optional scope)\n */\nfunction initAll(scopeOrConfig = {}) {\n  const config = isObject(scopeOrConfig) ? scopeOrConfig : {}\n\n  // Extract initialisation options\n  const options = normaliseOptions(scopeOrConfig)\n\n  try {\n    // Skip initialisation when GOV.UK Frontend is not supported\n    if (!isSupported()) {\n      throw new SupportError()\n    }\n\n    // Users can initialise GOV.UK Frontend in certain sections of the page\n    // unless the scope is null (for example, query selector not found)\n    if (options.scope === null) {\n      throw new ElementError({\n        element: options.scope,\n        identifier: 'GOV.UK Frontend scope element (`$scope`)'\n      })\n    }\n  } catch (error) {\n    if (options.onError) {\n      options.onError(error, {\n        config\n      })\n    } else {\n      console.log(error)\n    }\n\n    return\n  }\n\n  const components = /** @type {const} */ ([\n    [Accordion, config.accordion],\n    [Button, config.button],\n    [CharacterCount, config.characterCount],\n    [Checkboxes],\n    [ErrorSummary, config.errorSummary],\n    [ExitThisPage, config.exitThisPage],\n    [FileUpload, config.fileUpload],\n    [NotificationBanner, config.notificationBanner],\n    [PasswordInput, config.passwordInput],\n    [Radios],\n    [ServiceNavigation],\n    [SkipLink],\n    [Tabs]\n  ])\n\n  components.forEach(([Component, componentConfig]) => {\n    createAll(Component, componentConfig, options)\n  })\n}\n\n/**\n * Create all instances of a specific component on the page\n *\n * Uses the `data-module` attribute to find all elements matching the specified\n * component on the page, creating instances of the component object for each\n * of them.\n *\n * Any component errors will be caught and logged to the console.\n *\n * @template {CompatibleClass} ComponentClass\n * @param {ComponentClass} Component - class of the component to create\n * @param {ComponentConfig<ComponentClass>} [config] - Config supplied to component\n * @param {OnErrorCallback<ComponentClass> | Element | Document | null | CreateAllOptions<ComponentClass>} [scopeOrOptions] - options for createAll including scope of the document to search within and callback function if error throw by component on init\n * @returns {Array<InstanceType<ComponentClass>>} - array of instantiated components\n */\nfunction createAll(Component, config, scopeOrOptions) {\n  let /** @type {NodeListOf<Element> | undefined} */ $elements\n\n  // Extract initialisation options\n  const options = normaliseOptions(scopeOrOptions)\n\n  try {\n    // Skip initialisation when GOV.UK Frontend is not supported\n    if (!isSupported()) {\n      throw new SupportError()\n    }\n\n    // Users can initialise GOV.UK Frontend in certain sections of the page\n    // unless the scope is null (for example, query selector not found)\n    if (options.scope === null) {\n      throw new ElementError({\n        element: options.scope,\n        component: Component,\n        identifier: 'Scope element (`$scope`)'\n      })\n    }\n\n    $elements = options.scope?.querySelectorAll(\n      `[data-module=\"${Component.moduleName}\"]`\n    )\n  } catch (error) {\n    if (options.onError) {\n      options.onError(error, {\n        component: Component,\n        config\n      })\n    } else {\n      console.log(error)\n    }\n\n    return []\n  }\n\n  /* eslint-disable-next-line @typescript-eslint/no-unsafe-return --\n   * We can't define CompatibleClass as `{new(): CompatibleClass, moduleName: string}`,\n   * as when doing `typeof Accordion` (or any component), TypeScript doesn't seem\n   * to acknowledge the static `moduleName` that's set in our component classes.\n   * This means we have to set the constructor of `CompatibleClass` as `{new(): any}`,\n   * leading to ESLint frowning that we're returning `any[]`.\n   */\n  return Array.from($elements ?? [])\n    .map(($element) => {\n      try {\n        // Only pass config to components that accept it\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n        return typeof config !== 'undefined'\n          ? new Component($element, config)\n          : new Component($element)\n      } catch (error) {\n        if (options.onError) {\n          options.onError(error, {\n            element: $element,\n            component: Component,\n            config\n          })\n        } else {\n          console.log(error)\n        }\n\n        return null\n      }\n    })\n    .filter(Boolean) // Exclude components that errored\n}\n\nexport { initAll, createAll }\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 {{new (...args: any[]): any, moduleName: string}} CompatibleClass\n */\n\n/* eslint-enable jsdoc/valid-types */\n\n/**\n * Config for all components via `initAll()`\n *\n * @typedef {object} Config\n * @property {Element | Document | null} [scope] - Scope of the document to search within\n * @property {OnErrorCallback<CompatibleClass>} [onError] - Initialisation error callback\n * @property {AccordionConfig} [accordion] - Accordion config\n * @property {ButtonConfig} [button] - Button config\n * @property {CharacterCountConfig} [characterCount] - Character Count config\n * @property {ErrorSummaryConfig} [errorSummary] - Error Summary config\n * @property {ExitThisPageConfig} [exitThisPage] - Exit This Page config\n * @property {FileUploadConfig} [fileUpload] - File Upload config\n * @property {NotificationBannerConfig} [notificationBanner] - Notification Banner config\n * @property {PasswordInputConfig} [passwordInput] - Password input config\n */\n\n/**\n * Config for individual components\n *\n * @import { AccordionConfig } from './components/accordion/accordion.mjs'\n * @import { ButtonConfig } from './components/button/button.mjs'\n * @import { CharacterCountConfig } from './components/character-count/character-count.mjs'\n * @import { ErrorSummaryConfig } from './components/error-summary/error-summary.mjs'\n * @import { ExitThisPageConfig } from './components/exit-this-page/exit-this-page.mjs'\n * @import { NotificationBannerConfig } from './components/notification-banner/notification-banner.mjs'\n * @import { PasswordInputConfig } from './components/password-input/password-input.mjs'\n * @import { FileUploadConfig } from './components/file-upload/file-upload.mjs'\n */\n\n/**\n * Component config keys, e.g. `accordion` and `characterCount`\n *\n * @typedef {keyof Omit<Config, 'scope' | 'onError'>} ConfigKey\n */\n\n/**\n * @template {CompatibleClass} ComponentClass\n * @typedef {ConstructorParameters<ComponentClass>[1]} ComponentConfig\n */\n\n/**\n * @template {CompatibleClass} ComponentClass\n * @typedef {object} ErrorContext\n * @property {Element} [element] - Element used for component module initialisation\n * @property {ComponentClass} [component] - Class of component\n * @property {Config | ComponentConfig<ComponentClass>} [config] - Config supplied to components\n */\n\n/**\n * @template {CompatibleClass} ComponentClass\n * @callback OnErrorCallback\n * @param {unknown} error - Thrown error\n * @param {ErrorContext<ComponentClass>} context - Object containing the element, component class and configuration\n */\n\n/**\n * @template {CompatibleClass} ComponentClass\n * @typedef {object} CreateAllOptions\n * @property {Element | Document | null} [scope] - scope of the document to search within\n * @property {OnErrorCallback<ComponentClass>} [onError] - callback function if error throw by component on init\n */\n"],"names":["initAll","scopeOrConfig","config","isObject","options","normaliseOptions","isSupported","SupportError","scope","ElementError","element","identifier","error","onError","console","log","components","Accordion","accordion","Button","button","CharacterCount","characterCount","Checkboxes","ErrorSummary","errorSummary","ExitThisPage","exitThisPage","FileUpload","fileUpload","NotificationBanner","notificationBanner","PasswordInput","passwordInput","Radios","ServiceNavigation","SkipLink","Tabs","forEach","Component","componentConfig","createAll","scopeOrOptions","$elements","_options$scope","component","querySelectorAll","moduleName","Array","from","map","$element","filter","Boolean"],"mappings":"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"}