Focus file upload modal on open (#32188)

GitOrigin-RevId: 89ad65e4ad5af59d46f04ca4e057f88120e8293f
This commit is contained in:
Alf Eaton
2026-03-19 10:45:27 +00:00
committed by Copybot
parent 46d1064837
commit 616f99fece
2 changed files with 46 additions and 26 deletions

View File

@@ -1,5 +1,5 @@
import { useTranslation } from 'react-i18next'
import { useCallback, useEffect, useState } from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import Uppy from '@uppy/core'
import XHRUpload from '@uppy/xhr-upload'
import { Dashboard } from '@uppy/react'
@@ -35,6 +35,7 @@ export default function FileTreeUploadDoc() {
const [conflicts, setConflicts] = useState<Conflict[]>([])
const [folderConflicts, setFolderConflicts] = useState<Conflict[]>([])
const [overwrite, setOverwrite] = useState(false)
const dashboardRef = useRef<HTMLDivElement>(null)
const maxNumberOfFiles = 180
const maxFileSize = getMeta('ol-ExposedSettings').maxUploadSize
@@ -263,6 +264,22 @@ export default function FileTreeUploadDoc() {
!overwrite && !showFolderUploadConflicts && conflicts.length > 0
const showDashboard = !showFileUploadConfilcts && !showFolderUploadConflicts
useEffect(() => {
if (!showDashboard) {
return
}
const frameId = window.requestAnimationFrame(() => {
dashboardRef.current
?.querySelector<HTMLButtonElement>('.uppy-Dashboard-browse')
?.focus()
})
return () => {
window.cancelAnimationFrame(frameId)
}
}, [showDashboard])
return (
<>
{error && (
@@ -284,30 +301,32 @@ export default function FileTreeUploadDoc() {
/>
)}
{showDashboard && (
<Dashboard
uppy={uppy}
showProgressDetails
// note={`Up to ${maxNumberOfFiles} files, up to ${maxFileSize / (1024 * 1024)}MB`}
height={400}
width="100%"
showLinkToFileUploadResult={false}
proudlyDisplayPoweredByUppy={false}
// allow files or folders to be selected
fileManagerSelectionType="both"
locale={{
strings: {
// Text to show on the droppable area.
// `%{browse}` is replaced with a link that opens the system file selection dialog.
// TODO: 'drag_here' or 'drop_files_here_to_upload'?
// dropHereOr: `${t('drag_here')} ${t('or')} %{browse}`,
dropPasteBoth: `Drop or paste your files, folder, or images here. %{browseFiles} or %{browseFolders} from your computer.`,
// Used as the label for the link that opens the system file selection dialog.
// browseFiles: t('select_from_your_computer')
browseFiles: 'Select files',
browseFolders: 'select a folder',
},
}}
/>
<div ref={dashboardRef}>
<Dashboard
uppy={uppy}
showProgressDetails
// note={`Up to ${maxNumberOfFiles} files, up to ${maxFileSize / (1024 * 1024)}MB`}
height={400}
width="100%"
showLinkToFileUploadResult={false}
proudlyDisplayPoweredByUppy={false}
// allow files or folders to be selected
fileManagerSelectionType="both"
locale={{
strings: {
// Text to show on the droppable area.
// `%{browse}` is replaced with a link that opens the system file selection dialog.
// TODO: 'drag_here' or 'drop_files_here_to_upload'?
// dropHereOr: `${t('drag_here')} ${t('or')} %{browse}`,
dropPasteBoth: `Drop or paste your files, folder, or images here. %{browseFiles} or %{browseFolders} from your computer.`,
// Used as the label for the link that opens the system file selection dialog.
// browseFiles: t('select_from_your_computer')
browseFiles: 'Select files',
browseFolders: 'select a folder',
},
}}
/>
</div>
)}
</>
)

View File

@@ -530,13 +530,14 @@ describe('<FileTreeModalCreateFile/>', function () {
// the submit button should not be present
cy.findByRole('button', { name: 'Create' }).should('not.exist')
cy.findByRole('button', { name: 'Select files' }).should('be.focused')
cy.wrap(null).then(() => {
const clipboardData = new DataTransfer()
clipboardData.items.add(
new File(['test'], 'test.tex', { type: 'text/plain' })
)
cy.findByLabelText('Uppy Dashboard').trigger('paste', { clipboardData })
cy.focused().trigger('paste', { clipboardData })
})
cy.wait('@uploadFile')