diff --git a/packages/react/src/internals/usePressAndHold.ts b/packages/react/src/internals/usePressAndHold.ts
index 45555c7025b..c6813ad7691 100644
--- a/packages/react/src/internals/usePressAndHold.ts
+++ b/packages/react/src/internals/usePressAndHold.ts
@@ -169,6 +169,12 @@ export function usePressAndHold(params: UsePressAndHoldParameters): UsePressAndH
[stopAutoChange],
);
+ React.useEffect(() => {
+ if (disabled) {
+ stopAutoChange();
+ }
+ }, [disabled, stopAutoChange]);
+
const pointerHandlers: UsePressAndHoldReturnValue['pointerHandlers'] = {
onTouchStart() {
isTouchingButtonRef.current = true;
diff --git a/packages/react/src/number-field/increment/NumberFieldIncrement.test.tsx b/packages/react/src/number-field/increment/NumberFieldIncrement.test.tsx
index 6c6d0847846..263b063a9db 100644
--- a/packages/react/src/number-field/increment/NumberFieldIncrement.test.tsx
+++ b/packages/react/src/number-field/increment/NumberFieldIncrement.test.tsx
@@ -306,6 +306,42 @@ describe('', () => {
expect(input).toHaveValue('4');
});
+ it('stops an active press-and-hold interaction when disabled', async () => {
+ function App() {
+ const [disabled, setDisabled] = React.useState(false);
+
+ return (
+
+
+
+
+
+ );
+ }
+
+ await render();
+
+ const input = screen.getByRole('textbox');
+ const increment = screen.getByRole('button', { name: 'Increase' });
+
+ fireEvent.pointerDown(increment, {
+ button: 0,
+ pointerType: 'mouse',
+ });
+
+ expect(input).toHaveValue('1');
+
+ fireEvent.click(screen.getByRole('button', { name: 'Disable' }));
+
+ clock.tick(START_AUTO_CHANGE_DELAY);
+ clock.tick(CHANGE_VALUE_TICK_DELAY);
+ clock.tick(CHANGE_VALUE_TICK_DELAY);
+
+ expect(input).toHaveValue('1');
+ });
+
it('removes the global release listener when unmounted during a hold', async () => {
const addEventListener = vi.spyOn(window, 'addEventListener');
const removeEventListener = vi.spyOn(window, 'removeEventListener');
diff --git a/packages/react/src/number-field/root/NumberFieldRoot.test.tsx b/packages/react/src/number-field/root/NumberFieldRoot.test.tsx
index 96693587308..3cd7dec6bb5 100644
--- a/packages/react/src/number-field/root/NumberFieldRoot.test.tsx
+++ b/packages/react/src/number-field/root/NumberFieldRoot.test.tsx
@@ -931,6 +931,26 @@ describe('', () => {
const input = screen.getByRole('textbox');
expect(input).toHaveAttribute('disabled');
});
+
+ it('stops an active press-and-hold interaction when disabled', async () => {
+ const { setProps } = await render();
+ const input = screen.getByRole('textbox');
+
+ fireEvent.pointerDown(screen.getByLabelText('Increase'), {
+ button: 0,
+ pointerType: 'mouse',
+ });
+ expect(input).toHaveValue('1');
+
+ await setProps({ disabled: true });
+ await act(async () => {
+ await new Promise((resolve) => {
+ setTimeout(resolve, 500);
+ });
+ });
+
+ expect(input).toHaveValue('1');
+ });
});
describe('prop: readOnly', () => {