UNPKG

@awsui/components-react

Version:

On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en

92 lines 8.33 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { __rest } from "tslib"; import React, { useRef, useState } from 'react'; import clsx from 'clsx'; import { warnOnce } from '@awsui/component-toolkit/internal'; import InternalBox from '../box/internal'; import { useFormFieldContext } from '../contexts/form-field'; import InternalFileDropzone from '../file-dropzone/internal'; import { useFilesDragging } from '../file-dropzone/use-files-dragging'; import InternalFileInput from '../file-input/internal'; import InternalFileTokenGroup from '../file-token-group/internal'; import { ConstraintText, FormFieldError, FormFieldWarning } from '../form-field/internal'; import { useInternalI18n } from '../i18n/context'; import { getBaseProps } from '../internal/base-component'; import { fireNonCancelableEvent } from '../internal/events'; import checkControlled from '../internal/hooks/check-controlled'; import { useListFocusController } from '../internal/hooks/use-list-focus-controller'; import { useMergeRefs } from '../internal/hooks/use-merge-refs'; import { useUniqueId } from '../internal/hooks/use-unique-id'; import { joinStrings } from '../internal/utils/strings'; import InternalSpaceBetween from '../space-between/internal'; import fileInputStyles from '../file-input/styles.css.js'; import tokenListStyles from '../internal/components/token-list/styles.css.js'; import styles from './styles.css.js'; export default React.forwardRef(InternalFileUpload); function InternalFileUpload(_a, externalRef) { var _b, _c, _d; var { accept, ariaRequired, multiple = false, onChange, value, tokenLimit, showFileSize, showFileLastModified, showFileThumbnail, i18nStrings, __internalRootRef = null, constraintText, errorText, warningText, fileErrors, fileWarnings, fileTokenAlignment = 'vertical' } = _a, restProps = __rest(_a, ["accept", "ariaRequired", "multiple", "onChange", "value", "tokenLimit", "showFileSize", "showFileLastModified", "showFileThumbnail", "i18nStrings", "__internalRootRef", "constraintText", "errorText", "warningText", "fileErrors", "fileWarnings", "fileTokenAlignment"]); const [nextFocusIndex, setNextFocusIndex] = useState(null); const tokenListRef = useListFocusController({ nextFocusIndex, onFocusMoved: target => { target.focus(); setNextFocusIndex(null); }, listItemSelector: `.${tokenListStyles['list-item']}`, showMoreSelector: `.${tokenListStyles.toggle}`, fallbackSelector: `.${fileInputStyles['file-input']}`, }); const i18n = useInternalI18n('file-upload'); const baseProps = getBaseProps(restProps); const metadata = { showFileSize, showFileLastModified, showFileThumbnail }; const errorId = useUniqueId('error-'); const warningId = useUniqueId('warning-'); const constraintTextId = useUniqueId('constraint-text-'); const fileInputRef = useRef(null); const ref = useMergeRefs(fileInputRef, externalRef); checkControlled('FileUpload', 'value', value, 'onChange', onChange); if (!multiple && value.length > 1) { warnOnce('FileUpload', 'Value must be an array of size 0 or 1 when `multiple=false`.'); } const handleFilesChange = (newFiles) => { const newValue = multiple ? [...value, ...newFiles] : newFiles[0] ? newFiles.slice(0, 1) : [...value]; fireNonCancelableEvent(onChange, { value: newValue }); }; const onFileRemove = (removeFileIndex) => { const newValue = value.filter((_, fileIndex) => fileIndex !== removeFileIndex); fireNonCancelableEvent(onChange, { value: newValue }); setNextFocusIndex(removeFileIndex); }; const { areFilesDragging } = useFilesDragging(); const showWarning = warningText && !errorText; if (warningText && errorText) { warnOnce('FileUpload', 'Both `errorText` and `warningText` exist. `warningText` will not be shown.'); } const formFieldContext = useFormFieldContext(restProps); const ariaDescribedBy = joinStrings((_b = restProps.ariaDescribedby) !== null && _b !== void 0 ? _b : formFieldContext.ariaDescribedby, errorText ? errorId : undefined, showWarning ? warningId : undefined, constraintText ? constraintTextId : undefined); const hasError = Boolean(errorText || (fileErrors === null || fileErrors === void 0 ? void 0 : fileErrors.filter(Boolean).length)); const invalid = restProps.invalid || formFieldContext.invalid || hasError; return (React.createElement(InternalSpaceBetween, Object.assign({}, baseProps, { size: "xs", className: clsx(baseProps.className, styles.root), __internalRootRef: __internalRootRef, ref: tokenListRef }), React.createElement(InternalBox, null, areFilesDragging ? (React.createElement(InternalFileDropzone, { onChange: event => handleFilesChange(event.detail.value) }, i18n('i18nStrings.dropzoneText', (_c = i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.dropzoneText) === null || _c === void 0 ? void 0 : _c.call(i18nStrings, multiple), format => format({ multiple: `${multiple}` })))) : (React.createElement(InternalFileInput, { ref: ref, accept: accept, ariaRequired: ariaRequired, multiple: multiple, onChange: event => handleFilesChange(event.detail.value), value: value, ariaLabelledby: restProps.ariaLabelledby, controlId: restProps.controlId, ariaDescribedby: ariaDescribedBy, invalid: invalid }, i18n('i18nStrings.uploadButtonText', (_d = i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.uploadButtonText) === null || _d === void 0 ? void 0 : _d.call(i18nStrings, multiple), format => format({ multiple: `${multiple}` })))), (constraintText || errorText || warningText) && (React.createElement("div", { className: styles.hints }, errorText && (React.createElement(FormFieldError, { id: errorId, errorIconAriaLabel: i18n('i18nStrings.errorIconAriaLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.errorIconAriaLabel) }, errorText)), showWarning && (React.createElement(FormFieldWarning, { id: warningId, warningIconAriaLabel: i18n('i18nStrings.warningIconAriaLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.warningIconAriaLabel) }, warningText)), constraintText && (React.createElement(ConstraintText, { id: constraintTextId, hasValidationText: !!errorText || !!warningText }, constraintText))))), value.length > 0 ? (React.createElement(InternalFileTokenGroup, { limit: tokenLimit, alignment: fileTokenAlignment, items: value.map((file, fileIndex) => ({ file, errorText: fileErrors === null || fileErrors === void 0 ? void 0 : fileErrors[fileIndex], warningText: fileWarnings === null || fileWarnings === void 0 ? void 0 : fileWarnings[fileIndex], })), showFileLastModified: metadata.showFileLastModified, showFileSize: metadata.showFileSize, showFileThumbnail: metadata.showFileThumbnail, i18nStrings: { removeFileAriaLabel: i18n('i18nStrings.removeFileAriaLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.removeFileAriaLabel, format => fileIndex => format({ fileIndex: fileIndex + 1 })), limitShowFewer: i18n('i18nStrings.limitShowFewer', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.limitShowFewer), limitShowMore: i18n('i18nStrings.limitShowMore', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.limitShowMore), formatFileSize: i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.formatFileSize, formatFileLastModified: i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.formatFileLastModified, errorIconAriaLabel: i18n('i18nStrings.errorIconAriaLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.errorIconAriaLabel), warningIconAriaLabel: i18n('i18nStrings.warningIconAriaLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.warningIconAriaLabel), }, onDismiss: event => onFileRemove(event.detail.fileIndex) })) : null)); } //# sourceMappingURL=internal.js.map