Let the slider keep the drag the browser wanted to take
Docs / docs (push) Successful in 22s
Playwright Tests / test-playwright (1, 2) (push) Failing after 2m38s
Playwright Tests / test-playwright (2, 2) (push) Failing after 1m41s
pre-commit / pre-commit (push) Failing after 2m47s
Test Backend / test-backend (push) Successful in 2m19s
Compose Smoke Test / test-compose (push) Successful in 32s
Playwright Tests / merge-reports (push) Failing after 1m4s
Docs / docs (push) Successful in 22s
Playwright Tests / test-playwright (1, 2) (push) Failing after 2m38s
Playwright Tests / test-playwright (2, 2) (push) Failing after 1m41s
pre-commit / pre-commit (push) Failing after 2m47s
Test Backend / test-backend (push) Successful in 2m19s
Compose Smoke Test / test-compose (push) Successful in 32s
Playwright Tests / merge-reports (push) Failing after 1m4s
Dragging the brightness slider on the wall panel set the handle and published nothing; tapping a point on the track worked. The control is a native range input laid transparent over the drawn track, and only the release publishes — but the input never said the drag was its own. On a touch panel a sideways swipe is a pan, or a back-navigation, so the browser took the pointer over mid-drag and ended it in `pointercancel`. The value had followed the finger and was never sent. `touch-action: none`, as the colour disk beside it has always had. The release also answers `pointercancel` and `lostpointercapture` now, which covers a mouse let go outside the input and leaves no way for a draft to sit there unpublished. Two checks: a drag across the track reaches the engine, and the input still owns its gesture. The second fails against a build without the CSS, which is what makes it worth having. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012n6CehUsHYYUXJ48rxaD18
This commit is contained in:
@@ -203,6 +203,13 @@ export function useSliderDrag({
|
||||
onChange: (event: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setDraft(Number(event.target.value)),
|
||||
onPointerUp: release,
|
||||
// A drag can end without a `pointerup` on this element: the browser can
|
||||
// claim the gesture and cancel the pointer, and a mouse released outside
|
||||
// the input reports the release elsewhere. Either way the draft would sit
|
||||
// there unpublished, showing a value nobody was ever sent. `release`
|
||||
// ignores a second call, so overlapping ends are free.
|
||||
onPointerCancel: release,
|
||||
onLostPointerCapture: release,
|
||||
onKeyUp: release,
|
||||
onBlur: release,
|
||||
},
|
||||
|
||||
@@ -250,6 +250,13 @@
|
||||
background: none;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
/* The drag is the control, so the browser may not read it as a gesture of
|
||||
its own. Without this a sideways swipe on a touch panel is a pan — or a
|
||||
back-navigation — and the browser takes the pointer over mid-drag, which
|
||||
ends the drag in `pointercancel` rather than `pointerup`. The value
|
||||
followed the finger and was never published. Same reason `.dui-disc`
|
||||
has it. */
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.dui-slider[data-orientation="vertical"] .dui-slider-input {
|
||||
|
||||
Reference in New Issue
Block a user