UNPKG

@base-ui/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.

128 lines (127 loc) 4.12 kB
"use strict"; 'use client'; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useFieldControlRegistration = useFieldControlRegistration; var React = _interopRequireWildcard(require("react")); var _useIsoLayoutEffect = require("@base-ui/utils/useIsoLayoutEffect"); var _useStableCallback = require("@base-ui/utils/useStableCallback"); var _getCombinedFieldValidityData = require("../../field/utils/getCombinedFieldValidityData"); var _FormContext = require("../form-context/FormContext"); function useFieldControlRegistration(params) { const { commit, invalid, markedDirtyRef, name, setRegisteredFieldId, setValidityData, validityData } = params; const { formRef } = (0, _FormContext.useFormContext)(); const activeFieldControlSourceRef = React.useRef(null); const registrationRef = React.useRef(null); const fallbackControlRef = React.useRef(null); const getValueForForm = (0, _useStableCallback.useStableCallback)(() => { const registration = registrationRef.current; if (!registration) { return undefined; } if (registration.getValue) { return registration.getValue(); } return registration.value; }); const validate = (0, _useStableCallback.useStableCallback)(() => { const registration = registrationRef.current; if (!registration) { return; } let nextValue = registration.value; if (nextValue === undefined) { nextValue = getValueForForm(); } markedDirtyRef.current = true; commit(nextValue); }); function refreshRegistration() { const registration = registrationRef.current; if (!registration || !registration.id) { return; } formRef.current.fields.set(registration.id, { getValue: getValueForForm, name, controlRef: registration.controlRef ?? fallbackControlRef, validityData: (0, _getCombinedFieldValidityData.getCombinedFieldValidityData)(validityData, invalid), validate }); } function deleteRegistration(id = registrationRef.current?.id) { if (id) { formRef.current.fields.delete(id); } } function syncInitialValue() { const registration = registrationRef.current; if (!registration) { return; } let initialValue = registration.value; if (initialValue === undefined) { initialValue = getValueForForm(); } if (validityData.initialValue === null && initialValue !== null) { setValidityData(prev => ({ ...prev, initialValue })); } } (0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => { const registration = registrationRef.current; if (!registration || !registration.id) { return; } formRef.current.fields.set(registration.id, { getValue: getValueForForm, name, controlRef: registration.controlRef ?? fallbackControlRef, validityData: (0, _getCombinedFieldValidityData.getCombinedFieldValidityData)(validityData, invalid), validate }); }, [formRef, getValueForForm, invalid, name, validate, validityData]); (0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => { const fields = formRef.current.fields; return () => { const id = registrationRef.current?.id; if (id) { fields.delete(id); } }; }, [formRef]); return (0, _useStableCallback.useStableCallback)((source, registration) => { if (!registration) { if (activeFieldControlSourceRef.current === source) { activeFieldControlSourceRef.current = null; deleteRegistration(); registrationRef.current = null; setRegisteredFieldId(undefined); } return; } const previousId = registrationRef.current?.id; activeFieldControlSourceRef.current = source; registrationRef.current = registration; setRegisteredFieldId(registration.id); if (previousId && previousId !== registration.id) { deleteRegistration(previousId); } syncInitialValue(); refreshRegistration(); }); }