import type { Body, Meta, State, UIPlugin, UIPluginOptions, Uppy, } from '@uppy/core' import type { I18n } from '@uppy/core/utils' import { useRef } from '@uppy/core/utils/preact/hooks' import classNames from 'classnames' import type { ComponentChildren, MouseEventHandler, TargetedDragEvent, } from 'preact' import type { DashboardState } from '../Dashboard.js' import ignoreEvent from '../utils/ignoreEvent.js' interface PickerPanelContentProps { activePickerPanel: NonNullable['activePickerPanel']> className?: string | undefined hideAllPanels: MouseEventHandler i18n: I18n state: State uppy: Uppy } function PickerPanelContent({ activePickerPanel, className, hideAllPanels, i18n, state, uppy, }: PickerPanelContentProps): ComponentChildren { const ref = useRef(null) const activePlugin = uppy.getPlugin(activePickerPanel.id) as | (UIPlugin & { // `standalone` and `acceptsFileDrops` are experimental, for the // file-management plugins (`@uppy/s3`); they will change. acceptsFileDrops?: boolean }) | undefined // A plugin that is the whole page (a file library rather than a picker) // asks for no chrome: the page around it owns the heading, and there is // nothing to cancel. const standalone = Boolean(activePlugin?.opts.standalone) // A picker's panel ignores dropped files: they would not end up where it // shows (a Google Drive folder, say). A plugin can opt in with // `acceptsFileDrops` (a storage browser); then the Dashboard takes a drag of // files as it would anywhere else. Not a drag of text or links, nor one over // a text field or an open dialog. const leaveToDashboard = (event: TargetedDragEvent) => { const target = event.target as Element return ( Boolean(activePlugin?.acceptsFileDrops) && Boolean(event.dataTransfer?.types.includes('Files')) && target.closest('input, textarea, dialog') == null ) } const ignoreDrag = (event: TargetedDragEvent) => { if (leaveToDashboard(event)) return ignoreEvent(event) // Where that blocked the drop (anywhere but a text field), don't show the // copy cursor that promises one. if ( event.type === 'dragover' && event.defaultPrevented && event.dataTransfer ) event.dataTransfer.dropEffect = 'none' } return (
{!standalone && (
{i18n('importFrom', { name: activePickerPanel.name })}
)}
{/* The panel can still be rendered once while its plugin is being removed (uppy.removePlugin / uppy.destroy), so tolerate a missing plugin instead of throwing during teardown. */} {activePlugin?.render(state, ref.current!)}
) } export default PickerPanelContent