UNPKG

@uswds/uswds

Version:

Open source UI components and visual style guide for U.S. government websites

63 lines (50 loc) 2.18 kB
const debounce = require("./debounce"); const { prefix: PREFIX } = require("../config"); const CHECKED_CLASS = `${PREFIX}-checklist__item--checked`; module.exports = function validate(el) { const id = el.dataset.validationElement; const checkList = id.charAt(0) === "#" ? document.querySelector(id) : document.getElementById(id); if (!checkList) { throw new Error(`No validation element found with id: "${id}"`); } let statusSummary = ""; Object.entries(el.dataset).forEach(([key, value]) => { if (key.startsWith("validate")) { const validatorName = key.substr("validate".length).toLowerCase(); const validatorPattern = new RegExp(value); const validatorSelector = `[data-validator="${validatorName}"]`; const validatorCheckbox = checkList.querySelector(validatorSelector); const validatorParent = el.parentNode; const statusSummaryContainer = validatorParent.querySelector( `[data-validation-status]`, ); const checked = validatorPattern.test(el.value); validatorCheckbox.classList.toggle(CHECKED_CLASS, checked); if (!validatorCheckbox) { throw new Error(`No validator checkbox found for: "${validatorName}"`); } // Create status reports for checklist items const statusComplete = el.dataset.validationComplete || "status complete"; const statusIncomplete = el.dataset.validationIncomplete || "status incomplete"; let checkboxContent = `${validatorCheckbox.textContent} `; if (validatorCheckbox.classList.contains(CHECKED_CLASS)) { checkboxContent += statusComplete; } else { checkboxContent += statusIncomplete; } // move status updates to aria-label on checklist item validatorCheckbox.setAttribute("aria-label", checkboxContent); // Create a summary of status for all checklist items statusSummary += `${checkboxContent}. `; // Add summary to screen reader summary container, after a delay const srUpdateStatus = debounce(() => { statusSummaryContainer.textContent = statusSummary; }, 1000); srUpdateStatus(); } }); };