From b9253f797a3a782cfc9d1a5ec84e5c3716642d5c Mon Sep 17 00:00:00 2001 From: Enver <39167353+EnverUsta@users.noreply.github.com> Date: Fri, 24 Apr 2026 13:30:02 +0300 Subject: [PATCH] @uppy/dashboard: My Device button respects fileManagerSelectionType (#6258) Fixes #6256 ## Problem When `fileManagerSelectionType` is set to `'folders'`, clicking the **My Device** tab/button still opens the file picker instead of the folder picker. The inline "browse" link in the tagline correctly respects the setting, but `renderMyDeviceAcquirer` in `AddFiles.tsx` always called `triggerFileInputClick` regardless of the `fileManagerSelectionType` prop. ## Solution `renderMyDeviceAcquirer` now reads `fileManagerSelectionType` and calls `triggerFolderInputClick` when set to `'folders'`, or `triggerFileInputClick` for `'files'` and `'both'`. For `'both'` mode, the button defaults to file selection because a single HTML `` cannot handle both files and folders simultaneously (`webkitdirectory` is all-or-nothing). The folder picker remains accessible via the tagline's "browse folders" link. --------- Co-authored-by: Prakash --- .changeset/few-plants-pump.md | 5 + .../dashboard/src/components/AddFiles.tsx | 9 +- packages/@uppy/dashboard/src/index.test.ts | 102 ++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 .changeset/few-plants-pump.md diff --git a/.changeset/few-plants-pump.md b/.changeset/few-plants-pump.md new file mode 100644 index 000000000..a094e2988 --- /dev/null +++ b/.changeset/few-plants-pump.md @@ -0,0 +1,5 @@ +--- +"@uppy/dashboard": patch +--- + +fix "My Device" button in dashboard, it now respects the fileManagerSelectionType. diff --git a/packages/@uppy/dashboard/src/components/AddFiles.tsx b/packages/@uppy/dashboard/src/components/AddFiles.tsx index bbfd6ac95..643170295 100644 --- a/packages/@uppy/dashboard/src/components/AddFiles.tsx +++ b/packages/@uppy/dashboard/src/components/AddFiles.tsx @@ -106,6 +106,13 @@ class AddFiles extends Component { } private renderMyDeviceAcquirer = () => { + // Cannot select both files and folders at once (webkitdirectory is all-or-nothing), + // so in 'both' mode the folder picker remains accessible via the tagline browse link. + const triggerMyDeviceInputClick = + this.props.fileManagerSelectionType === 'folders' + ? this.triggerFolderInputClick + : this.triggerFileInputClick + return (
{ role="tab" tabIndex={0} data-uppy-super-focusable - onClick={this.triggerFileInputClick} + onClick={triggerMyDeviceInputClick} >
{ core.destroy() }) + + describe('My Device acquirer respects fileManagerSelectionType', () => { + // `showNativePhotoCameraButton: true` is used to force the My Device tab + // to render — Dashboard hides it when it would be the only entry in the list + // (see `hasOnlyMyDevice` in AddFiles.tsx). + const mountDashboard = ( + fileManagerSelectionType: 'files' | 'folders' | 'both', + ) => { + document.body.innerHTML = '' + const core = new Core() + core.use(DashboardPlugin, { + inline: true, + target: 'body', + fileManagerSelectionType, + showNativePhotoCameraButton: true, + }) + return core + } + + const getInputs = () => { + const fileInput = document.querySelector( + '.uppy-Dashboard-input:not([webkitdirectory])', + )! + const folderInput = document.querySelector( + '.uppy-Dashboard-input[webkitdirectory]', + )! + return { fileInput, folderInput } + } + + const clickMyDeviceTab = () => { + const tab = document.querySelector( + '[data-uppy-acquirer-id="MyDevice"] button[role="tab"]', + )! + tab.click() + } + + it('triggers the folder input when set to "folders"', () => { + const core = mountDashboard('folders') + const { fileInput, folderInput } = getInputs() + + let fileClicked = false + let folderClicked = false + fileInput.addEventListener('click', () => { + fileClicked = true + }) + folderInput.addEventListener('click', () => { + folderClicked = true + }) + + clickMyDeviceTab() + + expect(folderClicked).toBe(true) + expect(fileClicked).toBe(false) + + core.destroy() + }) + + it('triggers the file input when set to "files"', () => { + const core = mountDashboard('files') + const { fileInput, folderInput } = getInputs() + + let fileClicked = false + let folderClicked = false + fileInput.addEventListener('click', () => { + fileClicked = true + }) + folderInput.addEventListener('click', () => { + folderClicked = true + }) + + clickMyDeviceTab() + + expect(fileClicked).toBe(true) + expect(folderClicked).toBe(false) + + core.destroy() + }) + + // `both` mode intentionally falls back to the file picker because a single + // HTML