@base-ui-components/react
Version:
Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.
53 lines • 1.76 kB
JavaScript
import * as ReactDOM from 'react-dom';
import { useEnhancedEffect } from '../utils/useEnhancedEffect.js';
import { getCombinedFieldValidityData } from './utils/getCombinedFieldValidityData.js';
import { useFormContext } from '../form/FormContext.js';
import { useFieldRootContext } from './root/FieldRootContext.js';
import { useLatestRef } from '../utils/useLatestRef.js';
export function useField(params) {
const {
formRef
} = useFormContext();
const {
invalid,
markedDirtyRef,
validityData,
setValidityData
} = useFieldRootContext();
const {
value,
id,
controlRef,
commitValidation
} = params;
const getValueRef = useLatestRef(params.getValue);
useEnhancedEffect(() => {
let initialValue = value;
if (initialValue === undefined) {
initialValue = getValueRef.current?.();
}
if (validityData.initialValue === null && initialValue !== validityData.initialValue) {
setValidityData(prev => ({
...prev,
initialValue
}));
}
}, [setValidityData, value, validityData.initialValue, getValueRef]);
useEnhancedEffect(() => {
if (id) {
formRef.current.fields.set(id, {
controlRef,
validityData: getCombinedFieldValidityData(validityData, invalid),
validate() {
let nextValue = value;
if (nextValue === undefined) {
nextValue = getValueRef.current?.();
}
markedDirtyRef.current = true;
// Synchronously update the validity state so the submit event can be prevented.
ReactDOM.flushSync(() => commitValidation(nextValue));
}
});
}
}, [commitValidation, controlRef, formRef, getValueRef, id, invalid, markedDirtyRef, validityData, value]);
}