diff --git a/client/src/components/Studio/StudioPaintPicker.tsx b/client/src/components/Studio/StudioPaintPicker.tsx index 078c00f10..b2c785e3c 100644 --- a/client/src/components/Studio/StudioPaintPicker.tsx +++ b/client/src/components/Studio/StudioPaintPicker.tsx @@ -8,7 +8,7 @@ import { type BookPatternPaint, } from '@trek/shared'; import { ArrowLeftRight, Ban, Trash2 } from 'lucide-react'; -import { useState } from 'react'; +import { useRef, useState } from 'react'; import '../../styles/studio-paint.css'; import { NumField } from './StudioControls'; import type { StudioT } from './StudioSidebar'; @@ -339,6 +339,8 @@ function Slider({ return log ? min * (max / min) ** t : min + (max - min) * t; }; const pos = Math.round((log ? Math.log(value / min) / Math.log(max / min) : (value - min) / (max - min)) * steps); + // What the slider was last moved to: a controlled input may still show the old value when it is let go. + const moved = useRef(value); return ( ); diff --git a/client/src/components/Studio/StudioSwatches.tsx b/client/src/components/Studio/StudioSwatches.tsx index 6aa05460a..0847f9534 100644 --- a/client/src/components/Studio/StudioSwatches.tsx +++ b/client/src/components/Studio/StudioSwatches.tsx @@ -114,7 +114,13 @@ export function AlphaSlider({ color, value, onChange, label }: { label?: string }) { const pct = Math.round(value * 100) - const finish = (raw: string) => onChange(Math.max(0, Math.min(100, Number(raw))) / 100, true) + // What the slider was last moved to: a controlled input may still show the old value when it is let go. + const moved = useRef(value) + const move = (raw: string) => { + moved.current = Math.max(0, Math.min(100, Number(raw))) / 100 + onChange(moved.current, false) + } + const finish = () => onChange(moved.current, true) return (
@@ -125,9 +131,11 @@ export function AlphaSlider({ color, value, onChange, label }: { step={1} value={pct} aria-label={label} - onChange={e => onChange(Number(e.target.value) / 100, false)} - onPointerUp={e => finish(e.currentTarget.value)} - onKeyUp={e => finish(e.currentTarget.value)} + onPointerDown={() => { moved.current = value }} + onKeyDown={() => { moved.current = value }} + onChange={e => move(e.target.value)} + onPointerUp={finish} + onKeyUp={finish} />
{pct}% diff --git a/client/tests/unit/studio/paintRender.test.tsx b/client/tests/unit/studio/paintRender.test.tsx index f7879aa74..602716fc6 100644 --- a/client/tests/unit/studio/paintRender.test.tsx +++ b/client/tests/unit/studio/paintRender.test.tsx @@ -65,7 +65,7 @@ const painted = (): BookSpread => ({ shape('g1', { paint: linear }), shape('h1', { shape: 'heart', paint: dots, stroke: '#000000', strokeWidth: 1 }), shape('r1', { shape: 'rect', radius: 4, paint: dots }), - shape('old', { fill: '#336699', gradient: 'down', shape: 'star' }), + shape('old', { fill: '#336699', gradient: 'down', shape: 'star-5' }), bookPhotoElementSchema.parse({ id: 'p1', kind: 'photo', frame, photoId: 3, mask: 'heart' }) as BookElement, ], parked: [],