prometheus: submit page — picker opens on tap, no double-fire

Two upload-zone fixes:

1. The file input had `display:none`. Several mobile browsers (notably
   older iOS Safari and some Android WebViews) refuse to open the file
   picker for a display-none input even through a wrapping <label> or a
   scripted .click(). Replace with the visually-hidden pattern:
   position:absolute, 1x1 px, opacity:0 — the input stays a real
   clickable element but takes no visible space.

2. We had a redundant `dz.addEventListener('click', () => fi.click())`
   on the <label> that also wraps the input. The native label behavior
   ALREADY dispatches a click to the input; the scripted .click() fires
   a second one on top. Desktop Chrome ignores or errors on the second
   picker request. Dropped the handler; the native label path is
   enough and more reliable on mobile too.
This commit is contained in:
Local Dev 2026-10-23 20:53:55 +03:00
parent 1abaefe948
commit 97b658a0e1

View file

@ -385,7 +385,15 @@ export function submit() {
.drop-zone .drop-main{color:var(--ink);font-size:15px}
.drop-zone .drop-link{color:var(--acid);text-decoration:underline}
.drop-zone .drop-small{color:var(--dim);font-size:12.5px;margin-top:.5rem;display:block}
.drop-zone input[type=file]{display:none}
/* Visually hide the input, but keep it in the layout and clickable.
display:none on a file input makes several mobile browsers refuse
to open the picker, even when the input is wrapped by a <label> or
a scripted .click() is used. The pattern below keeps the input a
real, focusable, clickable element at 1px that nobody can see. */
.drop-zone input[type=file]{
position:absolute;left:0;top:0;width:1px;height:1px;
opacity:0;overflow:hidden;
}
</style>
<header class="hero compact">
@ -675,14 +683,13 @@ export function submit() {
}
// ===== STEP 1: upload (drag-drop zone + file picker) =====
// The drop zone IS a <label> wrapping the file input, so a tap/click on
// the label natively opens the picker — we don't bind our own click
// handler, because a scripted fi.click() on top of that fires a SECOND
// picker and some browsers (desktop Chrome in particular) ignore or
// error on the second one. Native-only is the reliable path.
const dz = $('drop-zone');
const fi = $('file-input');
dz.addEventListener('click', (ev) => {
// Clicking the hidden <input> directly works; stop click bubbling from
// the inner link span so we don't open the picker twice.
if (ev.target === fi) return;
fi.click();
});
['dragover','dragenter'].forEach((e) => dz.addEventListener(e, (ev) => {
ev.preventDefault(); dz.classList.add('dragover');
}));