Skip to content

Commit 1c3ebfe

Browse files
vanceingallsclaude
andcommitted
fix(studio): widen FlatSlider's click/drag hit area vertically
The track's visible line was only 2px tall, and pointerdown was bound directly to that thin element, making it hard to grab. The hit area is now 20px tall (a wrapping div) with the visible line rendered as a thin decorative child, centered inside it — the ratio math only reads left/width so click accuracy is unaffected. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 023b326 commit 1c3ebfe

2 files changed

Lines changed: 43 additions & 16 deletions

File tree

packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,33 @@ describe("FlatSlider", () => {
253253
expect(onCommit).toHaveBeenCalledWith(50);
254254
act(() => root.unmount());
255255
});
256+
257+
it("widens the click/drag hit area vertically beyond the thin visible line", () => {
258+
const onCommit = vi.fn();
259+
const { host, root } = renderInto(
260+
<FlatSlider
261+
label="Opacity"
262+
value={50}
263+
min={0}
264+
max={100}
265+
tier="explicitCustom"
266+
displayValue="50%"
267+
onCommit={onCommit}
268+
/>,
269+
);
270+
const track = host.querySelector<HTMLElement>('[data-flat-slider-track="true"]');
271+
if (!track) throw new Error("expected a track element");
272+
Object.defineProperty(track, "getBoundingClientRect", {
273+
value: () => ({ left: 0, width: 200, top: 0, height: 20, right: 200, bottom: 20 }),
274+
});
275+
act(() => {
276+
track.dispatchEvent(
277+
new MouseEvent("pointerdown", { bubbles: true, clientX: 20, clientY: 18 }),
278+
);
279+
});
280+
expect(onCommit).toHaveBeenCalledWith(10);
281+
act(() => root.unmount());
282+
});
256283
});
257284

258285
describe("FlatSlider — Grade extensions", () => {

packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -259,27 +259,27 @@ export function FlatSlider({
259259
aria-label={label}
260260
aria-valuenow={value}
261261
aria-disabled={disabled}
262-
className={`relative h-0.5 flex-1 rounded-full bg-panel-hover ${
263-
disabled ? "cursor-not-allowed" : "cursor-pointer"
264-
}`}
262+
className={`relative h-5 flex-1 ${disabled ? "cursor-not-allowed" : "cursor-pointer"}`}
265263
onPointerDown={(e) => {
266264
if (disabled) return;
267265
commitFromClientX(e.clientX, e.currentTarget.getBoundingClientRect());
268266
}}
269267
>
270-
{centerTick && (
271-
<div
272-
data-flat-slider-center-tick="true"
273-
className="absolute left-1/2 top-[-1px] h-1 w-px -translate-x-1/2 bg-panel-text-5"
274-
/>
275-
)}
276-
{tier === "explicitCustom" && (
277-
<div
278-
data-flat-slider-fill="true"
279-
className="absolute inset-y-0 left-0 rounded-full bg-panel-text-5"
280-
style={{ width: `${clampedPct}%` }}
281-
/>
282-
)}
268+
<div className="absolute inset-x-0 top-1/2 h-0.5 -translate-y-1/2 rounded-full bg-panel-hover">
269+
{centerTick && (
270+
<div
271+
data-flat-slider-center-tick="true"
272+
className="absolute left-1/2 top-[-1px] h-1 w-px -translate-x-1/2 bg-panel-text-5"
273+
/>
274+
)}
275+
{tier === "explicitCustom" && (
276+
<div
277+
data-flat-slider-fill="true"
278+
className="absolute inset-y-0 left-0 rounded-full bg-panel-text-5"
279+
style={{ width: `${clampedPct}%` }}
280+
/>
281+
)}
282+
</div>
283283
<div
284284
data-flat-slider-knob="true"
285285
className={`absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full ${

0 commit comments

Comments
 (0)