diff --git a/packages/@uppy/core/src/UIPlugin.ts b/packages/@uppy/core/src/UIPlugin.ts index 49f6772711..7aa3614e0f 100644 --- a/packages/@uppy/core/src/UIPlugin.ts +++ b/packages/@uppy/core/src/UIPlugin.ts @@ -183,7 +183,7 @@ class UIPlugin< // eslint-disable-next-line @typescript-eslint/no-unused-vars state: Record, // eslint-disable-next-line @typescript-eslint/no-unused-vars - container: HTMLElement, + container?: HTMLElement, ): any { throw new Error( 'Extend the render method to add your plugin to a DOM element', diff --git a/packages/@uppy/dashboard/src/Dashboard.tsx b/packages/@uppy/dashboard/src/Dashboard.tsx index 290761919f..dc9a7f5768 100644 --- a/packages/@uppy/dashboard/src/Dashboard.tsx +++ b/packages/@uppy/dashboard/src/Dashboard.tsx @@ -97,8 +97,8 @@ interface Target { type: string } -interface TargetWithRender extends Target { - icon: ComponentChild +export interface TargetWithRender extends Target { + icon: () => ComponentChild render: () => ComponentChild } @@ -110,6 +110,12 @@ export interface DashboardState { fileCardFor: string | null showFileEditor: boolean metaFields?: MetaField[] | ((file: UppyFile) => MetaField[]) + isHidden: boolean + isClosing: boolean + containerWidth: number + containerHeight: number + areInsidesReadyToBeVisible: boolean + isDraggingOver: boolean [key: string]: unknown } @@ -146,7 +152,7 @@ interface DashboardMiscOptions hideRetryButton?: boolean hideUploadButton?: boolean metaFields?: MetaField[] | ((file: UppyFile) => MetaField[]) - nativeCameraFacingMode?: ConstrainDOMString + nativeCameraFacingMode?: 'user' | 'environment' | '' note?: string | null onDragLeave?: (event: DragEvent) => void onDragOver?: (event: DragEvent) => void @@ -165,7 +171,7 @@ interface DashboardMiscOptions thumbnailHeight?: number thumbnailType?: string thumbnailWidth?: number - trigger?: string | Element + trigger?: string | Element | null waitForThumbnailsBeforeUpload?: boolean } @@ -178,9 +184,6 @@ export type DashboardOptions< const defaultOptions = { target: 'body', metaFields: [], - inline: false as boolean, - width: 750, - height: 550, thumbnailWidth: 280, thumbnailType: 'image/jpeg', waitForThumbnailsBeforeUpload: false, @@ -193,31 +196,44 @@ const defaultOptions = { hidePauseResumeButton: false, hideProgressAfterFinish: false, note: null, - closeModalOnClickOutside: false, - closeAfterFinish: false, singleFileFullScreen: true, disableStatusBar: false, disableInformer: false, disableThumbnailGenerator: false, - disablePageScrollWhenModalOpen: true, - animateOpenClose: true, fileManagerSelectionType: 'files', proudlyDisplayPoweredByUppy: true, showSelectedFiles: true, showRemoveButtonAfterComplete: false, - browserBackButtonClose: false, showNativePhotoCameraButton: false, showNativeVideoCameraButton: false, theme: 'light', autoOpen: null, disabled: false, disableLocalFiles: false, + nativeCameraFacingMode: '', + onDragLeave: () => {}, + onDragOver: () => {}, + onDrop: () => {}, + plugins: [], // Dynamic default options, they have to be defined in the constructor (because // they require access to the `this` keyword), but we still want them to // appear in the default options so TS knows they'll be defined. doneButtonHandler: undefined as any, onRequestCloseModal: null as any, + + // defaultModalOptions + inline: false as boolean, + animateOpenClose: true, + browserBackButtonClose: false, + closeAfterFinish: false, + closeModalOnClickOutside: false, + disablePageScrollWhenModalOpen: true, + trigger: null, + + // defaultInlineOptions + width: 750, + height: 550, } satisfies Partial> /** @@ -824,7 +840,7 @@ export default class Dashboard extends UIPlugin< this.setPluginState({ isDraggingOver: true }) - this.opts.onDragOver?.(event) + this.opts.onDragOver(event) } private handleDragLeave = (event: DragEvent) => { @@ -833,7 +849,7 @@ export default class Dashboard extends UIPlugin< this.setPluginState({ isDraggingOver: false }) - this.opts.onDragLeave?.(event) + this.opts.onDragLeave(event) } private handleDrop = async (event: DragEvent) => { @@ -872,7 +888,7 @@ export default class Dashboard extends UIPlugin< this.addFiles(files) } - this.opts.onDrop?.(event) + this.opts.onDrop(event) } private handleRequestThumbnail = (file: UppyFile) => { @@ -1260,7 +1276,7 @@ export default class Dashboard extends UIPlugin< } #addSpecifiedPluginsFromOptions = () => { - const plugins = this.opts.plugins || [] + const { plugins } = this.opts plugins.forEach((pluginID) => { const plugin = this.uppy.getPlugin(pluginID) @@ -1466,7 +1482,7 @@ export default class Dashboard extends UIPlugin< if (thumbnail) this.uppy.removePlugin(thumbnail) } - const plugins = this.opts.plugins || [] + const { plugins } = this.opts plugins.forEach((pluginID) => { const plugin = this.uppy.getPlugin(pluginID) if (plugin) (plugin as any).unmount() diff --git a/packages/@uppy/dashboard/src/components/AddFiles.tsx b/packages/@uppy/dashboard/src/components/AddFiles.tsx index 43597d4ced..68bd75ca4d 100644 --- a/packages/@uppy/dashboard/src/components/AddFiles.tsx +++ b/packages/@uppy/dashboard/src/components/AddFiles.tsx @@ -1,34 +1,51 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck Typing this file requires more work, skipping it to unblock the rest of the transition. - /* eslint-disable react/destructuring-assignment */ import { h, Component, Fragment, type ComponentChild } from 'preact' +import type { I18n } from '@uppy/utils/lib/Translator' +import type Translator from '@uppy/utils/lib/Translator' +import type { TargetedEvent } from 'preact/compat' +import type { DashboardState, TargetWithRender } from '../Dashboard' + +interface AddFilesProps { + i18n: I18n + i18nArray: Translator['translateArray'] + acquirers: TargetWithRender[] + handleInputChange: (event: TargetedEvent) => void + maxNumberOfFiles: number | null + allowedFileTypes: string[] | null + showNativePhotoCameraButton: boolean + showNativeVideoCameraButton: boolean + nativeCameraFacingMode: 'user' | 'environment' | '' + showPanel: (id: string) => void + activePickerPanel: DashboardState['activePickerPanel'] + disableLocalFiles: boolean + fileManagerSelectionType: string + note: string | null + proudlyDisplayPoweredByUppy: boolean +} -type $TSFixMe = any - -class AddFiles extends Component { - fileInput: $TSFixMe +class AddFiles extends Component { + fileInput: HTMLInputElement | null = null - folderInput: $TSFixMe + folderInput: HTMLInputElement | null = null - mobilePhotoFileInput: $TSFixMe + mobilePhotoFileInput: HTMLInputElement | null = null - mobileVideoFileInput: $TSFixMe + mobileVideoFileInput: HTMLInputElement | null = null private triggerFileInputClick = () => { - this.fileInput.click() + this.fileInput?.click() } private triggerFolderInputClick = () => { - this.folderInput.click() + this.folderInput?.click() } private triggerVideoCameraInputClick = () => { - this.mobileVideoFileInput.click() + this.mobileVideoFileInput?.click() } private triggerPhotoCameraInputClick = () => { - this.mobilePhotoFileInput.click() + this.mobilePhotoFileInput?.click() } private onFileInputChange = ( @@ -42,13 +59,17 @@ class AddFiles extends Component { event.currentTarget.value = '' } - private renderHiddenInput = (isFolder: $TSFixMe, refCallback: $TSFixMe) => { + private renderHiddenInput = ( + isFolder: boolean, + refCallback: (ref: HTMLInputElement | null) => void, + ) => { return ( void, ) => { const typeToAccept = { photo: 'image/*', video: 'video/*' } const accept = typeToAccept[type] @@ -193,7 +214,10 @@ class AddFiles extends Component { ) } - private renderBrowseButton = (text: $TSFixMe, onClickFn: $TSFixMe) => { + private renderBrowseButton = ( + text: string, + onClickFn: (event: Event) => void, + ) => { const numberOfAcquirers = this.props.acquirers.length return (