@ministryofjustice/frontend 5.0.0 → 5.1.0
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.
- package/moj/all.bundle.js +1549 -1062
- package/moj/all.bundle.js.map +1 -1
- package/moj/all.bundle.mjs +1845 -1054
- package/moj/all.bundle.mjs.map +1 -1
- package/moj/all.mjs +7 -90
- package/moj/all.mjs.map +1 -1
- package/moj/all.scss +1 -0
- package/moj/all.scss.map +1 -1
- package/moj/common/index.mjs +57 -0
- package/moj/common/index.mjs.map +1 -0
- package/moj/common/moj-frontend-version.mjs +14 -0
- package/moj/common/moj-frontend-version.mjs.map +1 -0
- package/moj/components/add-another/add-another.bundle.js +105 -76
- package/moj/components/add-another/add-another.bundle.js.map +1 -1
- package/moj/components/add-another/add-another.bundle.mjs +222 -71
- package/moj/components/add-another/add-another.bundle.mjs.map +1 -1
- package/moj/components/add-another/add-another.mjs +103 -72
- package/moj/components/add-another/add-another.mjs.map +1 -1
- package/moj/components/alert/alert.bundle.js +115 -191
- package/moj/components/alert/alert.bundle.js.map +1 -1
- package/moj/components/alert/alert.bundle.mjs +354 -186
- package/moj/components/alert/alert.bundle.mjs.map +1 -1
- package/moj/components/alert/alert.mjs +55 -140
- package/moj/components/alert/alert.mjs.map +1 -1
- package/moj/components/button-menu/README.md +3 -1
- package/moj/components/button-menu/button-menu.bundle.js +91 -120
- package/moj/components/button-menu/button-menu.bundle.js.map +1 -1
- package/moj/components/button-menu/button-menu.bundle.mjs +329 -114
- package/moj/components/button-menu/button-menu.bundle.mjs.map +1 -1
- package/moj/components/button-menu/button-menu.mjs +89 -116
- package/moj/components/button-menu/button-menu.mjs.map +1 -1
- package/moj/components/date-picker/date-picker.bundle.js +174 -154
- package/moj/components/date-picker/date-picker.bundle.js.map +1 -1
- package/moj/components/date-picker/date-picker.bundle.mjs +411 -147
- package/moj/components/date-picker/date-picker.bundle.mjs.map +1 -1
- package/moj/components/date-picker/date-picker.mjs +172 -150
- package/moj/components/date-picker/date-picker.mjs.map +1 -1
- package/moj/components/filter/template.njk +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js +133 -44
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js.map +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs +374 -41
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs.map +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.mjs +131 -40
- package/moj/components/filter-toggle-button/filter-toggle-button.mjs.map +1 -1
- package/moj/components/form-validator/form-validator.bundle.js +159 -69
- package/moj/components/form-validator/form-validator.bundle.js.map +1 -1
- package/moj/components/form-validator/form-validator.bundle.mjs +399 -65
- package/moj/components/form-validator/form-validator.bundle.mjs.map +1 -1
- package/moj/components/form-validator/form-validator.mjs +134 -54
- package/moj/components/form-validator/form-validator.mjs.map +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.bundle.js +291 -117
- package/moj/components/multi-file-upload/multi-file-upload.bundle.js.map +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs +527 -109
- package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs.map +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.mjs +288 -101
- package/moj/components/multi-file-upload/multi-file-upload.mjs.map +1 -1
- package/moj/components/multi-file-upload/template.njk +1 -1
- package/moj/components/multi-select/multi-select.bundle.js +106 -41
- package/moj/components/multi-select/multi-select.bundle.js.map +1 -1
- package/moj/components/multi-select/multi-select.bundle.mjs +346 -37
- package/moj/components/multi-select/multi-select.bundle.mjs.map +1 -1
- package/moj/components/multi-select/multi-select.mjs +104 -37
- package/moj/components/multi-select/multi-select.mjs.map +1 -1
- package/moj/components/password-reveal/_password-reveal.scss +3 -1
- package/moj/components/password-reveal/_password-reveal.scss.map +1 -1
- package/moj/components/password-reveal/password-reveal.bundle.js +32 -29
- package/moj/components/password-reveal/password-reveal.bundle.js.map +1 -1
- package/moj/components/password-reveal/password-reveal.bundle.mjs +149 -24
- package/moj/components/password-reveal/password-reveal.bundle.mjs.map +1 -1
- package/moj/components/password-reveal/password-reveal.mjs +30 -25
- package/moj/components/password-reveal/password-reveal.mjs.map +1 -1
- package/moj/components/rich-text-editor/README.md +4 -3
- package/moj/components/rich-text-editor/rich-text-editor.bundle.js +127 -62
- package/moj/components/rich-text-editor/rich-text-editor.bundle.js.map +1 -1
- package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs +367 -58
- package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs.map +1 -1
- package/moj/components/rich-text-editor/rich-text-editor.mjs +125 -58
- package/moj/components/rich-text-editor/rich-text-editor.mjs.map +1 -1
- package/moj/components/search-toggle/search-toggle.bundle.js +94 -26
- package/moj/components/search-toggle/search-toggle.bundle.js.map +1 -1
- package/moj/components/search-toggle/search-toggle.bundle.mjs +334 -22
- package/moj/components/search-toggle/search-toggle.bundle.mjs.map +1 -1
- package/moj/components/search-toggle/search-toggle.mjs +92 -22
- package/moj/components/search-toggle/search-toggle.mjs.map +1 -1
- package/moj/components/sortable-table/sortable-table.bundle.js +151 -83
- package/moj/components/sortable-table/sortable-table.bundle.js.map +1 -1
- package/moj/components/sortable-table/sortable-table.bundle.mjs +390 -78
- package/moj/components/sortable-table/sortable-table.bundle.mjs.map +1 -1
- package/moj/components/sortable-table/sortable-table.mjs +149 -79
- package/moj/components/sortable-table/sortable-table.mjs.map +1 -1
- package/moj/core/_all.scss +3 -0
- package/moj/core/_all.scss.map +1 -0
- package/moj/core/_moj-frontend-properties.scss +7 -0
- package/moj/core/_moj-frontend-properties.scss.map +1 -0
- package/moj/filters/prototype-kit-13-filters.js +4 -3
- package/moj/helpers.bundle.js +22 -77
- package/moj/helpers.bundle.js.map +1 -1
- package/moj/helpers.bundle.mjs +23 -74
- package/moj/helpers.bundle.mjs.map +1 -1
- package/moj/helpers.mjs +23 -74
- package/moj/helpers.mjs.map +1 -1
- package/moj/moj-frontend.min.css +1 -1
- package/moj/moj-frontend.min.css.map +1 -1
- package/moj/moj-frontend.min.js +1 -1
- package/moj/moj-frontend.min.js.map +1 -1
- package/package.json +1 -1
- package/moj/version.bundle.js +0 -12
- package/moj/version.bundle.js.map +0 -1
- package/moj/version.bundle.mjs +0 -4
- package/moj/version.bundle.mjs.map +0 -1
- package/moj/version.mjs +0 -4
- package/moj/version.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rich-text-editor.bundle.mjs","sources":["../../../../src/moj/components/rich-text-editor/rich-text-editor.mjs"],"sourcesContent":["export class RichTextEditor {\n /**\n * @param {RichTextEditorConfig} options\n */\n constructor(options = {}) {\n const { textarea } = options\n\n if (\n !textarea ||\n !textarea.parentElement ||\n !(textarea instanceof HTMLTextAreaElement) ||\n !('contentEditable' in document.documentElement)\n ) {\n return this\n }\n\n options.toolbar = options.toolbar || {\n bold: false,\n italic: false,\n underline: false,\n bullets: true,\n numbers: true\n }\n\n this.textarea = textarea\n this.container = this.textarea.parentElement\n this.options = options\n\n if (this.container.hasAttribute('data-rich-text-editor-init')) {\n return this\n }\n\n this.container.setAttribute('data-rich-text-editor-init', '')\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.container\n .querySelector('label')\n .addEventListener('click', this.onLabelClick.bind(this))\n\n this.toolbar.addEventListener('keydown', this.onToolbarKeydown.bind(this))\n }\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 const nextButton = focusableButton.nextElementSibling\n if (nextButton instanceof HTMLButtonElement) {\n nextButton.focus()\n focusableButton.setAttribute('tabindex', '-1')\n nextButton.setAttribute('tabindex', '0')\n }\n break\n }\n case this.keys.left:\n case this.keys.up: {\n focusableButton = this.buttons.find(\n (button) => button.getAttribute('tabindex') === '0'\n )\n const previousButton = focusableButton.previousElementSibling\n if (previousButton instanceof HTMLButtonElement) {\n previousButton.focus()\n focusableButton.setAttribute('tabindex', '-1')\n previousButton.setAttribute('tabindex', '0')\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.options.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.options.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.options.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.options.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.options.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.container.append(this.toolbar)\n\n this.content = /** @type {HTMLDivElement} */ (\n this.container.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.container.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 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 onLabelClick(event) {\n event.preventDefault()\n this.content.focus()\n }\n}\n"],"names":["RichTextEditor","constructor","options","textarea","parentElement","HTMLTextAreaElement","document","documentElement","toolbar","bold","italic","underline","bullets","numbers","container","hasAttribute","setAttribute","createToolbar","hideDefault","configureToolbar","keys","left","right","up","down","content","addEventListener","onEditorInput","bind","querySelector","onLabelClick","onToolbarKeydown","event","focusableButton","keyCode","buttons","find","button","getAttribute","nextButton","nextElementSibling","HTMLButtonElement","focus","previousButton","previousElementSibling","getToolbarHtml","html","getEnhancedHtml","classList","add","createElement","className","innerHTML","append","$textarea","value","Array","from","querySelectorAll","forEach","index","onButtonClick","currentTarget","HTMLElement","execCommand","undefined","getContent","updateTextarea","preventDefault"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rich-text-editor.bundle.mjs","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","../../../../src/moj/components/rich-text-editor/rich-text-editor.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 { 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"],"names":["isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","document","body","classList","contains","isArray","option","Array","isObject","formatErrorMessage","Component","message","GOVUKFrontendError","Error","constructor","args","name","SupportError","supportMessage","HTMLScriptElement","prototype","ConfigError","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","configOverride","Symbol","for","ConfigurableComponent","param","config","_config","defaults","datasetConfig","normaliseDataset","dataset","mergeConfigs","normaliseString","value","property","trimmedValue","trim","output","outputType","type","includes","length","isFinite","Number","schema","out","entries","Object","properties","entry","namespace","field","toString","extractConfigByNamespace","configObjects","formattedConfigObject","configObject","key","keys","override","newObject","current","keyParts","split","index","RichTextEditor","$textarea","querySelector","HTMLTextAreaElement","createToolbar","hideDefault","configureToolbar","left","right","up","down","$content","addEventListener","onEditorInput","bind","onLabelClick","$toolbar","onToolbarKeydown","event","$focusableButton","keyCode","$buttons","find","button","getAttribute","$nextButton","nextElementSibling","HTMLButtonElement","focus","$previousButton","previousElementSibling","getToolbarHtml","html","toolbar","bold","italic","underline","bullets","numbers","getEnhancedHtml","add","createElement","className","innerHTML","append","from","querySelectorAll","forEach","$button","onButtonClick","currentTarget","execCommand","undefined","getContent","updateTextarea","preventDefault","documentElement","freeze"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|
|
@@ -1,28 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
import { ConfigurableComponent } from 'govuk-frontend';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @augments {ConfigurableComponent<RichTextEditorConfig>}
|
|
5
|
+
*/
|
|
6
|
+
class RichTextEditor extends ConfigurableComponent {
|
|
2
7
|
/**
|
|
3
|
-
* @param {
|
|
8
|
+
* @param {Element | null} $root - HTML element to use for rich text editor
|
|
9
|
+
* @param {RichTextEditorConfig} config
|
|
4
10
|
*/
|
|
5
|
-
constructor(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} = options;
|
|
9
|
-
if (!textarea || !textarea.parentElement || !(textarea instanceof HTMLTextAreaElement) || !('contentEditable' in document.documentElement)) {
|
|
11
|
+
constructor($root, config = {}) {
|
|
12
|
+
super($root, config);
|
|
13
|
+
if (!RichTextEditor.isSupported()) {
|
|
10
14
|
return this;
|
|
11
15
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
italic: false,
|
|
15
|
-
underline: false,
|
|
16
|
-
bullets: true,
|
|
17
|
-
numbers: true
|
|
18
|
-
};
|
|
19
|
-
this.textarea = textarea;
|
|
20
|
-
this.container = this.textarea.parentElement;
|
|
21
|
-
this.options = options;
|
|
22
|
-
if (this.container.hasAttribute('data-rich-text-editor-init')) {
|
|
16
|
+
const $textarea = this.$root.querySelector('.govuk-textarea');
|
|
17
|
+
if (!$textarea || !($textarea instanceof HTMLTextAreaElement)) {
|
|
23
18
|
return this;
|
|
24
19
|
}
|
|
25
|
-
this
|
|
20
|
+
this.$textarea = $textarea;
|
|
26
21
|
this.createToolbar();
|
|
27
22
|
this.hideDefault();
|
|
28
23
|
this.configureToolbar();
|
|
@@ -32,34 +27,42 @@ class RichTextEditor {
|
|
|
32
27
|
up: 38,
|
|
33
28
|
down: 40
|
|
34
29
|
};
|
|
35
|
-
this
|
|
36
|
-
this.
|
|
37
|
-
this
|
|
30
|
+
this.$content.addEventListener('input', this.onEditorInput.bind(this));
|
|
31
|
+
this.$root.querySelector('label').addEventListener('click', this.onLabelClick.bind(this));
|
|
32
|
+
this.$toolbar.addEventListener('keydown', this.onToolbarKeydown.bind(this));
|
|
38
33
|
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {KeyboardEvent} event - Click event
|
|
37
|
+
*/
|
|
39
38
|
onToolbarKeydown(event) {
|
|
40
|
-
let focusableButton;
|
|
39
|
+
let $focusableButton;
|
|
41
40
|
switch (event.keyCode) {
|
|
42
41
|
case this.keys.right:
|
|
43
42
|
case this.keys.down:
|
|
44
43
|
{
|
|
45
|
-
focusableButton = this
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
nextButton
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
$focusableButton = this.$buttons.find(button => button.getAttribute('tabindex') === '0');
|
|
45
|
+
if ($focusableButton) {
|
|
46
|
+
const $nextButton = $focusableButton.nextElementSibling;
|
|
47
|
+
if ($nextButton && $nextButton instanceof HTMLButtonElement) {
|
|
48
|
+
$nextButton.focus();
|
|
49
|
+
$focusableButton.setAttribute('tabindex', '-1');
|
|
50
|
+
$nextButton.setAttribute('tabindex', '0');
|
|
51
|
+
}
|
|
51
52
|
}
|
|
52
53
|
break;
|
|
53
54
|
}
|
|
54
55
|
case this.keys.left:
|
|
55
56
|
case this.keys.up:
|
|
56
57
|
{
|
|
57
|
-
focusableButton = this
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
previousButton
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
$focusableButton = this.$buttons.find(button => button.getAttribute('tabindex') === '0');
|
|
59
|
+
if ($focusableButton) {
|
|
60
|
+
const $previousButton = $focusableButton.previousElementSibling;
|
|
61
|
+
if ($previousButton && $previousButton instanceof HTMLButtonElement) {
|
|
62
|
+
$previousButton.focus();
|
|
63
|
+
$focusableButton.setAttribute('tabindex', '-1');
|
|
64
|
+
$previousButton.setAttribute('tabindex', '0');
|
|
65
|
+
}
|
|
63
66
|
}
|
|
64
67
|
break;
|
|
65
68
|
}
|
|
@@ -68,19 +71,19 @@ class RichTextEditor {
|
|
|
68
71
|
getToolbarHtml() {
|
|
69
72
|
let html = '';
|
|
70
73
|
html += '<div class="moj-rich-text-editor__toolbar" role="toolbar">';
|
|
71
|
-
if (this.
|
|
74
|
+
if (this.config.toolbar.bold) {
|
|
72
75
|
html += '<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>';
|
|
73
76
|
}
|
|
74
|
-
if (this.
|
|
77
|
+
if (this.config.toolbar.italic) {
|
|
75
78
|
html += '<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>';
|
|
76
79
|
}
|
|
77
|
-
if (this.
|
|
80
|
+
if (this.config.toolbar.underline) {
|
|
78
81
|
html += '<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>';
|
|
79
82
|
}
|
|
80
|
-
if (this.
|
|
83
|
+
if (this.config.toolbar.bullets) {
|
|
81
84
|
html += '<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>';
|
|
82
85
|
}
|
|
83
|
-
if (this.
|
|
86
|
+
if (this.config.toolbar.numbers) {
|
|
84
87
|
html += '<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>';
|
|
85
88
|
}
|
|
86
89
|
html += '</div>';
|
|
@@ -90,27 +93,31 @@ class RichTextEditor {
|
|
|
90
93
|
return `${this.getToolbarHtml()}<div class="govuk-textarea moj-rich-text-editor__content" contenteditable="true" spellcheck="false"></div>`;
|
|
91
94
|
}
|
|
92
95
|
hideDefault() {
|
|
93
|
-
this
|
|
94
|
-
this
|
|
95
|
-
this
|
|
96
|
+
this.$textarea.classList.add('govuk-visually-hidden');
|
|
97
|
+
this.$textarea.setAttribute('aria-hidden', 'true');
|
|
98
|
+
this.$textarea.setAttribute('tabindex', '-1');
|
|
96
99
|
}
|
|
97
100
|
createToolbar() {
|
|
98
|
-
this
|
|
99
|
-
this
|
|
100
|
-
this
|
|
101
|
-
this.
|
|
102
|
-
this
|
|
103
|
-
this.
|
|
104
|
-
this
|
|
101
|
+
this.$toolbar = document.createElement('div');
|
|
102
|
+
this.$toolbar.className = 'moj-rich-text-editor';
|
|
103
|
+
this.$toolbar.innerHTML = this.getEnhancedHtml();
|
|
104
|
+
this.$root.append(this.$toolbar);
|
|
105
|
+
this.$content = /** @type {HTMLElement} */
|
|
106
|
+
this.$root.querySelector('.moj-rich-text-editor__content');
|
|
107
|
+
this.$content.innerHTML = this.$textarea.value;
|
|
105
108
|
}
|
|
106
109
|
configureToolbar() {
|
|
107
|
-
this
|
|
108
|
-
this.
|
|
109
|
-
this
|
|
110
|
-
button.setAttribute('tabindex', !index ? '0' : '-1');
|
|
111
|
-
button.addEventListener('click', this.onButtonClick.bind(this));
|
|
110
|
+
this.$buttons = Array.from(/** @type {NodeListOf<HTMLButtonElement>} */
|
|
111
|
+
this.$root.querySelectorAll('.moj-rich-text-editor__toolbar-button'));
|
|
112
|
+
this.$buttons.forEach(($button, index) => {
|
|
113
|
+
$button.setAttribute('tabindex', !index ? '0' : '-1');
|
|
114
|
+
$button.addEventListener('click', this.onButtonClick.bind(this));
|
|
112
115
|
});
|
|
113
116
|
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {MouseEvent} event - Click event
|
|
120
|
+
*/
|
|
114
121
|
onButtonClick(event) {
|
|
115
122
|
if (!(event.currentTarget instanceof HTMLElement)) {
|
|
116
123
|
return;
|
|
@@ -118,20 +125,80 @@ class RichTextEditor {
|
|
|
118
125
|
document.execCommand(event.currentTarget.getAttribute('data-command'), false, undefined);
|
|
119
126
|
}
|
|
120
127
|
getContent() {
|
|
121
|
-
return this
|
|
128
|
+
return this.$content.innerHTML;
|
|
122
129
|
}
|
|
123
130
|
onEditorInput() {
|
|
124
131
|
this.updateTextarea();
|
|
125
132
|
}
|
|
126
133
|
updateTextarea() {
|
|
127
134
|
document.execCommand('defaultParagraphSeparator', false, 'p');
|
|
128
|
-
this
|
|
135
|
+
this.$textarea.value = this.getContent();
|
|
129
136
|
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @param {MouseEvent} event - Click event
|
|
140
|
+
*/
|
|
130
141
|
onLabelClick(event) {
|
|
131
142
|
event.preventDefault();
|
|
132
|
-
this
|
|
143
|
+
this.$content.focus();
|
|
133
144
|
}
|
|
145
|
+
static isSupported() {
|
|
146
|
+
return 'contentEditable' in document.documentElement;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Name for the component used when initialising using data-module attributes.
|
|
151
|
+
*/
|
|
134
152
|
}
|
|
135
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Rich text editor config
|
|
156
|
+
*
|
|
157
|
+
* @typedef {object} RichTextEditorConfig
|
|
158
|
+
* @property {RichTextEditorToolbar} [toolbar] - Toolbar options
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Rich text editor toolbar options
|
|
163
|
+
*
|
|
164
|
+
* @typedef {object} RichTextEditorToolbar
|
|
165
|
+
* @property {boolean} [bold] - Show the bold button
|
|
166
|
+
* @property {boolean} [italic] - Show the italic button
|
|
167
|
+
* @property {boolean} [underline] - Show the underline button
|
|
168
|
+
* @property {boolean} [bullets] - Show the bullets button
|
|
169
|
+
* @property {boolean} [numbers] - Show the numbers button
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'
|
|
174
|
+
*/
|
|
175
|
+
RichTextEditor.moduleName = 'moj-rich-text-editor';
|
|
176
|
+
/**
|
|
177
|
+
* Rich text editor config
|
|
178
|
+
*
|
|
179
|
+
* @type {RichTextEditorConfig}
|
|
180
|
+
*/
|
|
181
|
+
RichTextEditor.defaults = Object.freeze({
|
|
182
|
+
toolbar: {
|
|
183
|
+
bold: false,
|
|
184
|
+
italic: false,
|
|
185
|
+
underline: false,
|
|
186
|
+
bullets: true,
|
|
187
|
+
numbers: true
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
/**
|
|
191
|
+
* Rich text editor config schema
|
|
192
|
+
*
|
|
193
|
+
* @satisfies {Schema<RichTextEditorConfig>}
|
|
194
|
+
*/
|
|
195
|
+
RichTextEditor.schema = Object.freeze(/** @type {const} */{
|
|
196
|
+
properties: {
|
|
197
|
+
toolbar: {
|
|
198
|
+
type: 'object'
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
136
203
|
export { RichTextEditor };
|
|
137
204
|
//# sourceMappingURL=rich-text-editor.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rich-text-editor.mjs","sources":["../../../../src/moj/components/rich-text-editor/rich-text-editor.mjs"],"sourcesContent":["export class RichTextEditor {\n /**\n * @param {RichTextEditorConfig} options\n */\n constructor(options = {}) {\n const { textarea } = options\n\n if (\n !textarea ||\n !textarea.parentElement ||\n !(textarea instanceof HTMLTextAreaElement) ||\n !('contentEditable' in document.documentElement)\n ) {\n return this\n }\n\n options.toolbar = options.toolbar || {\n bold: false,\n italic: false,\n underline: false,\n bullets: true,\n numbers: true\n }\n\n this.textarea = textarea\n this.container = this.textarea.parentElement\n this.options = options\n\n if (this.container.hasAttribute('data-rich-text-editor-init')) {\n return this\n }\n\n this.container.setAttribute('data-rich-text-editor-init', '')\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.container\n .querySelector('label')\n .addEventListener('click', this.onLabelClick.bind(this))\n\n this.toolbar.addEventListener('keydown', this.onToolbarKeydown.bind(this))\n }\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 const nextButton = focusableButton.nextElementSibling\n if (nextButton instanceof HTMLButtonElement) {\n nextButton.focus()\n focusableButton.setAttribute('tabindex', '-1')\n nextButton.setAttribute('tabindex', '0')\n }\n break\n }\n case this.keys.left:\n case this.keys.up: {\n focusableButton = this.buttons.find(\n (button) => button.getAttribute('tabindex') === '0'\n )\n const previousButton = focusableButton.previousElementSibling\n if (previousButton instanceof HTMLButtonElement) {\n previousButton.focus()\n focusableButton.setAttribute('tabindex', '-1')\n previousButton.setAttribute('tabindex', '0')\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.options.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.options.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.options.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.options.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.options.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.container.append(this.toolbar)\n\n this.content = /** @type {HTMLDivElement} */ (\n this.container.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.container.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 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 onLabelClick(event) {\n event.preventDefault()\n this.content.focus()\n }\n}\n"],"names":["RichTextEditor","constructor","options","textarea","parentElement","HTMLTextAreaElement","document","documentElement","toolbar","bold","italic","underline","bullets","numbers","container","hasAttribute","setAttribute","createToolbar","hideDefault","configureToolbar","keys","left","right","up","down","content","addEventListener","onEditorInput","bind","querySelector","onLabelClick","onToolbarKeydown","event","focusableButton","keyCode","buttons","find","button","getAttribute","nextButton","nextElementSibling","HTMLButtonElement","focus","previousButton","previousElementSibling","getToolbarHtml","html","getEnhancedHtml","classList","add","createElement","className","innerHTML","append","$textarea","value","Array","from","querySelectorAll","forEach","index","onButtonClick","currentTarget","HTMLElement","execCommand","undefined","getContent","updateTextarea","preventDefault"],"mappings":"AAAO,MAAMA,cAAc,CAAC;AAC1B;AACF;AACA;AACEC,EAAAA,WAAWA,CAACC,OAAO,GAAG,EAAE,EAAE;IACxB,MAAM;AAAEC,MAAAA;AAAS,KAAC,GAAGD,OAAO;IAE5B,IACE,CAACC,QAAQ,IACT,CAACA,QAAQ,CAACC,aAAa,IACvB,EAAED,QAAQ,YAAYE,mBAAmB,CAAC,IAC1C,EAAE,iBAAiB,IAAIC,QAAQ,CAACC,eAAe,CAAC,EAChD;AACA,MAAA,OAAO,IAAI;AACb;AAEAL,IAAAA,OAAO,CAACM,OAAO,GAAGN,OAAO,CAACM,OAAO,IAAI;AACnCC,MAAAA,IAAI,EAAE,KAAK;AACXC,MAAAA,MAAM,EAAE,KAAK;AACbC,MAAAA,SAAS,EAAE,KAAK;AAChBC,MAAAA,OAAO,EAAE,IAAI;AACbC,MAAAA,OAAO,EAAE;KACV;IAED,IAAI,CAACV,QAAQ,GAAGA,QAAQ;AACxB,IAAA,IAAI,CAACW,SAAS,GAAG,IAAI,CAACX,QAAQ,CAACC,aAAa;IAC5C,IAAI,CAACF,OAAO,GAAGA,OAAO;IAEtB,IAAI,IAAI,CAACY,SAAS,CAACC,YAAY,CAAC,4BAA4B,CAAC,EAAE;AAC7D,MAAA,OAAO,IAAI;AACb;IAEA,IAAI,CAACD,SAAS,CAACE,YAAY,CAAC,4BAA4B,EAAE,EAAE,CAAC;IAE7D,IAAI,CAACC,aAAa,EAAE;IACpB,IAAI,CAACC,WAAW,EAAE;IAClB,IAAI,CAACC,gBAAgB,EAAE;IAEvB,IAAI,CAACC,IAAI,GAAG;AACVC,MAAAA,IAAI,EAAE,EAAE;AACRC,MAAAA,KAAK,EAAE,EAAE;AACTC,MAAAA,EAAE,EAAE,EAAE;AACNC,MAAAA,IAAI,EAAE;KACP;AAED,IAAA,IAAI,CAACC,OAAO,CAACC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACC,aAAa,CAACC,IAAI,CAAC,IAAI,CAAC,CAAC;IAErE,IAAI,CAACd,SAAS,CACXe,aAAa,CAAC,OAAO,CAAC,CACtBH,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACI,YAAY,CAACF,IAAI,CAAC,IAAI,CAAC,CAAC;AAE1D,IAAA,IAAI,CAACpB,OAAO,CAACkB,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAACK,gBAAgB,CAACH,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5E;EAEAG,gBAAgBA,CAACC,KAAK,EAAE;AACtB,IAAA,IAAIC,eAAe;IACnB,QAAQD,KAAK,CAACE,OAAO;AACnB,MAAA,KAAK,IAAI,CAACd,IAAI,CAACE,KAAK;AACpB,MAAA,KAAK,IAAI,CAACF,IAAI,CAACI,IAAI;AAAE,QAAA;AACnBS,UAAAA,eAAe,GAAG,IAAI,CAACE,OAAO,CAACC,IAAI,CAChCC,MAAM,IAAKA,MAAM,CAACC,YAAY,CAAC,UAAU,CAAC,KAAK,GAClD,CAAC;AACD,UAAA,MAAMC,UAAU,GAAGN,eAAe,CAACO,kBAAkB;UACrD,IAAID,UAAU,YAAYE,iBAAiB,EAAE;YAC3CF,UAAU,CAACG,KAAK,EAAE;AAClBT,YAAAA,eAAe,CAACjB,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;AAC9CuB,YAAAA,UAAU,CAACvB,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC;AAC1C;AACA,UAAA;AACF;AACA,MAAA,KAAK,IAAI,CAACI,IAAI,CAACC,IAAI;AACnB,MAAA,KAAK,IAAI,CAACD,IAAI,CAACG,EAAE;AAAE,QAAA;AACjBU,UAAAA,eAAe,GAAG,IAAI,CAACE,OAAO,CAACC,IAAI,CAChCC,MAAM,IAAKA,MAAM,CAACC,YAAY,CAAC,UAAU,CAAC,KAAK,GAClD,CAAC;AACD,UAAA,MAAMK,cAAc,GAAGV,eAAe,CAACW,sBAAsB;UAC7D,IAAID,cAAc,YAAYF,iBAAiB,EAAE;YAC/CE,cAAc,CAACD,KAAK,EAAE;AACtBT,YAAAA,eAAe,CAACjB,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;AAC9C2B,YAAAA,cAAc,CAAC3B,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC;AAC9C;AACA,UAAA;AACF;AACF;AACF;AAEA6B,EAAAA,cAAcA,GAAG;IACf,IAAIC,IAAI,GAAG,EAAE;AAEbA,IAAAA,IAAI,IAAI,4DAA4D;AAEpE,IAAA,IAAI,IAAI,CAAC5C,OAAO,CAACM,OAAO,CAACC,IAAI,EAAE;AAC7BqC,MAAAA,IAAI,IACF,4LAA4L;AAChM;AAEA,IAAA,IAAI,IAAI,CAAC5C,OAAO,CAACM,OAAO,CAACE,MAAM,EAAE;AAC/BoC,MAAAA,IAAI,IACF,kMAAkM;AACtM;AAEA,IAAA,IAAI,IAAI,CAAC5C,OAAO,CAACM,OAAO,CAACG,SAAS,EAAE;AAClCmC,MAAAA,IAAI,IACF,2MAA2M;AAC/M;AAEA,IAAA,IAAI,IAAI,CAAC5C,OAAO,CAACM,OAAO,CAACI,OAAO,EAAE;AAChCkC,MAAAA,IAAI,IACF,+NAA+N;AACnO;AAEA,IAAA,IAAI,IAAI,CAAC5C,OAAO,CAACM,OAAO,CAACK,OAAO,EAAE;AAChCiC,MAAAA,IAAI,IACF,yNAAyN;AAC7N;AAEAA,IAAAA,IAAI,IAAI,QAAQ;AAChB,IAAA,OAAOA,IAAI;AACb;AAEAC,EAAAA,eAAeA,GAAG;AAChB,IAAA,OAAO,GAAG,IAAI,CAACF,cAAc,EAAE,CAA4G,0GAAA,CAAA;AAC7I;AAEA3B,EAAAA,WAAWA,GAAG;IACZ,IAAI,CAACf,QAAQ,CAAC6C,SAAS,CAACC,GAAG,CAAC,uBAAuB,CAAC;IACpD,IAAI,CAAC9C,QAAQ,CAACa,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC;IACjD,IAAI,CAACb,QAAQ,CAACa,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;AAC9C;AAEAC,EAAAA,aAAaA,GAAG;IACd,IAAI,CAACT,OAAO,GAAGF,QAAQ,CAAC4C,aAAa,CAAC,KAAK,CAAC;AAC5C,IAAA,IAAI,CAAC1C,OAAO,CAAC2C,SAAS,GAAG,sBAAsB;IAC/C,IAAI,CAAC3C,OAAO,CAAC4C,SAAS,GAAG,IAAI,CAACL,eAAe,EAAE;IAC/C,IAAI,CAACjC,SAAS,CAACuC,MAAM,CAAC,IAAI,CAAC7C,OAAO,CAAC;IAEnC,IAAI,CAACiB,OAAO;AACV,IAAA,IAAI,CAACX,SAAS,CAACe,aAAa,CAAC,gCAAgC,CAC9D;IAED,IAAI,CAACJ,OAAO,CAAC2B,SAAS,GAAG,IAAI,CAACE,SAAS,CAACC,KAAK;AAC/C;AAEApC,EAAAA,gBAAgBA,GAAG;AACjB,IAAA,IAAI,CAACgB,OAAO,GAAGqB,KAAK,CAACC,IAAI;AAEtB,IAAA,IAAI,CAAC3C,SAAS,CAAC4C,gBAAgB,CAAC,uCAAuC,CAC1E,CAAC;IAED,IAAI,CAACvB,OAAO,CAACwB,OAAO,CAAC,CAACtB,MAAM,EAAEuB,KAAK,KAAK;MACtCvB,MAAM,CAACrB,YAAY,CAAC,UAAU,EAAE,CAAC4C,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC;AACpDvB,MAAAA,MAAM,CAACX,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACmC,aAAa,CAACjC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjE,KAAC,CAAC;AACJ;EAEAiC,aAAaA,CAAC7B,KAAK,EAAE;AACnB,IAAA,IAAI,EAAEA,KAAK,CAAC8B,aAAa,YAAYC,WAAW,CAAC,EAAE;AACjD,MAAA;AACF;AAEAzD,IAAAA,QAAQ,CAAC0D,WAAW,CAClBhC,KAAK,CAAC8B,aAAa,CAACxB,YAAY,CAAC,cAAc,CAAC,EAChD,KAAK,EACL2B,SACF,CAAC;AACH;AAEAC,EAAAA,UAAUA,GAAG;AACX,IAAA,OAAO,IAAI,CAACzC,OAAO,CAAC2B,SAAS;AAC/B;AAEAzB,EAAAA,aAAaA,GAAG;IACd,IAAI,CAACwC,cAAc,EAAE;AACvB;AAEAA,EAAAA,cAAcA,GAAG;IACf7D,QAAQ,CAAC0D,WAAW,CAAC,2BAA2B,EAAE,KAAK,EAAE,GAAG,CAAC;IAC7D,IAAI,CAAC7D,QAAQ,CAACoD,KAAK,GAAG,IAAI,CAACW,UAAU,EAAE;AACzC;EAEApC,YAAYA,CAACE,KAAK,EAAE;IAClBA,KAAK,CAACoC,cAAc,EAAE;AACtB,IAAA,IAAI,CAAC3C,OAAO,CAACiB,KAAK,EAAE;AACtB;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"rich-text-editor.mjs","sources":["../../../../src/moj/components/rich-text-editor/rich-text-editor.mjs"],"sourcesContent":["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"],"names":["RichTextEditor","ConfigurableComponent","constructor","$root","config","isSupported","$textarea","querySelector","HTMLTextAreaElement","createToolbar","hideDefault","configureToolbar","keys","left","right","up","down","$content","addEventListener","onEditorInput","bind","onLabelClick","$toolbar","onToolbarKeydown","event","$focusableButton","keyCode","$buttons","find","button","getAttribute","$nextButton","nextElementSibling","HTMLButtonElement","focus","setAttribute","$previousButton","previousElementSibling","getToolbarHtml","html","toolbar","bold","italic","underline","bullets","numbers","getEnhancedHtml","classList","add","document","createElement","className","innerHTML","append","value","Array","from","querySelectorAll","forEach","$button","index","onButtonClick","currentTarget","HTMLElement","execCommand","undefined","getContent","updateTextarea","preventDefault","documentElement","moduleName","defaults","Object","freeze","schema","properties","type"],"mappings":";;AAEA;AACA;AACA;AACO,MAAMA,cAAc,SAASC,qBAAqB,CAAC;AACxD;AACF;AACA;AACA;AACEC,EAAAA,WAAWA,CAACC,KAAK,EAAEC,MAAM,GAAG,EAAE,EAAE;AAC9B,IAAA,KAAK,CAACD,KAAK,EAAEC,MAAM,CAAC;AAEpB,IAAA,IAAI,CAACJ,cAAc,CAACK,WAAW,EAAE,EAAE;AACjC,MAAA,OAAO,IAAI;AACb;IAEA,MAAMC,SAAS,GAAG,IAAI,CAACH,KAAK,CAACI,aAAa,CAAC,iBAAiB,CAAC;IAC7D,IAAI,CAACD,SAAS,IAAI,EAAEA,SAAS,YAAYE,mBAAmB,CAAC,EAAE;AAC7D,MAAA,OAAO,IAAI;AACb;IAEA,IAAI,CAACF,SAAS,GAAGA,SAAS;IAE1B,IAAI,CAACG,aAAa,EAAE;IACpB,IAAI,CAACC,WAAW,EAAE;IAClB,IAAI,CAACC,gBAAgB,EAAE;IAEvB,IAAI,CAACC,IAAI,GAAG;AACVC,MAAAA,IAAI,EAAE,EAAE;AACRC,MAAAA,KAAK,EAAE,EAAE;AACTC,MAAAA,EAAE,EAAE,EAAE;AACNC,MAAAA,IAAI,EAAE;KACP;AAED,IAAA,IAAI,CAACC,QAAQ,CAACC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACC,aAAa,CAACC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEtE,IAAI,CAACjB,KAAK,CACPI,aAAa,CAAC,OAAO,CAAC,CACtBW,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACG,YAAY,CAACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAE1D,IAAA,IAAI,CAACE,QAAQ,CAACJ,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAACK,gBAAgB,CAACH,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7E;;AAEA;AACF;AACA;EACEG,gBAAgBA,CAACC,KAAK,EAAE;AACtB,IAAA,IAAIC,gBAAgB;IACpB,QAAQD,KAAK,CAACE,OAAO;AACnB,MAAA,KAAK,IAAI,CAACd,IAAI,CAACE,KAAK;AACpB,MAAA,KAAK,IAAI,CAACF,IAAI,CAACI,IAAI;AAAE,QAAA;AACnBS,UAAAA,gBAAgB,GAAG,IAAI,CAACE,QAAQ,CAACC,IAAI,CAClCC,MAAM,IAAKA,MAAM,CAACC,YAAY,CAAC,UAAU,CAAC,KAAK,GAClD,CAAC;AAED,UAAA,IAAIL,gBAAgB,EAAE;AACpB,YAAA,MAAMM,WAAW,GAAGN,gBAAgB,CAACO,kBAAkB;AAEvD,YAAA,IAAID,WAAW,IAAIA,WAAW,YAAYE,iBAAiB,EAAE;cAC3DF,WAAW,CAACG,KAAK,EAAE;AACnBT,cAAAA,gBAAgB,CAACU,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;AAC/CJ,cAAAA,WAAW,CAACI,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC;AAC3C;AACF;AAEA,UAAA;AACF;AAEA,MAAA,KAAK,IAAI,CAACvB,IAAI,CAACC,IAAI;AACnB,MAAA,KAAK,IAAI,CAACD,IAAI,CAACG,EAAE;AAAE,QAAA;AACjBU,UAAAA,gBAAgB,GAAG,IAAI,CAACE,QAAQ,CAACC,IAAI,CAClCC,MAAM,IAAKA,MAAM,CAACC,YAAY,CAAC,UAAU,CAAC,KAAK,GAClD,CAAC;AAED,UAAA,IAAIL,gBAAgB,EAAE;AACpB,YAAA,MAAMW,eAAe,GAAGX,gBAAgB,CAACY,sBAAsB;AAE/D,YAAA,IAAID,eAAe,IAAIA,eAAe,YAAYH,iBAAiB,EAAE;cACnEG,eAAe,CAACF,KAAK,EAAE;AACvBT,cAAAA,gBAAgB,CAACU,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;AAC/CC,cAAAA,eAAe,CAACD,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC;AAC/C;AACF;AAEA,UAAA;AACF;AACF;AACF;AAEAG,EAAAA,cAAcA,GAAG;IACf,IAAIC,IAAI,GAAG,EAAE;AAEbA,IAAAA,IAAI,IAAI,4DAA4D;AAEpE,IAAA,IAAI,IAAI,CAACnC,MAAM,CAACoC,OAAO,CAACC,IAAI,EAAE;AAC5BF,MAAAA,IAAI,IACF,4LAA4L;AAChM;AAEA,IAAA,IAAI,IAAI,CAACnC,MAAM,CAACoC,OAAO,CAACE,MAAM,EAAE;AAC9BH,MAAAA,IAAI,IACF,kMAAkM;AACtM;AAEA,IAAA,IAAI,IAAI,CAACnC,MAAM,CAACoC,OAAO,CAACG,SAAS,EAAE;AACjCJ,MAAAA,IAAI,IACF,2MAA2M;AAC/M;AAEA,IAAA,IAAI,IAAI,CAACnC,MAAM,CAACoC,OAAO,CAACI,OAAO,EAAE;AAC/BL,MAAAA,IAAI,IACF,+NAA+N;AACnO;AAEA,IAAA,IAAI,IAAI,CAACnC,MAAM,CAACoC,OAAO,CAACK,OAAO,EAAE;AAC/BN,MAAAA,IAAI,IACF,yNAAyN;AAC7N;AAEAA,IAAAA,IAAI,IAAI,QAAQ;AAChB,IAAA,OAAOA,IAAI;AACb;AAEAO,EAAAA,eAAeA,GAAG;AAChB,IAAA,OAAO,GAAG,IAAI,CAACR,cAAc,EAAE,CAA4G,0GAAA,CAAA;AAC7I;AAEA5B,EAAAA,WAAWA,GAAG;IACZ,IAAI,CAACJ,SAAS,CAACyC,SAAS,CAACC,GAAG,CAAC,uBAAuB,CAAC;IACrD,IAAI,CAAC1C,SAAS,CAAC6B,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC;IAClD,IAAI,CAAC7B,SAAS,CAAC6B,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;AAC/C;AAEA1B,EAAAA,aAAaA,GAAG;IACd,IAAI,CAACa,QAAQ,GAAG2B,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;AAC7C,IAAA,IAAI,CAAC5B,QAAQ,CAAC6B,SAAS,GAAG,sBAAsB;IAChD,IAAI,CAAC7B,QAAQ,CAAC8B,SAAS,GAAG,IAAI,CAACN,eAAe,EAAE;IAChD,IAAI,CAAC3C,KAAK,CAACkD,MAAM,CAAC,IAAI,CAAC/B,QAAQ,CAAC;IAEhC,IAAI,CAACL,QAAQ;AACX,IAAA,IAAI,CAACd,KAAK,CAACI,aAAa,CAAC,gCAAgC,CAC1D;IAED,IAAI,CAACU,QAAQ,CAACmC,SAAS,GAAG,IAAI,CAAC9C,SAAS,CAACgD,KAAK;AAChD;AAEA3C,EAAAA,gBAAgBA,GAAG;AACjB,IAAA,IAAI,CAACgB,QAAQ,GAAG4B,KAAK,CAACC,IAAI;AAEvB,IAAA,IAAI,CAACrD,KAAK,CAACsD,gBAAgB,CAAC,uCAAuC,CACtE,CAAC;IAED,IAAI,CAAC9B,QAAQ,CAAC+B,OAAO,CAAC,CAACC,OAAO,EAAEC,KAAK,KAAK;MACxCD,OAAO,CAACxB,YAAY,CAAC,UAAU,EAAE,CAACyB,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC;AACrDD,MAAAA,OAAO,CAACzC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC2C,aAAa,CAACzC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClE,KAAC,CAAC;AACJ;;AAEA;AACF;AACA;EACEyC,aAAaA,CAACrC,KAAK,EAAE;AACnB,IAAA,IAAI,EAAEA,KAAK,CAACsC,aAAa,YAAYC,WAAW,CAAC,EAAE;AACjD,MAAA;AACF;AAEAd,IAAAA,QAAQ,CAACe,WAAW,CAClBxC,KAAK,CAACsC,aAAa,CAAChC,YAAY,CAAC,cAAc,CAAC,EAChD,KAAK,EACLmC,SACF,CAAC;AACH;AAEAC,EAAAA,UAAUA,GAAG;AACX,IAAA,OAAO,IAAI,CAACjD,QAAQ,CAACmC,SAAS;AAChC;AAEAjC,EAAAA,aAAaA,GAAG;IACd,IAAI,CAACgD,cAAc,EAAE;AACvB;AAEAA,EAAAA,cAAcA,GAAG;IACflB,QAAQ,CAACe,WAAW,CAAC,2BAA2B,EAAE,KAAK,EAAE,GAAG,CAAC;IAC7D,IAAI,CAAC1D,SAAS,CAACgD,KAAK,GAAG,IAAI,CAACY,UAAU,EAAE;AAC1C;;AAEA;AACF;AACA;EACE7C,YAAYA,CAACG,KAAK,EAAE;IAClBA,KAAK,CAAC4C,cAAc,EAAE;AACtB,IAAA,IAAI,CAACnD,QAAQ,CAACiB,KAAK,EAAE;AACvB;EAEA,OAAO7B,WAAWA,GAAG;AACnB,IAAA,OAAO,iBAAiB,IAAI4C,QAAQ,CAACoB,eAAe;AACtD;;AAEA;AACF;AACA;AA8BA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AAxParE,cAAc,CAqMlBsE,UAAU,GAAG,sBAAsB;AAE1C;AACF;AACA;AACA;AACA;AA3MatE,cAAc,CA4MlBuE,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAAC;AAC9BjC,EAAAA,OAAO,EAAE;AACPC,IAAAA,IAAI,EAAE,KAAK;AACXC,IAAAA,MAAM,EAAE,KAAK;AACbC,IAAAA,SAAS,EAAE,KAAK;AAChBC,IAAAA,OAAO,EAAE,IAAI;AACbC,IAAAA,OAAO,EAAE;AACX;AACF,CAAC,CAAC;AAEF;AACF;AACA;AACA;AACA;AA1Na7C,cAAc,CA2NlB0E,MAAM,GAAGF,MAAM,CAACC,MAAM,qBACL;AACpBE,EAAAA,UAAU,EAAE;AACVnC,IAAAA,OAAO,EAAE;AAAEoC,MAAAA,IAAI,EAAE;AAAS;AAC5B;AACF,CACF,CAAC;;;;"}
|
|
@@ -1,53 +1,121 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MOJFrontend = global.MOJFrontend || {}));
|
|
5
|
-
})(this, (function (exports) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('govuk-frontend')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'govuk-frontend'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MOJFrontend = global.MOJFrontend || {}, global.GOVUKFrontend));
|
|
5
|
+
})(this, (function (exports, govukFrontend) { 'use strict';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
/**
|
|
8
|
+
* @augments {ConfigurableComponent<SearchToggleConfig>}
|
|
9
|
+
*/
|
|
10
|
+
class SearchToggle extends govukFrontend.ConfigurableComponent {
|
|
11
|
+
/**
|
|
12
|
+
* @param {Element | null} $root - HTML element to use for search toggle
|
|
13
|
+
* @param {SearchToggleConfig} [config] - Search toggle config
|
|
14
|
+
*/
|
|
15
|
+
constructor($root, config = {}) {
|
|
16
|
+
var _this$config$searchCo, _this$config$toggleBu;
|
|
17
|
+
super($root, config);
|
|
18
|
+
const $searchContainer = (_this$config$searchCo = this.config.searchContainer.element) != null ? _this$config$searchCo : this.$root.querySelector(this.config.searchContainer.selector);
|
|
19
|
+
const $toggleButtonContainer = (_this$config$toggleBu = this.config.toggleButtonContainer.element) != null ? _this$config$toggleBu : this.$root.querySelector(this.config.toggleButtonContainer.selector);
|
|
20
|
+
if (!$searchContainer || !$toggleButtonContainer || !($searchContainer instanceof HTMLElement) || !($toggleButtonContainer instanceof HTMLElement)) {
|
|
13
21
|
return this;
|
|
14
22
|
}
|
|
15
|
-
this
|
|
23
|
+
this.$searchContainer = $searchContainer;
|
|
24
|
+
this.$toggleButtonContainer = $toggleButtonContainer;
|
|
16
25
|
const svg = '<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>';
|
|
17
|
-
this
|
|
18
|
-
this
|
|
19
|
-
this
|
|
20
|
-
this
|
|
21
|
-
this
|
|
22
|
-
this
|
|
23
|
-
this
|
|
24
|
-
this
|
|
26
|
+
this.$toggleButton = document.createElement('button');
|
|
27
|
+
this.$toggleButton.setAttribute('class', 'moj-search-toggle__button');
|
|
28
|
+
this.$toggleButton.setAttribute('type', 'button');
|
|
29
|
+
this.$toggleButton.setAttribute('aria-haspopup', 'true');
|
|
30
|
+
this.$toggleButton.setAttribute('aria-expanded', 'false');
|
|
31
|
+
this.$toggleButton.innerHTML = `${this.config.toggleButton.text} ${svg}`;
|
|
32
|
+
this.$toggleButton.addEventListener('click', this.onToggleButtonClick.bind(this));
|
|
33
|
+
this.$toggleButtonContainer.append(this.$toggleButton);
|
|
25
34
|
document.addEventListener('click', this.onDocumentClick.bind(this));
|
|
26
35
|
document.addEventListener('focusin', this.onDocumentClick.bind(this));
|
|
27
36
|
}
|
|
28
37
|
showMenu() {
|
|
29
|
-
this
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
38
|
+
this.$toggleButton.setAttribute('aria-expanded', 'true');
|
|
39
|
+
this.$searchContainer.classList.remove('moj-js-hidden');
|
|
40
|
+
this.$searchContainer.querySelector('input').focus();
|
|
32
41
|
}
|
|
33
42
|
hideMenu() {
|
|
34
|
-
this.
|
|
35
|
-
this
|
|
43
|
+
this.$searchContainer.classList.add('moj-js-hidden');
|
|
44
|
+
this.$toggleButton.setAttribute('aria-expanded', 'false');
|
|
36
45
|
}
|
|
37
46
|
onToggleButtonClick() {
|
|
38
|
-
if (this
|
|
47
|
+
if (this.$toggleButton.getAttribute('aria-expanded') === 'false') {
|
|
39
48
|
this.showMenu();
|
|
40
49
|
} else {
|
|
41
50
|
this.hideMenu();
|
|
42
51
|
}
|
|
43
52
|
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {MouseEvent | FocusEvent} event
|
|
56
|
+
*/
|
|
44
57
|
onDocumentClick(event) {
|
|
45
|
-
if (!this
|
|
58
|
+
if (event.target instanceof Node && !this.$toggleButtonContainer.contains(event.target) && !this.$searchContainer.contains(event.target)) {
|
|
46
59
|
this.hideMenu();
|
|
47
60
|
}
|
|
48
61
|
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Name for the component used when initialising using data-module attributes.
|
|
65
|
+
*/
|
|
49
66
|
}
|
|
50
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @typedef {object} SearchToggleConfig
|
|
70
|
+
* @property {object} [searchContainer] - Search config
|
|
71
|
+
* @property {string} [searchContainer.selector] - Selector for search container
|
|
72
|
+
* @property {Element | null} [searchContainer.element] - HTML element for search container
|
|
73
|
+
* @property {object} [toggleButton] - Toggle button config
|
|
74
|
+
* @property {string} [toggleButton.text] - Text for toggle button
|
|
75
|
+
* @property {object} [toggleButtonContainer] - Toggle button container config
|
|
76
|
+
* @property {string} [toggleButtonContainer.selector] - Selector for toggle button container
|
|
77
|
+
* @property {Element | null} [toggleButtonContainer.element] - HTML element for toggle button container
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'
|
|
82
|
+
*/
|
|
83
|
+
SearchToggle.moduleName = 'moj-search-toggle';
|
|
84
|
+
/**
|
|
85
|
+
* Search toggle config
|
|
86
|
+
*
|
|
87
|
+
* @type {SearchToggleConfig}
|
|
88
|
+
*/
|
|
89
|
+
SearchToggle.defaults = Object.freeze({
|
|
90
|
+
searchContainer: {
|
|
91
|
+
selector: '.moj-search'
|
|
92
|
+
},
|
|
93
|
+
toggleButton: {
|
|
94
|
+
text: 'Search'
|
|
95
|
+
},
|
|
96
|
+
toggleButtonContainer: {
|
|
97
|
+
selector: '.moj-search-toggle__toggle'
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
/**
|
|
101
|
+
* Search toggle config schema
|
|
102
|
+
*
|
|
103
|
+
* @satisfies {Schema<SearchToggleConfig>}
|
|
104
|
+
*/
|
|
105
|
+
SearchToggle.schema = Object.freeze(/** @type {const} */{
|
|
106
|
+
properties: {
|
|
107
|
+
searchContainer: {
|
|
108
|
+
type: 'object'
|
|
109
|
+
},
|
|
110
|
+
toggleButton: {
|
|
111
|
+
type: 'object'
|
|
112
|
+
},
|
|
113
|
+
toggleButtonContainer: {
|
|
114
|
+
type: 'object'
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
51
119
|
exports.SearchToggle = SearchToggle;
|
|
52
120
|
|
|
53
121
|
}));
|