Dialog closes when a file input inside it has its picker cancelled
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 85/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- bootstrap, javascript, typescript
- Domain
- frontend
Research direction
Start with the cancel handler in js/src/dialog-base.ts, linked in the issue, and check how nearby dialog event handlers distinguish events from descendants. Add coverage using the issue's reproduction steps and verify that cancelling the file picker leaves the dialog open, while the dialog's own cancel behavior still works.
Written by the indexing model from the issue text.
Description
Prerequisites
- I have searched for duplicate or closed issues
- I have validated any HTML to avoid common problems
- I have read the contributing guidelines
Describe the issue
A dialog closes when the user opens the file picker of an <input type="file"> inside it and then dismisses the picker without choosing a file.
When a file picker is dismissed, browsers fire a cancel event at the input, and the HTML spec has it bubble (spec). It reaches the <dialog>, where DialogBase listens for cancel to handle Escape. That handler does not check event.target, so it treats the bubbled event as the dialog's own cancel and calls hide():
The native cancel event of a <dialog> does not bubble, so any cancel that arrives from a descendant is never the dialog's own. The backdrop click handler a few lines further down already guards with event.target !== this._element.
Steps to reproduce with the test case below:
- Click "Open dialog".
- Click the file input, so the file picker opens.
- Press Cancel in the file picker.
Expected: the dialog stays open.
Actual: the dialog closes. With data-bs-keyboard="false" it plays the static-backdrop animation instead, which is just as unexpected.
Suggested fix: ignore cancel events from descendants at the top of the handler:
this._cancelHandler = event => {
if (event.target !== this._element) {
return
}
event.preventDefault()
// …
}
The workaround until then is to stop the event on the input:
input.addEventListener('cancel', event => event.stopPropagation())
Reduced test cases
CodePen: https://codepen.io/editor/aloysiu5/pen/01a1a134-60a4-7254-98af-7ffc218ae510
The same as a self-contained page against the alpha.1 CDN build:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Dialog closes when a file picker is cancelled</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="p-6">
<button type="button" class="btn-solid theme-primary" data-bs-toggle="dialog" data-bs-target="#upload">Open dialog</button>
<dialog class="dialog" id="upload" aria-labelledby="upload-title">
<div class="dialog-header">
<h2 class="dialog-title" id="upload-title">Upload</h2>
<button type="button" class="btn-close" data-bs-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="dialog-body">
<label for="file" class="form-label">Choose a file, then cancel the picker</label>
<input type="file" class="form-control" id="file">
</div>
</dialog>
<script type="module">
import "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
document.getElementById("file").addEventListener("cancel", (event) => {
console.log("cancel on", event.target.tagName, "bubbles:", event.bubbles)
})
</script>
</body>
</html>
The console line shows the event that closes the dialog: cancel on INPUT bubbles: true.
What operating system(s) are you seeing the problem on?
macOS
What browser(s) are you seeing the problem on?
Chrome
What version of Bootstrap are you using?
v6.0.0-alpha.1 (the handler is unchanged on main at 7e914e3)
- Dominant language
- MDX
- Stars
- 175k
- Forks
- 78.5k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 111
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from twbs/bootstrap
-
v6 alpha - hover-lift effect on menu dropdown only works when mouse is over the buttonPossibly taken @Aryan9891 claimed this 2 days ago. Openbug confirmed css has-pr v6
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Maintainers usually reply within 1 day
-
docs js on-hold v6
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Toasts seem to be hidden behind drawersPossibly taken @ump45nose claimed this 9 days ago. Openbug confirmed docs has-pr html v6
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
File input height taller than expectedPossibly taken A pull request linked to this issue is open or already merged. Openbug confirmed css has-pr v6
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
Maintainers usually reply within 1 day
-
Theme variations like theme-contrast do not work as expected in a table.Possibly taken @bercedev claimed this 15 days ago. Openbug confirmed css has-pr v6
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
Similar issues
-
ipaas: Configure form shows "Deploy to apply." and "Overrides selected Link" when they don't applyOpen
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
wso2/integration-control-plane#1118 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
UTDNebula/utd-notebook#311 ·
Maintainers usually reply within 2 days
-
Bug
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Maintainers usually reply within 1 day
-
claude
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
sprain/sprainocchio#26 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 4 days