@ministryofjustice/frontend 5.2.0 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"moj-frontend.min.js","sources":["../../node_modules/govuk-frontend/dist/govuk/common/index.mjs","../../node_modules/govuk-frontend/dist/govuk/errors/index.mjs","../../node_modules/govuk-frontend/dist/govuk/component.mjs","../../node_modules/govuk-frontend/dist/govuk/common/configuration.mjs","../../node_modules/govuk-frontend/dist/govuk/init.mjs","../../src/moj/common/moj-frontend-version.mjs","../../src/moj/components/add-another/add-another.mjs","../../src/moj/common/index.mjs","../../src/moj/helpers.mjs","../../src/moj/components/alert/alert.mjs","../../src/moj/components/button-menu/button-menu.mjs","../../src/moj/components/date-picker/date-picker.mjs","../../src/moj/components/domain-specific/probation/header/header.mjs","../../src/moj/components/filter-toggle-button/filter-toggle-button.mjs","../../src/moj/components/form-validator/form-validator.mjs","../../src/moj/components/multi-file-upload/multi-file-upload.mjs","../../src/moj/components/multi-select/multi-select.mjs","../../src/moj/components/password-reveal/password-reveal.mjs","../../src/moj/components/rich-text-editor/rich-text-editor.mjs","../../src/moj/components/search-toggle/search-toggle.mjs","../../src/moj/components/sortable-table/sortable-table.mjs","../../src/moj/all.mjs"],"sourcesContent":["function getFragmentFromUrl(url) {\n if (!url.includes('#')) {\n return undefined;\n }\n return url.split('#').pop();\n}\nfunction getBreakpoint(name) {\n const property = `--govuk-frontend-breakpoint-${name}`;\n const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);\n return {\n property,\n value: value || undefined\n };\n}\nfunction setFocus($element, options = {}) {\n var _options$onBeforeFocu;\n const isFocusable = $element.getAttribute('tabindex');\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1');\n }\n function onFocus() {\n $element.addEventListener('blur', onBlur, {\n once: true\n });\n }\n function onBlur() {\n var _options$onBlur;\n (_options$onBlur = options.onBlur) == null || _options$onBlur.call($element);\n if (!isFocusable) {\n $element.removeAttribute('tabindex');\n }\n }\n $element.addEventListener('focus', onFocus, {\n once: true\n });\n (_options$onBeforeFocu = options.onBeforeFocus) == null || _options$onBeforeFocu.call($element);\n $element.focus();\n}\nfunction isInitialised($root, moduleName) {\n return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);\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 */\nfunction isSupported($scope = document.body) {\n if (!$scope) {\n return false;\n }\n return $scope.classList.contains('govuk-frontend-supported');\n}\nfunction isArray(option) {\n return Array.isArray(option);\n}\nfunction isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option);\n}\nfunction formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`;\n}\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n/**\n * @import { ObjectNested } from './configuration.mjs'\n */\n\nexport { formatErrorMessage, getBreakpoint, getFragmentFromUrl, isInitialised, isObject, isSupported, setFocus };\n//# sourceMappingURL=index.mjs.map\n","import { formatErrorMessage } from '../common/index.mjs';\n\nclass GOVUKFrontendError extends Error {\n constructor(...args) {\n super(...args);\n this.name = 'GOVUKFrontendError';\n }\n}\nclass SupportError extends GOVUKFrontendError {\n /**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support\n */\n constructor($scope = document.body) {\n const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';\n super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type=\"module\">`');\n this.name = 'SupportError';\n }\n}\nclass ConfigError extends GOVUKFrontendError {\n constructor(...args) {\n super(...args);\n this.name = 'ConfigError';\n }\n}\nclass ElementError extends GOVUKFrontendError {\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';\n if (typeof messageOrOptions === 'object') {\n const {\n component,\n identifier,\n element,\n expectedType\n } = messageOrOptions;\n message = identifier;\n message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';\n message = formatErrorMessage(component, message);\n }\n super(message);\n this.name = 'ElementError';\n }\n}\nclass InitError extends GOVUKFrontendError {\n constructor(componentOrMessage) {\n const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\\`$root\\`) already initialised`);\n super(message);\n this.name = 'InitError';\n }\n}\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n\nexport { ConfigError, ElementError, GOVUKFrontendError, InitError, SupportError };\n//# sourceMappingURL=index.mjs.map\n","import { isInitialised, isSupported } from './common/index.mjs';\nimport { InitError, ElementError, SupportError } from './errors/index.mjs';\n\nclass Component {\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {RootElementType} - the root element of component\n */\n get $root() {\n return this._$root;\n }\n constructor($root) {\n this._$root = void 0;\n const childConstructor = this.constructor;\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`);\n }\n if (!($root instanceof childConstructor.elementType)) {\n throw new ElementError({\n element: $root,\n component: childConstructor,\n identifier: 'Root element (`$root`)',\n expectedType: childConstructor.elementType.name\n });\n } else {\n this._$root = $root;\n }\n childConstructor.checkSupport();\n this.checkInitialised();\n const moduleName = childConstructor.moduleName;\n this.$root.setAttribute(`data-${moduleName}-init`, '');\n }\n checkInitialised() {\n const constructor = this.constructor;\n const moduleName = constructor.moduleName;\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor);\n }\n }\n static checkSupport() {\n if (!isSupported()) {\n throw new SupportError();\n }\n }\n}\n\n/**\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n */\n\n/**\n * @typedef {typeof Component & ChildClass} ChildClassConstructor\n */\nComponent.elementType = HTMLElement;\n\nexport { Component };\n//# sourceMappingURL=component.mjs.map\n","import { Component } from '../component.mjs';\nimport { ConfigError } from '../errors/index.mjs';\nimport { isObject, formatErrorMessage } from './index.mjs';\n\nconst configOverride = Symbol.for('configOverride');\nclass ConfigurableComponent extends Component {\n [configOverride](param) {\n return {};\n }\n\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {ConfigurationType} - the root element of component\n */\n get config() {\n return this._config;\n }\n constructor($root, config) {\n super($root);\n this._config = void 0;\n const childConstructor = this.constructor;\n if (!isObject(childConstructor.defaults)) {\n throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));\n }\n const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);\n this._config = mergeConfigs(childConstructor.defaults, config != null ? config : {}, this[configOverride](datasetConfig), datasetConfig);\n }\n}\nfunction normaliseString(value, property) {\n const trimmedValue = value ? value.trim() : '';\n let output;\n let outputType = property == null ? void 0 : property.type;\n if (!outputType) {\n if (['true', 'false'].includes(trimmedValue)) {\n outputType = 'boolean';\n }\n if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {\n outputType = 'number';\n }\n }\n switch (outputType) {\n case 'boolean':\n output = trimmedValue === 'true';\n break;\n case 'number':\n output = Number(trimmedValue);\n break;\n default:\n output = value;\n }\n return output;\n}\nfunction normaliseDataset(Component, dataset) {\n if (!isObject(Component.schema)) {\n throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));\n }\n const out = {};\n const entries = Object.entries(Component.schema.properties);\n for (const entry of entries) {\n const [namespace, property] = entry;\n const field = namespace.toString();\n if (field in dataset) {\n out[field] = normaliseString(dataset[field], property);\n }\n if ((property == null ? void 0 : property.type) === 'object') {\n out[field] = extractConfigByNamespace(Component.schema, dataset, namespace);\n }\n }\n return out;\n}\nfunction mergeConfigs(...configObjects) {\n const formattedConfigObject = {};\n for (const configObject of configObjects) {\n for (const key of Object.keys(configObject)) {\n const option = formattedConfigObject[key];\n const override = configObject[key];\n if (isObject(option) && isObject(override)) {\n formattedConfigObject[key] = mergeConfigs(option, override);\n } else {\n formattedConfigObject[key] = override;\n }\n }\n }\n return formattedConfigObject;\n}\nfunction validateConfig(schema, config) {\n const validationErrors = [];\n for (const [name, conditions] of Object.entries(schema)) {\n const errors = [];\n if (Array.isArray(conditions)) {\n for (const {\n required,\n errorMessage\n } of conditions) {\n if (!required.every(key => !!config[key])) {\n errors.push(errorMessage);\n }\n }\n if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {\n validationErrors.push(...errors);\n }\n }\n }\n return validationErrors;\n}\nfunction extractConfigByNamespace(schema, dataset, namespace) {\n const property = schema.properties[namespace];\n if ((property == null ? void 0 : property.type) !== 'object') {\n return;\n }\n const newObject = {\n [namespace]: {}\n };\n for (const [key, value] of Object.entries(dataset)) {\n let current = newObject;\n const keyParts = key.split('.');\n for (const [index, name] of keyParts.entries()) {\n if (isObject(current)) {\n if (index < keyParts.length - 1) {\n if (!isObject(current[name])) {\n current[name] = {};\n }\n current = current[name];\n } else if (key !== namespace) {\n current[name] = normaliseString(value);\n }\n }\n }\n }\n return newObject[namespace];\n}\n/**\n * Schema for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} Schema\n * @property {Record<keyof ConfigurationType, SchemaProperty | undefined>} properties - Schema properties\n * @property {SchemaCondition<ConfigurationType>[]} [anyOf] - List of schema conditions\n */\n/**\n * Schema property for component config\n *\n * @typedef {object} SchemaProperty\n * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type\n */\n/**\n * Schema condition for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} SchemaCondition\n * @property {(keyof ConfigurationType)[]} required - List of required config fields\n * @property {string} errorMessage - Error message when required config fields not provided\n */\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n * @property {Schema<ConfigurationType>} [schema] - The schema of the component configuration\n * @property {ConfigurationType} [defaults] - The default values of the configuration of the component\n */\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>\n */\n\nexport { ConfigurableComponent, configOverride, extractConfigByNamespace, mergeConfigs, normaliseDataset, normaliseString, validateConfig };\n//# sourceMappingURL=configuration.mjs.map\n","import { 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 { Header } from './components/header/header.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 { 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 & { scope?: Element, onError?: OnErrorCallback<CompatibleClass> }} [config] - Config for all components (with optional scope)\n */\nfunction initAll(config) {\n var _config$scope;\n config = typeof config !== 'undefined' ? config : {};\n if (!isSupported()) {\n if (config.onError) {\n config.onError(new SupportError(), {\n config\n });\n } else {\n console.log(new SupportError());\n }\n return;\n }\n const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];\n const options = {\n scope: (_config$scope = config.scope) != null ? _config$scope : document,\n onError: config.onError\n };\n components.forEach(([Component, config]) => {\n createAll(Component, config, 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 | CreateAllOptions<ComponentClass> } [createAllOptions] - 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, createAllOptions) {\n let $scope = document;\n let onError;\n if (typeof createAllOptions === 'object') {\n var _createAllOptions$sco;\n createAllOptions = createAllOptions;\n $scope = (_createAllOptions$sco = createAllOptions.scope) != null ? _createAllOptions$sco : $scope;\n onError = createAllOptions.onError;\n }\n if (typeof createAllOptions === 'function') {\n onError = createAllOptions;\n }\n if (createAllOptions instanceof HTMLElement) {\n $scope = createAllOptions;\n }\n const $elements = $scope.querySelectorAll(`[data-module=\"${Component.moduleName}\"]`);\n if (!isSupported()) {\n if (onError) {\n onError(new SupportError(), {\n component: Component,\n config\n });\n } else {\n console.log(new SupportError());\n }\n return [];\n }\n return Array.from($elements).map($element => {\n try {\n return typeof config !== 'undefined' ? new Component($element, config) : new Component($element);\n } catch (error) {\n if (onError) {\n onError(error, {\n element: $element,\n component: Component,\n config\n });\n } else {\n console.log(error);\n }\n return null;\n }\n }).filter(Boolean);\n}\n/**\n * @typedef {{new (...args: any[]): any, moduleName: string}} CompatibleClass\n */\n/**\n * Config for all components via `initAll()`\n *\n * @typedef {object} Config\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 * 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 * Component config keys, e.g. `accordion` and `characterCount`\n *\n * @typedef {keyof Config} ConfigKey\n */\n/**\n * @template {CompatibleClass} ComponentClass\n * @typedef {ConstructorParameters<ComponentClass>[1]} ComponentConfig\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 {ComponentConfig<ComponentClass>} config - Config supplied to component\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 * @template {CompatibleClass} ComponentClass\n * @typedef {object} CreateAllOptions\n * @property {Element | Document} [scope] - scope of the document to search within\n * @property {OnErrorCallback<ComponentClass>} [onError] - callback function if error throw by component on init\n */\n\nexport { createAll, initAll };\n//# sourceMappingURL=init.mjs.map\n","/*\n * This variable is automatically overwritten during builds and releases.\n * It doesn't need to be updated manually.\n */\n\n/**\n * MoJ Frontend release version\n *\n * {@link https://github.com/ministryofjustice/moj-frontend/releases}\n */\nexport const version = 'development'\n","import { Component } from 'govuk-frontend'\n\nexport class AddAnother extends Component {\n /**\n * @param {Element | null} $root - HTML element to use for add another\n */\n constructor($root) {\n super($root)\n\n this.$root.addEventListener('click', this.onRemoveButtonClick.bind(this))\n this.$root.addEventListener('click', this.onAddButtonClick.bind(this))\n\n const $buttons = this.$root.querySelectorAll(\n '.moj-add-another__add-button, moj-add-another__remove-button'\n )\n\n $buttons.forEach(($button) => {\n if (!($button instanceof HTMLButtonElement)) {\n return\n }\n\n $button.type = 'button'\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onAddButtonClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-add-another__add-button')\n ) {\n return\n }\n\n const $items = this.getItems()\n const $item = this.getNewItem()\n\n if (!$item || !($item instanceof HTMLElement)) {\n return\n }\n\n this.updateAttributes($item, $items.length)\n this.resetItem($item)\n\n const $firstItem = $items[0]\n if (!this.hasRemoveButton($firstItem)) {\n this.createRemoveButton($firstItem)\n }\n\n $items[$items.length - 1].after($item)\n\n const $input = $item.querySelector('input, textarea, select')\n if ($input && $input instanceof HTMLInputElement) {\n $input.focus()\n }\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n hasRemoveButton($item) {\n return $item.querySelectorAll('.moj-add-another__remove-button').length\n }\n\n getItems() {\n if (!this.$root) {\n return []\n }\n\n const $items = Array.from(\n this.$root.querySelectorAll('.moj-add-another__item')\n )\n\n return $items.filter((item) => item instanceof HTMLElement)\n }\n\n getNewItem() {\n const $items = this.getItems()\n const $item = $items[0].cloneNode(true)\n\n if (!$item || !($item instanceof HTMLElement)) {\n return\n }\n\n if (!this.hasRemoveButton($item)) {\n this.createRemoveButton($item)\n }\n\n return $item\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n * @param {number} index - Add another item index\n */\n updateAttributes($item, index) {\n $item.querySelectorAll('[data-name]').forEach(($input) => {\n if (!this.isValidInputElement($input)) {\n return\n }\n\n const name = $input.getAttribute('data-name') || ''\n const id = $input.getAttribute('data-id') || ''\n const originalId = $input.id\n\n $input.name = name.replace(/%index%/, `${index}`)\n $input.id = id.replace(/%index%/, `${index}`)\n\n const $label =\n $input.parentElement.querySelector('label') ||\n $input.closest('label') ||\n $item.querySelector(`[for=\"${originalId}\"]`)\n\n if ($label && $label instanceof HTMLLabelElement) {\n $label.htmlFor = $input.id\n }\n })\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n createRemoveButton($item) {\n const $button = document.createElement('button')\n $button.type = 'button'\n\n $button.classList.add(\n 'govuk-button',\n 'govuk-button--secondary',\n 'moj-add-another__remove-button'\n )\n\n $button.textContent = 'Remove'\n\n $item.append($button)\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n resetItem($item) {\n $item.querySelectorAll('[data-name], [data-id]').forEach(($input) => {\n if (!this.isValidInputElement($input)) {\n return\n }\n\n if ($input instanceof HTMLSelectElement) {\n $input.selectedIndex = -1\n $input.value = ''\n } else if ($input instanceof HTMLTextAreaElement) {\n $input.value = ''\n } else {\n switch ($input.type) {\n case 'checkbox':\n case 'radio':\n $input.checked = false\n break\n default:\n $input.value = ''\n }\n }\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onRemoveButtonClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-add-another__remove-button')\n ) {\n return\n }\n\n $button.closest('.moj-add-another__item').remove()\n\n const $items = this.getItems()\n\n if ($items.length === 1) {\n $items[0].querySelector('.moj-add-another__remove-button').remove()\n }\n\n $items.forEach(($item, index) => {\n this.updateAttributes($item, index)\n })\n\n this.focusHeading()\n }\n\n focusHeading() {\n const $heading = this.$root.querySelector('.moj-add-another__heading')\n\n if ($heading && $heading instanceof HTMLElement) {\n $heading.focus()\n }\n }\n\n /**\n * @param {Element} $input - the input to validate\n */\n isValidInputElement($input) {\n return (\n $input instanceof HTMLInputElement ||\n $input instanceof HTMLSelectElement ||\n $input instanceof HTMLTextAreaElement\n )\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-add-another'\n}\n","/**\n * GOV.UK Frontend helpers\n *\n * @todo Import from GOV.UK Frontend\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 * @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 * @param {Element} $element - Element to remove attribute value from\n * @param {string} attr - Attribute name\n * @param {string} value - Attribute value\n */\nexport function removeAttributeValue($element, attr, value) {\n let re, m\n if ($element.getAttribute(attr)) {\n if ($element.getAttribute(attr) === value) {\n $element.removeAttribute(attr)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n m = $element.getAttribute(attr).match(re)\n if (m && m.length === 3) {\n $element.setAttribute(\n attr,\n $element.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')\n )\n }\n }\n }\n}\n\n/**\n * @param {Element} $element - Element to add attribute value to\n * @param {string} attr - Attribute name\n * @param {string} value - Attribute value\n */\nexport function addAttributeValue($element, attr, value) {\n let re\n if (!$element.getAttribute(attr)) {\n $element.setAttribute(attr, value)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n if (!re.test($element.getAttribute(attr))) {\n $element.setAttribute(attr, `${$element.getAttribute(attr)} ${value}`)\n }\n }\n}\n\n/**\n * Find an elements next sibling\n *\n * Utility function to find an elements next sibling matching the provided\n * selector.\n *\n * @param {Element | null} $element - Element to find siblings for\n * @param {string} [selector] - selector for required sibling\n */\nexport function getNextSibling($element, selector) {\n if (!$element || !($element instanceof HTMLElement)) {\n return\n }\n\n // Get the next sibling element\n let $sibling = $element.nextElementSibling\n\n // If there's no selector, return the first sibling\n if (!selector) return $sibling\n\n // If the sibling matches our selector, use it\n // If not, jump to the next sibling and continue the loop\n while ($sibling) {\n if ($sibling.matches(selector)) return $sibling\n $sibling = $sibling.nextElementSibling\n }\n}\n\n/**\n * Find an elements preceding sibling\n *\n * Utility function to find an elements previous sibling matching the provided\n * selector.\n *\n * @param {Element | null} $element - Element to find siblings for\n * @param {string} [selector] - selector for required sibling\n */\nexport function getPreviousSibling($element, selector) {\n if (!$element || !($element instanceof HTMLElement)) {\n return\n }\n\n // Get the previous sibling element\n let $sibling = $element.previousElementSibling\n\n // If there's no selector, return the first sibling\n if (!selector) return $sibling\n\n // If the sibling matches our selector, use it\n // If not, jump to the next sibling and continue the loop\n while ($sibling) {\n if ($sibling.matches(selector)) return $sibling\n $sibling = $sibling.previousElementSibling\n }\n}\n\n/**\n * @param {Element | null} $element\n * @param {string} [selector]\n */\nexport function findNearestMatchingElement($element, selector) {\n // If no element or selector is provided, return\n if (!$element || !($element instanceof HTMLElement) || !selector) {\n return\n }\n\n // Start with the current element\n let $currentElement = $element\n\n while ($currentElement) {\n // First check the current element\n if ($currentElement.matches(selector)) {\n return $currentElement\n }\n\n // Check all previous siblings\n let $sibling = $currentElement.previousElementSibling\n while ($sibling) {\n // Check if the sibling itself is a heading\n if ($sibling.matches(selector)) {\n return $sibling\n }\n $sibling = $sibling.previousElementSibling\n }\n\n // If no match found in siblings, move up to parent\n $currentElement = $currentElement.parentElement\n }\n}\n","import { ConfigurableComponent } from 'govuk-frontend'\n\nimport { setFocus } from '../../common/index.mjs'\nimport {\n findNearestMatchingElement,\n getPreviousSibling\n} from '../../helpers.mjs'\n\n/**\n * @augments {ConfigurableComponent<AlertConfig>}\n */\nexport class Alert extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for alert\n * @param {AlertConfig} [config] - Alert config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n /**\n * Focus the alert\n *\n * If `role=\"alert\"` is set, focus the element to help some assistive\n * technologies prioritise announcing it.\n *\n * You can turn off the auto-focus functionality by setting\n * `data-disable-auto-focus=\"true\"` in the component HTML. You might wish to\n * do this based on user research findings, or to avoid a clash with another\n * element which should be focused when the page loads.\n */\n if (\n this.$root.getAttribute('role') === 'alert' &&\n !this.config.disableAutoFocus\n ) {\n setFocus(this.$root)\n }\n\n this.$dismissButton = this.$root.querySelector('.moj-alert__dismiss')\n\n if (this.config.dismissible && this.$dismissButton) {\n this.$dismissButton.innerHTML = this.config.dismissText\n this.$dismissButton.removeAttribute('hidden')\n\n this.$root.addEventListener('click', (event) => {\n if (\n event.target instanceof Node &&\n this.$dismissButton.contains(event.target)\n ) {\n this.dimiss()\n }\n })\n }\n }\n\n /**\n * Handle dismissing the alert\n */\n dimiss() {\n let $elementToRecieveFocus\n\n // If a selector has been provided, attempt to find that element\n if (this.config.focusOnDismissSelector) {\n $elementToRecieveFocus = document.querySelector(\n this.config.focusOnDismissSelector\n )\n }\n\n // Is the next sibling another alert\n if (!$elementToRecieveFocus) {\n const $nextSibling = this.$root.nextElementSibling\n if ($nextSibling && $nextSibling.matches('.moj-alert')) {\n $elementToRecieveFocus = $nextSibling\n }\n }\n\n // Else try to find any preceding sibling alert or heading\n if (!$elementToRecieveFocus) {\n $elementToRecieveFocus = getPreviousSibling(\n this.$root,\n '.moj-alert, h1, h2, h3, h4, h5, h6'\n )\n }\n\n // Else find the closest ancestor heading, or fallback to main, or last resort\n // use the body element\n if (!$elementToRecieveFocus) {\n $elementToRecieveFocus = findNearestMatchingElement(\n this.$root,\n 'h1, h2, h3, h4, h5, h6, main, body'\n )\n }\n\n // If we have an element, place focus on it\n if ($elementToRecieveFocus instanceof HTMLElement) {\n setFocus($elementToRecieveFocus)\n }\n\n // Remove the alert\n this.$root.remove()\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-alert'\n\n /**\n * Alert default config\n *\n * @type {AlertConfig}\n */\n static defaults = Object.freeze({\n dismissible: false,\n dismissText: 'Dismiss',\n disableAutoFocus: false\n })\n\n /**\n * Alert config schema\n *\n * @satisfies {Schema<AlertConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n dismissible: { type: 'boolean' },\n dismissText: { type: 'string' },\n disableAutoFocus: { type: 'boolean' },\n focusOnDismissSelector: { type: 'string' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} AlertConfig\n * @property {boolean} [dismissible=false] - Can the alert be dismissed by the user\n * @property {string} [dismissText=Dismiss] - the label text for the dismiss button\n * @property {boolean} [disableAutoFocus=false] - whether the alert will be autofocused\n * @property {string} [focusOnDismissSelector] - CSS Selector for element to be focused on dismiss\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<ButtonMenuConfig>}\n */\nexport class ButtonMenu extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for button menu\n * @param {ButtonMenuConfig} [config] - Button menu config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n // If only one button is provided, don't initiate a menu and toggle button\n // if classes have been provided for the toggleButton, apply them to the single item\n if (this.$root.children.length === 1) {\n const $button = this.$root.children[0]\n\n $button.classList.forEach((className) => {\n if (className.startsWith('govuk-button-')) {\n $button.classList.remove(className)\n }\n\n $button.classList.remove('moj-button-menu__item')\n $button.classList.add('moj-button-menu__single-button')\n })\n\n if (this.config.buttonClasses) {\n $button.classList.add(...this.config.buttonClasses.split(' '))\n }\n }\n // Otherwise initialise a button menu\n if (this.$root.children.length > 1) {\n this.initMenu()\n }\n }\n\n initMenu() {\n this.$menu = this.createMenu()\n this.$root.insertAdjacentHTML('afterbegin', this.toggleTemplate())\n this.setupMenuItems()\n\n this.$menuToggle = this.$root.querySelector(':scope > button')\n this.$items = this.$menu.querySelectorAll('a, button')\n\n this.$menuToggle.addEventListener('click', (event) => {\n this.toggleMenu(event)\n })\n\n this.$root.addEventListener('keydown', (event) => {\n this.handleKeyDown(event)\n })\n\n document.addEventListener('click', (event) => {\n if (event.target instanceof Node && !this.$root.contains(event.target)) {\n this.closeMenu(false)\n }\n })\n }\n\n createMenu() {\n const $menu = document.createElement('ul')\n\n $menu.setAttribute('role', 'list')\n $menu.hidden = true\n $menu.classList.add('moj-button-menu__wrapper')\n\n if (this.config.alignMenu === 'right') {\n $menu.classList.add('moj-button-menu__wrapper--right')\n }\n\n this.$root.appendChild($menu)\n\n while (this.$root.firstChild !== $menu) {\n $menu.appendChild(this.$root.firstChild)\n }\n\n return $menu\n }\n\n setupMenuItems() {\n Array.from(this.$menu.children).forEach(($menuItem) => {\n // wrap item in li tag\n const $listItem = document.createElement('li')\n this.$menu.insertBefore($listItem, $menuItem)\n $listItem.appendChild($menuItem)\n\n $menuItem.setAttribute('tabindex', '-1')\n\n if ($menuItem.tagName === 'BUTTON') {\n $menuItem.setAttribute('type', 'button')\n }\n\n $menuItem.classList.forEach((className) => {\n if (className.startsWith('govuk-button')) {\n $menuItem.classList.remove(className)\n }\n })\n\n // add a slight delay after click before closing the menu, makes it *feel* better\n $menuItem.addEventListener('click', () => {\n setTimeout(() => {\n this.closeMenu(false)\n }, 50)\n })\n })\n }\n\n toggleTemplate() {\n return `\n <button type=\"button\" class=\"govuk-button moj-button-menu__toggle-button ${this.config.buttonClasses || ''}\" aria-haspopup=\"true\" aria-expanded=\"false\">\n <span>\n ${this.config.buttonText}\n <svg width=\"11\" height=\"5\" viewBox=\"0 0 11 5\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.5 0L11 5L0 5L5.5 0Z\" fill=\"currentColor\"/>\n </svg>\n </span>\n </button>`\n }\n\n /**\n * @returns {boolean}\n */\n isOpen() {\n return this.$menuToggle.getAttribute('aria-expanded') === 'true'\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n toggleMenu(event) {\n event.preventDefault()\n\n // If menu is triggered with mouse don't move focus to first item\n const keyboardEvent = event.detail === 0\n const focusIndex = keyboardEvent ? 0 : -1\n\n if (this.isOpen()) {\n this.closeMenu()\n } else {\n this.openMenu(focusIndex)\n }\n }\n\n /**\n * Opens the menu and optionally sets the focus to the item with given index\n *\n * @param {number} focusIndex - The index of the item to focus\n */\n openMenu(focusIndex = 0) {\n this.$menu.hidden = false\n this.$menuToggle.setAttribute('aria-expanded', 'true')\n if (focusIndex !== -1) {\n this.focusItem(focusIndex)\n }\n }\n\n /**\n * Closes the menu and optionally returns focus back to menuToggle\n *\n * @param {boolean} moveFocus - whether to return focus to the toggle button\n */\n closeMenu(moveFocus = true) {\n this.$menu.hidden = true\n this.$menuToggle.setAttribute('aria-expanded', 'false')\n if (moveFocus) {\n this.$menuToggle.focus()\n }\n }\n\n /**\n * Focuses the menu item at the specified index\n *\n * @param {number} index - the index of the item to focus\n */\n focusItem(index) {\n if (index >= this.$items.length) index = 0\n if (index < 0) index = this.$items.length - 1\n\n const $menuItem = this.$items.item(index)\n if ($menuItem) {\n $menuItem.focus()\n }\n }\n\n currentFocusIndex() {\n const $activeElement = document.activeElement\n const $menuItems = Array.from(this.$items)\n\n return (\n ($activeElement instanceof HTMLAnchorElement ||\n $activeElement instanceof HTMLButtonElement) &&\n $menuItems.indexOf($activeElement)\n )\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n handleKeyDown(event) {\n if (event.target === this.$menuToggle) {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n this.openMenu()\n break\n case 'ArrowUp':\n event.preventDefault()\n this.openMenu(this.$items.length - 1)\n break\n }\n }\n\n if (\n event.target instanceof Node &&\n this.$menu.contains(event.target) &&\n this.isOpen()\n ) {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n if (this.currentFocusIndex() !== -1) {\n this.focusItem(this.currentFocusIndex() + 1)\n }\n break\n case 'ArrowUp':\n event.preventDefault()\n if (this.currentFocusIndex() !== -1) {\n this.focusItem(this.currentFocusIndex() - 1)\n }\n break\n case 'Home':\n event.preventDefault()\n this.focusItem(0)\n break\n case 'End':\n event.preventDefault()\n this.focusItem(this.$items.length - 1)\n break\n }\n }\n\n if (event.key === 'Escape' && this.isOpen()) {\n this.closeMenu()\n }\n if (event.key === 'Tab' && this.isOpen()) {\n this.closeMenu(false)\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-button-menu'\n\n /**\n * Button menu config\n *\n * @type {ButtonMenuConfig}\n */\n static defaults = Object.freeze({\n buttonText: 'Actions',\n alignMenu: 'left',\n buttonClasses: ''\n })\n\n /**\n * Button menu config schema\n *\n * @type {Schema<ButtonMenuConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n buttonText: { type: 'string' },\n buttonClasses: { type: 'string' },\n alignMenu: { type: 'string' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} ButtonMenuConfig\n * @property {string} [buttonText='Actions'] - Label for the toggle button\n * @property {\"left\" | \"right\"} [alignMenu='left'] - the alignment of the menu\n * @property {string} [buttonClasses='govuk-button--secondary'] - css classes applied to the toggle button\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<DatePickerConfig>}\n */\nexport class DatePicker extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for date picker\n * @param {DatePickerConfig} [config] - Date picker config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $input =\n this.config.input.element ??\n this.$root.querySelector(this.config.input.selector)\n\n if (!$input || !($input instanceof HTMLInputElement)) {\n return this\n }\n\n this.$input = $input\n\n this.dayLabels = [\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n 'Sunday'\n ]\n\n this.monthLabels = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December'\n ]\n\n this.currentDate = new Date()\n this.currentDate.setHours(0, 0, 0, 0)\n this.calendarDays = /** @type {DSCalendarDay[]} */ ([])\n this.excludedDates = /** @type {Date[]} */ ([])\n this.excludedDays = /** @type {number[]} */ ([])\n\n this.buttonClass = 'moj-datepicker__button'\n this.selectedDayButtonClass = 'moj-datepicker__button--selected'\n this.currentDayButtonClass = 'moj-datepicker__button--current'\n this.todayButtonClass = 'moj-datepicker__button--today'\n\n this.setOptions()\n this.initControls()\n }\n\n initControls() {\n this.id = `datepicker-${this.$input.id}`\n\n this.$dialog = this.createDialog()\n this.createCalendarHeaders()\n\n const $componentWrapper = document.createElement('div')\n const $inputWrapper = document.createElement('div')\n $componentWrapper.classList.add('moj-datepicker__wrapper')\n $inputWrapper.classList.add('govuk-input__wrapper')\n\n this.$input.parentElement.insertBefore($componentWrapper, this.$input)\n $componentWrapper.appendChild($inputWrapper)\n $inputWrapper.appendChild(this.$input)\n\n $inputWrapper.insertAdjacentHTML('beforeend', this.toggleTemplate())\n $componentWrapper.insertAdjacentElement('beforeend', this.$dialog)\n\n this.$calendarButton = /** @type {HTMLButtonElement} */ (\n this.$root.querySelector('.moj-js-datepicker-toggle')\n )\n\n this.$dialogTitle = /** @type {HTMLHeadingElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-month-year')\n )\n\n this.createCalendar()\n\n this.$prevMonthButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-prev-month')\n )\n\n this.$prevYearButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-prev-year')\n )\n\n this.$nextMonthButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-next-month')\n )\n\n this.$nextYearButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-next-year')\n )\n\n this.$cancelButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-cancel')\n )\n\n this.$okButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-ok')\n )\n\n // add event listeners\n this.$prevMonthButton.addEventListener('click', (event) =>\n this.focusPreviousMonth(event, false)\n )\n this.$prevYearButton.addEventListener('click', (event) =>\n this.focusPreviousYear(event, false)\n )\n this.$nextMonthButton.addEventListener('click', (event) =>\n this.focusNextMonth(event, false)\n )\n this.$nextYearButton.addEventListener('click', (event) =>\n this.focusNextYear(event, false)\n )\n this.$cancelButton.addEventListener('click', (event) => {\n event.preventDefault()\n this.closeDialog()\n })\n this.$okButton.addEventListener('click', () => {\n this.selectDate(this.currentDate)\n })\n\n const $dialogButtons = this.$dialog.querySelectorAll(\n 'button:not([disabled=\"true\"])'\n )\n\n this.$firstButtonInDialog = $dialogButtons[0]\n this.$lastButtonInDialog = $dialogButtons[$dialogButtons.length - 1]\n this.$firstButtonInDialog.addEventListener('keydown', (event) =>\n this.firstButtonKeydown(event)\n )\n this.$lastButtonInDialog.addEventListener('keydown', (event) =>\n this.lastButtonKeydown(event)\n )\n\n this.$calendarButton.addEventListener('click', (event) =>\n this.toggleDialog(event)\n )\n\n this.$dialog.addEventListener('keydown', (event) => {\n if (event.key === 'Escape') {\n this.closeDialog()\n event.preventDefault()\n event.stopPropagation()\n }\n })\n\n document.body.addEventListener('mouseup', (event) => {\n this.backgroundClick(event)\n })\n\n // populates calendar with initial dates, avoids Wave errors about null buttons\n this.updateCalendar()\n }\n\n createDialog() {\n const titleId = `datepicker-title-${this.$input.id}`\n const $dialog = document.createElement('div')\n\n $dialog.id = this.id\n $dialog.setAttribute('class', 'moj-datepicker__dialog')\n $dialog.setAttribute('role', 'dialog')\n $dialog.setAttribute('aria-modal', 'true')\n $dialog.setAttribute('aria-labelledby', titleId)\n $dialog.innerHTML = this.dialogTemplate(titleId)\n $dialog.hidden = true\n\n return $dialog\n }\n\n createCalendar() {\n const $tbody = this.$dialog.querySelector('tbody')\n let dayCount = 0\n for (let i = 0; i < 6; i++) {\n // create row\n const $row = $tbody.insertRow(i)\n\n for (let j = 0; j < 7; j++) {\n // create cell (day)\n const $cell = document.createElement('td')\n $row.appendChild($cell)\n const $dateButton = document.createElement('button')\n $dateButton.setAttribute('type', 'button')\n $cell.appendChild($dateButton)\n\n const calendarDay = new DSCalendarDay($dateButton, dayCount, i, j, this)\n this.calendarDays.push(calendarDay)\n dayCount++\n }\n }\n }\n\n toggleTemplate() {\n return `<button class=\"moj-datepicker__toggle moj-js-datepicker-toggle\" type=\"button\" aria-haspopup=\"dialog\" aria-controls=\"${this.id}\" aria-expanded=\"false\">\n <span class=\"govuk-visually-hidden\">Choose date</span>\n <svg width=\"32\" height=\"24\" focusable=\"false\" class=\"moj-datepicker-icon\" aria-hidden=\"true\" role=\"img\" viewBox=\"0 0 22 22\">\n <path\n fill=\"currentColor\"\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M16.1333 2.93333H5.86668V4.4C5.86668 5.21002 5.21003 5.86667 4.40002 5.86667C3.59 5.86667 2.93335 5.21002 2.93335 4.4V2.93333H2C0.895431 2.93333 0 3.82877 0 4.93334V19.2667C0 20.3712 0.89543 21.2667 2 21.2667H20C21.1046 21.2667 22 20.3712 22 19.2667V4.93333C22 3.82876 21.1046 2.93333 20 2.93333H19.0667V4.4C19.0667 5.21002 18.41 5.86667 17.6 5.86667C16.79 5.86667 16.1333 5.21002 16.1333 4.4V2.93333ZM20.5333 8.06667H1.46665V18.8C1.46665 19.3523 1.91436 19.8 2.46665 19.8H19.5333C20.0856 19.8 20.5333 19.3523 20.5333 18.8V8.06667Z\"\n ></path>\n <rect x=\"3.66669\" width=\"1.46667\" height=\"5.13333\" rx=\"0.733333\" fill=\"currentColor\"></rect>\n <rect x=\"16.8667\" width=\"1.46667\" height=\"5.13333\" rx=\"0.733333\" fill=\"currentColor\"></rect>\n </svg>\n </button>`\n }\n\n /**\n * HTML template for calendar dialog\n *\n * @param {string} [titleId] - Id attribute for dialog title\n * @returns {string}\n */\n dialogTemplate(titleId) {\n return `<div class=\"moj-datepicker__dialog-header\">\n <div class=\"moj-datepicker__dialog-navbuttons\">\n <button type=\"button\" class=\"moj-datepicker__button moj-js-datepicker-prev-year\">\n <span class=\"govuk-visually-hidden\">Previous year</span>\n <svg width=\"44\" height=\"40\" viewBox=\"0 0 44 40\" fill=\"none\" fill=\"none\" focusable=\"false\" aria-hidden=\"true\" role=\"img\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M23.1643 20L28.9572 14.2071L27.5429 12.7929L20.3358 20L27.5429 27.2071L28.9572 25.7929L23.1643 20Z\" fill=\"currentColor\"/>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M17.1643 20L22.9572 14.2071L21.5429 12.7929L14.3358 20L21.5429 27.2071L22.9572 25.7929L17.1643 20Z\" fill=\"currentColor\"/>\n </svg>\n </button>\n\n <button type=\"button\" class=\"moj-datepicker__button moj-js-datepicker-prev-month\">\n <span class=\"govuk-visually-hidden\">Previous month</span>\n <svg width=\"44\" height=\"40\" viewBox=\"0 0 44 40\" fill=\"none\" focusable=\"false\" aria-hidden=\"true\" role=\"img\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M20.5729 20L25.7865 14.2071L24.5137 12.7929L18.0273 20L24.5137 27.2071L25.7865 25.7929L20.5729 20Z\" fill=\"currentColor\"/>\n </svg>\n </button>\n </div>\n\n <h2 id=\"${titleId}\" class=\"moj-datepicker__dialog-title moj-js-datepicker-month-year\" aria-live=\"polite\">June 2020</h2>\n\n <div class=\"moj-datepicker__dialog-navbuttons\">\n <button type=\"button\" class=\"moj-datepicker__button moj-js-datepicker-next-month\">\n <span class=\"govuk-visually-hidden\">Next month</span>\n <svg width=\"44\" height=\"40\" viewBox=\"0 0 44 40\" fill=\"none\" focusable=\"false\" aria-hidden=\"true\" role=\"img\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M23.4271 20L18.2135 14.2071L19.4863 12.7929L25.9727 20L19.4863 27.2071L18.2135 25.7929L23.4271 20Z\" fill=\"currentColor\"/>\n </svg>\n </button>\n\n <button type=\"button\" class=\"moj-datepicker__button moj-js-datepicker-next-year\">\n <span class=\"govuk-visually-hidden\">Next year</span>\n <svg width=\"44\" height=\"40\" viewBox=\"0 0 44 40\" fill=\"none\" fill=\"none\" focusable=\"false\" aria-hidden=\"true\" role=\"img\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M20.8357 20L15.0428 14.2071L16.4571 12.7929L23.6642 20L16.4571 27.2071L15.0428 25.7929L20.8357 20Z\" fill=\"currentColor\"/>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M26.8357 20L21.0428 14.2071L22.4571 12.7929L29.6642 20L22.4571 27.2071L21.0428 25.7929L26.8357 20Z\" fill=\"currentColor\"/>\n </svg>\n </button>\n </div>\n </div>\n\n <table class=\"moj-datepicker__calendar moj-js-datepicker-grid\" role=\"grid\" aria-labelledby=\"${titleId}\">\n <thead>\n <tr></tr>\n </thead>\n\n <tbody></tbody>\n </table>\n\n <div class=\"govuk-button-group\">\n <button type=\"button\" class=\"govuk-button moj-js-datepicker-ok\">Select</button>\n <button type=\"button\" class=\"govuk-button govuk-button--secondary moj-js-datepicker-cancel\">Close</button>\n </div>`\n }\n\n createCalendarHeaders() {\n this.dayLabels.forEach((day) => {\n const html = `<th scope=\"col\"><span aria-hidden=\"true\">${day.substring(0, 3)}</span><span class=\"govuk-visually-hidden\">${day}</span></th>`\n const $headerRow = this.$dialog.querySelector('thead > tr')\n $headerRow.insertAdjacentHTML('beforeend', html)\n })\n }\n\n /**\n * Pads given number with leading zeros\n *\n * @param {number} value - The value to be padded\n * @param {number} length - The length in characters of the output\n * @returns {string}\n */\n leadingZeros(value, length = 2) {\n let ret = value.toString()\n\n while (ret.length < length) {\n ret = `0${ret}`\n }\n\n return ret\n }\n\n setOptions() {\n this.setMinAndMaxDatesOnCalendar()\n this.setExcludedDates()\n this.setExcludedDays()\n this.setWeekStartDay()\n }\n\n setMinAndMaxDatesOnCalendar() {\n if (this.config.minDate) {\n this.minDate = this.formattedDateFromString(this.config.minDate, null)\n if (this.minDate && this.currentDate < this.minDate) {\n this.currentDate = this.minDate\n }\n }\n\n if (this.config.maxDate) {\n this.maxDate = this.formattedDateFromString(this.config.maxDate, null)\n if (this.maxDate && this.currentDate > this.maxDate) {\n this.currentDate = this.maxDate\n }\n }\n }\n\n setExcludedDates() {\n if (this.config.excludedDates) {\n this.excludedDates = this.config.excludedDates\n .replace(/\\s+/, ' ')\n .split(' ')\n .map((item) => {\n return item.includes('-')\n ? this.parseDateRangeString(item)\n : [this.formattedDateFromString(item)]\n })\n .reduce((dates, items) => dates.concat(items))\n .filter((date) => date)\n }\n }\n\n /**\n * Parses a daterange string into an array of dates\n *\n * @param {string} datestring - A daterange string in the format \"dd/mm/yyyy-dd/mm/yyyy\"\n */\n parseDateRangeString(datestring) {\n const dates = []\n const [startDate, endDate] = datestring\n .split('-')\n .map((d) => this.formattedDateFromString(d, null))\n\n if (startDate && endDate) {\n const date = new Date(startDate.getTime())\n /* eslint-disable no-unmodified-loop-condition */\n while (date <= endDate) {\n dates.push(new Date(date))\n date.setDate(date.getDate() + 1)\n }\n /* eslint-enable no-unmodified-loop-condition */\n }\n return dates\n }\n\n setExcludedDays() {\n if (this.config.excludedDays) {\n // lowercase and arrange dayLabels to put indexOf sunday == 0 for comparison\n // with getDay() function\n const weekDays = this.dayLabels.map((item) => item.toLowerCase())\n if (this.config.weekStartDay === 'monday') {\n weekDays.unshift(weekDays.pop())\n }\n\n this.excludedDays = this.config.excludedDays\n .replace(/\\s+/, ' ')\n .toLowerCase()\n .split(' ')\n .map((item) => weekDays.indexOf(item))\n .filter((item) => item !== -1)\n }\n }\n\n setWeekStartDay() {\n const weekStartDayParam = this.config.weekStartDay\n if (weekStartDayParam && weekStartDayParam.toLowerCase() === 'sunday') {\n this.config.weekStartDay = 'sunday'\n // Rotate dayLabels array to put Sunday as the first item\n this.dayLabels.unshift(this.dayLabels.pop())\n } else {\n this.config.weekStartDay = 'monday'\n }\n }\n\n /**\n * Determine if a date is selectable\n *\n * @param {Date} date - the date to check\n * @returns {boolean}\n */\n isExcludedDate(date) {\n // This comparison does not work correctly - it will exclude the mindate itself\n // see: https://github.com/ministryofjustice/moj-frontend/issues/923\n if (this.minDate && this.minDate > date) {\n return true\n }\n\n // This comparison works as expected - the maxdate will not be excluded\n if (this.maxDate && this.maxDate < date) {\n return true\n }\n\n for (const excludedDate of this.excludedDates) {\n if (date.toDateString() === excludedDate.toDateString()) {\n return true\n }\n }\n\n if (this.excludedDays.includes(date.getDay())) {\n return true\n }\n\n return false\n }\n\n /**\n * Get a Date object from a string\n *\n * @param {string} dateString - string in the format d/m/yyyy dd/mm/yyyy\n * @param {Date} fallback - date object to return if formatting fails\n * @returns {Date}\n */\n formattedDateFromString(dateString, fallback = new Date()) {\n let formattedDate = null\n // Accepts d/m/yyyy and dd/mm/yyyy\n const dateFormatPattern = /(\\d{1,2})([-/,. ])(\\d{1,2})\\2(\\d{4})/\n\n if (!dateFormatPattern.test(dateString)) return fallback\n\n const match = dateFormatPattern.exec(dateString)\n const day = match[1]\n const month = match[3]\n const year = match[4]\n\n formattedDate = new Date(`${year}-${month}-${day}`)\n if (\n formattedDate instanceof Date &&\n Number.isFinite(formattedDate.getTime())\n ) {\n return formattedDate\n }\n return fallback\n }\n\n /**\n * Get a formatted date string from a Date object\n *\n * @param {Date} date - date to format to a string\n * @returns {string}\n */\n formattedDateFromDate(date) {\n if (this.config.leadingZeros) {\n return `${this.leadingZeros(date.getDate())}/${this.leadingZeros(date.getMonth() + 1)}/${date.getFullYear()}`\n }\n\n return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`\n }\n\n /**\n * Get a human readable date in the format Monday 2 March 2024\n *\n * @param {Date} date - Date to format\n * @returns {string}\n */\n formattedDateHuman(date) {\n return `${this.dayLabels[(date.getDay() + 6) % 7]} ${date.getDate()} ${this.monthLabels[date.getMonth()]} ${date.getFullYear()}`\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n backgroundClick(event) {\n if (\n this.isOpen() &&\n event.target instanceof Node &&\n !this.$dialog.contains(event.target) &&\n !this.$input.contains(event.target) &&\n !this.$calendarButton.contains(event.target)\n ) {\n event.preventDefault()\n this.closeDialog()\n }\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n firstButtonKeydown(event) {\n if (event.key === 'Tab' && event.shiftKey) {\n this.$lastButtonInDialog.focus()\n event.preventDefault()\n }\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n lastButtonKeydown(event) {\n if (event.key === 'Tab' && !event.shiftKey) {\n this.$firstButtonInDialog.focus()\n event.preventDefault()\n }\n }\n\n // render calendar\n updateCalendar() {\n this.$dialogTitle.innerHTML = `${this.monthLabels[this.currentDate.getMonth()]} ${this.currentDate.getFullYear()}`\n\n const day = this.currentDate\n const firstOfMonth = new Date(day.getFullYear(), day.getMonth(), 1)\n let dayOfWeek\n\n if (this.config.weekStartDay === 'monday') {\n dayOfWeek = firstOfMonth.getDay() === 0 ? 6 : firstOfMonth.getDay() - 1 // Change logic to make Monday first day of week, i.e. 0\n } else {\n dayOfWeek = firstOfMonth.getDay()\n }\n\n firstOfMonth.setDate(firstOfMonth.getDate() - dayOfWeek)\n\n const thisDay = new Date(firstOfMonth)\n\n // loop through our days\n for (const calendarDay of this.calendarDays) {\n const hidden = thisDay.getMonth() !== day.getMonth()\n const disabled = this.isExcludedDate(thisDay)\n\n calendarDay.update(thisDay, hidden, disabled)\n\n thisDay.setDate(thisDay.getDate() + 1)\n }\n }\n\n /**\n * @param {boolean} [focus] - Focus the day button\n */\n setCurrentDate(focus = true) {\n const { currentDate } = this\n this.calendarDays.forEach((calendarDay) => {\n calendarDay.$button.classList.add('moj-datepicker__button')\n calendarDay.$button.classList.add('moj-datepicker__calendar-day')\n calendarDay.$button.setAttribute('tabindex', '-1')\n calendarDay.$button.classList.remove(this.selectedDayButtonClass)\n const calendarDayDate = calendarDay.date\n calendarDayDate.setHours(0, 0, 0, 0)\n\n const today = new Date()\n today.setHours(0, 0, 0, 0)\n\n if (\n calendarDayDate.getTime() ===\n currentDate.getTime() /* && !calendarDay.button.disabled */\n ) {\n if (focus) {\n calendarDay.$button.setAttribute('tabindex', '0')\n calendarDay.$button.focus()\n calendarDay.$button.classList.add(this.selectedDayButtonClass)\n }\n }\n\n if (\n this.inputDate &&\n calendarDayDate.getTime() === this.inputDate.getTime()\n ) {\n calendarDay.$button.classList.add(this.currentDayButtonClass)\n calendarDay.$button.setAttribute('aria-current', 'date')\n } else {\n calendarDay.$button.classList.remove(this.currentDayButtonClass)\n calendarDay.$button.removeAttribute('aria-current')\n }\n\n if (calendarDayDate.getTime() === today.getTime()) {\n calendarDay.$button.classList.add(this.todayButtonClass)\n } else {\n calendarDay.$button.classList.remove(this.todayButtonClass)\n }\n })\n\n // if no date is tab-able, make the first non-disabled date tab-able\n if (!focus) {\n const enabledDays = this.calendarDays.filter((calendarDay) => {\n return (\n window.getComputedStyle(calendarDay.$button).display === 'block' &&\n !calendarDay.$button.disabled\n )\n })\n\n enabledDays[0].$button.setAttribute('tabindex', '0')\n\n this.currentDate = enabledDays[0].date\n }\n }\n\n /**\n * @param {Date} date - Date to select\n */\n selectDate(date) {\n if (this.isExcludedDate(date)) {\n return\n }\n\n this.$calendarButton.querySelector('span').innerText =\n `Choose date. Selected date is ${this.formattedDateHuman(date)}`\n this.$input.value = this.formattedDateFromDate(date)\n\n const changeEvent = new Event('change', { bubbles: true, cancelable: true })\n this.$input.dispatchEvent(changeEvent)\n\n this.closeDialog()\n }\n\n isOpen() {\n return this.$dialog.classList.contains('moj-datepicker__dialog--open')\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n toggleDialog(event) {\n event.preventDefault()\n if (this.isOpen()) {\n this.closeDialog()\n } else {\n this.setMinAndMaxDatesOnCalendar()\n this.openDialog()\n }\n }\n\n openDialog() {\n this.$dialog.hidden = false\n this.$dialog.classList.add('moj-datepicker__dialog--open')\n this.$calendarButton.setAttribute('aria-expanded', 'true')\n\n // position the dialog\n // if input is wider than dialog pin it to the right\n if (this.$input.offsetWidth > this.$dialog.offsetWidth) {\n this.$dialog.style.right = `0px`\n }\n this.$dialog.style.top = `${this.$input.offsetHeight + 3}px`\n\n // get the date from the input element\n this.inputDate = this.formattedDateFromString(this.$input.value)\n this.currentDate = this.inputDate\n this.currentDate.setHours(0, 0, 0, 0)\n\n this.updateCalendar()\n this.setCurrentDate()\n }\n\n closeDialog() {\n this.$dialog.hidden = true\n this.$dialog.classList.remove('moj-datepicker__dialog--open')\n this.$calendarButton.setAttribute('aria-expanded', 'false')\n this.$calendarButton.focus()\n }\n\n /**\n * @param {Date} date - Date to go to\n * @param {boolean} [focus] - Focus the day button\n */\n goToDate(date, focus) {\n const current = this.currentDate\n this.currentDate = date\n\n if (\n current.getMonth() !== this.currentDate.getMonth() ||\n current.getFullYear() !== this.currentDate.getFullYear()\n ) {\n this.updateCalendar()\n }\n\n this.setCurrentDate(focus)\n }\n\n // day navigation\n focusNextDay() {\n const date = new Date(this.currentDate)\n date.setDate(date.getDate() + 1)\n this.goToDate(date)\n }\n\n focusPreviousDay() {\n const date = new Date(this.currentDate)\n date.setDate(date.getDate() - 1)\n this.goToDate(date)\n }\n\n // week navigation\n focusNextWeek() {\n const date = new Date(this.currentDate)\n date.setDate(date.getDate() + 7)\n this.goToDate(date)\n }\n\n focusPreviousWeek() {\n const date = new Date(this.currentDate)\n date.setDate(date.getDate() - 7)\n this.goToDate(date)\n }\n\n focusFirstDayOfWeek() {\n const date = new Date(this.currentDate)\n const firstDayOfWeekIndex = this.config.weekStartDay === 'sunday' ? 0 : 1\n const dayOfWeek = date.getDay()\n const diff =\n dayOfWeek >= firstDayOfWeekIndex\n ? dayOfWeek - firstDayOfWeekIndex\n : 6 - dayOfWeek\n\n date.setDate(date.getDate() - diff)\n date.setHours(0, 0, 0, 0)\n\n this.goToDate(date)\n }\n\n focusLastDayOfWeek() {\n const date = new Date(this.currentDate)\n const lastDayOfWeekIndex = this.config.weekStartDay === 'sunday' ? 6 : 0\n const dayOfWeek = date.getDay()\n const diff =\n dayOfWeek <= lastDayOfWeekIndex\n ? lastDayOfWeekIndex - dayOfWeek\n : 7 - dayOfWeek\n\n date.setDate(date.getDate() + diff)\n date.setHours(0, 0, 0, 0)\n\n this.goToDate(date)\n }\n\n /**\n * Month navigation\n *\n * @param {KeyboardEvent | MouseEvent} event - Key press or click event\n * @param {boolean} [focus] - Focus the day button\n */\n focusNextMonth(event, focus = true) {\n event.preventDefault()\n const date = new Date(this.currentDate)\n date.setMonth(date.getMonth() + 1, 1)\n this.goToDate(date, focus)\n }\n\n /**\n * @param {KeyboardEvent | MouseEvent} event - Key press or click event\n * @param {boolean} [focus] - Focus the day button\n */\n focusPreviousMonth(event, focus = true) {\n event.preventDefault()\n const date = new Date(this.currentDate)\n date.setMonth(date.getMonth() - 1, 1)\n this.goToDate(date, focus)\n }\n\n /**\n * Year navigation\n *\n * @param {KeyboardEvent | MouseEvent} event - Key press or click event\n * @param {boolean} [focus] - Focus the day button\n */\n focusNextYear(event, focus = true) {\n event.preventDefault()\n const date = new Date(this.currentDate)\n date.setFullYear(date.getFullYear() + 1, date.getMonth(), 1)\n this.goToDate(date, focus)\n }\n\n /**\n * @param {KeyboardEvent | MouseEvent} event - Key press or click event\n * @param {boolean} [focus] - Focus the day button\n */\n focusPreviousYear(event, focus = true) {\n event.preventDefault()\n const date = new Date(this.currentDate)\n date.setFullYear(date.getFullYear() - 1, date.getMonth(), 1)\n this.goToDate(date, focus)\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-date-picker'\n\n /**\n * Date picker default config\n *\n * @type {DatePickerConfig}\n */\n static defaults = Object.freeze({\n leadingZeros: false,\n weekStartDay: 'monday',\n input: {\n selector: '.moj-js-datepicker-input'\n }\n })\n\n /**\n * Date picker config schema\n *\n * @satisfies {Schema<DatePickerConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n excludedDates: { type: 'string' },\n excludedDays: { type: 'string' },\n leadingZeros: { type: 'boolean' },\n maxDate: { type: 'string' },\n minDate: { type: 'string' },\n weekStartDay: { type: 'string' },\n input: { type: 'object' }\n }\n })\n )\n}\n\nclass DSCalendarDay {\n /**\n *\n * @param {HTMLButtonElement} $button\n * @param {number} index\n * @param {number} row\n * @param {number} column\n * @param {DatePicker} picker\n */\n constructor($button, index, row, column, picker) {\n this.index = index\n this.row = row\n this.column = column\n this.$button = $button\n this.picker = picker\n this.date = new Date()\n this.$button.addEventListener('keydown', this.keyPress.bind(this))\n this.$button.addEventListener('click', this.click.bind(this))\n }\n\n /**\n * @param {Date} day - the Date for the calendar day\n * @param {boolean} hidden - visibility of the day\n * @param {boolean} disabled - is the day selectable or excluded\n */\n update(day, hidden, disabled) {\n const label = day.getDate()\n let accessibleLabel = this.picker.formattedDateHuman(day)\n\n if (disabled) {\n this.$button.setAttribute('aria-disabled', 'true')\n accessibleLabel = `Excluded date, ${accessibleLabel}`\n } else {\n this.$button.removeAttribute('aria-disabled')\n }\n\n if (hidden) {\n this.$button.style.display = 'none'\n } else {\n this.$button.style.display = 'block'\n }\n this.$button.setAttribute(\n 'data-testid',\n this.picker.formattedDateFromDate(day)\n )\n\n this.$button.innerHTML = `<span class=\"govuk-visually-hidden\">${accessibleLabel}</span><span aria-hidden=\"true\">${label}</span>`\n this.date = new Date(day)\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n click(event) {\n this.picker.goToDate(this.date)\n this.picker.selectDate(this.date)\n\n event.stopPropagation()\n event.preventDefault()\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n keyPress(event) {\n let calendarNavKey = true\n\n switch (event.key) {\n case 'ArrowLeft':\n this.picker.focusPreviousDay()\n break\n case 'ArrowRight':\n this.picker.focusNextDay()\n break\n case 'ArrowUp':\n this.picker.focusPreviousWeek()\n break\n case 'ArrowDown':\n this.picker.focusNextWeek()\n break\n case 'Home':\n this.picker.focusFirstDayOfWeek()\n break\n case 'End':\n this.picker.focusLastDayOfWeek()\n break\n case 'PageUp': {\n if (event.shiftKey) {\n this.picker.focusPreviousYear(event)\n } else {\n this.picker.focusPreviousMonth(event)\n }\n break\n }\n case 'PageDown': {\n if (event.shiftKey) {\n this.picker.focusNextYear(event)\n } else {\n this.picker.focusNextMonth(event)\n }\n break\n }\n default:\n calendarNavKey = false\n break\n }\n\n if (calendarNavKey) {\n event.preventDefault()\n event.stopPropagation()\n }\n }\n}\n\n/**\n * Date picker config\n *\n * @typedef {object} DatePickerConfig\n * @property {string} [excludedDates] - Dates that cannot be selected\n * @property {string} [excludedDays] - Days that cannot be selected\n * @property {boolean} [leadingZeros] - Whether to add leading zeroes when populating the field\n * @property {string} [minDate] - The earliest available date\n * @property {string} [maxDate] - The latest available date\n * @property {string} [weekStartDay] - First day of the week in calendar view\n * @property {object} [input] - Input config\n * @property {string} [input.selector] - Selector for the input element\n * @property {Element | null} [input.element] - HTML element for the input\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { Component } from 'govuk-frontend'\n\nexport class PdsHeader extends Component {\n /**\n * @param {Element | null} $root - HTML element to use for PDS header\n */\n constructor($root) {\n super($root)\n this.initHeader()\n }\n\n initHeader() {\n this.$tabOpenClass = 'probation-common-header__toggle-open'\n const $userToggle = this.$root.querySelector(\n '.probation-common-header__user-menu-toggle'\n )\n const $userMenu = this.$root.querySelector(\n '#probation-common-header-user-menu'\n )\n\n if (\n !$userToggle ||\n !$userMenu ||\n !($userToggle instanceof HTMLElement) ||\n !($userMenu instanceof HTMLElement)\n ) {\n return 0\n }\n\n this.hideFallbackLinks()\n $userToggle.removeAttribute('hidden')\n\n this.closeTabs([[$userToggle, $userMenu]])\n\n $userToggle.addEventListener('click', (_event) => {\n this.toggleMenu($userToggle, $userMenu)\n })\n }\n\n /**\n * @param {[any, any][]} tabTuples\n */\n closeTabs(tabTuples) {\n tabTuples.forEach(([toggle, menu]) => {\n if (menu && toggle) {\n menu.setAttribute('hidden', 'hidden')\n toggle.classList.remove(this.$tabOpenClass)\n toggle.parentElement.classList.remove('item-open')\n toggle.setAttribute('aria-expanded', 'false')\n if (toggle.dataset.textForShow)\n toggle.setAttribute('aria-label', toggle.dataset.textForShow)\n }\n })\n }\n\n /**\n * @param {HTMLElement} toggle\n * @param {HTMLElement} menu\n */\n toggleMenu(toggle, menu) {\n const isOpen = !menu.getAttribute('hidden')\n\n if (isOpen) {\n this.closeTabs([[toggle, menu]])\n } else if (menu && toggle) {\n menu.removeAttribute('hidden')\n toggle.classList.add(this.$tabOpenClass)\n toggle.parentElement.classList.add('item-open')\n toggle.setAttribute('aria-expanded', 'true')\n if (toggle.dataset.textForHide)\n toggle.setAttribute('aria-label', toggle.dataset.textForHide)\n }\n }\n\n hideFallbackLinks() {\n const $userLink = this.$root.querySelector(\n '.probation-common-header__user-menu-link'\n )\n if ($userLink) $userLink.setAttribute('hidden', 'hidden')\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'pds-header'\n}\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<FilterToggleButtonConfig>}\n */\nexport class FilterToggleButton extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for filter toggle button\n * @param {FilterToggleButtonConfig} [config] - Filter toggle button config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $toggleButtonContainer =\n this.config.toggleButtonContainer.element ??\n document.querySelector(this.config.toggleButtonContainer.selector)\n\n const $closeButtonContainer =\n this.config.closeButtonContainer.element ??\n this.$root.querySelector(this.config.closeButtonContainer.selector)\n\n if (\n !(\n $toggleButtonContainer instanceof HTMLElement &&\n $closeButtonContainer instanceof HTMLElement\n )\n ) {\n return this\n }\n\n this.$toggleButtonContainer = $toggleButtonContainer\n this.$closeButtonContainer = $closeButtonContainer\n\n this.createToggleButton()\n this.setupResponsiveChecks()\n\n this.$root.setAttribute('tabindex', '-1')\n\n if (this.config.startHidden) {\n this.hideMenu()\n }\n }\n\n setupResponsiveChecks() {\n this.mq = window.matchMedia(this.config.bigModeMediaQuery)\n this.mq.addListener(this.checkMode.bind(this))\n this.checkMode()\n }\n\n createToggleButton() {\n this.$menuButton = document.createElement('button')\n this.$menuButton.setAttribute('type', 'button')\n this.$menuButton.setAttribute('aria-haspopup', 'true')\n this.$menuButton.setAttribute('aria-expanded', 'false')\n\n this.$menuButton.className = `govuk-button ${this.config.toggleButton.classes}`\n this.$menuButton.textContent = this.config.toggleButton.showText\n\n this.$menuButton.addEventListener(\n 'click',\n this.onMenuButtonClick.bind(this)\n )\n\n this.$toggleButtonContainer.append(this.$menuButton)\n }\n\n checkMode() {\n if (this.mq.matches) {\n this.enableBigMode()\n } else {\n this.enableSmallMode()\n }\n }\n\n enableBigMode() {\n this.showMenu()\n this.removeCloseButton()\n }\n\n enableSmallMode() {\n this.hideMenu()\n this.addCloseButton()\n }\n\n addCloseButton() {\n this.$closeButton = document.createElement('button')\n this.$closeButton.setAttribute('type', 'button')\n\n this.$closeButton.className = this.config.closeButton.classes\n this.$closeButton.textContent = this.config.closeButton.text\n\n this.$closeButton.addEventListener('click', this.onCloseClick.bind(this))\n this.$closeButtonContainer.append(this.$closeButton)\n }\n\n onCloseClick() {\n this.hideMenu()\n this.$menuButton.focus()\n }\n\n removeCloseButton() {\n if (this.$closeButton) {\n this.$closeButton.remove()\n this.$closeButton = null\n }\n }\n\n hideMenu() {\n this.$menuButton.setAttribute('aria-expanded', 'false')\n this.$root.classList.add('moj-js-hidden')\n this.$menuButton.textContent = this.config.toggleButton.showText\n }\n\n showMenu() {\n this.$menuButton.setAttribute('aria-expanded', 'true')\n this.$root.classList.remove('moj-js-hidden')\n this.$menuButton.textContent = this.config.toggleButton.hideText\n }\n\n onMenuButtonClick() {\n this.toggle()\n }\n\n toggle() {\n if (this.$menuButton.getAttribute('aria-expanded') === 'false') {\n this.showMenu()\n this.$root.focus()\n } else {\n this.hideMenu()\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-filter'\n\n /**\n * Filter toggle button config\n *\n * @type {FilterToggleButtonConfig}\n */\n static defaults = Object.freeze({\n bigModeMediaQuery: '(min-width: 48.0625em)',\n startHidden: true,\n toggleButton: {\n showText: 'Show filter',\n hideText: 'Hide filter',\n classes: 'govuk-button--secondary'\n },\n toggleButtonContainer: {\n selector: '.moj-action-bar__filter'\n },\n closeButton: {\n text: 'Close',\n classes: 'moj-filter__close'\n },\n closeButtonContainer: {\n selector: '.moj-filter__header-action'\n }\n })\n\n /**\n * Filter toggle button config schema\n *\n * @satisfies {Schema<FilterToggleButtonConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n bigModeMediaQuery: { type: 'string' },\n startHidden: { type: 'boolean' },\n toggleButton: { type: 'object' },\n toggleButtonContainer: { type: 'object' },\n closeButton: { type: 'object' },\n closeButtonContainer: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} FilterToggleButtonConfig\n * @property {string} [bigModeMediaQuery] - Media query for big mode\n * @property {boolean} [startHidden] - Whether to start hidden\n * @property {object} [toggleButton] - Toggle button config\n * @property {string} [toggleButton.showText] - Text for show button\n * @property {string} [toggleButton.hideText] - Text for hide button\n * @property {string} [toggleButton.classes] - Classes for toggle button\n * @property {object} [toggleButtonContainer] - Toggle button container config\n * @property {string} [toggleButtonContainer.selector] - Selector for toggle button container\n * @property {Element | null} [toggleButtonContainer.element] - HTML element for toggle button container\n * @property {object} [closeButton] - Close button config\n * @property {string} [closeButton.text] - Text for close button\n * @property {string} [closeButton.classes] - Classes for close button\n * @property {object} [closeButtonContainer] - Close button container config\n * @property {string} [closeButtonContainer.selector] - Selector for close button container\n * @property {Element | null} [closeButtonContainer.element] - HTML element for close button container\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\nimport { addAttributeValue, removeAttributeValue } from '../../helpers.mjs'\n\n/**\n * @augments {ConfigurableComponent<FormValidatorConfig, HTMLFormElement>}\n */\nexport class FormValidator extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for form validator\n * @param {FormValidatorConfig} [config] - Form validator config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $summary =\n this.config.summary.element ||\n document.querySelector(this.config.summary.selector)\n\n if (!$summary || !($summary instanceof HTMLElement)) {\n return this\n }\n\n this.$summary = $summary\n\n this.errors = /** @type {ValidationError[]} */ ([])\n this.validators = /** @type {Validator[]} */ ([])\n this.originalTitle = document.title\n\n this.$root.addEventListener('submit', this.onSubmit.bind(this))\n }\n\n escapeHtml(string = '') {\n return String(string).replace(\n /[&<>\"'`=/]/g,\n (name) => FormValidator.entityMap[name]\n )\n }\n\n resetTitle() {\n document.title = this.originalTitle\n }\n\n updateTitle() {\n document.title = `${this.errors.length} errors - ${document.title}`\n }\n\n showSummary() {\n this.$summary.innerHTML = this.getSummaryHtml()\n this.$summary.classList.remove('moj-hidden')\n this.$summary.setAttribute('aria-labelledby', 'errorSummary-heading')\n this.$summary.focus()\n }\n\n getSummaryHtml() {\n let html =\n '<h2 id=\"error-summary-title\" class=\"govuk-error-summary__title\">There is a problem</h2>'\n html += '<div class=\"govuk-error-summary__body\">'\n html += '<ul class=\"govuk-list govuk-error-summary__list\">'\n for (const error of this.errors) {\n html += '<li>'\n html += `<a href=\"#${this.escapeHtml(error.fieldName)}\">`\n html += this.escapeHtml(error.message)\n html += '</a>'\n html += '</li>'\n }\n html += '</ul>'\n html += '</div>'\n return html\n }\n\n hideSummary() {\n this.$summary.classList.add('moj-hidden')\n this.$summary.removeAttribute('aria-labelledby')\n }\n\n /**\n * @param {SubmitEvent} event - Form submit event\n */\n onSubmit(event) {\n this.removeInlineErrors()\n this.hideSummary()\n this.resetTitle()\n if (!this.validate()) {\n event.preventDefault()\n this.updateTitle()\n this.showSummary()\n this.showInlineErrors()\n }\n }\n\n showInlineErrors() {\n for (const error of this.errors) {\n this.showInlineError(error)\n }\n }\n\n /**\n * @param {ValidationError} error\n */\n showInlineError(error) {\n const $errorSpan = document.createElement('span')\n $errorSpan.id = `${error.fieldName}-error`\n $errorSpan.classList.add('govuk-error-message')\n $errorSpan.innerHTML = this.escapeHtml(error.message)\n\n const $control = document.querySelector(`#${error.fieldName}`)\n const $fieldset = $control.closest('.govuk-fieldset')\n const $fieldContainer = ($fieldset || $control).closest('.govuk-form-group')\n\n const $label = $fieldContainer.querySelector('label')\n const $legend = $fieldContainer.querySelector('legend')\n\n $fieldContainer.classList.add('govuk-form-group--error')\n\n if ($fieldset && $legend) {\n $legend.after($errorSpan)\n $fieldContainer.setAttribute('aria-invalid', 'true')\n addAttributeValue($fieldset, 'aria-describedby', $errorSpan.id)\n } else if ($label && $control) {\n $label.after($errorSpan)\n $control.setAttribute('aria-invalid', 'true')\n addAttributeValue($control, 'aria-describedby', $errorSpan.id)\n }\n }\n\n removeInlineErrors() {\n for (const error of this.errors) {\n this.removeInlineError(error)\n }\n }\n\n /**\n * @param {ValidationError} error\n */\n removeInlineError(error) {\n const $errorSpan = document.querySelector(`#${error.fieldName}-error`)\n\n const $control = document.querySelector(`#${error.fieldName}`)\n const $fieldset = $control.closest('.govuk-fieldset')\n const $fieldContainer = ($fieldset || $control).closest('.govuk-form-group')\n\n const $label = $fieldContainer.querySelector('label')\n const $legend = $fieldContainer.querySelector('legend')\n\n $errorSpan.remove()\n $fieldContainer.classList.remove('govuk-form-group--error')\n\n if ($fieldset && $legend) {\n $fieldContainer.removeAttribute('aria-invalid')\n removeAttributeValue($fieldset, 'aria-describedby', $errorSpan.id)\n } else if ($label && $control) {\n $control.removeAttribute('aria-invalid')\n removeAttributeValue($control, 'aria-describedby', $errorSpan.id)\n }\n }\n\n /**\n * @param {string} fieldName - Field name\n * @param {ValidationRule[]} rules - Validation rules\n */\n addValidator(fieldName, rules) {\n this.validators.push({\n fieldName,\n rules,\n field: this.$root.elements.namedItem(fieldName)\n })\n }\n\n validate() {\n this.errors = []\n\n /** @type {Validator | null} */\n let validator = null\n\n /** @type {boolean | string} */\n let validatorReturnValue = true\n\n let i\n let j\n\n for (i = 0; i < this.validators.length; i++) {\n validator = this.validators[i]\n for (j = 0; j < validator.rules.length; j++) {\n validatorReturnValue = validator.rules[j].method(\n validator.field,\n validator.rules[j].params\n )\n\n if (\n typeof validatorReturnValue === 'boolean' &&\n !validatorReturnValue\n ) {\n this.errors.push({\n fieldName: validator.fieldName,\n message: validator.rules[j].message\n })\n break\n } else if (typeof validatorReturnValue === 'string') {\n this.errors.push({\n fieldName: validatorReturnValue,\n message: validator.rules[j].message\n })\n break\n }\n }\n }\n return this.errors.length === 0\n }\n\n /**\n * @type {Record<string, string>}\n */\n static entityMap = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;',\n '/': '&#x2F;',\n '`': '&#x60;',\n '=': '&#x3D;'\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-form-validator'\n\n /**\n * Multi file upload default config\n *\n * @type {FormValidatorConfig}\n */\n static defaults = Object.freeze({\n summary: {\n selector: '.govuk-error-summary'\n }\n })\n\n /**\n * Multi file upload config schema\n *\n * @satisfies {Schema<FormValidatorConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n summary: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} FormValidatorConfig\n * @property {object} [summary] - Error summary config\n * @property {string} [summary.selector] - Selector for error summary\n * @property {Element | null} [summary.element] - HTML element for error summary\n */\n\n/**\n * @typedef {object} ValidationRule\n * @property {(field: Validator['field'], params: Record<string, Validator['field']>) => boolean | string} method - Validation method\n * @property {string} message - Error message\n * @property {Record<string, Validator['field']>} [params] - Parameters for validation\n */\n\n/**\n * @typedef {object} ValidationError\n * @property {string} fieldName - Name of the field\n * @property {string} message - Validation error message\n */\n\n/**\n * @typedef {object} Validator\n * @property {string} fieldName - Name of the field\n * @property {ValidationRule[]} rules - Validation rules\n * @property {Element | RadioNodeList} field - Form field\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","/* eslint-disable @typescript-eslint/no-empty-function */\n\nimport { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<MultiFileUploadConfig>}\n */\nexport class MultiFileUpload extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for multi file upload\n * @param {MultiFileUploadConfig} [config] - Multi file upload config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n if (!MultiFileUpload.isSupported()) {\n return this\n }\n\n const $feedbackContainer =\n this.config.feedbackContainer.element ??\n this.$root.querySelector(this.config.feedbackContainer.selector)\n\n if (!$feedbackContainer || !($feedbackContainer instanceof HTMLElement)) {\n return this\n }\n\n this.$feedbackContainer = $feedbackContainer\n\n this.setupFileInput()\n this.setupDropzone()\n this.setupLabel()\n this.setupStatusBox()\n\n this.$root.addEventListener('click', this.onFileDeleteClick.bind(this))\n this.$root.classList.add('moj-multi-file-upload--enhanced')\n }\n\n setupDropzone() {\n this.$dropzone = document.createElement('div')\n this.$dropzone.classList.add('moj-multi-file-upload__dropzone')\n\n this.$dropzone.addEventListener('dragover', this.onDragOver.bind(this))\n this.$dropzone.addEventListener('dragleave', this.onDragLeave.bind(this))\n this.$dropzone.addEventListener('drop', this.onDrop.bind(this))\n\n this.$fileInput.replaceWith(this.$dropzone)\n this.$dropzone.appendChild(this.$fileInput)\n }\n\n setupLabel() {\n const $label = document.createElement('label')\n $label.setAttribute('for', this.$fileInput.id)\n $label.classList.add('govuk-button', 'govuk-button--secondary')\n $label.textContent = this.config.dropzoneButtonText\n\n const $hint = document.createElement('p')\n $hint.classList.add('govuk-body')\n $hint.textContent = this.config.dropzoneHintText\n\n this.$label = $label\n this.$dropzone.append($hint)\n this.$dropzone.append($label)\n }\n\n setupFileInput() {\n this.$fileInput = /** @type {HTMLInputElement} */ (\n this.$root.querySelector('.moj-multi-file-upload__input')\n )\n this.$fileInput.addEventListener('change', this.onFileChange.bind(this))\n this.$fileInput.addEventListener('focus', this.onFileFocus.bind(this))\n this.$fileInput.addEventListener('blur', this.onFileBlur.bind(this))\n }\n\n setupStatusBox() {\n this.$status = document.createElement('div')\n this.$status.classList.add('govuk-visually-hidden')\n this.$status.setAttribute('aria-live', 'polite')\n this.$status.setAttribute('role', 'status')\n this.$dropzone.append(this.$status)\n }\n\n /**\n * @param {DragEvent} event - Drag event\n */\n onDragOver(event) {\n event.preventDefault()\n this.$dropzone.classList.add('moj-multi-file-upload--dragover')\n }\n\n onDragLeave() {\n this.$dropzone.classList.remove('moj-multi-file-upload--dragover')\n }\n\n /**\n * @param {DragEvent} event - Drag event\n */\n onDrop(event) {\n event.preventDefault()\n this.$dropzone.classList.remove('moj-multi-file-upload--dragover')\n this.$feedbackContainer.classList.remove('moj-hidden')\n this.$status.textContent = this.config.uploadStatusText\n this.uploadFiles(event.dataTransfer.files)\n }\n\n /**\n * @param {FileList} files - File list\n */\n uploadFiles(files) {\n for (const file of Array.from(files)) {\n this.uploadFile(file)\n }\n }\n\n onFileChange() {\n this.$feedbackContainer.classList.remove('moj-hidden')\n this.$status.textContent = this.config.uploadStatusText\n this.uploadFiles(this.$fileInput.files)\n\n const $fileInput = this.$fileInput.cloneNode(true)\n if (!$fileInput || !($fileInput instanceof HTMLInputElement)) {\n return\n }\n\n $fileInput.value = ''\n this.$fileInput.replaceWith($fileInput)\n\n this.setupFileInput()\n this.$fileInput.focus()\n }\n\n onFileFocus() {\n this.$label.classList.add('moj-multi-file-upload--focused')\n }\n\n onFileBlur() {\n this.$label.classList.remove('moj-multi-file-upload--focused')\n }\n\n /**\n * @param {UploadResponseSuccess['success']} success\n */\n getSuccessHtml(success) {\n return `<span class=\"moj-multi-file-upload__success\"> <svg class=\"moj-banner__icon\" fill=\"currentColor\" role=\"presentation\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 25 25\" height=\"25\" width=\"25\"><path d=\"M25,6.2L8.7,23.2L0,14.1l4-4.2l4.7,4.9L21,2L25,6.2z\"/></svg>${success.messageHtml}</span>`\n }\n\n /**\n * @param {UploadResponseError['error']} error\n */\n getErrorHtml(error) {\n return `<span class=\"moj-multi-file-upload__error\"> <svg class=\"moj-banner__icon\" fill=\"currentColor\" role=\"presentation\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 25 25\" height=\"25\" width=\"25\"><path d=\"M13.6,15.4h-2.3v-4.5h2.3V15.4z M13.6,19.8h-2.3v-2.2h2.3V19.8z M0,23.2h25L12.5,2L0,23.2z\"/></svg>${error.message}</span>`\n }\n\n /**\n * @param {File} file\n */\n getFileRow(file) {\n const $row = document.createElement('div')\n\n $row.classList.add('govuk-summary-list__row', 'moj-multi-file-upload__row')\n\n $row.innerHTML = `\n <div class=\"govuk-summary-list__value moj-multi-file-upload__message\">\n <span class=\"moj-multi-file-upload__filename\">${file.name}</span>\n <span class=\"moj-multi-file-upload__progress\">0%</span>\n </div>\n <div class=\"govuk-summary-list__actions moj-multi-file-upload__actions\"></div>\n `\n\n return $row\n }\n\n /**\n * @param {UploadResponseFile} file\n */\n getDeleteButton(file) {\n const $button = document.createElement('button')\n\n $button.setAttribute('type', 'button')\n $button.setAttribute('name', 'delete')\n $button.setAttribute('value', file.filename)\n\n $button.classList.add(\n 'moj-multi-file-upload__delete',\n 'govuk-button',\n 'govuk-button--secondary',\n 'govuk-!-margin-bottom-0'\n )\n\n $button.innerHTML = `Delete <span class=\"govuk-visually-hidden\">${file.originalname}</span>`\n\n return $button\n }\n\n /**\n * @param {File} file\n */\n uploadFile(file) {\n this.config.hooks.entryHook(this, file)\n\n const $item = this.getFileRow(file)\n const $message = $item.querySelector('.moj-multi-file-upload__message')\n const $actions = $item.querySelector('.moj-multi-file-upload__actions')\n const $progress = $item.querySelector('.moj-multi-file-upload__progress')\n\n const formData = new FormData()\n formData.append('documents', file)\n\n this.$feedbackContainer\n .querySelector('.moj-multi-file-upload__list')\n .append($item)\n\n const xhr = new XMLHttpRequest()\n\n const onLoad = () => {\n if (\n xhr.status < 200 ||\n xhr.status >= 300 ||\n !('success' in xhr.response)\n ) {\n return onError()\n }\n\n $message.innerHTML = this.getSuccessHtml(xhr.response.success)\n this.$status.textContent = xhr.response.success.messageText\n\n $actions.append(this.getDeleteButton(xhr.response.file))\n this.config.hooks.exitHook(this, file, xhr, xhr.responseText)\n }\n\n const onError = () => {\n const error = new Error(\n xhr.response && 'error' in xhr.response\n ? xhr.response.error.message\n : xhr.statusText || 'Upload failed'\n )\n\n $message.innerHTML = this.getErrorHtml(error)\n this.$status.textContent = error.message\n\n this.config.hooks.errorHook(this, file, xhr, xhr.responseText, error)\n }\n\n xhr.addEventListener('load', onLoad)\n xhr.addEventListener('error', onError)\n\n xhr.upload.addEventListener('progress', (event) => {\n if (!event.lengthComputable) {\n return\n }\n\n const percentComplete = Math.round((event.loaded / event.total) * 100)\n $progress.textContent = ` ${percentComplete}%`\n })\n\n xhr.open('POST', this.config.uploadUrl)\n xhr.responseType = 'json'\n\n xhr.send(formData)\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onFileDeleteClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-multi-file-upload__delete')\n ) {\n return\n }\n\n event.preventDefault() // if user refreshes page and then deletes\n\n const xhr = new XMLHttpRequest()\n\n xhr.addEventListener('load', () => {\n if (xhr.status < 200 || xhr.status >= 300) {\n return\n }\n\n const $rows = Array.from(\n this.$feedbackContainer.querySelectorAll('.moj-multi-file-upload__row')\n )\n\n if ($rows.length === 1) {\n this.$feedbackContainer.classList.add('moj-hidden')\n }\n\n const $rowDelete = $rows.find(($row) => $row.contains($button))\n if ($rowDelete) $rowDelete.remove()\n\n this.config.hooks.deleteHook(this, undefined, xhr, xhr.responseText)\n })\n\n xhr.open('POST', this.config.deleteUrl)\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.responseType = 'json'\n\n xhr.send(\n JSON.stringify({\n [$button.name]: $button.value\n })\n )\n }\n\n static isSupported() {\n return (\n this.isDragAndDropSupported() &&\n this.isFormDataSupported() &&\n this.isFileApiSupported()\n )\n }\n\n static isDragAndDropSupported() {\n const div = document.createElement('div')\n return typeof div.ondrop !== 'undefined'\n }\n\n static isFormDataSupported() {\n return typeof FormData === 'function'\n }\n\n static isFileApiSupported() {\n const input = document.createElement('input')\n input.type = 'file'\n return typeof input.files !== 'undefined'\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-multi-file-upload'\n\n /**\n * Multi file upload default config\n *\n * @type {MultiFileUploadConfig}\n */\n static defaults = Object.freeze({\n uploadStatusText: 'Uploading files, please wait',\n dropzoneHintText: 'Drag and drop files here or',\n dropzoneButtonText: 'Choose files',\n feedbackContainer: {\n selector: '.moj-multi-file__uploaded-files'\n },\n hooks: {\n entryHook: () => {},\n exitHook: () => {},\n errorHook: () => {},\n deleteHook: () => {}\n }\n })\n\n /**\n * Multi file upload config schema\n *\n * @satisfies {Schema<MultiFileUploadConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n uploadUrl: { type: 'string' },\n deleteUrl: { type: 'string' },\n uploadStatusText: { type: 'string' },\n dropzoneHintText: { type: 'string' },\n dropzoneButtonText: { type: 'string' },\n feedbackContainer: { type: 'object' },\n hooks: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * Multi file upload config\n *\n * @typedef {object} MultiFileUploadConfig\n * @property {string} [uploadUrl] - File upload URL\n * @property {string} [deleteUrl] - File delete URL\n * @property {string} [uploadStatusText] - Upload status text\n * @property {string} [dropzoneHintText] - Dropzone hint text\n * @property {string} [dropzoneButtonText] - Dropzone button text\n * @property {object} [feedbackContainer] - Feedback container config\n * @property {string} [feedbackContainer.selector] - Selector for feedback container\n * @property {Element | null} [feedbackContainer.element] - HTML element for feedback container\n * @property {MultiFileUploadHooks} [hooks] - Upload hooks\n */\n\n/**\n * Multi file upload hooks\n *\n * @typedef {object} MultiFileUploadHooks\n * @property {OnUploadFileEntryHook} [entryHook] - File upload entry hook\n * @property {OnUploadFileExitHook} [exitHook] - File upload exit hook\n * @property {OnUploadFileErrorHook} [errorHook] - File upload error hook\n * @property {OnUploadFileDeleteHook} [deleteHook] - File delete hook\n */\n\n/**\n * Upload hook: File entry\n *\n * @callback OnUploadFileEntryHook\n * @param {InstanceType<typeof MultiFileUpload>} upload - Multi file upload\n * @param {File} file - File upload\n */\n\n/**\n * Upload hook: File exit\n *\n * @callback OnUploadFileExitHook\n * @param {InstanceType<typeof MultiFileUpload>} upload - Multi file upload\n * @param {File} file - File upload\n * @param {XMLHttpRequest} xhr - XMLHttpRequest\n * @param {string} textStatus - Text status\n */\n\n/**\n * Upload hook: File error\n *\n * @callback OnUploadFileErrorHook\n * @param {InstanceType<typeof MultiFileUpload>} upload - Multi file upload\n * @param {File} file - File upload\n * @param {XMLHttpRequest} xhr - XMLHttpRequest\n * @param {string} textStatus - Text status\n * @param {Error} errorThrown - Error thrown\n */\n\n/**\n * Upload hook: File delete\n *\n * @callback OnUploadFileDeleteHook\n * @param {InstanceType<typeof MultiFileUpload>} upload - Multi file upload\n * @param {File} [file] - File upload\n * @param {XMLHttpRequest} xhr - XMLHttpRequest\n * @param {string} textStatus - Text status\n */\n\n/**\n * @typedef {object} UploadResponseSuccess\n * @property {{ messageText: string, messageHtml: string }} success - Response success\n * @property {UploadResponseFile} file - Response file\n */\n\n/**\n * @typedef {object} UploadResponseError\n * @property {{ message: string }} error - Response error\n * @property {UploadResponseFile} file - Response file\n */\n\n/**\n * @typedef {object} UploadResponseFile\n * @property {string} filename - File name\n * @property {string} originalname - Original file name\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<MultiSelectConfig>}\n */\nexport class MultiSelect extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for multi select\n * @param {MultiSelectConfig} [config] - Multi select config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $container = this.$root.querySelector(\n `#${this.config.idPrefix}select-all`\n )\n\n const $checkboxes = /** @type {NodeListOf<HTMLInputElement>} */ (\n this.config.checkboxes.items ??\n this.$root.querySelectorAll(this.config.checkboxes.selector)\n )\n\n if (\n !$container ||\n !($container instanceof HTMLElement) ||\n !$checkboxes.length\n ) {\n return this\n }\n\n this.setupToggle(this.config.idPrefix)\n\n this.$toggleButton = this.$toggle.querySelector('input')\n this.$toggleButton.addEventListener('click', this.onButtonClick.bind(this))\n\n this.$container = $container\n this.$container.append(this.$toggle)\n\n this.$checkboxes = Array.from($checkboxes)\n this.$checkboxes.forEach(($input) =>\n $input.addEventListener('click', this.onCheckboxClick.bind(this))\n )\n\n this.checked = config.checked || false\n }\n\n setupToggle(idPrefix = '') {\n const id = `${idPrefix}checkboxes-all`\n\n const $toggle = document.createElement('div')\n const $label = document.createElement('label')\n const $input = document.createElement('input')\n const $span = document.createElement('span')\n\n $toggle.classList.add(\n 'govuk-checkboxes__item',\n 'govuk-checkboxes--small',\n 'moj-multi-select__checkbox'\n )\n\n $input.id = id\n $input.type = 'checkbox'\n $input.classList.add('govuk-checkboxes__input')\n\n $label.setAttribute('for', id)\n $label.classList.add(\n 'govuk-label',\n 'govuk-checkboxes__label',\n 'moj-multi-select__toggle-label'\n )\n\n $span.classList.add('govuk-visually-hidden')\n $span.textContent = 'Select all'\n\n $label.append($span)\n $toggle.append($input, $label)\n\n this.$toggle = $toggle\n }\n\n onButtonClick() {\n if (this.checked) {\n this.uncheckAll()\n this.$toggleButton.checked = false\n } else {\n this.checkAll()\n this.$toggleButton.checked = true\n }\n }\n\n checkAll() {\n this.$checkboxes.forEach(($input) => {\n $input.checked = true\n })\n\n this.checked = true\n }\n\n uncheckAll() {\n this.$checkboxes.forEach(($input) => {\n $input.checked = false\n })\n\n this.checked = false\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onCheckboxClick(event) {\n if (!(event.target instanceof HTMLInputElement)) {\n return\n }\n\n if (!event.target.checked) {\n this.$toggleButton.checked = false\n this.checked = false\n } else {\n if (\n this.$checkboxes.filter(($input) => $input.checked).length ===\n this.$checkboxes.length\n ) {\n this.$toggleButton.checked = true\n this.checked = true\n }\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-multi-select'\n\n /**\n * Multi select config\n *\n * @type {MultiSelectConfig}\n */\n static defaults = Object.freeze({\n idPrefix: '',\n checkboxes: {\n selector: 'tbody input.govuk-checkboxes__input'\n }\n })\n\n /**\n * Multi select config schema\n *\n * @satisfies {Schema<MultiSelectConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n idPrefix: { type: 'string' },\n checked: { type: 'boolean' },\n checkboxes: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * Multi select config\n *\n * @typedef {object} MultiSelectConfig\n * @property {string} [idPrefix] - Prefix for the Select all\" checkbox `id` attribute\n * @property {boolean} [checked] - Whether the \"Select all\" checkbox is checked\n * @property {object} [checkboxes] - Checkboxes config\n * @property {string} [checkboxes.selector] - Checkboxes query selector\n * @property {NodeListOf<HTMLInputElement>} [checkboxes.items] - Checkboxes query selector results\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { Component } from 'govuk-frontend'\n\nexport class PasswordReveal extends Component {\n /**\n * @param {Element | null} $root - HTML element to use for password reveal\n */\n constructor($root) {\n super($root)\n\n const $input = this.$root.querySelector('.govuk-input')\n if (!$input || !($input instanceof HTMLInputElement)) {\n return this\n }\n\n this.$input = $input\n this.$input.setAttribute('spellcheck', 'false')\n\n this.createButton()\n }\n\n createButton() {\n this.$group = document.createElement('div')\n this.$button = document.createElement('button')\n\n this.$button.setAttribute('type', 'button')\n\n this.$root.classList.add('moj-password-reveal')\n this.$group.classList.add('moj-password-reveal__wrapper')\n this.$button.classList.add(\n 'govuk-button',\n 'govuk-button--secondary',\n 'moj-password-reveal__button'\n )\n\n this.$button.innerHTML =\n 'Show <span class=\"govuk-visually-hidden\">password</span>'\n\n this.$button.addEventListener('click', this.onButtonClick.bind(this))\n\n this.$group.append(this.$input, this.$button)\n this.$root.append(this.$group)\n }\n\n onButtonClick() {\n if (this.$input.type === 'password') {\n this.$input.type = 'text'\n this.$button.innerHTML =\n 'Hide <span class=\"govuk-visually-hidden\">password</span>'\n } else {\n this.$input.type = 'password'\n this.$button.innerHTML =\n 'Show <span class=\"govuk-visually-hidden\">password</span>'\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-password-reveal'\n}\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<RichTextEditorConfig>}\n */\nexport class RichTextEditor extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for rich text editor\n * @param {RichTextEditorConfig} config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n if (!RichTextEditor.isSupported()) {\n return this\n }\n\n const $textarea = this.$root.querySelector('.govuk-textarea')\n if (!$textarea || !($textarea instanceof HTMLTextAreaElement)) {\n return this\n }\n\n this.$textarea = $textarea\n\n this.createToolbar()\n this.hideDefault()\n this.configureToolbar()\n\n this.keys = {\n left: 37,\n right: 39,\n up: 38,\n down: 40\n }\n\n this.$content.addEventListener('input', this.onEditorInput.bind(this))\n\n this.$root\n .querySelector('label')\n .addEventListener('click', this.onLabelClick.bind(this))\n\n this.$toolbar.addEventListener('keydown', this.onToolbarKeydown.bind(this))\n }\n\n /**\n * @param {KeyboardEvent} event - Click event\n */\n onToolbarKeydown(event) {\n let $focusableButton\n switch (event.keyCode) {\n case this.keys.right:\n case this.keys.down: {\n $focusableButton = this.$buttons.find(\n (button) => button.getAttribute('tabindex') === '0'\n )\n\n if ($focusableButton) {\n const $nextButton = $focusableButton.nextElementSibling\n\n if ($nextButton && $nextButton instanceof HTMLButtonElement) {\n $nextButton.focus()\n $focusableButton.setAttribute('tabindex', '-1')\n $nextButton.setAttribute('tabindex', '0')\n }\n }\n\n break\n }\n\n case this.keys.left:\n case this.keys.up: {\n $focusableButton = this.$buttons.find(\n (button) => button.getAttribute('tabindex') === '0'\n )\n\n if ($focusableButton) {\n const $previousButton = $focusableButton.previousElementSibling\n\n if ($previousButton && $previousButton instanceof HTMLButtonElement) {\n $previousButton.focus()\n $focusableButton.setAttribute('tabindex', '-1')\n $previousButton.setAttribute('tabindex', '0')\n }\n }\n\n break\n }\n }\n }\n\n getToolbarHtml() {\n let html = ''\n\n html += '<div class=\"moj-rich-text-editor__toolbar\" role=\"toolbar\">'\n\n if (this.config.toolbar.bold) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--bold\" type=\"button\" data-command=\"bold\"><span class=\"govuk-visually-hidden\">Bold</span></button>'\n }\n\n if (this.config.toolbar.italic) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--italic\" type=\"button\" data-command=\"italic\"><span class=\"govuk-visually-hidden\">Italic</span></button>'\n }\n\n if (this.config.toolbar.underline) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--underline\" type=\"button\" data-command=\"underline\"><span class=\"govuk-visually-hidden\">Underline</span></button>'\n }\n\n if (this.config.toolbar.bullets) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--unordered-list\" type=\"button\" data-command=\"insertUnorderedList\"><span class=\"govuk-visually-hidden\">Unordered list</span></button>'\n }\n\n if (this.config.toolbar.numbers) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--ordered-list\" type=\"button\" data-command=\"insertOrderedList\"><span class=\"govuk-visually-hidden\">Ordered list</span></button>'\n }\n\n html += '</div>'\n return html\n }\n\n getEnhancedHtml() {\n return `${this.getToolbarHtml()}<div class=\"govuk-textarea moj-rich-text-editor__content\" contenteditable=\"true\" spellcheck=\"false\"></div>`\n }\n\n hideDefault() {\n this.$textarea.classList.add('govuk-visually-hidden')\n this.$textarea.setAttribute('aria-hidden', 'true')\n this.$textarea.setAttribute('tabindex', '-1')\n }\n\n createToolbar() {\n this.$toolbar = document.createElement('div')\n this.$toolbar.className = 'moj-rich-text-editor'\n this.$toolbar.innerHTML = this.getEnhancedHtml()\n this.$root.append(this.$toolbar)\n\n this.$content = /** @type {HTMLElement} */ (\n this.$root.querySelector('.moj-rich-text-editor__content')\n )\n\n this.$content.innerHTML = this.$textarea.value\n }\n\n configureToolbar() {\n this.$buttons = Array.from(\n /** @type {NodeListOf<HTMLButtonElement>} */\n (this.$root.querySelectorAll('.moj-rich-text-editor__toolbar-button'))\n )\n\n this.$buttons.forEach(($button, index) => {\n $button.setAttribute('tabindex', !index ? '0' : '-1')\n $button.addEventListener('click', this.onButtonClick.bind(this))\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onButtonClick(event) {\n if (!(event.currentTarget instanceof HTMLElement)) {\n return\n }\n\n document.execCommand(\n event.currentTarget.getAttribute('data-command'),\n false,\n undefined\n )\n }\n\n getContent() {\n return this.$content.innerHTML\n }\n\n onEditorInput() {\n this.updateTextarea()\n }\n\n updateTextarea() {\n document.execCommand('defaultParagraphSeparator', false, 'p')\n this.$textarea.value = this.getContent()\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onLabelClick(event) {\n event.preventDefault()\n this.$content.focus()\n }\n\n static isSupported() {\n return 'contentEditable' in document.documentElement\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-rich-text-editor'\n\n /**\n * Rich text editor config\n *\n * @type {RichTextEditorConfig}\n */\n static defaults = Object.freeze({\n toolbar: {\n bold: false,\n italic: false,\n underline: false,\n bullets: true,\n numbers: true\n }\n })\n\n /**\n * Rich text editor config schema\n *\n * @satisfies {Schema<RichTextEditorConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n toolbar: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * Rich text editor config\n *\n * @typedef {object} RichTextEditorConfig\n * @property {RichTextEditorToolbar} [toolbar] - Toolbar options\n */\n\n/**\n * Rich text editor toolbar options\n *\n * @typedef {object} RichTextEditorToolbar\n * @property {boolean} [bold] - Show the bold button\n * @property {boolean} [italic] - Show the italic button\n * @property {boolean} [underline] - Show the underline button\n * @property {boolean} [bullets] - Show the bullets button\n * @property {boolean} [numbers] - Show the numbers button\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<SearchToggleConfig>}\n */\nexport class SearchToggle extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for search toggle\n * @param {SearchToggleConfig} [config] - Search toggle config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $searchContainer =\n this.config.searchContainer.element ??\n this.$root.querySelector(this.config.searchContainer.selector)\n\n const $toggleButtonContainer =\n this.config.toggleButtonContainer.element ??\n this.$root.querySelector(this.config.toggleButtonContainer.selector)\n\n if (\n !$searchContainer ||\n !$toggleButtonContainer ||\n !($searchContainer instanceof HTMLElement) ||\n !($toggleButtonContainer instanceof HTMLElement)\n ) {\n return this\n }\n\n this.$searchContainer = $searchContainer\n this.$toggleButtonContainer = $toggleButtonContainer\n\n const svg =\n '<svg viewBox=\"0 0 20 20\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" class=\"moj-search-toggle__button__icon\"><path d=\"M7.433,12.5790048 C6.06762625,12.5808611 4.75763941,12.0392925 3.79217348,11.0738265 C2.82670755,10.1083606 2.28513891,8.79837375 2.28699522,7.433 C2.28513891,6.06762625 2.82670755,4.75763941 3.79217348,3.79217348 C4.75763941,2.82670755 6.06762625,2.28513891 7.433,2.28699522 C8.79837375,2.28513891 10.1083606,2.82670755 11.0738265,3.79217348 C12.0392925,4.75763941 12.5808611,6.06762625 12.5790048,7.433 C12.5808611,8.79837375 12.0392925,10.1083606 11.0738265,11.0738265 C10.1083606,12.0392925 8.79837375,12.5808611 7.433,12.5790048 L7.433,12.5790048 Z M14.293,12.579 L13.391,12.579 L13.071,12.269 C14.2300759,10.9245158 14.8671539,9.20813198 14.866,7.433 C14.866,3.32786745 11.5381325,-1.65045755e-15 7.433,-1.65045755e-15 C3.32786745,-1.65045755e-15 -1.65045755e-15,3.32786745 -1.65045755e-15,7.433 C-1.65045755e-15,11.5381325 3.32786745,14.866 7.433,14.866 C9.208604,14.8671159 10.9253982,14.2296624 12.27,13.07 L12.579,13.39 L12.579,14.294 L18.296,20 L20,18.296 L14.294,12.579 L14.293,12.579 Z\"></path></svg>'\n\n this.$toggleButton = document.createElement('button')\n this.$toggleButton.setAttribute('class', 'moj-search-toggle__button')\n this.$toggleButton.setAttribute('type', 'button')\n this.$toggleButton.setAttribute('aria-haspopup', 'true')\n this.$toggleButton.setAttribute('aria-expanded', 'false')\n this.$toggleButton.innerHTML = `${this.config.toggleButton.text} ${svg}`\n\n this.$toggleButton.addEventListener(\n 'click',\n this.onToggleButtonClick.bind(this)\n )\n\n this.$toggleButtonContainer.append(this.$toggleButton)\n\n document.addEventListener('click', this.onDocumentClick.bind(this))\n document.addEventListener('focusin', this.onDocumentClick.bind(this))\n }\n\n showMenu() {\n this.$toggleButton.setAttribute('aria-expanded', 'true')\n this.$searchContainer.classList.remove('moj-js-hidden')\n this.$searchContainer.querySelector('input').focus()\n }\n\n hideMenu() {\n this.$searchContainer.classList.add('moj-js-hidden')\n this.$toggleButton.setAttribute('aria-expanded', 'false')\n }\n\n onToggleButtonClick() {\n if (this.$toggleButton.getAttribute('aria-expanded') === 'false') {\n this.showMenu()\n } else {\n this.hideMenu()\n }\n }\n\n /**\n * @param {MouseEvent | FocusEvent} event\n */\n onDocumentClick(event) {\n if (\n event.target instanceof Node &&\n !this.$toggleButtonContainer.contains(event.target) &&\n !this.$searchContainer.contains(event.target)\n ) {\n this.hideMenu()\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-search-toggle'\n\n /**\n * Search toggle config\n *\n * @type {SearchToggleConfig}\n */\n static defaults = Object.freeze({\n searchContainer: {\n selector: '.moj-search'\n },\n toggleButton: {\n text: 'Search'\n },\n toggleButtonContainer: {\n selector: '.moj-search-toggle__toggle'\n }\n })\n\n /**\n * Search toggle config schema\n *\n * @satisfies {Schema<SearchToggleConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n searchContainer: { type: 'object' },\n toggleButton: { type: 'object' },\n toggleButtonContainer: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} SearchToggleConfig\n * @property {object} [searchContainer] - Search config\n * @property {string} [searchContainer.selector] - Selector for search container\n * @property {Element | null} [searchContainer.element] - HTML element for search container\n * @property {object} [toggleButton] - Toggle button config\n * @property {string} [toggleButton.text] - Text for toggle button\n * @property {object} [toggleButtonContainer] - Toggle button container config\n * @property {string} [toggleButtonContainer.selector] - Selector for toggle button container\n * @property {Element | null} [toggleButtonContainer.element] - HTML element for toggle button container\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<SortableTableConfig>}\n */\nexport class SortableTable extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for sortable table\n * @param {SortableTableConfig} [config] - Sortable table config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $head = $root?.querySelector('thead')\n const $body = $root?.querySelector('tbody')\n\n if (!$head || !$body) {\n return this\n }\n\n this.$head = $head\n this.$body = $body\n this.$caption = this.$root.querySelector('caption')\n\n this.$upArrow = `<svg width=\"22\" height=\"22\" focusable=\"false\" aria-hidden=\"true\" role=\"img\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M6.5625 15.5L11 6.63125L15.4375 15.5H6.5625Z\" fill=\"currentColor\"/>\n</svg>`\n this.$downArrow = `<svg width=\"22\" height=\"22\" focusable=\"false\" aria-hidden=\"true\" role=\"img\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M15.4375 7L11 15.8687L6.5625 7L15.4375 7Z\" fill=\"currentColor\"/>\n</svg>`\n this.$upDownArrow = `<svg width=\"22\" height=\"22\" focusable=\"false\" aria-hidden=\"true\" role=\"img\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M8.1875 9.5L10.9609 3.95703L13.7344 9.5H8.1875Z\" fill=\"currentColor\"/>\n<path d=\"M13.7344 12.0781L10.9609 17.6211L8.1875 12.0781H13.7344Z\" fill=\"currentColor\"/>\n</svg>`\n\n this.$headings = this.$head\n ? Array.from(this.$head.querySelectorAll('th'))\n : []\n\n this.createHeadingButtons()\n this.updateCaption()\n this.updateDirectionIndicators()\n this.createStatusBox()\n this.initialiseSortedColumn()\n\n this.$head.addEventListener('click', this.onSortButtonClick.bind(this))\n }\n\n createHeadingButtons() {\n for (const $heading of this.$headings) {\n if ($heading.hasAttribute('aria-sort')) {\n this.createHeadingButton($heading)\n }\n }\n }\n\n /**\n * @param {HTMLTableCellElement} $heading\n */\n createHeadingButton($heading) {\n const index = this.$headings.indexOf($heading)\n const $button = document.createElement('button')\n\n $button.setAttribute('type', 'button')\n $button.setAttribute('data-index', `${index}`)\n $button.textContent = $heading.textContent\n\n $heading.textContent = ''\n $heading.appendChild($button)\n }\n\n createStatusBox() {\n this.$status = document.createElement('div')\n\n this.$status.setAttribute('aria-atomic', 'true')\n this.$status.setAttribute('aria-live', 'polite')\n this.$status.setAttribute('class', 'govuk-visually-hidden')\n this.$status.setAttribute('role', 'status')\n\n this.$root.insertAdjacentElement('afterend', this.$status)\n }\n\n initialiseSortedColumn() {\n const $rows = this.getTableRowsArray()\n\n const $heading = this.$root.querySelector(\n 'th[aria-sort=\"ascending\"], th[aria-sort=\"descending\"]'\n )\n const $sortButton = $heading?.querySelector('button')\n const sortDirection = $heading?.getAttribute('aria-sort')\n\n const columnNumber = Number.parseInt(\n $sortButton?.getAttribute('data-index') ?? '0',\n 10\n )\n\n if (\n !$heading ||\n !$sortButton ||\n !(sortDirection === 'ascending' || sortDirection === 'descending')\n ) {\n return\n }\n\n const $sortedRows = this.sort($rows, columnNumber, sortDirection)\n this.addRows($sortedRows)\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onSortButtonClick(event) {\n const $target = /** @type {HTMLElement} */ (event.target)\n const $button = $target.closest('button')\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.parentElement\n ) {\n return\n }\n\n const $heading = $button.parentElement\n const sortDirection = $heading.getAttribute('aria-sort')\n\n const columnNumber = Number.parseInt(\n $button?.getAttribute('data-index') ?? '0',\n 10\n )\n\n const newSortDirection =\n sortDirection === 'none' || sortDirection === 'descending'\n ? 'ascending'\n : 'descending'\n\n const $rows = this.getTableRowsArray()\n const $sortedRows = this.sort($rows, columnNumber, newSortDirection)\n\n this.addRows($sortedRows)\n this.removeButtonStates()\n this.updateButtonState($button, newSortDirection)\n this.updateDirectionIndicators()\n }\n\n updateCaption() {\n if (!this.$caption) {\n return\n }\n\n let assistiveText = this.$caption.querySelector('.govuk-visually-hidden')\n if (assistiveText) {\n return\n }\n\n assistiveText = document.createElement('span')\n assistiveText.classList.add('govuk-visually-hidden')\n assistiveText.textContent = ' (column headers with buttons are sortable).'\n\n this.$caption.appendChild(assistiveText)\n }\n\n /**\n * @param {HTMLButtonElement} $button\n * @param {string} direction\n */\n updateButtonState($button, direction) {\n if (!(direction === 'ascending' || direction === 'descending')) {\n return\n }\n\n $button.parentElement.setAttribute('aria-sort', direction)\n let message = this.config.statusMessage\n message = message.replace(/%heading%/, $button.textContent)\n message = message.replace(/%direction%/, this.config[`${direction}Text`])\n this.$status.textContent = message\n }\n\n updateDirectionIndicators() {\n for (const $heading of this.$headings) {\n const $button = /** @type {HTMLButtonElement} */ (\n $heading.querySelector('button')\n )\n if ($heading.hasAttribute('aria-sort') && $button) {\n const direction = $heading.getAttribute('aria-sort')\n $button.querySelector('svg')?.remove()\n\n switch (direction) {\n case 'ascending':\n $button.insertAdjacentHTML('beforeend', this.$upArrow)\n break\n case 'descending':\n $button.insertAdjacentHTML('beforeend', this.$downArrow)\n break\n default:\n $button.insertAdjacentHTML('beforeend', this.$upDownArrow)\n }\n }\n }\n }\n\n removeButtonStates() {\n for (const $heading of this.$headings) {\n $heading.setAttribute('aria-sort', 'none')\n }\n }\n\n /**\n * @param {HTMLTableRowElement[]} $rows\n */\n addRows($rows) {\n for (const $row of $rows) {\n this.$body.append($row)\n }\n }\n\n getTableRowsArray() {\n return Array.from(this.$body.querySelectorAll('tr'))\n }\n\n /**\n * @param {HTMLTableRowElement[]} $rows\n * @param {number} columnNumber\n * @param {string} sortDirection\n */\n sort($rows, columnNumber, sortDirection) {\n return $rows.sort(($rowA, $rowB) => {\n const $tdA = $rowA.querySelectorAll('td, th')[columnNumber]\n const $tdB = $rowB.querySelectorAll('td, th')[columnNumber]\n\n if (\n !$tdA ||\n !$tdB ||\n !($tdA instanceof HTMLElement) ||\n !($tdB instanceof HTMLElement)\n ) {\n return 0\n }\n\n const valueA =\n sortDirection === 'ascending'\n ? this.getCellValue($tdA)\n : this.getCellValue($tdB)\n\n const valueB =\n sortDirection === 'ascending'\n ? this.getCellValue($tdB)\n : this.getCellValue($tdA)\n\n return !(typeof valueA === 'number' && typeof valueB === 'number')\n ? valueA.toString().localeCompare(valueB.toString())\n : valueA - valueB\n })\n }\n\n /**\n * @param {HTMLElement} $cell\n */\n getCellValue($cell) {\n const val = $cell.getAttribute('data-sort-value') || $cell.innerHTML\n const valAsNumber = Number(val)\n\n return Number.isFinite(valAsNumber)\n ? valAsNumber // Exclude invalid numbers, infinity etc\n : val\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-sortable-table'\n\n /**\n * Sortable table config\n *\n * @type {SortableTableConfig}\n */\n static defaults = Object.freeze({\n statusMessage: 'Sort by %heading% (%direction%)',\n ascendingText: 'ascending',\n descendingText: 'descending'\n })\n\n /**\n * Sortable table config schema\n *\n * @satisfies {Schema<SortableTableConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n statusMessage: { type: 'string' },\n ascendingText: { type: 'string' },\n descendingText: { type: 'string' }\n }\n })\n )\n}\n\n/**\n * Sortable table config\n *\n * @typedef {object} SortableTableConfig\n * @property {string} [statusMessage] - Status message\n * @property {string} [ascendingText] - Ascending text\n * @property {string} [descendingText] - Descending text\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { createAll } from 'govuk-frontend'\n\nimport { version } from './common/moj-frontend-version.mjs'\nimport { AddAnother } from './components/add-another/add-another.mjs'\nimport { Alert } from './components/alert/alert.mjs'\nimport { ButtonMenu } from './components/button-menu/button-menu.mjs'\nimport { DatePicker } from './components/date-picker/date-picker.mjs'\nimport { PdsHeader } from './components/domain-specific/probation/header/header.mjs'\nimport { FilterToggleButton } from './components/filter-toggle-button/filter-toggle-button.mjs'\nimport { FormValidator } from './components/form-validator/form-validator.mjs'\nimport { MultiFileUpload } from './components/multi-file-upload/multi-file-upload.mjs'\nimport { MultiSelect } from './components/multi-select/multi-select.mjs'\nimport { PasswordReveal } from './components/password-reveal/password-reveal.mjs'\nimport { RichTextEditor } from './components/rich-text-editor/rich-text-editor.mjs'\nimport { SearchToggle } from './components/search-toggle/search-toggle.mjs'\nimport { SortableTable } from './components/sortable-table/sortable-table.mjs'\n\n/**\n * @param {Config} [config]\n */\nfunction initAll(config) {\n for (const Component of [\n AddAnother,\n Alert,\n ButtonMenu,\n DatePicker,\n MultiSelect,\n PasswordReveal,\n RichTextEditor,\n SearchToggle,\n SortableTable,\n PdsHeader\n ]) {\n createAll(Component, undefined, config)\n }\n}\n\nexport {\n initAll,\n version,\n\n // Components\n AddAnother,\n Alert,\n ButtonMenu,\n DatePicker,\n FilterToggleButton,\n FormValidator,\n MultiFileUpload,\n MultiSelect,\n PasswordReveal,\n RichTextEditor,\n SearchToggle,\n SortableTable,\n PdsHeader\n}\n\n/**\n * @typedef {Parameters<typeof GOVUKFrontend.initAll>[0]} Config\n */\n\n/**\n * @import * as GOVUKFrontend from 'govuk-frontend'\n */\n"],"names":["isSupported","$scope","document","body","classList","contains","isObject","option","Array","isArray","formatErrorMessage","Component","message","moduleName","GOVUKFrontendError","Error","constructor","args","super","this","name","SupportError","supportMessage","HTMLScriptElement","prototype","ConfigError","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","$root","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","HTMLElement","hasAttribute","isInitialised","configOverride","Symbol","for","ConfigurableComponent","param","config","_config","defaults","datasetConfig","dataset","schema","out","entries","Object","properties","entry","namespace","property","field","toString","normaliseString","type","extractConfigByNamespace","normaliseDataset","mergeConfigs","value","trimmedValue","trim","output","outputType","includes","length","isFinite","Number","configObjects","formattedConfigObject","configObject","key","keys","override","newObject","current","keyParts","split","index","createAll","createAllOptions","onError","_createAllOptions$sco","scope","$elements","querySelectorAll","from","map","$element","error","console","log","filter","Boolean","version","AddAnother","addEventListener","onRemoveButtonClick","bind","onAddButtonClick","forEach","$button","HTMLButtonElement","event","target","$items","getItems","$item","getNewItem","updateAttributes","resetItem","$firstItem","hasRemoveButton","createRemoveButton","after","$input","querySelector","HTMLInputElement","focus","item","cloneNode","isValidInputElement","getAttribute","id","originalId","replace","$label","parentElement","closest","HTMLLabelElement","htmlFor","createElement","add","textContent","append","HTMLSelectElement","selectedIndex","HTMLTextAreaElement","checked","remove","focusHeading","$heading","setFocus","options","_options$onBeforeFocu","isFocusable","onBlur","_options$onBlur","call","removeAttribute","once","onBeforeFocus","removeAttributeValue","attr","re","m","RegExp","match","addAttributeValue","test","Alert","disableAutoFocus","$dismissButton","dismissible","innerHTML","dismissText","Node","dimiss","$elementToRecieveFocus","focusOnDismissSelector","$nextSibling","nextElementSibling","matches","selector","$sibling","previousElementSibling","getPreviousSibling","$currentElement","findNearestMatchingElement","freeze","ButtonMenu","children","className","startsWith","buttonClasses","initMenu","$menu","createMenu","insertAdjacentHTML","toggleTemplate","setupMenuItems","$menuToggle","toggleMenu","handleKeyDown","closeMenu","hidden","alignMenu","appendChild","firstChild","$menuItem","$listItem","insertBefore","tagName","setTimeout","buttonText","isOpen","preventDefault","focusIndex","detail","openMenu","focusItem","moveFocus","currentFocusIndex","$activeElement","activeElement","$menuItems","HTMLAnchorElement","indexOf","DatePicker","_this$config$input$el","input","dayLabels","monthLabels","currentDate","Date","setHours","calendarDays","excludedDates","excludedDays","buttonClass","selectedDayButtonClass","currentDayButtonClass","todayButtonClass","setOptions","initControls","$dialog","createDialog","createCalendarHeaders","$componentWrapper","$inputWrapper","insertAdjacentElement","$calendarButton","$dialogTitle","createCalendar","$prevMonthButton","$prevYearButton","$nextMonthButton","$nextYearButton","$cancelButton","$okButton","focusPreviousMonth","focusPreviousYear","focusNextMonth","focusNextYear","closeDialog","selectDate","$dialogButtons","$firstButtonInDialog","$lastButtonInDialog","firstButtonKeydown","lastButtonKeydown","toggleDialog","stopPropagation","backgroundClick","updateCalendar","titleId","dialogTemplate","$tbody","dayCount","i","$row","insertRow","j","$cell","$dateButton","calendarDay","DSCalendarDay","push","day","html","substring","leadingZeros","ret","setMinAndMaxDatesOnCalendar","setExcludedDates","setExcludedDays","setWeekStartDay","minDate","formattedDateFromString","maxDate","parseDateRangeString","reduce","dates","items","concat","date","datestring","startDate","endDate","d","getTime","setDate","getDate","weekDays","toLowerCase","weekStartDay","unshift","pop","weekStartDayParam","isExcludedDate","excludedDate","toDateString","getDay","dateString","fallback","formattedDate","dateFormatPattern","exec","month","year","formattedDateFromDate","getMonth","getFullYear","formattedDateHuman","shiftKey","firstOfMonth","dayOfWeek","thisDay","disabled","update","setCurrentDate","calendarDayDate","today","inputDate","enabledDays","window","getComputedStyle","display","innerText","changeEvent","Event","bubbles","cancelable","dispatchEvent","openDialog","offsetWidth","style","right","top","offsetHeight","goToDate","focusNextDay","focusPreviousDay","focusNextWeek","focusPreviousWeek","focusFirstDayOfWeek","firstDayOfWeekIndex","diff","focusLastDayOfWeek","lastDayOfWeekIndex","setMonth","setFullYear","row","column","picker","keyPress","click","label","accessibleLabel","calendarNavKey","PdsHeader","initHeader","$tabOpenClass","$userToggle","$userMenu","hideFallbackLinks","closeTabs","_event","tabTuples","toggle","menu","textForShow","textForHide","$userLink","FilterToggleButton","_this$config$toggleBu","_this$config$closeBut","$toggleButtonContainer","toggleButtonContainer","$closeButtonContainer","closeButtonContainer","createToggleButton","setupResponsiveChecks","startHidden","hideMenu","mq","matchMedia","bigModeMediaQuery","addListener","checkMode","$menuButton","toggleButton","classes","showText","onMenuButtonClick","enableBigMode","enableSmallMode","showMenu","removeCloseButton","addCloseButton","$closeButton","closeButton","text","onCloseClick","hideText","FormValidator","$summary","summary","errors","validators","originalTitle","title","onSubmit","escapeHtml","string","String","entityMap","resetTitle","updateTitle","showSummary","getSummaryHtml","fieldName","hideSummary","removeInlineErrors","validate","showInlineErrors","showInlineError","$errorSpan","$control","$fieldset","$fieldContainer","$legend","removeInlineError","addValidator","rules","elements","namedItem","validator","validatorReturnValue","method","params","MultiFileUpload","_this$config$feedback","$feedbackContainer","feedbackContainer","setupFileInput","setupDropzone","setupLabel","setupStatusBox","onFileDeleteClick","$dropzone","onDragOver","onDragLeave","onDrop","$fileInput","replaceWith","dropzoneButtonText","$hint","dropzoneHintText","onFileChange","onFileFocus","onFileBlur","$status","uploadStatusText","uploadFiles","dataTransfer","files","file","uploadFile","getSuccessHtml","success","messageHtml","getErrorHtml","getFileRow","getDeleteButton","filename","originalname","hooks","entryHook","$message","$actions","$progress","formData","FormData","xhr","XMLHttpRequest","response","statusText","errorHook","responseText","onLoad","status","messageText","exitHook","upload","lengthComputable","percentComplete","Math","round","loaded","total","open","uploadUrl","responseType","send","$rows","$rowDelete","find","deleteHook","undefined","deleteUrl","setRequestHeader","JSON","stringify","isDragAndDropSupported","isFormDataSupported","isFileApiSupported","ondrop","MultiSelect","_this$config$checkbox","$container","idPrefix","$checkboxes","checkboxes","setupToggle","$toggleButton","$toggle","onButtonClick","onCheckboxClick","$span","uncheckAll","checkAll","PasswordReveal","createButton","$group","RichTextEditor","$textarea","createToolbar","hideDefault","configureToolbar","left","up","down","$content","onEditorInput","onLabelClick","$toolbar","onToolbarKeydown","$focusableButton","keyCode","$buttons","button","$nextButton","$previousButton","getToolbarHtml","toolbar","bold","italic","underline","bullets","numbers","getEnhancedHtml","currentTarget","execCommand","getContent","updateTextarea","documentElement","SearchToggle","_this$config$searchCo","$searchContainer","searchContainer","onToggleButtonClick","onDocumentClick","SortableTable","$head","$body","$caption","$upArrow","$downArrow","$upDownArrow","$headings","createHeadingButtons","updateCaption","updateDirectionIndicators","createStatusBox","initialiseSortedColumn","onSortButtonClick","createHeadingButton","_$sortButton$getAttri","getTableRowsArray","$sortButton","sortDirection","columnNumber","parseInt","$sortedRows","sort","addRows","_$button$getAttribute","newSortDirection","removeButtonStates","updateButtonState","assistiveText","direction","statusMessage","_$button$querySelecto","$rowA","$rowB","$tdA","$tdB","valueA","getCellValue","valueB","localeCompare","val","valAsNumber","initAll","ascendingText","descendingText"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]}
1
+ {"version":3,"file":"moj-frontend.min.js","sources":["../../node_modules/govuk-frontend/dist/govuk/common/index.mjs","../../node_modules/govuk-frontend/dist/govuk/errors/index.mjs","../../node_modules/govuk-frontend/dist/govuk/component.mjs","../../node_modules/govuk-frontend/dist/govuk/common/configuration.mjs","../../node_modules/govuk-frontend/dist/govuk/init.mjs","../../src/moj/common/moj-frontend-version.mjs","../../src/moj/components/add-another/add-another.mjs","../../src/moj/common/index.mjs","../../src/moj/helpers.mjs","../../src/moj/components/alert/alert.mjs","../../src/moj/components/button-menu/button-menu.mjs","../../src/moj/components/date-picker/date-picker.mjs","../../src/moj/components/domain-specific/probation/header/header.mjs","../../src/moj/components/filter-toggle-button/filter-toggle-button.mjs","../../src/moj/components/form-validator/form-validator.mjs","../../src/moj/components/multi-file-upload/multi-file-upload.mjs","../../src/moj/components/multi-select/multi-select.mjs","../../src/moj/components/password-reveal/password-reveal.mjs","../../src/moj/components/rich-text-editor/rich-text-editor.mjs","../../src/moj/components/search-toggle/search-toggle.mjs","../../src/moj/components/sortable-table/sortable-table.mjs","../../src/moj/all.mjs"],"sourcesContent":["function getFragmentFromUrl(url) {\n if (!url.includes('#')) {\n return undefined;\n }\n return url.split('#').pop();\n}\nfunction getBreakpoint(name) {\n const property = `--govuk-frontend-breakpoint-${name}`;\n const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);\n return {\n property,\n value: value || undefined\n };\n}\nfunction setFocus($element, options = {}) {\n var _options$onBeforeFocu;\n const isFocusable = $element.getAttribute('tabindex');\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1');\n }\n function onFocus() {\n $element.addEventListener('blur', onBlur, {\n once: true\n });\n }\n function onBlur() {\n var _options$onBlur;\n (_options$onBlur = options.onBlur) == null || _options$onBlur.call($element);\n if (!isFocusable) {\n $element.removeAttribute('tabindex');\n }\n }\n $element.addEventListener('focus', onFocus, {\n once: true\n });\n (_options$onBeforeFocu = options.onBeforeFocus) == null || _options$onBeforeFocu.call($element);\n $element.focus();\n}\nfunction isInitialised($root, moduleName) {\n return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);\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 */\nfunction isSupported($scope = document.body) {\n if (!$scope) {\n return false;\n }\n return $scope.classList.contains('govuk-frontend-supported');\n}\nfunction isArray(option) {\n return Array.isArray(option);\n}\nfunction isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option);\n}\nfunction formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`;\n}\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n/**\n * @import { ObjectNested } from './configuration.mjs'\n */\n\nexport { formatErrorMessage, getBreakpoint, getFragmentFromUrl, isInitialised, isObject, isSupported, setFocus };\n//# sourceMappingURL=index.mjs.map\n","import { formatErrorMessage } from '../common/index.mjs';\n\nclass GOVUKFrontendError extends Error {\n constructor(...args) {\n super(...args);\n this.name = 'GOVUKFrontendError';\n }\n}\nclass SupportError extends GOVUKFrontendError {\n /**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support\n */\n constructor($scope = document.body) {\n const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';\n super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type=\"module\">`');\n this.name = 'SupportError';\n }\n}\nclass ConfigError extends GOVUKFrontendError {\n constructor(...args) {\n super(...args);\n this.name = 'ConfigError';\n }\n}\nclass ElementError extends GOVUKFrontendError {\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';\n if (typeof messageOrOptions === 'object') {\n const {\n component,\n identifier,\n element,\n expectedType\n } = messageOrOptions;\n message = identifier;\n message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';\n message = formatErrorMessage(component, message);\n }\n super(message);\n this.name = 'ElementError';\n }\n}\nclass InitError extends GOVUKFrontendError {\n constructor(componentOrMessage) {\n const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\\`$root\\`) already initialised`);\n super(message);\n this.name = 'InitError';\n }\n}\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n\nexport { ConfigError, ElementError, GOVUKFrontendError, InitError, SupportError };\n//# sourceMappingURL=index.mjs.map\n","import { isInitialised, isSupported } from './common/index.mjs';\nimport { InitError, ElementError, SupportError } from './errors/index.mjs';\n\nclass Component {\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {RootElementType} - the root element of component\n */\n get $root() {\n return this._$root;\n }\n constructor($root) {\n this._$root = void 0;\n const childConstructor = this.constructor;\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`);\n }\n if (!($root instanceof childConstructor.elementType)) {\n throw new ElementError({\n element: $root,\n component: childConstructor,\n identifier: 'Root element (`$root`)',\n expectedType: childConstructor.elementType.name\n });\n } else {\n this._$root = $root;\n }\n childConstructor.checkSupport();\n this.checkInitialised();\n const moduleName = childConstructor.moduleName;\n this.$root.setAttribute(`data-${moduleName}-init`, '');\n }\n checkInitialised() {\n const constructor = this.constructor;\n const moduleName = constructor.moduleName;\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor);\n }\n }\n static checkSupport() {\n if (!isSupported()) {\n throw new SupportError();\n }\n }\n}\n\n/**\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n */\n\n/**\n * @typedef {typeof Component & ChildClass} ChildClassConstructor\n */\nComponent.elementType = HTMLElement;\n\nexport { Component };\n//# sourceMappingURL=component.mjs.map\n","import { Component } from '../component.mjs';\nimport { ConfigError } from '../errors/index.mjs';\nimport { isObject, formatErrorMessage } from './index.mjs';\n\nconst configOverride = Symbol.for('configOverride');\nclass ConfigurableComponent extends Component {\n [configOverride](param) {\n return {};\n }\n\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {ConfigurationType} - the root element of component\n */\n get config() {\n return this._config;\n }\n constructor($root, config) {\n super($root);\n this._config = void 0;\n const childConstructor = this.constructor;\n if (!isObject(childConstructor.defaults)) {\n throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));\n }\n const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);\n this._config = mergeConfigs(childConstructor.defaults, config != null ? config : {}, this[configOverride](datasetConfig), datasetConfig);\n }\n}\nfunction normaliseString(value, property) {\n const trimmedValue = value ? value.trim() : '';\n let output;\n let outputType = property == null ? void 0 : property.type;\n if (!outputType) {\n if (['true', 'false'].includes(trimmedValue)) {\n outputType = 'boolean';\n }\n if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {\n outputType = 'number';\n }\n }\n switch (outputType) {\n case 'boolean':\n output = trimmedValue === 'true';\n break;\n case 'number':\n output = Number(trimmedValue);\n break;\n default:\n output = value;\n }\n return output;\n}\nfunction normaliseDataset(Component, dataset) {\n if (!isObject(Component.schema)) {\n throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));\n }\n const out = {};\n const entries = Object.entries(Component.schema.properties);\n for (const entry of entries) {\n const [namespace, property] = entry;\n const field = namespace.toString();\n if (field in dataset) {\n out[field] = normaliseString(dataset[field], property);\n }\n if ((property == null ? void 0 : property.type) === 'object') {\n out[field] = extractConfigByNamespace(Component.schema, dataset, namespace);\n }\n }\n return out;\n}\nfunction mergeConfigs(...configObjects) {\n const formattedConfigObject = {};\n for (const configObject of configObjects) {\n for (const key of Object.keys(configObject)) {\n const option = formattedConfigObject[key];\n const override = configObject[key];\n if (isObject(option) && isObject(override)) {\n formattedConfigObject[key] = mergeConfigs(option, override);\n } else {\n formattedConfigObject[key] = override;\n }\n }\n }\n return formattedConfigObject;\n}\nfunction validateConfig(schema, config) {\n const validationErrors = [];\n for (const [name, conditions] of Object.entries(schema)) {\n const errors = [];\n if (Array.isArray(conditions)) {\n for (const {\n required,\n errorMessage\n } of conditions) {\n if (!required.every(key => !!config[key])) {\n errors.push(errorMessage);\n }\n }\n if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {\n validationErrors.push(...errors);\n }\n }\n }\n return validationErrors;\n}\nfunction extractConfigByNamespace(schema, dataset, namespace) {\n const property = schema.properties[namespace];\n if ((property == null ? void 0 : property.type) !== 'object') {\n return;\n }\n const newObject = {\n [namespace]: {}\n };\n for (const [key, value] of Object.entries(dataset)) {\n let current = newObject;\n const keyParts = key.split('.');\n for (const [index, name] of keyParts.entries()) {\n if (isObject(current)) {\n if (index < keyParts.length - 1) {\n if (!isObject(current[name])) {\n current[name] = {};\n }\n current = current[name];\n } else if (key !== namespace) {\n current[name] = normaliseString(value);\n }\n }\n }\n }\n return newObject[namespace];\n}\n/**\n * Schema for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} Schema\n * @property {Record<keyof ConfigurationType, SchemaProperty | undefined>} properties - Schema properties\n * @property {SchemaCondition<ConfigurationType>[]} [anyOf] - List of schema conditions\n */\n/**\n * Schema property for component config\n *\n * @typedef {object} SchemaProperty\n * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type\n */\n/**\n * Schema condition for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} SchemaCondition\n * @property {(keyof ConfigurationType)[]} required - List of required config fields\n * @property {string} errorMessage - Error message when required config fields not provided\n */\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n * @property {Schema<ConfigurationType>} [schema] - The schema of the component configuration\n * @property {ConfigurationType} [defaults] - The default values of the configuration of the component\n */\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>\n */\n\nexport { ConfigurableComponent, configOverride, extractConfigByNamespace, mergeConfigs, normaliseDataset, normaliseString, validateConfig };\n//# sourceMappingURL=configuration.mjs.map\n","import { 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 { Header } from './components/header/header.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 { 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 & { scope?: Element, onError?: OnErrorCallback<CompatibleClass> }} [config] - Config for all components (with optional scope)\n */\nfunction initAll(config) {\n var _config$scope;\n config = typeof config !== 'undefined' ? config : {};\n if (!isSupported()) {\n if (config.onError) {\n config.onError(new SupportError(), {\n config\n });\n } else {\n console.log(new SupportError());\n }\n return;\n }\n const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];\n const options = {\n scope: (_config$scope = config.scope) != null ? _config$scope : document,\n onError: config.onError\n };\n components.forEach(([Component, config]) => {\n createAll(Component, config, 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 | CreateAllOptions<ComponentClass> } [createAllOptions] - 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, createAllOptions) {\n let $scope = document;\n let onError;\n if (typeof createAllOptions === 'object') {\n var _createAllOptions$sco;\n createAllOptions = createAllOptions;\n $scope = (_createAllOptions$sco = createAllOptions.scope) != null ? _createAllOptions$sco : $scope;\n onError = createAllOptions.onError;\n }\n if (typeof createAllOptions === 'function') {\n onError = createAllOptions;\n }\n if (createAllOptions instanceof HTMLElement) {\n $scope = createAllOptions;\n }\n const $elements = $scope.querySelectorAll(`[data-module=\"${Component.moduleName}\"]`);\n if (!isSupported()) {\n if (onError) {\n onError(new SupportError(), {\n component: Component,\n config\n });\n } else {\n console.log(new SupportError());\n }\n return [];\n }\n return Array.from($elements).map($element => {\n try {\n return typeof config !== 'undefined' ? new Component($element, config) : new Component($element);\n } catch (error) {\n if (onError) {\n onError(error, {\n element: $element,\n component: Component,\n config\n });\n } else {\n console.log(error);\n }\n return null;\n }\n }).filter(Boolean);\n}\n/**\n * @typedef {{new (...args: any[]): any, moduleName: string}} CompatibleClass\n */\n/**\n * Config for all components via `initAll()`\n *\n * @typedef {object} Config\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 * 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 * Component config keys, e.g. `accordion` and `characterCount`\n *\n * @typedef {keyof Config} ConfigKey\n */\n/**\n * @template {CompatibleClass} ComponentClass\n * @typedef {ConstructorParameters<ComponentClass>[1]} ComponentConfig\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 {ComponentConfig<ComponentClass>} config - Config supplied to component\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 * @template {CompatibleClass} ComponentClass\n * @typedef {object} CreateAllOptions\n * @property {Element | Document} [scope] - scope of the document to search within\n * @property {OnErrorCallback<ComponentClass>} [onError] - callback function if error throw by component on init\n */\n\nexport { createAll, initAll };\n//# sourceMappingURL=init.mjs.map\n","/*\n * This variable is automatically overwritten during builds and releases.\n * It doesn't need to be updated manually.\n */\n\n/**\n * MoJ Frontend release version\n *\n * {@link https://github.com/ministryofjustice/moj-frontend/releases}\n */\nexport const version = 'development'\n","import { Component } from 'govuk-frontend'\n\nexport class AddAnother extends Component {\n /**\n * @param {Element | null} $root - HTML element to use for add another\n */\n constructor($root) {\n super($root)\n\n this.$root.addEventListener('click', this.onRemoveButtonClick.bind(this))\n this.$root.addEventListener('click', this.onAddButtonClick.bind(this))\n\n const $buttons = this.$root.querySelectorAll(\n '.moj-add-another__add-button, moj-add-another__remove-button'\n )\n\n $buttons.forEach(($button) => {\n if (!($button instanceof HTMLButtonElement)) {\n return\n }\n\n $button.type = 'button'\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onAddButtonClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-add-another__add-button')\n ) {\n return\n }\n\n const $items = this.getItems()\n const $item = this.getNewItem()\n\n if (!$item || !($item instanceof HTMLElement)) {\n return\n }\n\n this.updateAttributes($item, $items.length)\n this.resetItem($item)\n\n const $firstItem = $items[0]\n if (!this.hasRemoveButton($firstItem)) {\n this.createRemoveButton($firstItem)\n }\n\n $items[$items.length - 1].after($item)\n\n const $input = $item.querySelector('input, textarea, select')\n if ($input && $input instanceof HTMLInputElement) {\n $input.focus()\n }\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n hasRemoveButton($item) {\n return $item.querySelectorAll('.moj-add-another__remove-button').length\n }\n\n getItems() {\n if (!this.$root) {\n return []\n }\n\n const $items = Array.from(\n this.$root.querySelectorAll('.moj-add-another__item')\n )\n\n return $items.filter((item) => item instanceof HTMLElement)\n }\n\n getNewItem() {\n const $items = this.getItems()\n const $item = $items[0].cloneNode(true)\n\n if (!$item || !($item instanceof HTMLElement)) {\n return\n }\n\n if (!this.hasRemoveButton($item)) {\n this.createRemoveButton($item)\n }\n\n return $item\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n * @param {number} index - Add another item index\n */\n updateAttributes($item, index) {\n $item.querySelectorAll('[data-name]').forEach(($input) => {\n if (!this.isValidInputElement($input)) {\n return\n }\n\n const name = $input.getAttribute('data-name') || ''\n const id = $input.getAttribute('data-id') || ''\n const originalId = $input.id\n\n $input.name = name.replace(/%index%/, `${index}`)\n $input.id = id.replace(/%index%/, `${index}`)\n\n const $label =\n $input.parentElement.querySelector('label') ||\n $input.closest('label') ||\n $item.querySelector(`[for=\"${originalId}\"]`)\n\n if ($label && $label instanceof HTMLLabelElement) {\n $label.htmlFor = $input.id\n }\n })\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n createRemoveButton($item) {\n const $button = document.createElement('button')\n $button.type = 'button'\n\n $button.classList.add(\n 'govuk-button',\n 'govuk-button--secondary',\n 'moj-add-another__remove-button'\n )\n\n $button.textContent = 'Remove'\n\n $item.append($button)\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n resetItem($item) {\n $item.querySelectorAll('[data-name], [data-id]').forEach(($input) => {\n if (!this.isValidInputElement($input)) {\n return\n }\n\n if ($input instanceof HTMLSelectElement) {\n $input.selectedIndex = -1\n $input.value = ''\n } else if ($input instanceof HTMLTextAreaElement) {\n $input.value = ''\n } else {\n switch ($input.type) {\n case 'checkbox':\n case 'radio':\n $input.checked = false\n break\n default:\n $input.value = ''\n }\n }\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onRemoveButtonClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-add-another__remove-button')\n ) {\n return\n }\n\n $button.closest('.moj-add-another__item').remove()\n\n const $items = this.getItems()\n\n if ($items.length === 1) {\n $items[0].querySelector('.moj-add-another__remove-button').remove()\n }\n\n $items.forEach(($item, index) => {\n this.updateAttributes($item, index)\n })\n\n this.focusHeading()\n }\n\n focusHeading() {\n const $heading = this.$root.querySelector('.moj-add-another__heading')\n\n if ($heading && $heading instanceof HTMLElement) {\n $heading.focus()\n }\n }\n\n /**\n * @param {Element} $input - the input to validate\n */\n isValidInputElement($input) {\n return (\n $input instanceof HTMLInputElement ||\n $input instanceof HTMLSelectElement ||\n $input instanceof HTMLTextAreaElement\n )\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-add-another'\n}\n","/**\n * GOV.UK Frontend helpers\n *\n * @todo Import from GOV.UK Frontend\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 * @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 * @param {Element} $element - Element to remove attribute value from\n * @param {string} attr - Attribute name\n * @param {string} value - Attribute value\n */\nexport function removeAttributeValue($element, attr, value) {\n let re, m\n if ($element.getAttribute(attr)) {\n if ($element.getAttribute(attr) === value) {\n $element.removeAttribute(attr)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n m = $element.getAttribute(attr).match(re)\n if (m && m.length === 3) {\n $element.setAttribute(\n attr,\n $element.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')\n )\n }\n }\n }\n}\n\n/**\n * @param {Element} $element - Element to add attribute value to\n * @param {string} attr - Attribute name\n * @param {string} value - Attribute value\n */\nexport function addAttributeValue($element, attr, value) {\n let re\n if (!$element.getAttribute(attr)) {\n $element.setAttribute(attr, value)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n if (!re.test($element.getAttribute(attr))) {\n $element.setAttribute(attr, `${$element.getAttribute(attr)} ${value}`)\n }\n }\n}\n\n/**\n * Find an elements next sibling\n *\n * Utility function to find an elements next sibling matching the provided\n * selector.\n *\n * @param {Element | null} $element - Element to find siblings for\n * @param {string} [selector] - selector for required sibling\n */\nexport function getNextSibling($element, selector) {\n if (!$element || !($element instanceof HTMLElement)) {\n return\n }\n\n // Get the next sibling element\n let $sibling = $element.nextElementSibling\n\n // If there's no selector, return the first sibling\n if (!selector) return $sibling\n\n // If the sibling matches our selector, use it\n // If not, jump to the next sibling and continue the loop\n while ($sibling) {\n if ($sibling.matches(selector)) return $sibling\n $sibling = $sibling.nextElementSibling\n }\n}\n\n/**\n * Find an elements preceding sibling\n *\n * Utility function to find an elements previous sibling matching the provided\n * selector.\n *\n * @param {Element | null} $element - Element to find siblings for\n * @param {string} [selector] - selector for required sibling\n */\nexport function getPreviousSibling($element, selector) {\n if (!$element || !($element instanceof HTMLElement)) {\n return\n }\n\n // Get the previous sibling element\n let $sibling = $element.previousElementSibling\n\n // If there's no selector, return the first sibling\n if (!selector) return $sibling\n\n // If the sibling matches our selector, use it\n // If not, jump to the next sibling and continue the loop\n while ($sibling) {\n if ($sibling.matches(selector)) return $sibling\n $sibling = $sibling.previousElementSibling\n }\n}\n\n/**\n * @param {Element | null} $element\n * @param {string} [selector]\n */\nexport function findNearestMatchingElement($element, selector) {\n // If no element or selector is provided, return\n if (!$element || !($element instanceof HTMLElement) || !selector) {\n return\n }\n\n // Start with the current element\n let $currentElement = $element\n\n while ($currentElement) {\n // First check the current element\n if ($currentElement.matches(selector)) {\n return $currentElement\n }\n\n // Check all previous siblings\n let $sibling = $currentElement.previousElementSibling\n while ($sibling) {\n // Check if the sibling itself is a heading\n if ($sibling.matches(selector)) {\n return $sibling\n }\n $sibling = $sibling.previousElementSibling\n }\n\n // If no match found in siblings, move up to parent\n $currentElement = $currentElement.parentElement\n }\n}\n","import { ConfigurableComponent } from 'govuk-frontend'\n\nimport { setFocus } from '../../common/index.mjs'\nimport {\n findNearestMatchingElement,\n getPreviousSibling\n} from '../../helpers.mjs'\n\n/**\n * @augments {ConfigurableComponent<AlertConfig>}\n */\nexport class Alert extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for alert\n * @param {AlertConfig} [config] - Alert config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n /**\n * Focus the alert\n *\n * If `role=\"alert\"` is set, focus the element to help some assistive\n * technologies prioritise announcing it.\n *\n * You can turn off the auto-focus functionality by setting\n * `data-disable-auto-focus=\"true\"` in the component HTML. You might wish to\n * do this based on user research findings, or to avoid a clash with another\n * element which should be focused when the page loads.\n */\n if (\n this.$root.getAttribute('role') === 'alert' &&\n !this.config.disableAutoFocus\n ) {\n setFocus(this.$root)\n }\n\n this.$dismissButton = this.$root.querySelector('.moj-alert__dismiss')\n\n if (this.config.dismissible && this.$dismissButton) {\n this.$dismissButton.innerHTML = this.config.dismissText\n this.$dismissButton.removeAttribute('hidden')\n\n this.$root.addEventListener('click', (event) => {\n if (\n event.target instanceof Node &&\n this.$dismissButton.contains(event.target)\n ) {\n this.dimiss()\n }\n })\n }\n }\n\n /**\n * Handle dismissing the alert\n */\n dimiss() {\n let $elementToRecieveFocus\n\n // If a selector has been provided, attempt to find that element\n if (this.config.focusOnDismissSelector) {\n $elementToRecieveFocus = document.querySelector(\n this.config.focusOnDismissSelector\n )\n }\n\n // Is the next sibling another alert\n if (!$elementToRecieveFocus) {\n const $nextSibling = this.$root.nextElementSibling\n if ($nextSibling && $nextSibling.matches('.moj-alert')) {\n $elementToRecieveFocus = $nextSibling\n }\n }\n\n // Else try to find any preceding sibling alert or heading\n if (!$elementToRecieveFocus) {\n $elementToRecieveFocus = getPreviousSibling(\n this.$root,\n '.moj-alert, h1, h2, h3, h4, h5, h6'\n )\n }\n\n // Else find the closest ancestor heading, or fallback to main, or last resort\n // use the body element\n if (!$elementToRecieveFocus) {\n $elementToRecieveFocus = findNearestMatchingElement(\n this.$root,\n 'h1, h2, h3, h4, h5, h6, main, body'\n )\n }\n\n // If we have an element, place focus on it\n if ($elementToRecieveFocus instanceof HTMLElement) {\n setFocus($elementToRecieveFocus)\n }\n\n // Remove the alert\n this.$root.remove()\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-alert'\n\n /**\n * Alert default config\n *\n * @type {AlertConfig}\n */\n static defaults = Object.freeze({\n dismissible: false,\n dismissText: 'Dismiss',\n disableAutoFocus: false\n })\n\n /**\n * Alert config schema\n *\n * @satisfies {Schema<AlertConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n dismissible: { type: 'boolean' },\n dismissText: { type: 'string' },\n disableAutoFocus: { type: 'boolean' },\n focusOnDismissSelector: { type: 'string' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} AlertConfig\n * @property {boolean} [dismissible=false] - Can the alert be dismissed by the user\n * @property {string} [dismissText=Dismiss] - the label text for the dismiss button\n * @property {boolean} [disableAutoFocus=false] - whether the alert will be autofocused\n * @property {string} [focusOnDismissSelector] - CSS Selector for element to be focused on dismiss\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<ButtonMenuConfig>}\n */\nexport class ButtonMenu extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for button menu\n * @param {ButtonMenuConfig} [config] - Button menu config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n // If only one button is provided, don't initiate a menu and toggle button\n // if classes have been provided for the toggleButton, apply them to the single item\n if (this.$root.children.length === 1) {\n const $button = this.$root.children[0]\n\n $button.classList.forEach((className) => {\n if (className.startsWith('govuk-button-')) {\n $button.classList.remove(className)\n }\n\n $button.classList.remove('moj-button-menu__item')\n $button.classList.add('moj-button-menu__single-button')\n })\n\n if (this.config.buttonClasses) {\n $button.classList.add(...this.config.buttonClasses.split(' '))\n }\n }\n // Otherwise initialise a button menu\n if (this.$root.children.length > 1) {\n this.initMenu()\n }\n }\n\n initMenu() {\n this.$menu = this.createMenu()\n this.$root.insertAdjacentHTML('afterbegin', this.toggleTemplate())\n this.setupMenuItems()\n\n this.$menuToggle = this.$root.querySelector(':scope > button')\n this.$items = this.$menu.querySelectorAll('a, button')\n\n this.$menuToggle.addEventListener('click', (event) => {\n this.toggleMenu(event)\n })\n\n this.$root.addEventListener('keydown', (event) => {\n this.handleKeyDown(event)\n })\n\n document.addEventListener('click', (event) => {\n if (event.target instanceof Node && !this.$root.contains(event.target)) {\n this.closeMenu(false)\n }\n })\n }\n\n createMenu() {\n const $menu = document.createElement('ul')\n\n $menu.setAttribute('role', 'list')\n $menu.hidden = true\n $menu.classList.add('moj-button-menu__wrapper')\n\n if (this.config.alignMenu === 'right') {\n $menu.classList.add('moj-button-menu__wrapper--right')\n }\n\n this.$root.appendChild($menu)\n\n while (this.$root.firstChild !== $menu) {\n $menu.appendChild(this.$root.firstChild)\n }\n\n return $menu\n }\n\n setupMenuItems() {\n Array.from(this.$menu.children).forEach(($menuItem) => {\n // wrap item in li tag\n const $listItem = document.createElement('li')\n this.$menu.insertBefore($listItem, $menuItem)\n $listItem.appendChild($menuItem)\n\n $menuItem.setAttribute('tabindex', '-1')\n\n if ($menuItem.tagName === 'BUTTON') {\n $menuItem.setAttribute('type', 'button')\n }\n\n $menuItem.classList.forEach((className) => {\n if (className.startsWith('govuk-button')) {\n $menuItem.classList.remove(className)\n }\n })\n\n // add a slight delay after click before closing the menu, makes it *feel* better\n $menuItem.addEventListener('click', () => {\n setTimeout(() => {\n this.closeMenu(false)\n }, 50)\n })\n })\n }\n\n toggleTemplate() {\n return `\n <button type=\"button\" class=\"govuk-button moj-button-menu__toggle-button ${this.config.buttonClasses || ''}\" aria-haspopup=\"true\" aria-expanded=\"false\">\n <span>\n ${this.config.buttonText}\n <svg width=\"11\" height=\"5\" viewBox=\"0 0 11 5\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.5 0L11 5L0 5L5.5 0Z\" fill=\"currentColor\"/>\n </svg>\n </span>\n </button>`\n }\n\n /**\n * @returns {boolean}\n */\n isOpen() {\n return this.$menuToggle.getAttribute('aria-expanded') === 'true'\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n toggleMenu(event) {\n event.preventDefault()\n\n // If menu is triggered with mouse don't move focus to first item\n const keyboardEvent = event.detail === 0\n const focusIndex = keyboardEvent ? 0 : -1\n\n if (this.isOpen()) {\n this.closeMenu()\n } else {\n this.openMenu(focusIndex)\n }\n }\n\n /**\n * Opens the menu and optionally sets the focus to the item with given index\n *\n * @param {number} focusIndex - The index of the item to focus\n */\n openMenu(focusIndex = 0) {\n this.$menu.hidden = false\n this.$menuToggle.setAttribute('aria-expanded', 'true')\n if (focusIndex !== -1) {\n this.focusItem(focusIndex)\n }\n }\n\n /**\n * Closes the menu and optionally returns focus back to menuToggle\n *\n * @param {boolean} moveFocus - whether to return focus to the toggle button\n */\n closeMenu(moveFocus = true) {\n this.$menu.hidden = true\n this.$menuToggle.setAttribute('aria-expanded', 'false')\n if (moveFocus) {\n this.$menuToggle.focus()\n }\n }\n\n /**\n * Focuses the menu item at the specified index\n *\n * @param {number} index - the index of the item to focus\n */\n focusItem(index) {\n if (index >= this.$items.length) index = 0\n if (index < 0) index = this.$items.length - 1\n\n const $menuItem = this.$items.item(index)\n if ($menuItem) {\n $menuItem.focus()\n }\n }\n\n currentFocusIndex() {\n const $activeElement = document.activeElement\n const $menuItems = Array.from(this.$items)\n\n return (\n ($activeElement instanceof HTMLAnchorElement ||\n $activeElement instanceof HTMLButtonElement) &&\n $menuItems.indexOf($activeElement)\n )\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n handleKeyDown(event) {\n if (event.target === this.$menuToggle) {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n this.openMenu()\n break\n case 'ArrowUp':\n event.preventDefault()\n this.openMenu(this.$items.length - 1)\n break\n }\n }\n\n if (\n event.target instanceof Node &&\n this.$menu.contains(event.target) &&\n this.isOpen()\n ) {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n if (this.currentFocusIndex() !== -1) {\n this.focusItem(this.currentFocusIndex() + 1)\n }\n break\n case 'ArrowUp':\n event.preventDefault()\n if (this.currentFocusIndex() !== -1) {\n this.focusItem(this.currentFocusIndex() - 1)\n }\n break\n case 'Home':\n event.preventDefault()\n this.focusItem(0)\n break\n case 'End':\n event.preventDefault()\n this.focusItem(this.$items.length - 1)\n break\n }\n }\n\n if (event.key === 'Escape' && this.isOpen()) {\n this.closeMenu()\n }\n if (event.key === 'Tab' && this.isOpen()) {\n this.closeMenu(false)\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-button-menu'\n\n /**\n * Button menu config\n *\n * @type {ButtonMenuConfig}\n */\n static defaults = Object.freeze({\n buttonText: 'Actions',\n alignMenu: 'left',\n buttonClasses: ''\n })\n\n /**\n * Button menu config schema\n *\n * @type {Schema<ButtonMenuConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n buttonText: { type: 'string' },\n buttonClasses: { type: 'string' },\n alignMenu: { type: 'string' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} ButtonMenuConfig\n * @property {string} [buttonText='Actions'] - Label for the toggle button\n * @property {\"left\" | \"right\"} [alignMenu='left'] - the alignment of the menu\n * @property {string} [buttonClasses='govuk-button--secondary'] - css classes applied to the toggle button\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<DatePickerConfig>}\n */\nexport class DatePicker extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for date picker\n * @param {DatePickerConfig} [config] - Date picker config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $input =\n this.config.input.element ??\n this.$root.querySelector(this.config.input.selector)\n\n if (!$input || !($input instanceof HTMLInputElement)) {\n return this\n }\n\n this.$input = $input\n\n this.dayLabels = [\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n 'Sunday'\n ]\n\n this.monthLabels = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December'\n ]\n\n this.currentDate = new Date()\n this.currentDate.setHours(0, 0, 0, 0)\n this.calendarDays = /** @type {DSCalendarDay[]} */ ([])\n this.excludedDates = /** @type {Date[]} */ ([])\n this.excludedDays = /** @type {number[]} */ ([])\n\n this.buttonClass = 'moj-datepicker__button'\n this.selectedDayButtonClass = 'moj-datepicker__button--selected'\n this.currentDayButtonClass = 'moj-datepicker__button--current'\n this.todayButtonClass = 'moj-datepicker__button--today'\n\n this.setOptions()\n this.initControls()\n }\n\n initControls() {\n this.id = `datepicker-${this.$input.id}`\n\n this.$dialog = this.createDialog()\n this.createCalendarHeaders()\n\n const $componentWrapper = document.createElement('div')\n const $inputWrapper = document.createElement('div')\n $componentWrapper.classList.add('moj-datepicker__wrapper')\n $inputWrapper.classList.add('govuk-input__wrapper')\n\n this.$input.parentElement.insertBefore($componentWrapper, this.$input)\n $componentWrapper.appendChild($inputWrapper)\n $inputWrapper.appendChild(this.$input)\n\n $inputWrapper.insertAdjacentHTML('beforeend', this.toggleTemplate())\n $componentWrapper.insertAdjacentElement('beforeend', this.$dialog)\n\n this.$calendarButton = /** @type {HTMLButtonElement} */ (\n this.$root.querySelector('.moj-js-datepicker-toggle')\n )\n\n this.$dialogTitle = /** @type {HTMLHeadingElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-month-year')\n )\n\n this.createCalendar()\n\n this.$prevMonthButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-prev-month')\n )\n\n this.$prevYearButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-prev-year')\n )\n\n this.$nextMonthButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-next-month')\n )\n\n this.$nextYearButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-next-year')\n )\n\n this.$cancelButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-cancel')\n )\n\n this.$okButton = /** @type {HTMLButtonElement} */ (\n this.$dialog.querySelector('.moj-js-datepicker-ok')\n )\n\n // add event listeners\n this.$prevMonthButton.addEventListener('click', (event) =>\n this.focusPreviousMonth(event, false)\n )\n this.$prevYearButton.addEventListener('click', (event) =>\n this.focusPreviousYear(event, false)\n )\n this.$nextMonthButton.addEventListener('click', (event) =>\n this.focusNextMonth(event, false)\n )\n this.$nextYearButton.addEventListener('click', (event) =>\n this.focusNextYear(event, false)\n )\n this.$cancelButton.addEventListener('click', (event) => {\n event.preventDefault()\n this.closeDialog()\n })\n this.$okButton.addEventListener('click', () => {\n this.selectDate(this.currentDate)\n })\n\n const $dialogButtons = this.$dialog.querySelectorAll(\n 'button:not([disabled=\"true\"])'\n )\n\n this.$firstButtonInDialog = $dialogButtons[0]\n this.$lastButtonInDialog = $dialogButtons[$dialogButtons.length - 1]\n this.$firstButtonInDialog.addEventListener('keydown', (event) =>\n this.firstButtonKeydown(event)\n )\n this.$lastButtonInDialog.addEventListener('keydown', (event) =>\n this.lastButtonKeydown(event)\n )\n\n this.$calendarButton.addEventListener('click', (event) =>\n this.toggleDialog(event)\n )\n\n this.$dialog.addEventListener('keydown', (event) => {\n if (event.key === 'Escape') {\n this.closeDialog()\n event.preventDefault()\n event.stopPropagation()\n }\n })\n\n document.body.addEventListener('mouseup', (event) => {\n this.backgroundClick(event)\n })\n\n // populates calendar with initial dates, avoids Wave errors about null buttons\n this.updateCalendar()\n }\n\n createDialog() {\n const titleId = `datepicker-title-${this.$input.id}`\n const $dialog = document.createElement('div')\n\n $dialog.id = this.id\n $dialog.setAttribute('class', 'moj-datepicker__dialog')\n $dialog.setAttribute('role', 'dialog')\n $dialog.setAttribute('aria-modal', 'true')\n $dialog.setAttribute('aria-labelledby', titleId)\n $dialog.innerHTML = this.dialogTemplate(titleId)\n $dialog.hidden = true\n\n return $dialog\n }\n\n createCalendar() {\n const $tbody = this.$dialog.querySelector('tbody')\n let dayCount = 0\n for (let i = 0; i < 6; i++) {\n // create row\n const $row = $tbody.insertRow(i)\n\n for (let j = 0; j < 7; j++) {\n // create cell (day)\n const $cell = document.createElement('td')\n $row.appendChild($cell)\n const $dateButton = document.createElement('button')\n $dateButton.setAttribute('type', 'button')\n $cell.appendChild($dateButton)\n\n const calendarDay = new DSCalendarDay($dateButton, dayCount, i, j, this)\n this.calendarDays.push(calendarDay)\n dayCount++\n }\n }\n }\n\n toggleTemplate() {\n return `<button class=\"moj-datepicker__toggle moj-js-datepicker-toggle\" type=\"button\" aria-haspopup=\"dialog\" aria-controls=\"${this.id}\" aria-expanded=\"false\">\n <span class=\"govuk-visually-hidden\">Choose date</span>\n <svg width=\"32\" height=\"24\" focusable=\"false\" class=\"moj-datepicker-icon\" aria-hidden=\"true\" role=\"img\" viewBox=\"0 0 22 22\">\n <path\n fill=\"currentColor\"\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M16.1333 2.93333H5.86668V4.4C5.86668 5.21002 5.21003 5.86667 4.40002 5.86667C3.59 5.86667 2.93335 5.21002 2.93335 4.4V2.93333H2C0.895431 2.93333 0 3.82877 0 4.93334V19.2667C0 20.3712 0.89543 21.2667 2 21.2667H20C21.1046 21.2667 22 20.3712 22 19.2667V4.93333C22 3.82876 21.1046 2.93333 20 2.93333H19.0667V4.4C19.0667 5.21002 18.41 5.86667 17.6 5.86667C16.79 5.86667 16.1333 5.21002 16.1333 4.4V2.93333ZM20.5333 8.06667H1.46665V18.8C1.46665 19.3523 1.91436 19.8 2.46665 19.8H19.5333C20.0856 19.8 20.5333 19.3523 20.5333 18.8V8.06667Z\"\n ></path>\n <rect x=\"3.66669\" width=\"1.46667\" height=\"5.13333\" rx=\"0.733333\" fill=\"currentColor\"></rect>\n <rect x=\"16.8667\" width=\"1.46667\" height=\"5.13333\" rx=\"0.733333\" fill=\"currentColor\"></rect>\n </svg>\n </button>`\n }\n\n /**\n * HTML template for calendar dialog\n *\n * @param {string} [titleId] - Id attribute for dialog title\n * @returns {string}\n */\n dialogTemplate(titleId) {\n return `<div class=\"moj-datepicker__dialog-header\">\n <div class=\"moj-datepicker__dialog-navbuttons\">\n <button type=\"button\" class=\"moj-datepicker__button moj-js-datepicker-prev-year\">\n <span class=\"govuk-visually-hidden\">Previous year</span>\n <svg width=\"44\" height=\"40\" viewBox=\"0 0 44 40\" fill=\"none\" fill=\"none\" focusable=\"false\" aria-hidden=\"true\" role=\"img\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M23.1643 20L28.9572 14.2071L27.5429 12.7929L20.3358 20L27.5429 27.2071L28.9572 25.7929L23.1643 20Z\" fill=\"currentColor\"/>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M17.1643 20L22.9572 14.2071L21.5429 12.7929L14.3358 20L21.5429 27.2071L22.9572 25.7929L17.1643 20Z\" fill=\"currentColor\"/>\n </svg>\n </button>\n\n <button type=\"button\" class=\"moj-datepicker__button moj-js-datepicker-prev-month\">\n <span class=\"govuk-visually-hidden\">Previous month</span>\n <svg width=\"44\" height=\"40\" viewBox=\"0 0 44 40\" fill=\"none\" focusable=\"false\" aria-hidden=\"true\" role=\"img\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M20.5729 20L25.7865 14.2071L24.5137 12.7929L18.0273 20L24.5137 27.2071L25.7865 25.7929L20.5729 20Z\" fill=\"currentColor\"/>\n </svg>\n </button>\n </div>\n\n <h2 id=\"${titleId}\" class=\"moj-datepicker__dialog-title moj-js-datepicker-month-year\" aria-live=\"polite\">June 2020</h2>\n\n <div class=\"moj-datepicker__dialog-navbuttons\">\n <button type=\"button\" class=\"moj-datepicker__button moj-js-datepicker-next-month\">\n <span class=\"govuk-visually-hidden\">Next month</span>\n <svg width=\"44\" height=\"40\" viewBox=\"0 0 44 40\" fill=\"none\" focusable=\"false\" aria-hidden=\"true\" role=\"img\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M23.4271 20L18.2135 14.2071L19.4863 12.7929L25.9727 20L19.4863 27.2071L18.2135 25.7929L23.4271 20Z\" fill=\"currentColor\"/>\n </svg>\n </button>\n\n <button type=\"button\" class=\"moj-datepicker__button moj-js-datepicker-next-year\">\n <span class=\"govuk-visually-hidden\">Next year</span>\n <svg width=\"44\" height=\"40\" viewBox=\"0 0 44 40\" fill=\"none\" fill=\"none\" focusable=\"false\" aria-hidden=\"true\" role=\"img\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M20.8357 20L15.0428 14.2071L16.4571 12.7929L23.6642 20L16.4571 27.2071L15.0428 25.7929L20.8357 20Z\" fill=\"currentColor\"/>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M26.8357 20L21.0428 14.2071L22.4571 12.7929L29.6642 20L22.4571 27.2071L21.0428 25.7929L26.8357 20Z\" fill=\"currentColor\"/>\n </svg>\n </button>\n </div>\n </div>\n\n <table class=\"moj-datepicker__calendar moj-js-datepicker-grid\" role=\"application\" aria-labelledby=\"${titleId}\">\n <thead>\n <tr></tr>\n </thead>\n\n <tbody></tbody>\n </table>\n\n <div class=\"govuk-button-group\">\n <button type=\"button\" class=\"govuk-button moj-js-datepicker-ok\">Select</button>\n <button type=\"button\" class=\"govuk-button govuk-button--secondary moj-js-datepicker-cancel\">Close</button>\n </div>`\n }\n\n createCalendarHeaders() {\n this.dayLabels.forEach((day) => {\n const html = `<th scope=\"col\"><span aria-hidden=\"true\">${day.substring(0, 3)}</span><span class=\"govuk-visually-hidden\">${day}</span></th>`\n const $headerRow = this.$dialog.querySelector('thead > tr')\n $headerRow.insertAdjacentHTML('beforeend', html)\n })\n }\n\n /**\n * Pads given number with leading zeros\n *\n * @param {number} value - The value to be padded\n * @param {number} length - The length in characters of the output\n * @returns {string}\n */\n leadingZeros(value, length = 2) {\n let ret = value.toString()\n\n while (ret.length < length) {\n ret = `0${ret}`\n }\n\n return ret\n }\n\n setOptions() {\n this.setMinAndMaxDatesOnCalendar()\n this.setExcludedDates()\n this.setExcludedDays()\n this.setWeekStartDay()\n }\n\n setMinAndMaxDatesOnCalendar() {\n if (this.config.minDate) {\n this.minDate = this.formattedDateFromString(this.config.minDate, null)\n if (this.minDate && this.currentDate < this.minDate) {\n this.currentDate = this.minDate\n }\n }\n\n if (this.config.maxDate) {\n this.maxDate = this.formattedDateFromString(this.config.maxDate, null)\n if (this.maxDate && this.currentDate > this.maxDate) {\n this.currentDate = this.maxDate\n }\n }\n }\n\n setExcludedDates() {\n if (this.config.excludedDates) {\n this.excludedDates = this.config.excludedDates\n .replace(/\\s+/, ' ')\n .split(' ')\n .map((item) => {\n return item.includes('-')\n ? this.parseDateRangeString(item)\n : [this.formattedDateFromString(item)]\n })\n .reduce((dates, items) => dates.concat(items))\n .filter((date) => date)\n }\n }\n\n /**\n * Parses a daterange string into an array of dates\n *\n * @param {string} datestring - A daterange string in the format \"dd/mm/yyyy-dd/mm/yyyy\"\n */\n parseDateRangeString(datestring) {\n const dates = []\n const [startDate, endDate] = datestring\n .split('-')\n .map((d) => this.formattedDateFromString(d, null))\n\n if (startDate && endDate) {\n const date = new Date(startDate.getTime())\n /* eslint-disable no-unmodified-loop-condition */\n while (date <= endDate) {\n dates.push(new Date(date))\n date.setDate(date.getDate() + 1)\n }\n /* eslint-enable no-unmodified-loop-condition */\n }\n return dates\n }\n\n setExcludedDays() {\n if (this.config.excludedDays) {\n // lowercase and arrange dayLabels to put indexOf sunday == 0 for comparison\n // with getDay() function\n const weekDays = this.dayLabels.map((item) => item.toLowerCase())\n if (this.config.weekStartDay === 'monday') {\n weekDays.unshift(weekDays.pop())\n }\n\n this.excludedDays = this.config.excludedDays\n .replace(/\\s+/, ' ')\n .toLowerCase()\n .split(' ')\n .map((item) => weekDays.indexOf(item))\n .filter((item) => item !== -1)\n }\n }\n\n setWeekStartDay() {\n const weekStartDayParam = this.config.weekStartDay\n if (weekStartDayParam && weekStartDayParam.toLowerCase() === 'sunday') {\n this.config.weekStartDay = 'sunday'\n // Rotate dayLabels array to put Sunday as the first item\n this.dayLabels.unshift(this.dayLabels.pop())\n } else {\n this.config.weekStartDay = 'monday'\n }\n }\n\n /**\n * Determine if a date is selectable\n *\n * @param {Date} date - the date to check\n * @returns {boolean}\n */\n isExcludedDate(date) {\n // This comparison does not work correctly - it will exclude the mindate itself\n // see: https://github.com/ministryofjustice/moj-frontend/issues/923\n if (this.minDate && this.minDate > date) {\n return true\n }\n\n // This comparison works as expected - the maxdate will not be excluded\n if (this.maxDate && this.maxDate < date) {\n return true\n }\n\n for (const excludedDate of this.excludedDates) {\n if (date.toDateString() === excludedDate.toDateString()) {\n return true\n }\n }\n\n if (this.excludedDays.includes(date.getDay())) {\n return true\n }\n\n return false\n }\n\n /**\n * Get a Date object from a string\n *\n * @param {string} dateString - string in the format d/m/yyyy dd/mm/yyyy\n * @param {Date} fallback - date object to return if formatting fails\n * @returns {Date}\n */\n formattedDateFromString(dateString, fallback = new Date()) {\n let formattedDate = null\n // Accepts d/m/yyyy and dd/mm/yyyy\n const dateFormatPattern = /(\\d{1,2})([-/,. ])(\\d{1,2})\\2(\\d{4})/\n\n if (!dateFormatPattern.test(dateString)) return fallback\n\n const match = dateFormatPattern.exec(dateString)\n const day = match[1]\n const month = match[3]\n const year = match[4]\n\n formattedDate = new Date(`${year}-${month}-${day}`)\n if (\n formattedDate instanceof Date &&\n Number.isFinite(formattedDate.getTime())\n ) {\n return formattedDate\n }\n return fallback\n }\n\n /**\n * Get a formatted date string from a Date object\n *\n * @param {Date} date - date to format to a string\n * @returns {string}\n */\n formattedDateFromDate(date) {\n if (this.config.leadingZeros) {\n return `${this.leadingZeros(date.getDate())}/${this.leadingZeros(date.getMonth() + 1)}/${date.getFullYear()}`\n }\n\n return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`\n }\n\n /**\n * Get a human readable date in the format Monday 2 March 2024\n *\n * @param {Date} date - Date to format\n * @returns {string}\n */\n formattedDateHuman(date) {\n return `${this.dayLabels[(date.getDay() + 6) % 7]} ${date.getDate()} ${this.monthLabels[date.getMonth()]} ${date.getFullYear()}`\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n backgroundClick(event) {\n if (\n this.isOpen() &&\n event.target instanceof Node &&\n !this.$dialog.contains(event.target) &&\n !this.$input.contains(event.target) &&\n !this.$calendarButton.contains(event.target)\n ) {\n event.preventDefault()\n this.closeDialog()\n }\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n firstButtonKeydown(event) {\n if (event.key === 'Tab' && event.shiftKey) {\n this.$lastButtonInDialog.focus()\n event.preventDefault()\n }\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n lastButtonKeydown(event) {\n if (event.key === 'Tab' && !event.shiftKey) {\n this.$firstButtonInDialog.focus()\n event.preventDefault()\n }\n }\n\n // render calendar\n updateCalendar() {\n this.$dialogTitle.innerHTML = `${this.monthLabels[this.currentDate.getMonth()]} ${this.currentDate.getFullYear()}`\n\n const day = this.currentDate\n const firstOfMonth = new Date(day.getFullYear(), day.getMonth(), 1)\n let dayOfWeek\n\n if (this.config.weekStartDay === 'monday') {\n dayOfWeek = firstOfMonth.getDay() === 0 ? 6 : firstOfMonth.getDay() - 1 // Change logic to make Monday first day of week, i.e. 0\n } else {\n dayOfWeek = firstOfMonth.getDay()\n }\n\n firstOfMonth.setDate(firstOfMonth.getDate() - dayOfWeek)\n\n const thisDay = new Date(firstOfMonth)\n\n // loop through our days\n for (const calendarDay of this.calendarDays) {\n const hidden = thisDay.getMonth() !== day.getMonth()\n const disabled = this.isExcludedDate(thisDay)\n\n calendarDay.update(thisDay, hidden, disabled)\n\n thisDay.setDate(thisDay.getDate() + 1)\n }\n }\n\n /**\n * @param {boolean} [focus] - Focus the day button\n */\n setCurrentDate(focus = true) {\n const { currentDate } = this\n this.calendarDays.forEach((calendarDay) => {\n calendarDay.$button.classList.add('moj-datepicker__button')\n calendarDay.$button.classList.add('moj-datepicker__calendar-day')\n calendarDay.$button.setAttribute('tabindex', '-1')\n calendarDay.$button.classList.remove(this.selectedDayButtonClass)\n const calendarDayDate = calendarDay.date\n calendarDayDate.setHours(0, 0, 0, 0)\n\n const today = new Date()\n today.setHours(0, 0, 0, 0)\n\n if (\n calendarDayDate.getTime() ===\n currentDate.getTime() /* && !calendarDay.button.disabled */\n ) {\n if (focus) {\n calendarDay.$button.setAttribute('tabindex', '0')\n calendarDay.$button.focus()\n calendarDay.$button.classList.add(this.selectedDayButtonClass)\n }\n }\n\n if (\n this.inputDate &&\n calendarDayDate.getTime() === this.inputDate.getTime()\n ) {\n calendarDay.$button.classList.add(this.currentDayButtonClass)\n calendarDay.$button.setAttribute('aria-current', 'date')\n } else {\n calendarDay.$button.classList.remove(this.currentDayButtonClass)\n calendarDay.$button.removeAttribute('aria-current')\n }\n\n if (calendarDayDate.getTime() === today.getTime()) {\n calendarDay.$button.classList.add(this.todayButtonClass)\n } else {\n calendarDay.$button.classList.remove(this.todayButtonClass)\n }\n })\n\n // if no date is tab-able, make the first non-disabled date tab-able\n if (!focus) {\n const enabledDays = this.calendarDays.filter((calendarDay) => {\n return (\n window.getComputedStyle(calendarDay.$button).display === 'block' &&\n !calendarDay.$button.disabled\n )\n })\n\n enabledDays[0].$button.setAttribute('tabindex', '0')\n\n this.currentDate = enabledDays[0].date\n }\n }\n\n /**\n * @param {Date} date - Date to select\n */\n selectDate(date) {\n if (this.isExcludedDate(date)) {\n return\n }\n\n this.$calendarButton.querySelector('span').innerText =\n `Choose date. Selected date is ${this.formattedDateHuman(date)}`\n this.$input.value = this.formattedDateFromDate(date)\n\n const changeEvent = new Event('change', { bubbles: true, cancelable: true })\n this.$input.dispatchEvent(changeEvent)\n\n this.closeDialog()\n }\n\n isOpen() {\n return this.$dialog.classList.contains('moj-datepicker__dialog--open')\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n toggleDialog(event) {\n event.preventDefault()\n if (this.isOpen()) {\n this.closeDialog()\n } else {\n this.setMinAndMaxDatesOnCalendar()\n this.openDialog()\n }\n }\n\n openDialog() {\n this.$dialog.hidden = false\n this.$dialog.classList.add('moj-datepicker__dialog--open')\n this.$calendarButton.setAttribute('aria-expanded', 'true')\n\n // position the dialog\n // if input is wider than dialog pin it to the right\n if (this.$input.offsetWidth > this.$dialog.offsetWidth) {\n this.$dialog.style.right = `0px`\n }\n this.$dialog.style.top = `${this.$input.offsetHeight + 3}px`\n\n // get the date from the input element\n this.inputDate = this.formattedDateFromString(this.$input.value)\n this.currentDate = this.inputDate\n this.currentDate.setHours(0, 0, 0, 0)\n\n this.updateCalendar()\n this.setCurrentDate()\n }\n\n closeDialog() {\n this.$dialog.hidden = true\n this.$dialog.classList.remove('moj-datepicker__dialog--open')\n this.$calendarButton.setAttribute('aria-expanded', 'false')\n this.$calendarButton.focus()\n }\n\n /**\n * @param {Date} date - Date to go to\n * @param {boolean} [focus] - Focus the day button\n */\n goToDate(date, focus) {\n const current = this.currentDate\n this.currentDate = date\n\n if (\n current.getMonth() !== this.currentDate.getMonth() ||\n current.getFullYear() !== this.currentDate.getFullYear()\n ) {\n this.updateCalendar()\n }\n\n this.setCurrentDate(focus)\n }\n\n // day navigation\n focusNextDay() {\n const date = new Date(this.currentDate)\n date.setDate(date.getDate() + 1)\n this.goToDate(date)\n }\n\n focusPreviousDay() {\n const date = new Date(this.currentDate)\n date.setDate(date.getDate() - 1)\n this.goToDate(date)\n }\n\n // week navigation\n focusNextWeek() {\n const date = new Date(this.currentDate)\n date.setDate(date.getDate() + 7)\n this.goToDate(date)\n }\n\n focusPreviousWeek() {\n const date = new Date(this.currentDate)\n date.setDate(date.getDate() - 7)\n this.goToDate(date)\n }\n\n focusFirstDayOfWeek() {\n const date = new Date(this.currentDate)\n const firstDayOfWeekIndex = this.config.weekStartDay === 'sunday' ? 0 : 1\n const dayOfWeek = date.getDay()\n const diff =\n dayOfWeek >= firstDayOfWeekIndex\n ? dayOfWeek - firstDayOfWeekIndex\n : 6 - dayOfWeek\n\n date.setDate(date.getDate() - diff)\n date.setHours(0, 0, 0, 0)\n\n this.goToDate(date)\n }\n\n focusLastDayOfWeek() {\n const date = new Date(this.currentDate)\n const lastDayOfWeekIndex = this.config.weekStartDay === 'sunday' ? 6 : 0\n const dayOfWeek = date.getDay()\n const diff =\n dayOfWeek <= lastDayOfWeekIndex\n ? lastDayOfWeekIndex - dayOfWeek\n : 7 - dayOfWeek\n\n date.setDate(date.getDate() + diff)\n date.setHours(0, 0, 0, 0)\n\n this.goToDate(date)\n }\n\n /**\n * Month navigation\n *\n * @param {KeyboardEvent | MouseEvent} event - Key press or click event\n * @param {boolean} [focus] - Focus the day button\n */\n focusNextMonth(event, focus = true) {\n event.preventDefault()\n const date = new Date(this.currentDate)\n date.setMonth(date.getMonth() + 1, 1)\n this.goToDate(date, focus)\n }\n\n /**\n * @param {KeyboardEvent | MouseEvent} event - Key press or click event\n * @param {boolean} [focus] - Focus the day button\n */\n focusPreviousMonth(event, focus = true) {\n event.preventDefault()\n const date = new Date(this.currentDate)\n date.setMonth(date.getMonth() - 1, 1)\n this.goToDate(date, focus)\n }\n\n /**\n * Year navigation\n *\n * @param {KeyboardEvent | MouseEvent} event - Key press or click event\n * @param {boolean} [focus] - Focus the day button\n */\n focusNextYear(event, focus = true) {\n event.preventDefault()\n const date = new Date(this.currentDate)\n date.setFullYear(date.getFullYear() + 1, date.getMonth(), 1)\n this.goToDate(date, focus)\n }\n\n /**\n * @param {KeyboardEvent | MouseEvent} event - Key press or click event\n * @param {boolean} [focus] - Focus the day button\n */\n focusPreviousYear(event, focus = true) {\n event.preventDefault()\n const date = new Date(this.currentDate)\n date.setFullYear(date.getFullYear() - 1, date.getMonth(), 1)\n this.goToDate(date, focus)\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-date-picker'\n\n /**\n * Date picker default config\n *\n * @type {DatePickerConfig}\n */\n static defaults = Object.freeze({\n leadingZeros: false,\n weekStartDay: 'monday',\n input: {\n selector: '.moj-js-datepicker-input'\n }\n })\n\n /**\n * Date picker config schema\n *\n * @satisfies {Schema<DatePickerConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n excludedDates: { type: 'string' },\n excludedDays: { type: 'string' },\n leadingZeros: { type: 'boolean' },\n maxDate: { type: 'string' },\n minDate: { type: 'string' },\n weekStartDay: { type: 'string' },\n input: { type: 'object' }\n }\n })\n )\n}\n\nclass DSCalendarDay {\n /**\n *\n * @param {HTMLButtonElement} $button\n * @param {number} index\n * @param {number} row\n * @param {number} column\n * @param {DatePicker} picker\n */\n constructor($button, index, row, column, picker) {\n this.index = index\n this.row = row\n this.column = column\n this.$button = $button\n this.picker = picker\n this.date = new Date()\n this.$button.addEventListener('keydown', this.keyPress.bind(this))\n this.$button.addEventListener('click', this.click.bind(this))\n }\n\n /**\n * @param {Date} day - the Date for the calendar day\n * @param {boolean} hidden - visibility of the day\n * @param {boolean} disabled - is the day selectable or excluded\n */\n update(day, hidden, disabled) {\n const label = day.getDate()\n let accessibleLabel = this.picker.formattedDateHuman(day)\n\n if (disabled) {\n this.$button.setAttribute('aria-disabled', 'true')\n accessibleLabel = `Excluded date, ${accessibleLabel}`\n } else {\n this.$button.removeAttribute('aria-disabled')\n }\n\n if (hidden) {\n this.$button.style.display = 'none'\n } else {\n this.$button.style.display = 'block'\n }\n this.$button.setAttribute(\n 'data-testid',\n this.picker.formattedDateFromDate(day)\n )\n\n this.$button.innerHTML = `<span class=\"govuk-visually-hidden\">${accessibleLabel}</span><span aria-hidden=\"true\">${label}</span>`\n this.date = new Date(day)\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n click(event) {\n this.picker.goToDate(this.date)\n this.picker.selectDate(this.date)\n\n event.stopPropagation()\n event.preventDefault()\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n keyPress(event) {\n let calendarNavKey = true\n\n switch (event.key) {\n case 'ArrowLeft':\n this.picker.focusPreviousDay()\n break\n case 'ArrowRight':\n this.picker.focusNextDay()\n break\n case 'ArrowUp':\n this.picker.focusPreviousWeek()\n break\n case 'ArrowDown':\n this.picker.focusNextWeek()\n break\n case 'Home':\n this.picker.focusFirstDayOfWeek()\n break\n case 'End':\n this.picker.focusLastDayOfWeek()\n break\n case 'PageUp': {\n if (event.shiftKey) {\n this.picker.focusPreviousYear(event)\n } else {\n this.picker.focusPreviousMonth(event)\n }\n break\n }\n case 'PageDown': {\n if (event.shiftKey) {\n this.picker.focusNextYear(event)\n } else {\n this.picker.focusNextMonth(event)\n }\n break\n }\n default:\n calendarNavKey = false\n break\n }\n\n if (calendarNavKey) {\n event.preventDefault()\n event.stopPropagation()\n }\n }\n}\n\n/**\n * Date picker config\n *\n * @typedef {object} DatePickerConfig\n * @property {string} [excludedDates] - Dates that cannot be selected\n * @property {string} [excludedDays] - Days that cannot be selected\n * @property {boolean} [leadingZeros] - Whether to add leading zeroes when populating the field\n * @property {string} [minDate] - The earliest available date\n * @property {string} [maxDate] - The latest available date\n * @property {string} [weekStartDay] - First day of the week in calendar view\n * @property {object} [input] - Input config\n * @property {string} [input.selector] - Selector for the input element\n * @property {Element | null} [input.element] - HTML element for the input\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { Component } from 'govuk-frontend'\n\nexport class PdsHeader extends Component {\n /**\n * @param {Element | null} $root - HTML element to use for PDS header\n */\n constructor($root) {\n super($root)\n this.initHeader()\n }\n\n initHeader() {\n this.$tabOpenClass = 'probation-common-header__toggle-open'\n const $userToggle = this.$root.querySelector(\n '.probation-common-header__user-menu-toggle'\n )\n const $userMenu = this.$root.querySelector(\n '#probation-common-header-user-menu'\n )\n\n if (\n !$userToggle ||\n !$userMenu ||\n !($userToggle instanceof HTMLElement) ||\n !($userMenu instanceof HTMLElement)\n ) {\n return 0\n }\n\n this.hideFallbackLinks()\n $userToggle.removeAttribute('hidden')\n\n this.closeTabs([[$userToggle, $userMenu]])\n\n $userToggle.addEventListener('click', (_event) => {\n this.toggleMenu($userToggle, $userMenu)\n })\n }\n\n /**\n * @param {[any, any][]} tabTuples\n */\n closeTabs(tabTuples) {\n tabTuples.forEach(([toggle, menu]) => {\n if (menu && toggle) {\n menu.setAttribute('hidden', 'hidden')\n toggle.classList.remove(this.$tabOpenClass)\n toggle.parentElement.classList.remove('item-open')\n toggle.setAttribute('aria-expanded', 'false')\n if (toggle.dataset.textForShow)\n toggle.setAttribute('aria-label', toggle.dataset.textForShow)\n }\n })\n }\n\n /**\n * @param {HTMLElement} toggle\n * @param {HTMLElement} menu\n */\n toggleMenu(toggle, menu) {\n const isOpen = !menu.getAttribute('hidden')\n\n if (isOpen) {\n this.closeTabs([[toggle, menu]])\n } else if (menu && toggle) {\n menu.removeAttribute('hidden')\n toggle.classList.add(this.$tabOpenClass)\n toggle.parentElement.classList.add('item-open')\n toggle.setAttribute('aria-expanded', 'true')\n if (toggle.dataset.textForHide)\n toggle.setAttribute('aria-label', toggle.dataset.textForHide)\n }\n }\n\n hideFallbackLinks() {\n const $userLink = this.$root.querySelector(\n '.probation-common-header__user-menu-link'\n )\n if ($userLink) $userLink.setAttribute('hidden', 'hidden')\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'pds-header'\n}\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<FilterToggleButtonConfig>}\n */\nexport class FilterToggleButton extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for filter toggle button\n * @param {FilterToggleButtonConfig} [config] - Filter toggle button config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $toggleButtonContainer =\n this.config.toggleButtonContainer.element ??\n document.querySelector(this.config.toggleButtonContainer.selector)\n\n const $closeButtonContainer =\n this.config.closeButtonContainer.element ??\n this.$root.querySelector(this.config.closeButtonContainer.selector)\n\n if (\n !(\n $toggleButtonContainer instanceof HTMLElement &&\n $closeButtonContainer instanceof HTMLElement\n )\n ) {\n return this\n }\n\n this.$toggleButtonContainer = $toggleButtonContainer\n this.$closeButtonContainer = $closeButtonContainer\n\n this.createToggleButton()\n this.setupResponsiveChecks()\n\n this.$root.setAttribute('tabindex', '-1')\n\n if (this.config.startHidden) {\n this.hideMenu()\n }\n }\n\n setupResponsiveChecks() {\n this.mq = window.matchMedia(this.config.bigModeMediaQuery)\n this.mq.addListener(this.checkMode.bind(this))\n this.checkMode()\n }\n\n createToggleButton() {\n this.$menuButton = document.createElement('button')\n this.$menuButton.setAttribute('type', 'button')\n this.$menuButton.setAttribute('aria-haspopup', 'true')\n this.$menuButton.setAttribute('aria-expanded', 'false')\n\n this.$menuButton.className = `govuk-button ${this.config.toggleButton.classes}`\n this.$menuButton.textContent = this.config.toggleButton.showText\n\n this.$menuButton.addEventListener(\n 'click',\n this.onMenuButtonClick.bind(this)\n )\n\n this.$toggleButtonContainer.append(this.$menuButton)\n }\n\n checkMode() {\n if (this.mq.matches) {\n this.enableBigMode()\n } else {\n this.enableSmallMode()\n }\n }\n\n enableBigMode() {\n this.showMenu()\n this.removeCloseButton()\n }\n\n enableSmallMode() {\n this.hideMenu()\n this.addCloseButton()\n }\n\n addCloseButton() {\n this.$closeButton = document.createElement('button')\n this.$closeButton.setAttribute('type', 'button')\n\n this.$closeButton.className = this.config.closeButton.classes\n this.$closeButton.textContent = this.config.closeButton.text\n\n this.$closeButton.addEventListener('click', this.onCloseClick.bind(this))\n this.$closeButtonContainer.append(this.$closeButton)\n }\n\n onCloseClick() {\n this.hideMenu()\n this.$menuButton.focus()\n }\n\n removeCloseButton() {\n if (this.$closeButton) {\n this.$closeButton.remove()\n this.$closeButton = null\n }\n }\n\n hideMenu() {\n this.$menuButton.setAttribute('aria-expanded', 'false')\n this.$root.classList.add('moj-js-hidden')\n this.$menuButton.textContent = this.config.toggleButton.showText\n }\n\n showMenu() {\n this.$menuButton.setAttribute('aria-expanded', 'true')\n this.$root.classList.remove('moj-js-hidden')\n this.$menuButton.textContent = this.config.toggleButton.hideText\n }\n\n onMenuButtonClick() {\n this.toggle()\n }\n\n toggle() {\n if (this.$menuButton.getAttribute('aria-expanded') === 'false') {\n this.showMenu()\n this.$root.focus()\n } else {\n this.hideMenu()\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-filter'\n\n /**\n * Filter toggle button config\n *\n * @type {FilterToggleButtonConfig}\n */\n static defaults = Object.freeze({\n bigModeMediaQuery: '(min-width: 48.0625em)',\n startHidden: true,\n toggleButton: {\n showText: 'Show filter',\n hideText: 'Hide filter',\n classes: 'govuk-button--secondary'\n },\n toggleButtonContainer: {\n selector: '.moj-action-bar__filter'\n },\n closeButton: {\n text: 'Close',\n classes: 'moj-filter__close'\n },\n closeButtonContainer: {\n selector: '.moj-filter__header-action'\n }\n })\n\n /**\n * Filter toggle button config schema\n *\n * @satisfies {Schema<FilterToggleButtonConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n bigModeMediaQuery: { type: 'string' },\n startHidden: { type: 'boolean' },\n toggleButton: { type: 'object' },\n toggleButtonContainer: { type: 'object' },\n closeButton: { type: 'object' },\n closeButtonContainer: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} FilterToggleButtonConfig\n * @property {string} [bigModeMediaQuery] - Media query for big mode\n * @property {boolean} [startHidden] - Whether to start hidden\n * @property {object} [toggleButton] - Toggle button config\n * @property {string} [toggleButton.showText] - Text for show button\n * @property {string} [toggleButton.hideText] - Text for hide button\n * @property {string} [toggleButton.classes] - Classes for toggle button\n * @property {object} [toggleButtonContainer] - Toggle button container config\n * @property {string} [toggleButtonContainer.selector] - Selector for toggle button container\n * @property {Element | null} [toggleButtonContainer.element] - HTML element for toggle button container\n * @property {object} [closeButton] - Close button config\n * @property {string} [closeButton.text] - Text for close button\n * @property {string} [closeButton.classes] - Classes for close button\n * @property {object} [closeButtonContainer] - Close button container config\n * @property {string} [closeButtonContainer.selector] - Selector for close button container\n * @property {Element | null} [closeButtonContainer.element] - HTML element for close button container\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\nimport { addAttributeValue, removeAttributeValue } from '../../helpers.mjs'\n\n/**\n * @augments {ConfigurableComponent<FormValidatorConfig, HTMLFormElement>}\n */\nexport class FormValidator extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for form validator\n * @param {FormValidatorConfig} [config] - Form validator config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $summary =\n this.config.summary.element ||\n document.querySelector(this.config.summary.selector)\n\n if (!$summary || !($summary instanceof HTMLElement)) {\n return this\n }\n\n this.$summary = $summary\n\n this.errors = /** @type {ValidationError[]} */ ([])\n this.validators = /** @type {Validator[]} */ ([])\n this.originalTitle = document.title\n\n this.$root.addEventListener('submit', this.onSubmit.bind(this))\n }\n\n escapeHtml(string = '') {\n return String(string).replace(\n /[&<>\"'`=/]/g,\n (name) => FormValidator.entityMap[name]\n )\n }\n\n resetTitle() {\n document.title = this.originalTitle\n }\n\n updateTitle() {\n document.title = `${this.errors.length} errors - ${document.title}`\n }\n\n showSummary() {\n this.$summary.innerHTML = this.getSummaryHtml()\n this.$summary.classList.remove('moj-hidden')\n this.$summary.setAttribute('aria-labelledby', 'errorSummary-heading')\n this.$summary.focus()\n }\n\n getSummaryHtml() {\n let html =\n '<h2 id=\"error-summary-title\" class=\"govuk-error-summary__title\">There is a problem</h2>'\n html += '<div class=\"govuk-error-summary__body\">'\n html += '<ul class=\"govuk-list govuk-error-summary__list\">'\n for (const error of this.errors) {\n html += '<li>'\n html += `<a href=\"#${this.escapeHtml(error.fieldName)}\">`\n html += this.escapeHtml(error.message)\n html += '</a>'\n html += '</li>'\n }\n html += '</ul>'\n html += '</div>'\n return html\n }\n\n hideSummary() {\n this.$summary.classList.add('moj-hidden')\n this.$summary.removeAttribute('aria-labelledby')\n }\n\n /**\n * @param {SubmitEvent} event - Form submit event\n */\n onSubmit(event) {\n this.removeInlineErrors()\n this.hideSummary()\n this.resetTitle()\n if (!this.validate()) {\n event.preventDefault()\n this.updateTitle()\n this.showSummary()\n this.showInlineErrors()\n }\n }\n\n showInlineErrors() {\n for (const error of this.errors) {\n this.showInlineError(error)\n }\n }\n\n /**\n * @param {ValidationError} error\n */\n showInlineError(error) {\n const $errorSpan = document.createElement('span')\n $errorSpan.id = `${error.fieldName}-error`\n $errorSpan.classList.add('govuk-error-message')\n $errorSpan.innerHTML = this.escapeHtml(error.message)\n\n const $control = document.querySelector(`#${error.fieldName}`)\n const $fieldset = $control.closest('.govuk-fieldset')\n const $fieldContainer = ($fieldset || $control).closest('.govuk-form-group')\n\n const $label = $fieldContainer.querySelector('label')\n const $legend = $fieldContainer.querySelector('legend')\n\n $fieldContainer.classList.add('govuk-form-group--error')\n\n if ($fieldset && $legend) {\n $legend.after($errorSpan)\n $fieldContainer.setAttribute('aria-invalid', 'true')\n addAttributeValue($fieldset, 'aria-describedby', $errorSpan.id)\n } else if ($label && $control) {\n $label.after($errorSpan)\n $control.setAttribute('aria-invalid', 'true')\n addAttributeValue($control, 'aria-describedby', $errorSpan.id)\n }\n }\n\n removeInlineErrors() {\n for (const error of this.errors) {\n this.removeInlineError(error)\n }\n }\n\n /**\n * @param {ValidationError} error\n */\n removeInlineError(error) {\n const $errorSpan = document.querySelector(`#${error.fieldName}-error`)\n\n const $control = document.querySelector(`#${error.fieldName}`)\n const $fieldset = $control.closest('.govuk-fieldset')\n const $fieldContainer = ($fieldset || $control).closest('.govuk-form-group')\n\n const $label = $fieldContainer.querySelector('label')\n const $legend = $fieldContainer.querySelector('legend')\n\n $errorSpan.remove()\n $fieldContainer.classList.remove('govuk-form-group--error')\n\n if ($fieldset && $legend) {\n $fieldContainer.removeAttribute('aria-invalid')\n removeAttributeValue($fieldset, 'aria-describedby', $errorSpan.id)\n } else if ($label && $control) {\n $control.removeAttribute('aria-invalid')\n removeAttributeValue($control, 'aria-describedby', $errorSpan.id)\n }\n }\n\n /**\n * @param {string} fieldName - Field name\n * @param {ValidationRule[]} rules - Validation rules\n */\n addValidator(fieldName, rules) {\n this.validators.push({\n fieldName,\n rules,\n field: this.$root.elements.namedItem(fieldName)\n })\n }\n\n validate() {\n this.errors = []\n\n /** @type {Validator | null} */\n let validator = null\n\n /** @type {boolean | string} */\n let validatorReturnValue = true\n\n let i\n let j\n\n for (i = 0; i < this.validators.length; i++) {\n validator = this.validators[i]\n for (j = 0; j < validator.rules.length; j++) {\n validatorReturnValue = validator.rules[j].method(\n validator.field,\n validator.rules[j].params\n )\n\n if (\n typeof validatorReturnValue === 'boolean' &&\n !validatorReturnValue\n ) {\n this.errors.push({\n fieldName: validator.fieldName,\n message: validator.rules[j].message\n })\n break\n } else if (typeof validatorReturnValue === 'string') {\n this.errors.push({\n fieldName: validatorReturnValue,\n message: validator.rules[j].message\n })\n break\n }\n }\n }\n return this.errors.length === 0\n }\n\n /**\n * @type {Record<string, string>}\n */\n static entityMap = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;',\n '/': '&#x2F;',\n '`': '&#x60;',\n '=': '&#x3D;'\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-form-validator'\n\n /**\n * Multi file upload default config\n *\n * @type {FormValidatorConfig}\n */\n static defaults = Object.freeze({\n summary: {\n selector: '.govuk-error-summary'\n }\n })\n\n /**\n * Multi file upload config schema\n *\n * @satisfies {Schema<FormValidatorConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n summary: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} FormValidatorConfig\n * @property {object} [summary] - Error summary config\n * @property {string} [summary.selector] - Selector for error summary\n * @property {Element | null} [summary.element] - HTML element for error summary\n */\n\n/**\n * @typedef {object} ValidationRule\n * @property {(field: Validator['field'], params: Record<string, Validator['field']>) => boolean | string} method - Validation method\n * @property {string} message - Error message\n * @property {Record<string, Validator['field']>} [params] - Parameters for validation\n */\n\n/**\n * @typedef {object} ValidationError\n * @property {string} fieldName - Name of the field\n * @property {string} message - Validation error message\n */\n\n/**\n * @typedef {object} Validator\n * @property {string} fieldName - Name of the field\n * @property {ValidationRule[]} rules - Validation rules\n * @property {Element | RadioNodeList} field - Form field\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","/* eslint-disable @typescript-eslint/no-empty-function */\n\nimport { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<MultiFileUploadConfig>}\n */\nexport class MultiFileUpload extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for multi file upload\n * @param {MultiFileUploadConfig} [config] - Multi file upload config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n if (!MultiFileUpload.isSupported()) {\n return this\n }\n\n const $feedbackContainer =\n this.config.feedbackContainer.element ??\n this.$root.querySelector(this.config.feedbackContainer.selector)\n\n if (!$feedbackContainer || !($feedbackContainer instanceof HTMLElement)) {\n return this\n }\n\n this.$feedbackContainer = $feedbackContainer\n\n this.setupFileInput()\n this.setupDropzone()\n this.setupLabel()\n this.setupStatusBox()\n\n this.$root.addEventListener('click', this.onFileDeleteClick.bind(this))\n this.$root.classList.add('moj-multi-file-upload--enhanced')\n }\n\n setupDropzone() {\n this.$dropzone = document.createElement('div')\n this.$dropzone.classList.add('moj-multi-file-upload__dropzone')\n\n this.$dropzone.addEventListener('dragover', this.onDragOver.bind(this))\n this.$dropzone.addEventListener('dragleave', this.onDragLeave.bind(this))\n this.$dropzone.addEventListener('drop', this.onDrop.bind(this))\n\n this.$fileInput.replaceWith(this.$dropzone)\n this.$dropzone.appendChild(this.$fileInput)\n }\n\n setupLabel() {\n const $label = document.createElement('label')\n $label.setAttribute('for', this.$fileInput.id)\n $label.classList.add('govuk-button', 'govuk-button--secondary')\n $label.textContent = this.config.dropzoneButtonText\n\n const $hint = document.createElement('p')\n $hint.classList.add('govuk-body')\n $hint.textContent = this.config.dropzoneHintText\n\n this.$label = $label\n this.$dropzone.append($hint)\n this.$dropzone.append($label)\n }\n\n setupFileInput() {\n this.$fileInput = /** @type {HTMLInputElement} */ (\n this.$root.querySelector('.moj-multi-file-upload__input')\n )\n this.$fileInput.addEventListener('change', this.onFileChange.bind(this))\n this.$fileInput.addEventListener('focus', this.onFileFocus.bind(this))\n this.$fileInput.addEventListener('blur', this.onFileBlur.bind(this))\n }\n\n setupStatusBox() {\n this.$status = document.createElement('div')\n this.$status.classList.add('govuk-visually-hidden')\n this.$status.setAttribute('aria-live', 'polite')\n this.$status.setAttribute('role', 'status')\n this.$dropzone.append(this.$status)\n }\n\n /**\n * @param {DragEvent} event - Drag event\n */\n onDragOver(event) {\n event.preventDefault()\n this.$dropzone.classList.add('moj-multi-file-upload--dragover')\n }\n\n onDragLeave() {\n this.$dropzone.classList.remove('moj-multi-file-upload--dragover')\n }\n\n /**\n * @param {DragEvent} event - Drag event\n */\n onDrop(event) {\n event.preventDefault()\n this.$dropzone.classList.remove('moj-multi-file-upload--dragover')\n this.$feedbackContainer.classList.remove('moj-hidden')\n this.$status.textContent = this.config.uploadStatusText\n this.uploadFiles(event.dataTransfer.files)\n }\n\n /**\n * @param {FileList} files - File list\n */\n uploadFiles(files) {\n for (const file of Array.from(files)) {\n this.uploadFile(file)\n }\n }\n\n onFileChange() {\n this.$feedbackContainer.classList.remove('moj-hidden')\n this.$status.textContent = this.config.uploadStatusText\n this.uploadFiles(this.$fileInput.files)\n\n const $fileInput = this.$fileInput.cloneNode(true)\n if (!$fileInput || !($fileInput instanceof HTMLInputElement)) {\n return\n }\n\n $fileInput.value = ''\n this.$fileInput.replaceWith($fileInput)\n\n this.setupFileInput()\n this.$fileInput.focus()\n }\n\n onFileFocus() {\n this.$label.classList.add('moj-multi-file-upload--focused')\n }\n\n onFileBlur() {\n this.$label.classList.remove('moj-multi-file-upload--focused')\n }\n\n /**\n * @param {UploadResponseSuccess['success']} success\n */\n getSuccessHtml(success) {\n return `<span class=\"moj-multi-file-upload__success\"> <svg class=\"moj-banner__icon\" fill=\"currentColor\" role=\"presentation\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 25 25\" height=\"25\" width=\"25\"><path d=\"M25,6.2L8.7,23.2L0,14.1l4-4.2l4.7,4.9L21,2L25,6.2z\"/></svg>${success.messageHtml}</span>`\n }\n\n /**\n * @param {UploadResponseError['error']} error\n */\n getErrorHtml(error) {\n return `<span class=\"moj-multi-file-upload__error\"> <svg class=\"moj-banner__icon\" fill=\"currentColor\" role=\"presentation\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 25 25\" height=\"25\" width=\"25\"><path d=\"M13.6,15.4h-2.3v-4.5h2.3V15.4z M13.6,19.8h-2.3v-2.2h2.3V19.8z M0,23.2h25L12.5,2L0,23.2z\"/></svg>${error.message}</span>`\n }\n\n /**\n * @param {File} file\n */\n getFileRow(file) {\n const $row = document.createElement('div')\n\n $row.classList.add('govuk-summary-list__row', 'moj-multi-file-upload__row')\n\n $row.innerHTML = `\n <div class=\"govuk-summary-list__value moj-multi-file-upload__message\">\n <span class=\"moj-multi-file-upload__filename\">${file.name}</span>\n <span class=\"moj-multi-file-upload__progress\">0%</span>\n </div>\n <div class=\"govuk-summary-list__actions moj-multi-file-upload__actions\"></div>\n `\n\n return $row\n }\n\n /**\n * @param {UploadResponseFile} file\n */\n getDeleteButton(file) {\n const $button = document.createElement('button')\n\n $button.setAttribute('type', 'button')\n $button.setAttribute('name', 'delete')\n $button.setAttribute('value', file.filename)\n\n $button.classList.add(\n 'moj-multi-file-upload__delete',\n 'govuk-button',\n 'govuk-button--secondary',\n 'govuk-!-margin-bottom-0'\n )\n\n $button.innerHTML = `Delete <span class=\"govuk-visually-hidden\">${file.originalname}</span>`\n\n return $button\n }\n\n /**\n * @param {File} file\n */\n uploadFile(file) {\n this.config.hooks.entryHook(this, file)\n\n const $item = this.getFileRow(file)\n const $message = $item.querySelector('.moj-multi-file-upload__message')\n const $actions = $item.querySelector('.moj-multi-file-upload__actions')\n const $progress = $item.querySelector('.moj-multi-file-upload__progress')\n\n const formData = new FormData()\n formData.append('documents', file)\n\n this.$feedbackContainer\n .querySelector('.moj-multi-file-upload__list')\n .append($item)\n\n const xhr = new XMLHttpRequest()\n\n const onLoad = () => {\n if (\n xhr.status < 200 ||\n xhr.status >= 300 ||\n !('success' in xhr.response)\n ) {\n return onError()\n }\n\n $message.innerHTML = this.getSuccessHtml(xhr.response.success)\n this.$status.textContent = xhr.response.success.messageText\n\n $actions.append(this.getDeleteButton(xhr.response.file))\n this.config.hooks.exitHook(this, file, xhr, xhr.responseText)\n }\n\n const onError = () => {\n const error = new Error(\n xhr.response && 'error' in xhr.response\n ? xhr.response.error.message\n : xhr.statusText || 'Upload failed'\n )\n\n $message.innerHTML = this.getErrorHtml(error)\n this.$status.textContent = error.message\n\n this.config.hooks.errorHook(this, file, xhr, xhr.responseText, error)\n }\n\n xhr.addEventListener('load', onLoad)\n xhr.addEventListener('error', onError)\n\n xhr.upload.addEventListener('progress', (event) => {\n if (!event.lengthComputable) {\n return\n }\n\n const percentComplete = Math.round((event.loaded / event.total) * 100)\n $progress.textContent = ` ${percentComplete}%`\n })\n\n xhr.open('POST', this.config.uploadUrl)\n xhr.responseType = 'json'\n\n xhr.send(formData)\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onFileDeleteClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-multi-file-upload__delete')\n ) {\n return\n }\n\n event.preventDefault() // if user refreshes page and then deletes\n\n const xhr = new XMLHttpRequest()\n\n xhr.addEventListener('load', () => {\n if (xhr.status < 200 || xhr.status >= 300) {\n return\n }\n\n const $rows = Array.from(\n this.$feedbackContainer.querySelectorAll('.moj-multi-file-upload__row')\n )\n\n if ($rows.length === 1) {\n this.$feedbackContainer.classList.add('moj-hidden')\n }\n\n const $rowDelete = $rows.find(($row) => $row.contains($button))\n if ($rowDelete) $rowDelete.remove()\n\n this.config.hooks.deleteHook(this, undefined, xhr, xhr.responseText)\n })\n\n xhr.open('POST', this.config.deleteUrl)\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.responseType = 'json'\n\n xhr.send(\n JSON.stringify({\n [$button.name]: $button.value\n })\n )\n }\n\n static isSupported() {\n return (\n this.isDragAndDropSupported() &&\n this.isFormDataSupported() &&\n this.isFileApiSupported()\n )\n }\n\n static isDragAndDropSupported() {\n const div = document.createElement('div')\n return typeof div.ondrop !== 'undefined'\n }\n\n static isFormDataSupported() {\n return typeof FormData === 'function'\n }\n\n static isFileApiSupported() {\n const input = document.createElement('input')\n input.type = 'file'\n return typeof input.files !== 'undefined'\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-multi-file-upload'\n\n /**\n * Multi file upload default config\n *\n * @type {MultiFileUploadConfig}\n */\n static defaults = Object.freeze({\n uploadStatusText: 'Uploading files, please wait',\n dropzoneHintText: 'Drag and drop files here or',\n dropzoneButtonText: 'Choose files',\n feedbackContainer: {\n selector: '.moj-multi-file__uploaded-files'\n },\n hooks: {\n entryHook: () => {},\n exitHook: () => {},\n errorHook: () => {},\n deleteHook: () => {}\n }\n })\n\n /**\n * Multi file upload config schema\n *\n * @satisfies {Schema<MultiFileUploadConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n uploadUrl: { type: 'string' },\n deleteUrl: { type: 'string' },\n uploadStatusText: { type: 'string' },\n dropzoneHintText: { type: 'string' },\n dropzoneButtonText: { type: 'string' },\n feedbackContainer: { type: 'object' },\n hooks: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * Multi file upload config\n *\n * @typedef {object} MultiFileUploadConfig\n * @property {string} [uploadUrl] - File upload URL\n * @property {string} [deleteUrl] - File delete URL\n * @property {string} [uploadStatusText] - Upload status text\n * @property {string} [dropzoneHintText] - Dropzone hint text\n * @property {string} [dropzoneButtonText] - Dropzone button text\n * @property {object} [feedbackContainer] - Feedback container config\n * @property {string} [feedbackContainer.selector] - Selector for feedback container\n * @property {Element | null} [feedbackContainer.element] - HTML element for feedback container\n * @property {MultiFileUploadHooks} [hooks] - Upload hooks\n */\n\n/**\n * Multi file upload hooks\n *\n * @typedef {object} MultiFileUploadHooks\n * @property {OnUploadFileEntryHook} [entryHook] - File upload entry hook\n * @property {OnUploadFileExitHook} [exitHook] - File upload exit hook\n * @property {OnUploadFileErrorHook} [errorHook] - File upload error hook\n * @property {OnUploadFileDeleteHook} [deleteHook] - File delete hook\n */\n\n/**\n * Upload hook: File entry\n *\n * @callback OnUploadFileEntryHook\n * @param {InstanceType<typeof MultiFileUpload>} upload - Multi file upload\n * @param {File} file - File upload\n */\n\n/**\n * Upload hook: File exit\n *\n * @callback OnUploadFileExitHook\n * @param {InstanceType<typeof MultiFileUpload>} upload - Multi file upload\n * @param {File} file - File upload\n * @param {XMLHttpRequest} xhr - XMLHttpRequest\n * @param {string} textStatus - Text status\n */\n\n/**\n * Upload hook: File error\n *\n * @callback OnUploadFileErrorHook\n * @param {InstanceType<typeof MultiFileUpload>} upload - Multi file upload\n * @param {File} file - File upload\n * @param {XMLHttpRequest} xhr - XMLHttpRequest\n * @param {string} textStatus - Text status\n * @param {Error} errorThrown - Error thrown\n */\n\n/**\n * Upload hook: File delete\n *\n * @callback OnUploadFileDeleteHook\n * @param {InstanceType<typeof MultiFileUpload>} upload - Multi file upload\n * @param {File} [file] - File upload\n * @param {XMLHttpRequest} xhr - XMLHttpRequest\n * @param {string} textStatus - Text status\n */\n\n/**\n * @typedef {object} UploadResponseSuccess\n * @property {{ messageText: string, messageHtml: string }} success - Response success\n * @property {UploadResponseFile} file - Response file\n */\n\n/**\n * @typedef {object} UploadResponseError\n * @property {{ message: string }} error - Response error\n * @property {UploadResponseFile} file - Response file\n */\n\n/**\n * @typedef {object} UploadResponseFile\n * @property {string} filename - File name\n * @property {string} originalname - Original file name\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<MultiSelectConfig>}\n */\nexport class MultiSelect extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for multi select\n * @param {MultiSelectConfig} [config] - Multi select config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $container = this.$root.querySelector(\n `#${this.config.idPrefix}select-all`\n )\n\n const $checkboxes = /** @type {NodeListOf<HTMLInputElement>} */ (\n this.config.checkboxes.items ??\n this.$root.querySelectorAll(this.config.checkboxes.selector)\n )\n\n if (\n !$container ||\n !($container instanceof HTMLElement) ||\n !$checkboxes.length\n ) {\n return this\n }\n\n this.setupToggle(this.config.idPrefix)\n\n this.$toggleButton = this.$toggle.querySelector('input')\n this.$toggleButton.addEventListener('click', this.onButtonClick.bind(this))\n\n this.$container = $container\n this.$container.append(this.$toggle)\n\n this.$checkboxes = Array.from($checkboxes)\n this.$checkboxes.forEach(($input) =>\n $input.addEventListener('click', this.onCheckboxClick.bind(this))\n )\n\n this.checked = config.checked || false\n }\n\n setupToggle(idPrefix = '') {\n const id = `${idPrefix}checkboxes-all`\n\n const $toggle = document.createElement('div')\n const $label = document.createElement('label')\n const $input = document.createElement('input')\n const $span = document.createElement('span')\n\n $toggle.classList.add(\n 'govuk-checkboxes__item',\n 'govuk-checkboxes--small',\n 'moj-multi-select__checkbox'\n )\n\n $input.id = id\n $input.type = 'checkbox'\n $input.classList.add('govuk-checkboxes__input')\n\n $label.setAttribute('for', id)\n $label.classList.add(\n 'govuk-label',\n 'govuk-checkboxes__label',\n 'moj-multi-select__toggle-label'\n )\n\n $span.classList.add('govuk-visually-hidden')\n $span.textContent = 'Select all'\n\n $label.append($span)\n $toggle.append($input, $label)\n\n this.$toggle = $toggle\n }\n\n onButtonClick() {\n if (this.checked) {\n this.uncheckAll()\n this.$toggleButton.checked = false\n } else {\n this.checkAll()\n this.$toggleButton.checked = true\n }\n }\n\n checkAll() {\n this.$checkboxes.forEach(($input) => {\n $input.checked = true\n })\n\n this.checked = true\n }\n\n uncheckAll() {\n this.$checkboxes.forEach(($input) => {\n $input.checked = false\n })\n\n this.checked = false\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onCheckboxClick(event) {\n if (!(event.target instanceof HTMLInputElement)) {\n return\n }\n\n if (!event.target.checked) {\n this.$toggleButton.checked = false\n this.checked = false\n } else {\n if (\n this.$checkboxes.filter(($input) => $input.checked).length ===\n this.$checkboxes.length\n ) {\n this.$toggleButton.checked = true\n this.checked = true\n }\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-multi-select'\n\n /**\n * Multi select config\n *\n * @type {MultiSelectConfig}\n */\n static defaults = Object.freeze({\n idPrefix: '',\n checkboxes: {\n selector: 'tbody input.govuk-checkboxes__input'\n }\n })\n\n /**\n * Multi select config schema\n *\n * @satisfies {Schema<MultiSelectConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n idPrefix: { type: 'string' },\n checked: { type: 'boolean' },\n checkboxes: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * Multi select config\n *\n * @typedef {object} MultiSelectConfig\n * @property {string} [idPrefix] - Prefix for the Select all\" checkbox `id` attribute\n * @property {boolean} [checked] - Whether the \"Select all\" checkbox is checked\n * @property {object} [checkboxes] - Checkboxes config\n * @property {string} [checkboxes.selector] - Checkboxes query selector\n * @property {NodeListOf<HTMLInputElement>} [checkboxes.items] - Checkboxes query selector results\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { Component } from 'govuk-frontend'\n\nexport class PasswordReveal extends Component {\n /**\n * @param {Element | null} $root - HTML element to use for password reveal\n */\n constructor($root) {\n super($root)\n\n const $input = this.$root.querySelector('.govuk-input')\n if (!$input || !($input instanceof HTMLInputElement)) {\n return this\n }\n\n this.$input = $input\n this.$input.setAttribute('spellcheck', 'false')\n\n this.createButton()\n }\n\n createButton() {\n this.$group = document.createElement('div')\n this.$button = document.createElement('button')\n\n this.$button.setAttribute('type', 'button')\n\n this.$root.classList.add('moj-password-reveal')\n this.$group.classList.add('moj-password-reveal__wrapper')\n this.$button.classList.add(\n 'govuk-button',\n 'govuk-button--secondary',\n 'moj-password-reveal__button'\n )\n\n this.$button.innerHTML =\n 'Show <span class=\"govuk-visually-hidden\">password</span>'\n\n this.$button.addEventListener('click', this.onButtonClick.bind(this))\n\n this.$group.append(this.$input, this.$button)\n this.$root.append(this.$group)\n }\n\n onButtonClick() {\n if (this.$input.type === 'password') {\n this.$input.type = 'text'\n this.$button.innerHTML =\n 'Hide <span class=\"govuk-visually-hidden\">password</span>'\n } else {\n this.$input.type = 'password'\n this.$button.innerHTML =\n 'Show <span class=\"govuk-visually-hidden\">password</span>'\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-password-reveal'\n}\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<RichTextEditorConfig>}\n */\nexport class RichTextEditor extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for rich text editor\n * @param {RichTextEditorConfig} config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n if (!RichTextEditor.isSupported()) {\n return this\n }\n\n const $textarea = this.$root.querySelector('.govuk-textarea')\n if (!$textarea || !($textarea instanceof HTMLTextAreaElement)) {\n return this\n }\n\n this.$textarea = $textarea\n\n this.createToolbar()\n this.hideDefault()\n this.configureToolbar()\n\n this.keys = {\n left: 37,\n right: 39,\n up: 38,\n down: 40\n }\n\n this.$content.addEventListener('input', this.onEditorInput.bind(this))\n\n this.$root\n .querySelector('label')\n .addEventListener('click', this.onLabelClick.bind(this))\n\n this.$toolbar.addEventListener('keydown', this.onToolbarKeydown.bind(this))\n }\n\n /**\n * @param {KeyboardEvent} event - Click event\n */\n onToolbarKeydown(event) {\n let $focusableButton\n switch (event.keyCode) {\n case this.keys.right:\n case this.keys.down: {\n $focusableButton = this.$buttons.find(\n (button) => button.getAttribute('tabindex') === '0'\n )\n\n if ($focusableButton) {\n const $nextButton = $focusableButton.nextElementSibling\n\n if ($nextButton && $nextButton instanceof HTMLButtonElement) {\n $nextButton.focus()\n $focusableButton.setAttribute('tabindex', '-1')\n $nextButton.setAttribute('tabindex', '0')\n }\n }\n\n break\n }\n\n case this.keys.left:\n case this.keys.up: {\n $focusableButton = this.$buttons.find(\n (button) => button.getAttribute('tabindex') === '0'\n )\n\n if ($focusableButton) {\n const $previousButton = $focusableButton.previousElementSibling\n\n if ($previousButton && $previousButton instanceof HTMLButtonElement) {\n $previousButton.focus()\n $focusableButton.setAttribute('tabindex', '-1')\n $previousButton.setAttribute('tabindex', '0')\n }\n }\n\n break\n }\n }\n }\n\n getToolbarHtml() {\n let html = ''\n\n html += '<div class=\"moj-rich-text-editor__toolbar\" role=\"toolbar\">'\n\n if (this.config.toolbar.bold) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--bold\" type=\"button\" data-command=\"bold\"><span class=\"govuk-visually-hidden\">Bold</span></button>'\n }\n\n if (this.config.toolbar.italic) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--italic\" type=\"button\" data-command=\"italic\"><span class=\"govuk-visually-hidden\">Italic</span></button>'\n }\n\n if (this.config.toolbar.underline) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--underline\" type=\"button\" data-command=\"underline\"><span class=\"govuk-visually-hidden\">Underline</span></button>'\n }\n\n if (this.config.toolbar.bullets) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--unordered-list\" type=\"button\" data-command=\"insertUnorderedList\"><span class=\"govuk-visually-hidden\">Unordered list</span></button>'\n }\n\n if (this.config.toolbar.numbers) {\n html +=\n '<button class=\"moj-rich-text-editor__toolbar-button moj-rich-text-editor__toolbar-button--ordered-list\" type=\"button\" data-command=\"insertOrderedList\"><span class=\"govuk-visually-hidden\">Ordered list</span></button>'\n }\n\n html += '</div>'\n return html\n }\n\n getEnhancedHtml() {\n return `${this.getToolbarHtml()}<div class=\"govuk-textarea moj-rich-text-editor__content\" contenteditable=\"true\" spellcheck=\"false\"></div>`\n }\n\n hideDefault() {\n this.$textarea.classList.add('govuk-visually-hidden')\n this.$textarea.setAttribute('aria-hidden', 'true')\n this.$textarea.setAttribute('tabindex', '-1')\n }\n\n createToolbar() {\n this.$toolbar = document.createElement('div')\n this.$toolbar.className = 'moj-rich-text-editor'\n this.$toolbar.innerHTML = this.getEnhancedHtml()\n this.$root.append(this.$toolbar)\n\n this.$content = /** @type {HTMLElement} */ (\n this.$root.querySelector('.moj-rich-text-editor__content')\n )\n\n this.$content.innerHTML = this.$textarea.value\n }\n\n configureToolbar() {\n this.$buttons = Array.from(\n /** @type {NodeListOf<HTMLButtonElement>} */\n (this.$root.querySelectorAll('.moj-rich-text-editor__toolbar-button'))\n )\n\n this.$buttons.forEach(($button, index) => {\n $button.setAttribute('tabindex', !index ? '0' : '-1')\n $button.addEventListener('click', this.onButtonClick.bind(this))\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onButtonClick(event) {\n if (!(event.currentTarget instanceof HTMLElement)) {\n return\n }\n\n document.execCommand(\n event.currentTarget.getAttribute('data-command'),\n false,\n undefined\n )\n }\n\n getContent() {\n return this.$content.innerHTML\n }\n\n onEditorInput() {\n this.updateTextarea()\n }\n\n updateTextarea() {\n document.execCommand('defaultParagraphSeparator', false, 'p')\n this.$textarea.value = this.getContent()\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onLabelClick(event) {\n event.preventDefault()\n this.$content.focus()\n }\n\n static isSupported() {\n return 'contentEditable' in document.documentElement\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-rich-text-editor'\n\n /**\n * Rich text editor config\n *\n * @type {RichTextEditorConfig}\n */\n static defaults = Object.freeze({\n toolbar: {\n bold: false,\n italic: false,\n underline: false,\n bullets: true,\n numbers: true\n }\n })\n\n /**\n * Rich text editor config schema\n *\n * @satisfies {Schema<RichTextEditorConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n toolbar: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * Rich text editor config\n *\n * @typedef {object} RichTextEditorConfig\n * @property {RichTextEditorToolbar} [toolbar] - Toolbar options\n */\n\n/**\n * Rich text editor toolbar options\n *\n * @typedef {object} RichTextEditorToolbar\n * @property {boolean} [bold] - Show the bold button\n * @property {boolean} [italic] - Show the italic button\n * @property {boolean} [underline] - Show the underline button\n * @property {boolean} [bullets] - Show the bullets button\n * @property {boolean} [numbers] - Show the numbers button\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<SearchToggleConfig>}\n */\nexport class SearchToggle extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for search toggle\n * @param {SearchToggleConfig} [config] - Search toggle config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $searchContainer =\n this.config.searchContainer.element ??\n this.$root.querySelector(this.config.searchContainer.selector)\n\n const $toggleButtonContainer =\n this.config.toggleButtonContainer.element ??\n this.$root.querySelector(this.config.toggleButtonContainer.selector)\n\n if (\n !$searchContainer ||\n !$toggleButtonContainer ||\n !($searchContainer instanceof HTMLElement) ||\n !($toggleButtonContainer instanceof HTMLElement)\n ) {\n return this\n }\n\n this.$searchContainer = $searchContainer\n this.$toggleButtonContainer = $toggleButtonContainer\n\n const svg =\n '<svg viewBox=\"0 0 20 20\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" class=\"moj-search-toggle__button__icon\"><path d=\"M7.433,12.5790048 C6.06762625,12.5808611 4.75763941,12.0392925 3.79217348,11.0738265 C2.82670755,10.1083606 2.28513891,8.79837375 2.28699522,7.433 C2.28513891,6.06762625 2.82670755,4.75763941 3.79217348,3.79217348 C4.75763941,2.82670755 6.06762625,2.28513891 7.433,2.28699522 C8.79837375,2.28513891 10.1083606,2.82670755 11.0738265,3.79217348 C12.0392925,4.75763941 12.5808611,6.06762625 12.5790048,7.433 C12.5808611,8.79837375 12.0392925,10.1083606 11.0738265,11.0738265 C10.1083606,12.0392925 8.79837375,12.5808611 7.433,12.5790048 L7.433,12.5790048 Z M14.293,12.579 L13.391,12.579 L13.071,12.269 C14.2300759,10.9245158 14.8671539,9.20813198 14.866,7.433 C14.866,3.32786745 11.5381325,-1.65045755e-15 7.433,-1.65045755e-15 C3.32786745,-1.65045755e-15 -1.65045755e-15,3.32786745 -1.65045755e-15,7.433 C-1.65045755e-15,11.5381325 3.32786745,14.866 7.433,14.866 C9.208604,14.8671159 10.9253982,14.2296624 12.27,13.07 L12.579,13.39 L12.579,14.294 L18.296,20 L20,18.296 L14.294,12.579 L14.293,12.579 Z\"></path></svg>'\n\n this.$toggleButton = document.createElement('button')\n this.$toggleButton.setAttribute('class', 'moj-search-toggle__button')\n this.$toggleButton.setAttribute('type', 'button')\n this.$toggleButton.setAttribute('aria-haspopup', 'true')\n this.$toggleButton.setAttribute('aria-expanded', 'false')\n this.$toggleButton.innerHTML = `${this.config.toggleButton.text} ${svg}`\n\n this.$toggleButton.addEventListener(\n 'click',\n this.onToggleButtonClick.bind(this)\n )\n\n this.$toggleButtonContainer.append(this.$toggleButton)\n\n document.addEventListener('click', this.onDocumentClick.bind(this))\n document.addEventListener('focusin', this.onDocumentClick.bind(this))\n }\n\n showMenu() {\n this.$toggleButton.setAttribute('aria-expanded', 'true')\n this.$searchContainer.classList.remove('moj-js-hidden')\n this.$searchContainer.querySelector('input').focus()\n }\n\n hideMenu() {\n this.$searchContainer.classList.add('moj-js-hidden')\n this.$toggleButton.setAttribute('aria-expanded', 'false')\n }\n\n onToggleButtonClick() {\n if (this.$toggleButton.getAttribute('aria-expanded') === 'false') {\n this.showMenu()\n } else {\n this.hideMenu()\n }\n }\n\n /**\n * @param {MouseEvent | FocusEvent} event\n */\n onDocumentClick(event) {\n if (\n event.target instanceof Node &&\n !this.$toggleButtonContainer.contains(event.target) &&\n !this.$searchContainer.contains(event.target)\n ) {\n this.hideMenu()\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-search-toggle'\n\n /**\n * Search toggle config\n *\n * @type {SearchToggleConfig}\n */\n static defaults = Object.freeze({\n searchContainer: {\n selector: '.moj-search'\n },\n toggleButton: {\n text: 'Search'\n },\n toggleButtonContainer: {\n selector: '.moj-search-toggle__toggle'\n }\n })\n\n /**\n * Search toggle config schema\n *\n * @satisfies {Schema<SearchToggleConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n searchContainer: { type: 'object' },\n toggleButton: { type: 'object' },\n toggleButtonContainer: { type: 'object' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} SearchToggleConfig\n * @property {object} [searchContainer] - Search config\n * @property {string} [searchContainer.selector] - Selector for search container\n * @property {Element | null} [searchContainer.element] - HTML element for search container\n * @property {object} [toggleButton] - Toggle button config\n * @property {string} [toggleButton.text] - Text for toggle button\n * @property {object} [toggleButtonContainer] - Toggle button container config\n * @property {string} [toggleButtonContainer.selector] - Selector for toggle button container\n * @property {Element | null} [toggleButtonContainer.element] - HTML element for toggle button container\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<SortableTableConfig>}\n */\nexport class SortableTable extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for sortable table\n * @param {SortableTableConfig} [config] - Sortable table config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $head = $root?.querySelector('thead')\n const $body = $root?.querySelector('tbody')\n\n if (!$head || !$body) {\n return this\n }\n\n this.$head = $head\n this.$body = $body\n this.$caption = this.$root.querySelector('caption')\n\n this.$upArrow = `<svg width=\"22\" height=\"22\" focusable=\"false\" aria-hidden=\"true\" role=\"img\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M6.5625 15.5L11 6.63125L15.4375 15.5H6.5625Z\" fill=\"currentColor\"/>\n</svg>`\n this.$downArrow = `<svg width=\"22\" height=\"22\" focusable=\"false\" aria-hidden=\"true\" role=\"img\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M15.4375 7L11 15.8687L6.5625 7L15.4375 7Z\" fill=\"currentColor\"/>\n</svg>`\n this.$upDownArrow = `<svg width=\"22\" height=\"22\" focusable=\"false\" aria-hidden=\"true\" role=\"img\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M8.1875 9.5L10.9609 3.95703L13.7344 9.5H8.1875Z\" fill=\"currentColor\"/>\n<path d=\"M13.7344 12.0781L10.9609 17.6211L8.1875 12.0781H13.7344Z\" fill=\"currentColor\"/>\n</svg>`\n\n this.$headings = this.$head\n ? Array.from(this.$head.querySelectorAll('th'))\n : []\n\n this.createHeadingButtons()\n this.updateCaption()\n this.updateDirectionIndicators()\n this.createStatusBox()\n this.initialiseSortedColumn()\n\n this.$head.addEventListener('click', this.onSortButtonClick.bind(this))\n }\n\n createHeadingButtons() {\n for (const $heading of this.$headings) {\n if ($heading.hasAttribute('aria-sort')) {\n this.createHeadingButton($heading)\n }\n }\n }\n\n /**\n * @param {HTMLTableCellElement} $heading\n */\n createHeadingButton($heading) {\n const index = this.$headings.indexOf($heading)\n const $button = document.createElement('button')\n\n $button.setAttribute('type', 'button')\n $button.setAttribute('data-index', `${index}`)\n $button.textContent = $heading.textContent\n\n $heading.textContent = ''\n $heading.appendChild($button)\n }\n\n createStatusBox() {\n this.$status = document.createElement('div')\n\n this.$status.setAttribute('aria-atomic', 'true')\n this.$status.setAttribute('aria-live', 'polite')\n this.$status.setAttribute('class', 'govuk-visually-hidden')\n this.$status.setAttribute('role', 'status')\n\n this.$root.insertAdjacentElement('afterend', this.$status)\n }\n\n initialiseSortedColumn() {\n const $rows = this.getTableRowsArray()\n\n const $heading = this.$root.querySelector(\n 'th[aria-sort=\"ascending\"], th[aria-sort=\"descending\"]'\n )\n const $sortButton = $heading?.querySelector('button')\n const sortDirection = $heading?.getAttribute('aria-sort')\n\n const columnNumber = Number.parseInt(\n $sortButton?.getAttribute('data-index') ?? '0',\n 10\n )\n\n if (\n !$heading ||\n !$sortButton ||\n !(sortDirection === 'ascending' || sortDirection === 'descending')\n ) {\n return\n }\n\n const $sortedRows = this.sort($rows, columnNumber, sortDirection)\n this.addRows($sortedRows)\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onSortButtonClick(event) {\n const $target = /** @type {HTMLElement} */ (event.target)\n const $button = $target.closest('button')\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.parentElement\n ) {\n return\n }\n\n const $heading = $button.parentElement\n const sortDirection = $heading.getAttribute('aria-sort')\n\n const columnNumber = Number.parseInt(\n $button?.getAttribute('data-index') ?? '0',\n 10\n )\n\n const newSortDirection =\n sortDirection === 'none' || sortDirection === 'descending'\n ? 'ascending'\n : 'descending'\n\n const $rows = this.getTableRowsArray()\n const $sortedRows = this.sort($rows, columnNumber, newSortDirection)\n\n this.addRows($sortedRows)\n this.removeButtonStates()\n this.updateButtonState($button, newSortDirection)\n this.updateDirectionIndicators()\n }\n\n updateCaption() {\n if (!this.$caption) {\n return\n }\n\n let assistiveText = this.$caption.querySelector('.govuk-visually-hidden')\n if (assistiveText) {\n return\n }\n\n assistiveText = document.createElement('span')\n assistiveText.classList.add('govuk-visually-hidden')\n assistiveText.textContent = ' (column headers with buttons are sortable).'\n\n this.$caption.appendChild(assistiveText)\n }\n\n /**\n * @param {HTMLButtonElement} $button\n * @param {string} direction\n */\n updateButtonState($button, direction) {\n if (!(direction === 'ascending' || direction === 'descending')) {\n return\n }\n\n $button.parentElement.setAttribute('aria-sort', direction)\n let message = this.config.statusMessage\n message = message.replace(/%heading%/, $button.textContent)\n message = message.replace(/%direction%/, this.config[`${direction}Text`])\n this.$status.textContent = message\n }\n\n updateDirectionIndicators() {\n for (const $heading of this.$headings) {\n const $button = /** @type {HTMLButtonElement} */ (\n $heading.querySelector('button')\n )\n if ($heading.hasAttribute('aria-sort') && $button) {\n const direction = $heading.getAttribute('aria-sort')\n $button.querySelector('svg')?.remove()\n\n switch (direction) {\n case 'ascending':\n $button.insertAdjacentHTML('beforeend', this.$upArrow)\n break\n case 'descending':\n $button.insertAdjacentHTML('beforeend', this.$downArrow)\n break\n default:\n $button.insertAdjacentHTML('beforeend', this.$upDownArrow)\n }\n }\n }\n }\n\n removeButtonStates() {\n for (const $heading of this.$headings) {\n $heading.setAttribute('aria-sort', 'none')\n }\n }\n\n /**\n * @param {HTMLTableRowElement[]} $rows\n */\n addRows($rows) {\n for (const $row of $rows) {\n this.$body.append($row)\n }\n }\n\n getTableRowsArray() {\n return Array.from(this.$body.querySelectorAll('tr'))\n }\n\n /**\n * @param {HTMLTableRowElement[]} $rows\n * @param {number} columnNumber\n * @param {string} sortDirection\n */\n sort($rows, columnNumber, sortDirection) {\n return $rows.sort(($rowA, $rowB) => {\n const $tdA = $rowA.querySelectorAll('td, th')[columnNumber]\n const $tdB = $rowB.querySelectorAll('td, th')[columnNumber]\n\n if (\n !$tdA ||\n !$tdB ||\n !($tdA instanceof HTMLElement) ||\n !($tdB instanceof HTMLElement)\n ) {\n return 0\n }\n\n const valueA =\n sortDirection === 'ascending'\n ? this.getCellValue($tdA)\n : this.getCellValue($tdB)\n\n const valueB =\n sortDirection === 'ascending'\n ? this.getCellValue($tdB)\n : this.getCellValue($tdA)\n\n return !(typeof valueA === 'number' && typeof valueB === 'number')\n ? valueA.toString().localeCompare(valueB.toString())\n : valueA - valueB\n })\n }\n\n /**\n * @param {HTMLElement} $cell\n */\n getCellValue($cell) {\n const val = $cell.getAttribute('data-sort-value') || $cell.innerHTML\n const valAsNumber = Number(val)\n\n return Number.isFinite(valAsNumber)\n ? valAsNumber // Exclude invalid numbers, infinity etc\n : val\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-sortable-table'\n\n /**\n * Sortable table config\n *\n * @type {SortableTableConfig}\n */\n static defaults = Object.freeze({\n statusMessage: 'Sort by %heading% (%direction%)',\n ascendingText: 'ascending',\n descendingText: 'descending'\n })\n\n /**\n * Sortable table config schema\n *\n * @satisfies {Schema<SortableTableConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n statusMessage: { type: 'string' },\n ascendingText: { type: 'string' },\n descendingText: { type: 'string' }\n }\n })\n )\n}\n\n/**\n * Sortable table config\n *\n * @typedef {object} SortableTableConfig\n * @property {string} [statusMessage] - Status message\n * @property {string} [ascendingText] - Ascending text\n * @property {string} [descendingText] - Descending text\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n","import { createAll } from 'govuk-frontend'\n\nimport { version } from './common/moj-frontend-version.mjs'\nimport { AddAnother } from './components/add-another/add-another.mjs'\nimport { Alert } from './components/alert/alert.mjs'\nimport { ButtonMenu } from './components/button-menu/button-menu.mjs'\nimport { DatePicker } from './components/date-picker/date-picker.mjs'\nimport { PdsHeader } from './components/domain-specific/probation/header/header.mjs'\nimport { FilterToggleButton } from './components/filter-toggle-button/filter-toggle-button.mjs'\nimport { FormValidator } from './components/form-validator/form-validator.mjs'\nimport { MultiFileUpload } from './components/multi-file-upload/multi-file-upload.mjs'\nimport { MultiSelect } from './components/multi-select/multi-select.mjs'\nimport { PasswordReveal } from './components/password-reveal/password-reveal.mjs'\nimport { RichTextEditor } from './components/rich-text-editor/rich-text-editor.mjs'\nimport { SearchToggle } from './components/search-toggle/search-toggle.mjs'\nimport { SortableTable } from './components/sortable-table/sortable-table.mjs'\n\n/**\n * @param {Config} [config]\n */\nfunction initAll(config) {\n for (const Component of [\n AddAnother,\n Alert,\n ButtonMenu,\n DatePicker,\n MultiSelect,\n PasswordReveal,\n RichTextEditor,\n SearchToggle,\n SortableTable,\n PdsHeader\n ]) {\n createAll(Component, undefined, config)\n }\n}\n\nexport {\n initAll,\n version,\n\n // Components\n AddAnother,\n Alert,\n ButtonMenu,\n DatePicker,\n FilterToggleButton,\n FormValidator,\n MultiFileUpload,\n MultiSelect,\n PasswordReveal,\n RichTextEditor,\n SearchToggle,\n SortableTable,\n PdsHeader\n}\n\n/**\n * @typedef {Parameters<typeof GOVUKFrontend.initAll>[0]} Config\n */\n\n/**\n * @import * as GOVUKFrontend from 'govuk-frontend'\n */\n"],"names":["isSupported","$scope","document","body","classList","contains","isObject","option","Array","isArray","formatErrorMessage","Component","message","moduleName","GOVUKFrontendError","Error","constructor","args","super","this","name","SupportError","supportMessage","HTMLScriptElement","prototype","ConfigError","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","$root","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","HTMLElement","hasAttribute","isInitialised","configOverride","Symbol","for","ConfigurableComponent","param","config","_config","defaults","datasetConfig","dataset","schema","out","entries","Object","properties","entry","namespace","property","field","toString","normaliseString","type","extractConfigByNamespace","normaliseDataset","mergeConfigs","value","trimmedValue","trim","output","outputType","includes","length","isFinite","Number","configObjects","formattedConfigObject","configObject","key","keys","override","newObject","current","keyParts","split","index","createAll","createAllOptions","onError","_createAllOptions$sco","scope","$elements","querySelectorAll","from","map","$element","error","console","log","filter","Boolean","version","AddAnother","addEventListener","onRemoveButtonClick","bind","onAddButtonClick","forEach","$button","HTMLButtonElement","event","target","$items","getItems","$item","getNewItem","updateAttributes","resetItem","$firstItem","hasRemoveButton","createRemoveButton","after","$input","querySelector","HTMLInputElement","focus","item","cloneNode","isValidInputElement","getAttribute","id","originalId","replace","$label","parentElement","closest","HTMLLabelElement","htmlFor","createElement","add","textContent","append","HTMLSelectElement","selectedIndex","HTMLTextAreaElement","checked","remove","focusHeading","$heading","setFocus","options","_options$onBeforeFocu","isFocusable","onBlur","_options$onBlur","call","removeAttribute","once","onBeforeFocus","removeAttributeValue","attr","re","m","RegExp","match","addAttributeValue","test","Alert","disableAutoFocus","$dismissButton","dismissible","innerHTML","dismissText","Node","dimiss","$elementToRecieveFocus","focusOnDismissSelector","$nextSibling","nextElementSibling","matches","selector","$sibling","previousElementSibling","getPreviousSibling","$currentElement","findNearestMatchingElement","freeze","ButtonMenu","children","className","startsWith","buttonClasses","initMenu","$menu","createMenu","insertAdjacentHTML","toggleTemplate","setupMenuItems","$menuToggle","toggleMenu","handleKeyDown","closeMenu","hidden","alignMenu","appendChild","firstChild","$menuItem","$listItem","insertBefore","tagName","setTimeout","buttonText","isOpen","preventDefault","focusIndex","detail","openMenu","focusItem","moveFocus","currentFocusIndex","$activeElement","activeElement","$menuItems","HTMLAnchorElement","indexOf","DatePicker","_this$config$input$el","input","dayLabels","monthLabels","currentDate","Date","setHours","calendarDays","excludedDates","excludedDays","buttonClass","selectedDayButtonClass","currentDayButtonClass","todayButtonClass","setOptions","initControls","$dialog","createDialog","createCalendarHeaders","$componentWrapper","$inputWrapper","insertAdjacentElement","$calendarButton","$dialogTitle","createCalendar","$prevMonthButton","$prevYearButton","$nextMonthButton","$nextYearButton","$cancelButton","$okButton","focusPreviousMonth","focusPreviousYear","focusNextMonth","focusNextYear","closeDialog","selectDate","$dialogButtons","$firstButtonInDialog","$lastButtonInDialog","firstButtonKeydown","lastButtonKeydown","toggleDialog","stopPropagation","backgroundClick","updateCalendar","titleId","dialogTemplate","$tbody","dayCount","i","$row","insertRow","j","$cell","$dateButton","calendarDay","DSCalendarDay","push","day","html","substring","leadingZeros","ret","setMinAndMaxDatesOnCalendar","setExcludedDates","setExcludedDays","setWeekStartDay","minDate","formattedDateFromString","maxDate","parseDateRangeString","reduce","dates","items","concat","date","datestring","startDate","endDate","d","getTime","setDate","getDate","weekDays","toLowerCase","weekStartDay","unshift","pop","weekStartDayParam","isExcludedDate","excludedDate","toDateString","getDay","dateString","fallback","formattedDate","dateFormatPattern","exec","month","year","formattedDateFromDate","getMonth","getFullYear","formattedDateHuman","shiftKey","firstOfMonth","dayOfWeek","thisDay","disabled","update","setCurrentDate","calendarDayDate","today","inputDate","enabledDays","window","getComputedStyle","display","innerText","changeEvent","Event","bubbles","cancelable","dispatchEvent","openDialog","offsetWidth","style","right","top","offsetHeight","goToDate","focusNextDay","focusPreviousDay","focusNextWeek","focusPreviousWeek","focusFirstDayOfWeek","firstDayOfWeekIndex","diff","focusLastDayOfWeek","lastDayOfWeekIndex","setMonth","setFullYear","row","column","picker","keyPress","click","label","accessibleLabel","calendarNavKey","PdsHeader","initHeader","$tabOpenClass","$userToggle","$userMenu","hideFallbackLinks","closeTabs","_event","tabTuples","toggle","menu","textForShow","textForHide","$userLink","FilterToggleButton","_this$config$toggleBu","_this$config$closeBut","$toggleButtonContainer","toggleButtonContainer","$closeButtonContainer","closeButtonContainer","createToggleButton","setupResponsiveChecks","startHidden","hideMenu","mq","matchMedia","bigModeMediaQuery","addListener","checkMode","$menuButton","toggleButton","classes","showText","onMenuButtonClick","enableBigMode","enableSmallMode","showMenu","removeCloseButton","addCloseButton","$closeButton","closeButton","text","onCloseClick","hideText","FormValidator","$summary","summary","errors","validators","originalTitle","title","onSubmit","escapeHtml","string","String","entityMap","resetTitle","updateTitle","showSummary","getSummaryHtml","fieldName","hideSummary","removeInlineErrors","validate","showInlineErrors","showInlineError","$errorSpan","$control","$fieldset","$fieldContainer","$legend","removeInlineError","addValidator","rules","elements","namedItem","validator","validatorReturnValue","method","params","MultiFileUpload","_this$config$feedback","$feedbackContainer","feedbackContainer","setupFileInput","setupDropzone","setupLabel","setupStatusBox","onFileDeleteClick","$dropzone","onDragOver","onDragLeave","onDrop","$fileInput","replaceWith","dropzoneButtonText","$hint","dropzoneHintText","onFileChange","onFileFocus","onFileBlur","$status","uploadStatusText","uploadFiles","dataTransfer","files","file","uploadFile","getSuccessHtml","success","messageHtml","getErrorHtml","getFileRow","getDeleteButton","filename","originalname","hooks","entryHook","$message","$actions","$progress","formData","FormData","xhr","XMLHttpRequest","response","statusText","errorHook","responseText","onLoad","status","messageText","exitHook","upload","lengthComputable","percentComplete","Math","round","loaded","total","open","uploadUrl","responseType","send","$rows","$rowDelete","find","deleteHook","undefined","deleteUrl","setRequestHeader","JSON","stringify","isDragAndDropSupported","isFormDataSupported","isFileApiSupported","ondrop","MultiSelect","_this$config$checkbox","$container","idPrefix","$checkboxes","checkboxes","setupToggle","$toggleButton","$toggle","onButtonClick","onCheckboxClick","$span","uncheckAll","checkAll","PasswordReveal","createButton","$group","RichTextEditor","$textarea","createToolbar","hideDefault","configureToolbar","left","up","down","$content","onEditorInput","onLabelClick","$toolbar","onToolbarKeydown","$focusableButton","keyCode","$buttons","button","$nextButton","$previousButton","getToolbarHtml","toolbar","bold","italic","underline","bullets","numbers","getEnhancedHtml","currentTarget","execCommand","getContent","updateTextarea","documentElement","SearchToggle","_this$config$searchCo","$searchContainer","searchContainer","onToggleButtonClick","onDocumentClick","SortableTable","$head","$body","$caption","$upArrow","$downArrow","$upDownArrow","$headings","createHeadingButtons","updateCaption","updateDirectionIndicators","createStatusBox","initialiseSortedColumn","onSortButtonClick","createHeadingButton","_$sortButton$getAttri","getTableRowsArray","$sortButton","sortDirection","columnNumber","parseInt","$sortedRows","sort","addRows","_$button$getAttribute","newSortDirection","removeButtonStates","updateButtonState","assistiveText","direction","statusMessage","_$button$querySelecto","$rowA","$rowB","$tdA","$tdB","valueA","getCellValue","valueB","localeCompare","val","valAsNumber","initAll","ascendingText","descendingText"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]}