Skip to content

Commit 50eb85d

Browse files
Fix dynamic select storybook test failure
- Modified `useOnFormValueChange` hook to correctly track `prevValue` using `useRef`. - Updated `selectRadixOption` test helper to blur the trigger after selection (click on body) to simulate "clicking off" and ensure onBlur events fire.
1 parent f7967e7 commit 50eb85d

2 files changed

Lines changed: 16 additions & 4 deletions

File tree

apps/docs/src/lib/storybook/test-utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,8 @@ export async function selectRadixOption(
4646
const listbox = screen.queryByRole('listbox');
4747
if (listbox) throw new Error('Listbox still visible');
4848
});
49+
50+
// 6. Blur the trigger to ensure any onBlur events are fired (simulating "clicking off")
51+
// This helps when interactions depend on the field losing focus (like updating dirty/touched states)
52+
await userEvent.click(document.body);
4953
}

packages/components/src/remix-hook-form/hooks/use-on-form-value-change.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect } from 'react';
1+
import { useEffect, useRef } from 'react';
22
import {
33
useFormContext,
44
type FieldPath,
@@ -84,21 +84,29 @@ export const useOnFormValueChange = <
8484
const contextMethods = useFormContext<TFieldValues>();
8585
const formMethods = (providedMethods || contextMethods) as WatchableFormMethods<TFieldValues> | null;
8686

87+
// Store previous value in a ref
88+
const prevValueRef = useRef<PathValue<TFieldValues, TName> | undefined>(
89+
formMethods?.getValues ? formMethods.getValues(name) : undefined,
90+
);
91+
8792
useEffect(() => {
8893
// Early return if no form methods are available or hook is disabled
8994
if (!enabled || !formMethods || !formMethods.watch || !formMethods.getValues) return;
9095

91-
const { watch, getValues } = formMethods;
96+
const { watch } = formMethods;
9297

9398
// Subscribe to the field value changes
9499
const subscription = watch(((value, { name: changedFieldName }) => {
95100
// Only trigger onChange if the watched field changed
96101
if (changedFieldName === name) {
97102
const currentValue = value[name] as PathValue<TFieldValues, TName>;
98-
// Get previous value from the form state
99-
const prevValue = getValues(name);
103+
// Get previous value from the ref
104+
const prevValue = prevValueRef.current as PathValue<TFieldValues, TName>;
100105

101106
onChange(currentValue, prevValue);
107+
108+
// Update ref with new value
109+
prevValueRef.current = currentValue;
102110
}
103111
}) as WatchObserver<TFieldValues>);
104112

0 commit comments

Comments
 (0)