MCPcopy
hub / github.com/adobe/react-spectrum / useFormValidation

Function useFormValidation

packages/react-aria/src/form/useFormValidation.ts:28–132  ·  view source on GitHub ↗
(
  props: FormValidationProps<T>,
  state: FormValidationState,
  ref: RefObject<ValidatableElement | null> | undefined
)

Source from the content-addressed store, hash-verified

26}
27
28export function useFormValidation<T>(
29 props: FormValidationProps<T>,
30 state: FormValidationState,
31 ref: RefObject<ValidatableElement | null> | undefined
32): void {
33 let {validationBehavior, focus} = props;
34
35 // This is a useLayoutEffect so that it runs before the useEffect in useFormValidationState, which commits the validation change.
36 useLayoutEffect(() => {
37 if (
38 validationBehavior === 'native' &&
39 ref?.current &&
40 'setCustomValidity' in ref.current &&
41 !ref.current.disabled
42 ) {
43 let errorMessage = state.realtimeValidation.isInvalid
44 ? state.realtimeValidation.validationErrors.join(' ') || 'Invalid value.'
45 : '';
46 ref.current.setCustomValidity(errorMessage);
47
48 // Prevent default tooltip for validation message.
49 // https://bugzilla.mozilla.org/show_bug.cgi?id=605277
50 if (!ref.current.hasAttribute('title')) {
51 ref.current.title = '';
52 }
53
54 if (!state.realtimeValidation.isInvalid) {
55 state.updateValidation(getNativeValidity(ref.current));
56 }
57 }
58 });
59
60 let isIgnoredReset = useRef(false);
61 let onReset = useEffectEvent(() => {
62 if (!isIgnoredReset.current) {
63 state.resetValidation();
64 }
65 });
66
67 let onInvalid = useEffectEvent((e: Event) => {
68 // Only commit validation if we are not already displaying one.
69 // This avoids clearing server errors that the user didn't actually fix.
70 if (!state.displayValidation.isInvalid) {
71 state.commitValidation();
72 }
73
74 // Auto focus the first invalid input in a form, unless the error already had its default prevented.
75 let form = ref?.current?.form;
76 if (!e.defaultPrevented && ref && form && getFirstInvalidInput(form) === ref.current) {
77 if (focus) {
78 focus();
79 } else {
80 ref.current?.focus();
81 }
82
83 // Always show focus ring.
84 setInteractionModality('keyboard');
85 }

Callers 7

useRadioFunction · 0.90
useTextFieldFunction · 0.90
useToggleFunction · 0.90
useHiddenSelectFunction · 0.90
useDateFieldFunction · 0.90
MobileComboBox.tsxFile · 0.90

Calls 13

useEffectEventFunction · 0.90
setInteractionModalityFunction · 0.90
getEventTargetFunction · 0.90
getNativeValidityFunction · 0.85
getFirstInvalidInputFunction · 0.85
hasAttributeMethod · 0.80
updateValidationMethod · 0.80
resetValidationMethod · 0.80
commitValidationMethod · 0.80
focusMethod · 0.80
addEventListenerMethod · 0.80
removeEventListenerMethod · 0.80

Tested by

no test coverage detected