rsuite
Version:
A suite of react components
199 lines (196 loc) • 6.14 kB
JavaScript
'use client';
import _extends from "@babel/runtime/helpers/esm/extends";
import React, { useMemo } from 'react';
import FormControl from "../FormControl/index.js";
import FormControlLabel from "../FormControlLabel/index.js";
import FormErrorMessage from "../FormErrorMessage/index.js";
import FormGroup from "../FormGroup/index.js";
import FormHelpText from "../FormHelpText/index.js";
import FormStack from "../FormStack/index.js";
import Box from "../internals/Box/index.js";
import useSchemaModel from "./hooks/useSchemaModel.js";
import useFormValidate from "./hooks/useFormValidate.js";
import useFormValue from "./hooks/useFormValue.js";
import useFormRef from "./hooks/useFormRef.js";
import { forwardRef } from "../internals/utils/index.js";
import { SchemaModel } from 'schema-typed';
import { useEventCallback, useCustom } from "../internals/hooks/index.js";
import { FormValueProvider, FormProvider } from "./FormContext.js";
const defaultSchema = SchemaModel({});
const Subcomponents = {
Stack: FormStack,
Control: FormControl,
Label: FormControlLabel,
ErrorMessage: FormErrorMessage,
Group: FormGroup,
Text: FormHelpText,
/**
* @deprecated Use `Form.Label` instead
*/
ControlLabel: FormControlLabel,
/**
* @deprecated Use `Form.Text` instead
*/
HelpText: FormHelpText
};
/**
* The `Form` component is a form interface for collecting and validating user input.
* @see https://rsuitejs.com/components/form
*/
const Form = forwardRef((props, ref) => {
const {
propsWithDefaults
} = useCustom('Form', props);
const {
checkTrigger = 'change',
errorFromContext = true,
formDefaultValue = {},
formValue: controlledFormValue,
formError: controlledFormError,
nestedField = false,
fluid,
layout,
model: formModel = defaultSchema,
readOnly,
plaintext,
children,
disabled,
onSubmit,
onReset,
onCheck,
onError,
onChange,
...rest
} = propsWithDefaults;
const {
getCombinedModel,
pushFieldRule,
removeFieldRule
} = useSchemaModel(formModel, nestedField);
const {
formValue,
onRemoveValue,
setFieldValue,
resetFormValue
} = useFormValue(controlledFormValue, {
formDefaultValue,
nestedField
});
const formValidateProps = {
formValue,
getCombinedModel,
onCheck,
onError,
nestedField
};
const {
formError,
onRemoveError,
check,
checkAsync,
checkForField,
checkFieldForNextValue,
checkForFieldAsync,
checkFieldAsyncForNextValue,
cleanErrors,
resetErrors,
cleanErrorForField
} = useFormValidate(controlledFormError, formValidateProps);
const submit = useEventCallback(event => {
// Check the form before submitting
if (check()) {
onSubmit === null || onSubmit === void 0 || onSubmit(formValue, event);
}
});
const reset = useEventCallback(event => {
resetErrors();
const resetValue = resetFormValue();
if (resetValue) {
onChange === null || onChange === void 0 || onChange(resetValue);
}
onReset === null || onReset === void 0 || onReset(resetValue, event);
});
const handleSubmit = useEventCallback(event => {
var _event$preventDefault, _event$stopPropagatio;
event === null || event === void 0 || (_event$preventDefault = event.preventDefault) === null || _event$preventDefault === void 0 || _event$preventDefault.call(event);
event === null || event === void 0 || (_event$stopPropagatio = event.stopPropagation) === null || _event$stopPropagatio === void 0 || _event$stopPropagatio.call(event);
// Prevent submission when the form is disabled, readOnly, or plaintext
if (disabled || readOnly || plaintext) {
return;
}
submit(event);
});
const handleReset = useEventCallback(event => {
var _event$preventDefault2, _event$stopPropagatio2;
event === null || event === void 0 || (_event$preventDefault2 = event.preventDefault) === null || _event$preventDefault2 === void 0 || _event$preventDefault2.call(event);
event === null || event === void 0 || (_event$stopPropagatio2 = event.stopPropagation) === null || _event$stopPropagatio2 === void 0 || _event$stopPropagatio2.call(event);
// Prevent reset when the form is disabled, readOnly, or plaintext
if (disabled || readOnly || plaintext) {
return;
}
reset(event);
});
const imperativeMethods = {
check,
checkForField,
checkAsync,
checkForFieldAsync,
cleanErrors,
cleanErrorForField,
reset,
resetErrors,
submit
};
const formRef = useFormRef(ref, {
imperativeMethods
});
const removeFieldValue = useEventCallback(name => {
const formValue = onRemoveValue(name);
onChange === null || onChange === void 0 || onChange(formValue);
});
const removeFieldError = useEventCallback(name => {
onRemoveError(name);
});
const onFieldChange = useEventCallback((name, value, event) => {
const nextFormValue = setFieldValue(name, value);
onChange === null || onChange === void 0 || onChange(nextFormValue, event);
});
const formContextValue = {
errorFromContext,
checkTrigger,
plaintext,
readOnly,
disabled,
formError,
nestedField,
pushFieldRule,
removeFieldValue,
removeFieldError,
removeFieldRule,
onFieldChange,
checkFieldForNextValue,
checkFieldAsyncForNextValue
};
const formChild = useMemo(() => {
return fluid || layout ? /*#__PURE__*/React.createElement(FormStack, {
fluid: fluid,
layout: layout
}, children) : children;
}, [fluid, children, layout]);
return /*#__PURE__*/React.createElement(Box, _extends({
as: "form",
"data-rs": "form",
"data-disabled": disabled,
"data-readonly": readOnly,
"data-plaintext": plaintext,
ref: formRef,
onSubmit: handleSubmit,
onReset: handleReset
}, rest), /*#__PURE__*/React.createElement(FormProvider, {
value: formContextValue
}, /*#__PURE__*/React.createElement(FormValueProvider, {
value: formValue
}, formChild)));
}, Subcomponents);
Form.displayName = 'Form';
export default Form;