`);
- };
-
- // Not all files will be able to generate previews. In case this happens, we provide several types "generic previews" based on the file extension.
- reader.onloadend = function createFilePreview() {
- const imageId = createUniqueID(makeSafeForID(fileName));
- const previewImage = document.getElementById(imageId);
- if (fileName.indexOf(".pdf") > 0) {
- previewImage.setAttribute("onerror", `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${PDF_PREVIEW_CLASS}")`);
- } else if (fileName.indexOf(".doc") > 0 || fileName.indexOf(".pages") > 0) {
- previewImage.setAttribute("onerror", `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${WORD_PREVIEW_CLASS}")`);
- } else if (fileName.indexOf(".xls") > 0 || fileName.indexOf(".numbers") > 0) {
- previewImage.setAttribute("onerror", `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${EXCEL_PREVIEW_CLASS}")`);
- } else if (fileName.indexOf(".mov") > 0 || fileName.indexOf(".mp4") > 0) {
- previewImage.setAttribute("onerror", `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${VIDEO_PREVIEW_CLASS}")`);
- } else {
- previewImage.setAttribute("onerror", `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${GENERIC_PREVIEW_CLASS}")`);
- }
-
- // Removes loader and displays preview
- previewImage.classList.remove(LOADING_CLASS);
- previewImage.src = reader.result;
- };
- if (fileNames[i]) {
- reader.readAsDataURL(fileNames[i]);
- }
-
- // Adds heading above file previews, pluralizes if there are multiple
- if (i === 0) {
- dropTarget.insertBefore(filePreviewsHeading, instructions);
- filePreviewsHeading.innerHTML = `Selected file
Change file`;
- } else if (i >= 1) {
- dropTarget.insertBefore(filePreviewsHeading, instructions);
- filePreviewsHeading.innerHTML = Sanitizer.escapeHTML`${i + 1} files selected
Change files`;
- }
-
- // Hides null state content and sets preview heading class
- if (filePreviewsHeading) {
- instructions.classList.add(HIDDEN_CLASS);
- filePreviewsHeading.classList.add(PREVIEW_HEADING_CLASS);
- }
- }
-};
-
-/**
- * When using an Accept attribute, invalid files will be hidden from
- * file browser, but they can still be dragged to the input. This
- * function prevents them from being dragged and removes error states
- * when correct files are added.
- * @param {event} e
- * @param {HTMLElement} fileInputEl - file input element
- * @param {HTMLElement} instructions - text to inform users to drag or select files
- * @param {HTMLElement} dropTarget - target area div that encases the input
- */
-const preventInvalidFiles = (e, fileInputEl, instructions, dropTarget) => {
- const acceptedFilesAttr = fileInputEl.getAttribute("accept");
- dropTarget.classList.remove(INVALID_FILE_CLASS);
-
- /**
- * We can probably move away from this once IE11 support stops, and replace
- * with a simple es `.includes`
- * check if element is in array
- * check if 1 or more alphabets are in string
- * if element is present return the position value and -1 otherwise
- * @param {Object} file
- * @param {String} value
- * @returns {Boolean}
- */
- const isIncluded = (file, value) => {
- let returnValue = false;
- const pos = file.indexOf(value);
- if (pos >= 0) {
- returnValue = true;
- }
- return returnValue;
- };
-
- // Runs if only specific files are accepted
- if (acceptedFilesAttr) {
- const acceptedFiles = acceptedFilesAttr.split(",");
- const errorMessage = document.createElement("div");
-
- // If multiple files are dragged, this iterates through them and look for any files that are not accepted.
- let allFilesAllowed = true;
- const scannedFiles = e.target.files || e.dataTransfer.files;
- for (let i = 0; i < scannedFiles.length; i += 1) {
- const file = scannedFiles[i];
- if (allFilesAllowed) {
- for (let j = 0; j < acceptedFiles.length; j += 1) {
- const fileType = acceptedFiles[j];
- allFilesAllowed = file.name.indexOf(fileType) > 0 || isIncluded(file.type, fileType.replace(/\*/g, ""));
- if (allFilesAllowed) {
- TYPE_IS_VALID = true;
- break;
- }
- }
- } else break;
- }
-
- // If dragged files are not accepted, this removes them from the value of the input and creates and error state
- if (!allFilesAllowed) {
- removeOldPreviews(dropTarget, instructions);
- fileInputEl.value = ""; // eslint-disable-line no-param-reassign
- dropTarget.insertBefore(errorMessage, fileInputEl);
- errorMessage.textContent = fileInputEl.dataset.errormessage || `This is not a valid file type.`;
- errorMessage.classList.add(ACCEPTED_FILE_MESSAGE_CLASS);
- dropTarget.classList.add(INVALID_FILE_CLASS);
- TYPE_IS_VALID = false;
- e.preventDefault();
- e.stopPropagation();
- }
- }
-};
-
-/**
- * 1. passes through gate for preventing invalid files
- * 2. handles updates if file is valid
- * @param {event} event
- * @param {HTMLElement} element
- * @param {HTMLElement} instructionsEl
- * @param {HTMLElement} target
- */
-const handleUpload = (event, element, instructionsEl, dropTargetEl) => {
- preventInvalidFiles(event, element, instructionsEl, dropTargetEl);
- if (TYPE_IS_VALID === true) {
- handleChange(event, element, instructionsEl, dropTargetEl);
- }
-};
-const fileInput = behavior({}, {
- init(root) {
- selectOrMatches(DROPZONE, root).forEach(fileInputEl => {
- const {
- instructions,
- dropTarget
- } = buildFileInput(fileInputEl);
- dropTarget.addEventListener("dragover", function handleDragOver() {
- this.classList.add(DRAG_CLASS);
- }, false);
- dropTarget.addEventListener("dragleave", function handleDragLeave() {
- this.classList.remove(DRAG_CLASS);
- }, false);
- dropTarget.addEventListener("drop", function handleDrop() {
- this.classList.remove(DRAG_CLASS);
- }, false);
- fileInputEl.addEventListener("change", e => handleUpload(e, fileInputEl, instructions, dropTarget), false);
- });
- },
- teardown(root) {
- selectOrMatches(INPUT, root).forEach(fileInputEl => {
- const fileInputTopElement = fileInputEl.parentElement.parentElement;
- fileInputTopElement.parentElement.replaceChild(fileInputEl, fileInputTopElement);
- // eslint-disable-next-line no-param-reassign
- fileInputEl.className = DROPZONE_CLASS;
- });
- },
- getFileInputContext,
- disable,
- enable
-});
-module.exports = fileInput;
-
-},{"../../uswds-core/src/js/config":35,"../../uswds-core/src/js/utils/behavior":45,"../../uswds-core/src/js/utils/sanitizer":50,"../../uswds-core/src/js/utils/select-or-matches":52}],22:[function(require,module,exports){
-"use strict";
-
-const behavior = require("../../uswds-core/src/js/utils/behavior");
-const {
- CLICK
-} = require("../../uswds-core/src/js/events");
-const {
- prefix: PREFIX
-} = require("../../uswds-core/src/js/config");
-const SCOPE = `.${PREFIX}-footer--big`;
-const NAV = `${SCOPE} nav`;
-const BUTTON = `${NAV} .${PREFIX}-footer__primary-link`;
-const HIDE_MAX_WIDTH = 480;
-
-/**
- * Expands selected footer menu panel, while collapsing others
- */
-function showPanel() {
- if (window.innerWidth < HIDE_MAX_WIDTH) {
- const isOpen = this.getAttribute("aria-expanded") === "true";
- const thisFooter = this.closest(SCOPE);
-
- // Close all other menus
- thisFooter.querySelectorAll(BUTTON).forEach(button => {
- button.setAttribute("aria-expanded", false);
- });
- this.setAttribute("aria-expanded", !isOpen);
- }
-}
-
-/**
- * Swaps the
element for a