You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reported by Dawid, 12.09.2026, from the work form on a phone.
What happens
With the cursor left in a text field — the work's name at the top of the form, or the
display name at the top of the profile — moving either R360 slider pulls the page
straight back to that field. Every move does it, so the parameters cannot be set by hand
once anything has been typed.
Nothing is putting the focus back: it never left. A browser withholds the focus from a
slider on touch. Measured in mobile Chromium (Pixel 7 emulation, real touch events) on a
page holding a text field, an input[type=range], a <button> and a div role="slider" tabindex="0", the text field focused first each time:
touched
where the focus ends up
input[type=range], tapped
stays in the text field
input[type=range], dragged
stays in the text field
div role="slider" tabindex="0"
moves to the div
<button>
moves to the button
So the field keeps the caret, the on-screen keyboard stays up, and the browser holds the
caret in view. Each slider move re-renders the preview and changes the layout, and the
page is dragged back to the caret — which reads as "the page keeps jumping to the name
field".
Safari on iOS withholds the focus more widely than Chrome: a tap gives none to a <button> either, nor to a tabbable div. Dawid uses both platforms, so a fix that only
covers the two input[type=range] controls would leave the same fault on iOS behind every
button in the panel and behind the orbit preview itself.
The slider-shaped controls in the product:
RangeParam in src/app/[locale]/(public)/[handle]/r360-params.tsx — frames per
picture width, and ring flattening. The two this was reported on; broken on both
platforms.
src/components/ui/orbit-viewer.tsx — div role="slider" tabindex="0", the dragged
orbit. Takes the focus on Android, takes none on iOS.
src/components/ui/channel-reveal.tsx — the same shape, the two-channel handle.
What it should do
Touching a control moves the focus onto it, the way clicking it does on a desktop. The
text field then loses the caret, the keyboard goes down, and there is nothing left for the
browser to scroll back to.
The press is what takes it — onPointerDown → event.currentTarget.focus({ preventScroll: true }), verified in the same measurement (a slider carrying that handler ends up with the
focus). preventScroll because the element is already under the finger: there is nothing
to scroll into view, and scrolling to it would be a second jump.
To settle while writing it:
Buttons on iOS. The direction toggle, the cue buttons under the picture and "Use
this frame" have the same fault there, and so does every other button on a page with a
text field above it. Decide whether this is a property of our Button — a press takes the
focus — or whether the panel alone handles it. The first is one place and covers the
product; it also changes what has the focus after a tap everywhere, which is worth
looking at once before choosing it.
The focus ring. A programmatic focus() from a pointer press does not set :focus-visible, so no ring should appear for a finger while the keyboard's own ring is
untouched. Confirm rather than assume — it is the visible half of this change.
e2e with hasTouch: with the work's name field focused, a tap on the frames-per-width
slider leaves the focus on the slider and not in the field. That assertion fails today.
By hand on both phones, Android and iPhone: type in the name, then work the sliders, the
two toggles and "Use this frame" — the page stays where it is and the keyboard goes down
on the first touch.
Reported by Dawid, 12.09.2026, from the work form on a phone.
What happens
With the cursor left in a text field — the work's name at the top of the form, or the
display name at the top of the profile — moving either R360 slider pulls the page
straight back to that field. Every move does it, so the parameters cannot be set by hand
once anything has been typed.
Nothing is putting the focus back: it never left. A browser withholds the focus from a
slider on touch. Measured in mobile Chromium (Pixel 7 emulation, real touch events) on a
page holding a text field, an
input[type=range], a<button>and adiv role="slider" tabindex="0", the text field focused first each time:input[type=range], tappedinput[type=range], draggeddiv role="slider" tabindex="0"<button>So the field keeps the caret, the on-screen keyboard stays up, and the browser holds the
caret in view. Each slider move re-renders the preview and changes the layout, and the
page is dragged back to the caret — which reads as "the page keeps jumping to the name
field".
Safari on iOS withholds the focus more widely than Chrome: a tap gives none to a
<button>either, nor to a tabbablediv. Dawid uses both platforms, so a fix that onlycovers the two
input[type=range]controls would leave the same fault on iOS behind everybutton in the panel and behind the orbit preview itself.
The slider-shaped controls in the product:
RangeParaminsrc/app/[locale]/(public)/[handle]/r360-params.tsx— frames perpicture width, and ring flattening. The two this was reported on; broken on both
platforms.
src/components/ui/orbit-viewer.tsx—div role="slider" tabindex="0", the draggedorbit. Takes the focus on Android, takes none on iOS.
src/components/ui/channel-reveal.tsx— the same shape, the two-channel handle.What it should do
Touching a control moves the focus onto it, the way clicking it does on a desktop. The
text field then loses the caret, the keyboard goes down, and there is nothing left for the
browser to scroll back to.
The press is what takes it —
onPointerDown→event.currentTarget.focus({ preventScroll: true }), verified in the same measurement (a slider carrying that handler ends up with thefocus).
preventScrollbecause the element is already under the finger: there is nothingto scroll into view, and scrolling to it would be a second jump.
To settle while writing it:
this frame" have the same fault there, and so does every other button on a page with a
text field above it. Decide whether this is a property of our
Button— a press takes thefocus — or whether the panel alone handles it. The first is one place and covers the
product; it also changes what has the focus after a tap everywhere, which is worth
looking at once before choosing it.
focus()from a pointer press does not set:focus-visible, so no ring should appear for a finger while the keyboard's own ring isuntouched. Confirm rather than assume — it is the visible half of this change.
that is not a slider (the works and places drag handles, Small things to polish: a logo that stops leading away, two lists that keep their order, and a place a phone can add #66/Dragging a list should look like dragging: the held item follows, the others make room #173).
Verification
hasTouch: with the work's name field focused, a tap on the frames-per-widthslider leaves the focus on the slider and not in the field. That assertion fails today.
two toggles and "Use this frame" — the page stays where it is and the keyboard goes down
on the first touch.
Spec: SPEC.md A13 · Labels: bug, ux