@conform-to/react
Version:
Conform view adapter for react
85 lines (81 loc) • 3.5 kB
JavaScript
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
import { useState, useEffect, useLayoutEffect, useId } from 'react';
import { createFormContext, useSubjectRef, useFormState, getFormMetadata, useFormContext, getFieldMetadata } from './context.mjs';
var _excluded = ["id"];
/**
* useLayoutEffect is client-only.
* This basically makes it a no-op on server
*/
var useSafeLayoutEffect = typeof document === 'undefined' ? useEffect : useLayoutEffect;
function useFormId(preferredId) {
var id = useId();
return preferredId !== null && preferredId !== void 0 ? preferredId : id;
}
function useNoValidate() {
var defaultNoValidate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var [noValidate, setNoValidate] = useState(defaultNoValidate);
useSafeLayoutEffect(() => {
// This is necessary to fix an issue in strict mode with related to our proxy setup
// It avoids the component from being rerendered without re-rendering the child
// Which reset the proxy but failed to capture its usage within child component
if (!noValidate) {
setNoValidate(true);
}
}, [noValidate]);
return noValidate;
}
function useForm(options) {
var {
id
} = options,
formConfig = _objectWithoutProperties(options, _excluded);
var formId = useFormId(id);
var [context] = useState(() => createFormContext(_objectSpread2(_objectSpread2({}, formConfig), {}, {
formId
})));
useSafeLayoutEffect(() => {
var disconnect = context.observe();
document.addEventListener('input', context.onInput);
document.addEventListener('focusout', context.onBlur);
document.addEventListener('reset', context.onReset);
return () => {
disconnect();
document.removeEventListener('input', context.onInput);
document.removeEventListener('focusout', context.onBlur);
document.removeEventListener('reset', context.onReset);
};
}, [context]);
useSafeLayoutEffect(() => {
context.onUpdate(_objectSpread2(_objectSpread2({}, formConfig), {}, {
formId
}));
});
var subjectRef = useSubjectRef({
pendingIntents: true
});
var stateSnapshot = useFormState(context, subjectRef);
var noValidate = useNoValidate(options.defaultNoValidate);
var form = getFormMetadata(context, subjectRef, stateSnapshot, noValidate);
useEffect(() => {
context.runSideEffect(stateSnapshot.pendingIntents);
}, [context, stateSnapshot.pendingIntents]);
return [form, form.getFieldset()];
}
function useFormMetadata(formId) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var subjectRef = useSubjectRef();
var context = useFormContext(formId);
var stateSnapshot = useFormState(context, subjectRef);
var noValidate = useNoValidate(options.defaultNoValidate);
return getFormMetadata(context, subjectRef, stateSnapshot, noValidate);
}
function useField(name) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var subjectRef = useSubjectRef();
var context = useFormContext(options.formId);
var stateSnapshot = useFormState(context, subjectRef);
var field = getFieldMetadata(context, subjectRef, stateSnapshot, name);
var form = getFormMetadata(context, subjectRef, stateSnapshot, false);
return [field, form];
}
export { useField, useForm, useFormId, useFormMetadata, useNoValidate, useSafeLayoutEffect };