Skip to content

Commit

Permalink
fix(FileUploader): add missing typings to props variables (#14496)
Browse files Browse the repository at this point in the history
  • Loading branch information
lewandom authored Aug 24, 2023
1 parent d936b98 commit 7cc9941
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export interface FileUploaderSkeletonProps extends ReactAttr<HTMLDivElement> {
className?: string;
}

function FileUploaderSkeleton({ className, ...rest }) {
function FileUploaderSkeleton({
className,
...rest
}: FileUploaderSkeletonProps) {
const prefix = usePrefix();
return (
<div className={cx(`${prefix}--form-item`, className)} {...rest}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ export interface FileUploaderDropContainerProps

/**
* Event handler that is called after files are added to the uploader
* The event handler signature looks like `onAddFiles(evt, { addedFiles })`
*/
onAddFiles?: () => void;
onAddFiles?: (
event: React.SyntheticEvent<HTMLElement>,
content: { addedFiles: File[] }
) => void;

/**
* Provide an optional function to be called when the button element
Expand All @@ -70,6 +72,11 @@ export interface FileUploaderDropContainerProps
*/
pattern?: string;

/**
* Ref to pass to the inner button element
*/
innerRef?: React.LegacyRef<HTMLButtonElement>;

/**
* @deprecated The `role` prop for `FileUploaderButton` has been deprecated since it now renders a button element by default, and has an implicit role of button.
*/
Expand All @@ -81,21 +88,25 @@ export interface FileUploaderDropContainerProps
tabIndex?: number | string;
}

interface AddedFile extends File {
invalidFileType?: boolean;
}

function FileUploaderDropContainer({
accept,
accept = [],
className,
id,
disabled,
labelText,
multiple,
labelText = 'Add file',
multiple = false,
name,
onAddFiles,
onAddFiles = () => {},
onClick,
pattern,
pattern = '.[0-9a-z]+$',
// eslint-disable-next-line react/prop-types
innerRef,
...rest
}) {
}: FileUploaderDropContainerProps) {
const prefix = usePrefix();
const inputRef = useRef<HTMLInputElement>(null);
const { current: uid } = useRef(id || uniqueId());
Expand All @@ -106,46 +117,45 @@ function FileUploaderDropContainer({
{
[`${prefix}--file__drop-container--drag-over`]: isActive,
[`${prefix}--file-browse-btn--disabled`]: disabled,
[className]: className,
}
},
className
);

/**
* Filters the array of added files based on file type restrictions
* @param {Event} event - Event object, used to get the list of files added
*/
function validateFiles(event) {
const transferredFiles =
event.type === 'drop'
? [...event.dataTransfer.files]
: [...event.target.files];
function validateFiles(transferredFiles: AddedFile[]) {
if (!accept.length) {
return transferredFiles;
}
const acceptedTypes = new Set(accept);
return transferredFiles.reduce((acc, curr) => {
return transferredFiles.reduce<AddedFile[]>((acc, curr) => {
const { name, type: mimeType = '' } = curr;
const fileExtensionRegExp = new RegExp(pattern, 'i');
const hasFileExtension = fileExtensionRegExp.test(name);
if (!hasFileExtension) {
const [fileExtension] = name.match(fileExtensionRegExp) ?? [];
if (fileExtension === undefined) {
return acc;
}
const [fileExtension] = name.match(fileExtensionRegExp);

if (
acceptedTypes.has(mimeType) ||
acceptedTypes.has(fileExtension.toLowerCase())
) {
return acc.concat([curr]);
}

curr.invalidFileType = true;
return acc.concat([curr]);
}, []);
}

function handleChange(event) {
const addedFiles = validateFiles(event);
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
const files = [...(event.target.files ?? [])];
const addedFiles = validateFiles(files);
return onAddFiles(event, { addedFiles });
}

function handleDrop(event: React.DragEvent<HTMLDivElement>) {
const files = [...event.dataTransfer.files];
const addedFiles = validateFiles(files);
return onAddFiles(event, { addedFiles });
}

Expand Down Expand Up @@ -183,8 +193,9 @@ function FileUploaderDropContainer({
return;
}
setActive(false);
handleChange(evt);
handleDrop(evt);
}}>
{/* @ts-expect-error remove this ignore line when the explicit tabIndex prop is deleted */}
<button
type="button"
className={dropareaClasses}
Expand All @@ -209,7 +220,7 @@ function FileUploaderDropContainer({
ref={inputRef}
tabIndex={-1}
disabled={disabled}
accept={accept}
accept={accept.join(',')}
name={name}
multiple={multiple}
onChange={handleChange}
Expand Down
15 changes: 9 additions & 6 deletions packages/react/src/components/FileUploader/FileUploaderItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ export interface FileUploaderItemProps extends ReactAttr<HTMLSpanElement> {
* Event handler that is called after removing a file from the file uploader
* The event handler signature looks like `onDelete(evt, { uuid })`
*/
onDelete?: (event: any, opts: { uuid: string }) => void;
onDelete?: (
event: React.SyntheticEvent<HTMLElement>,
opts: { uuid: string }
) => void;

/**
* Specify the size of the FileUploaderButton, from a list of available
Expand All @@ -66,21 +69,21 @@ export interface FileUploaderItemProps extends ReactAttr<HTMLSpanElement> {
function FileUploaderItem({
uuid,
name,
status,
status = 'uploading',
iconDescription,
onDelete,
onDelete = () => {},
invalid,
errorSubject,
errorBody,
size,
...other
}) {
}: FileUploaderItemProps) {
const prefix = usePrefix();
const { current: id } = useRef(uuid || uid());
const classes = cx(`${prefix}--file__selected-file`, {
[`${prefix}--file__selected-file--invalid`]: invalid,
[`${prefix}--file__selected-file--md`]: size === 'field' || size === 'md',
[`${prefix}--file__selected-file--sm`]: size === 'small' || size === 'sm',
[`${prefix}--file__selected-file--md`]: size === 'md',
[`${prefix}--file__selected-file--sm`]: size === 'sm',
});
return (
<span className={classes} {...other}>
Expand Down

0 comments on commit 7cc9941

Please sign in to comment.