From 64560a5ac7b13087be77c3684560153f7b305c1d Mon Sep 17 00:00:00 2001 From: its-monotype Date: Wed, 14 Jan 2026 12:58:41 +0100 Subject: [PATCH 1/4] fix(slider): commit value on keyboard interactions --- .../src/components/Slider/SliderThumb.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/reshaped/src/components/Slider/SliderThumb.tsx b/packages/reshaped/src/components/Slider/SliderThumb.tsx index 6b30cad9..adc1a279 100644 --- a/packages/reshaped/src/components/Slider/SliderThumb.tsx +++ b/packages/reshaped/src/components/Slider/SliderThumb.tsx @@ -11,6 +11,17 @@ import { getPrecision } from "./Slider.utilities"; import type * as T from "./Slider.types"; +const COMMIT_KEYS = new Set([ + "ArrowLeft", + "ArrowRight", + "ArrowUp", + "ArrowDown", + "Home", + "End", + "PageUp", + "PageDown", +]); + const SliderThumb = React.forwardRef((props, ref) => { const { name, @@ -37,6 +48,12 @@ const SliderThumb = React.forwardRef((props, ref) onChange(+e.target.value, { native: true }); }; + const handleKeyUp = (e: React.KeyboardEvent) => { + if (!COMMIT_KEYS.has(e.key)) return; + + onChange(+e.currentTarget.value, { commit: true }); + }; + return ( <> ((props, ref) name={name} value={value} onChange={handleChange} + onKeyUp={handleKeyUp} disabled={disabled} max={max} min={min} From 8000484e878f68bd04af0056ef66762928779cc5 Mon Sep 17 00:00:00 2001 From: its-monotype Date: Wed, 14 Jan 2026 13:05:38 +0100 Subject: [PATCH 2/4] chore: add changeset --- .changeset/silver-geese-notice.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/silver-geese-notice.md diff --git a/.changeset/silver-geese-notice.md b/.changeset/silver-geese-notice.md new file mode 100644 index 00000000..f1f7b1de --- /dev/null +++ b/.changeset/silver-geese-notice.md @@ -0,0 +1,5 @@ +--- +"reshaped": patch +--- + +Fix Slider to trigger `onChangeCommit` when changing values via keyboard interactions. \ No newline at end of file From 0fa59f53198d6cda0bd8ec872d3bc5d11dca62a3 Mon Sep 17 00:00:00 2001 From: its-monotype Date: Wed, 14 Jan 2026 22:59:48 +0100 Subject: [PATCH 3/4] fix(Slider): simplify keyboard commit detection --- .../src/components/Slider/SliderControlled.tsx | 14 ++++++++++++-- .../src/components/Slider/SliderThumb.tsx | 18 ------------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/packages/reshaped/src/components/Slider/SliderControlled.tsx b/packages/reshaped/src/components/Slider/SliderControlled.tsx index c3b6488f..01d69a54 100644 --- a/packages/reshaped/src/components/Slider/SliderControlled.tsx +++ b/packages/reshaped/src/components/Slider/SliderControlled.tsx @@ -138,6 +138,11 @@ const SliderControlled: React.FC = (props) = // @ts-ignore if (options.commit) onChangeCommitRef.current?.(args); + // Keyboard changes should commit immediately + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + if (options.native && !draggingId) onChangeCommitRef.current?.(args); + // Manually controlled resolving of single/range handlers // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -145,7 +150,7 @@ const SliderControlled: React.FC = (props) = triggerChangeEvent(minInputRef.current!, value.toString()); }, - [maxValue, name, minName, maxName, range, onChangeCommitRef, onChangeRef] + [range, maxValue, name, minName, maxName, draggingId, onChangeCommitRef, onChangeRef] ); const handleMaxChange: T.ThumbProps["onChange"] = React.useCallback( @@ -159,6 +164,11 @@ const SliderControlled: React.FC = (props) = // @ts-ignore if (options.commit) onChangeCommitRef.current?.(args); + // Keyboard changes should commit immediately + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + if (options.native && !draggingId) onChangeCommitRef.current?.(args); + // Manually controlled resolving of single/range handlers // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -166,7 +176,7 @@ const SliderControlled: React.FC = (props) = triggerChangeEvent(maxInputRef.current!, value.toString()); }, - [minValue, name, minName, maxName, range, onChangeRef, onChangeCommitRef] + [range, minValue, name, minName, maxName, onChangeCommitRef, draggingId, onChangeRef] ); const handleMouseDown = ({ nativeEvent }: React.MouseEvent | React.TouchEvent) => { diff --git a/packages/reshaped/src/components/Slider/SliderThumb.tsx b/packages/reshaped/src/components/Slider/SliderThumb.tsx index adc1a279..6b30cad9 100644 --- a/packages/reshaped/src/components/Slider/SliderThumb.tsx +++ b/packages/reshaped/src/components/Slider/SliderThumb.tsx @@ -11,17 +11,6 @@ import { getPrecision } from "./Slider.utilities"; import type * as T from "./Slider.types"; -const COMMIT_KEYS = new Set([ - "ArrowLeft", - "ArrowRight", - "ArrowUp", - "ArrowDown", - "Home", - "End", - "PageUp", - "PageDown", -]); - const SliderThumb = React.forwardRef((props, ref) => { const { name, @@ -48,12 +37,6 @@ const SliderThumb = React.forwardRef((props, ref) onChange(+e.target.value, { native: true }); }; - const handleKeyUp = (e: React.KeyboardEvent) => { - if (!COMMIT_KEYS.has(e.key)) return; - - onChange(+e.currentTarget.value, { commit: true }); - }; - return ( <> ((props, ref) name={name} value={value} onChange={handleChange} - onKeyUp={handleKeyUp} disabled={disabled} max={max} min={min} From f0f53cb7f1c5c38451c58db8da512018b9047032 Mon Sep 17 00:00:00 2001 From: its-monotype Date: Wed, 14 Jan 2026 23:02:00 +0100 Subject: [PATCH 4/4] test(Slider): add onChangeCommit test cases --- .../Slider/tests/Slider.stories.tsx | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/reshaped/src/components/Slider/tests/Slider.stories.tsx b/packages/reshaped/src/components/Slider/tests/Slider.stories.tsx index cbfe8260..7f999e35 100644 --- a/packages/reshaped/src/components/Slider/tests/Slider.stories.tsx +++ b/packages/reshaped/src/components/Slider/tests/Slider.stories.tsx @@ -208,6 +208,10 @@ export const defaultValue: StoryObj<{ expect(args.handleChange).toHaveBeenCalledTimes(1); expect(args.handleChange).toHaveBeenCalledWith({ value: 51, name: "test-name" }); + + expect(args.handleChangeCommit).toHaveBeenCalledTimes(1); + expect(args.handleChangeCommit).toHaveBeenCalledWith({ value: 51, name: "test-name" }); + expect(input).toHaveValue("51"); }, }; @@ -240,6 +244,10 @@ export const value: StoryObj<{ expect(args.handleChange).toHaveBeenCalledTimes(1); expect(args.handleChange).toHaveBeenCalledWith({ value: 51, name: "test-name" }); + + expect(args.handleChangeCommit).toHaveBeenCalledTimes(1); + expect(args.handleChangeCommit).toHaveBeenCalledWith({ value: 51, name: "test-name" }); + expect(input).toHaveValue("50"); }, }; @@ -282,6 +290,15 @@ export const rangeDefaultValue: StoryObj<{ maxName: "test-name", }); + expect(args.handleChangeCommit).toHaveBeenCalledTimes(1); + expect(args.handleChangeCommit).toHaveBeenCalledWith({ + minValue: 51, + maxValue: 70, + name: "test-name", + minName: "test-name", + maxName: "test-name", + }); + expect(minInput).toHaveValue("51"); expect(maxInput).toHaveValue("70"); }, @@ -325,6 +342,14 @@ export const rangeValue: StoryObj<{ maxName: "test-name-max", }); + expect(args.handleChangeCommit).toHaveBeenCalledTimes(1); + expect(args.handleChangeCommit).toHaveBeenCalledWith({ + minValue: 51, + maxValue: 70, + minName: "test-name-min", + maxName: "test-name-max", + }); + expect(minInput).toHaveValue("50"); expect(maxInput).toHaveValue("70"); },