diff --git a/src/Components/Web.JS/src/InputFile.ts b/src/Components/Web.JS/src/InputFile.ts index 982e224f4628..c6377430f562 100644 --- a/src/Components/Web.JS/src/InputFile.ts +++ b/src/Components/Web.JS/src/InputFile.ts @@ -52,6 +52,15 @@ function init(callbackWrapper: any, elem: InputElement): void { callbackWrapper.invokeMethodAsync('NotifyChange', fileList); }); + + // The 'cancel' event is fired when the user cancels the file picker dialog. + // This event is part of the HTML5 standard and is supported in modern browsers. + // For browsers that don't support this event, it will be silently ignored. + elem.addEventListener('cancel', function(): void { + // Notify with an empty list when the file dialog is cancelled. + elem._blazorFilesById = {}; + callbackWrapper.invokeMethodAsync('NotifyChange', []); + }); } async function toImageFile(elem: InputElement, fileId: number, format: string, maxWidth: number, maxHeight: number): Promise { diff --git a/src/Components/test/E2ETest/Tests/InputFileTest.cs b/src/Components/test/E2ETest/Tests/InputFileTest.cs index bfeb682482fa..a83dcb56b217 100644 --- a/src/Components/test/E2ETest/Tests/InputFileTest.cs +++ b/src/Components/test/E2ETest/Tests/InputFileTest.cs @@ -196,6 +196,31 @@ public void ThrowsWhenOversizedFileIsSelected() Browser.Equal("Supplied file with size 32 bytes exceeds the maximum of 10 bytes.", () => exceptionMessage.Text); } + [Fact] + public void CanClearFilesByInvokingCancelEvent() + { + // Upload a file first + var file = TempFile.Create(_tempDirectory, "txt", "This is a test file."); + var inputFile = Browser.Exists(By.Id("input-file")); + inputFile.SendKeys(file.Path); + + // Verify the file was uploaded + var fileContainer = Browser.Exists(By.Id($"file-{file.Name}")); + + // Get the file count element + var fileCount = Browser.Exists(By.Id("file-count")); + Browser.Equal("1", () => fileCount.Text); + + // Trigger the cancel event via JavaScript to simulate canceling the file dialog + Browser.ExecuteJavaScript(@" + const inputElement = document.getElementById('input-file'); + inputElement.dispatchEvent(new Event('cancel')); + "); + + // Wait a moment for the event to be processed and verify the file list was cleared + Browser.Equal("0", () => Browser.Exists(By.Id("file-count")).Text); + } + public void Dispose() { Directory.Delete(_tempDirectory, recursive: true); diff --git a/src/Components/test/testassets/BasicTestApp/FormsTest/InputFileComponent.razor b/src/Components/test/testassets/BasicTestApp/FormsTest/InputFileComponent.razor index c05d1f053254..b919ad6c53ac 100644 --- a/src/Components/test/testassets/BasicTestApp/FormsTest/InputFileComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/FormsTest/InputFileComponent.razor @@ -16,6 +16,7 @@ Max allowed files:
+@loadedFiles.Count @exceptionMessage @if (isLoading)