UNPKG

govuk-frontend

Version:

GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.

89 lines (86 loc) 3.23 kB
import { ElementError } from '../../errors/index.mjs'; import { GOVUKFrontendComponent } from '../../govuk-frontend-component.mjs'; /** * Radios component * * @preserve */ class Radios extends GOVUKFrontendComponent { /** * Radios can be associated with a 'conditionally revealed' content block – * for example, a radio for 'Phone' could reveal an additional form field for * the user to enter their phone number. * * These associations are made using a `data-aria-controls` attribute, which * is promoted to an aria-controls attribute during initialisation. * * We also need to restore the state of any conditional reveals on the page * (for example if the user has navigated back), and set up event handlers to * keep the reveal in sync with the radio state. * * @param {Element | null} $root - HTML element to use for radios */ constructor($root) { super($root); this.$inputs = void 0; const $inputs = this.$root.querySelectorAll('input[type="radio"]'); if (!$inputs.length) { throw new ElementError({ component: Radios, identifier: 'Form inputs (`<input type="radio">`)' }); } this.$inputs = $inputs; this.$inputs.forEach($input => { const targetId = $input.getAttribute('data-aria-controls'); if (!targetId) { return; } if (!document.getElementById(targetId)) { throw new ElementError({ component: Radios, identifier: `Conditional reveal (\`id="${targetId}"\`)` }); } $input.setAttribute('aria-controls', targetId); $input.removeAttribute('data-aria-controls'); }); window.addEventListener('pageshow', () => this.syncAllConditionalReveals()); this.syncAllConditionalReveals(); this.$root.addEventListener('click', event => this.handleClick(event)); } syncAllConditionalReveals() { this.$inputs.forEach($input => this.syncConditionalRevealWithInputState($input)); } syncConditionalRevealWithInputState($input) { const targetId = $input.getAttribute('aria-controls'); if (!targetId) { return; } const $target = document.getElementById(targetId); if ($target != null && $target.classList.contains('govuk-radios__conditional')) { const inputIsChecked = $input.checked; $input.setAttribute('aria-expanded', inputIsChecked.toString()); $target.classList.toggle('govuk-radios__conditional--hidden', !inputIsChecked); } } handleClick(event) { const $clickedInput = event.target; if (!($clickedInput instanceof HTMLInputElement) || $clickedInput.type !== 'radio') { return; } const $allInputs = document.querySelectorAll('input[type="radio"][aria-controls]'); const $clickedInputForm = $clickedInput.form; const $clickedInputName = $clickedInput.name; $allInputs.forEach($input => { const hasSameFormOwner = $input.form === $clickedInputForm; const hasSameName = $input.name === $clickedInputName; if (hasSameName && hasSameFormOwner) { this.syncConditionalRevealWithInputState($input); } }); } } Radios.moduleName = 'govuk-radios'; export { Radios }; //# sourceMappingURL=radios.mjs.map