UNPKG

zent

Version:

一套前端设计语言和基于React的实现

239 lines (238 loc) 11 kB
import { __assign, __awaiter, __extends, __generator, __rest } from "tslib"; import { jsx as _jsx } from "react/jsx-runtime"; import cx from 'classnames'; import { Component, createRef } from 'react'; import { FormProvider, useField, useFieldArray, useFieldSet, field, set, array, form, FieldValue, FieldSetValue, useFieldArrayChildModels, ValidateOption, createAsyncValidator, isAsyncValidator, useFieldValue, FieldValid, useFieldValid, useModelValid, useModelValue, useNamedChildModel, } from './formulr'; import memorize from '../utils/memorize-one'; import { FormChildrenContext, } from './context'; import { useForm, useFormValue, useFormValid } from './ZentForm'; import { smoothScroll } from '../utils/scroll'; import { CombineErrors } from './CombineErrors'; import { ValidateOccasion, TouchWhen } from './shared'; import { Disabled } from '../disabled'; import getScrollPosition from '../utils/dom/getScollPosition'; import isPromise from '../utils/isPromise'; export { isViewDrivenProps, ValidateOccasion, } from './shared'; function makeChildrenContext(children) { return { children: children, }; } var Form = (function (_super) { __extends(Form, _super); function Form() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.formRef = createRef(); _this.children = []; _this.getChildrenContext = memorize(makeChildrenContext); _this.submitSubscription = null; _this.resetSubscription = null; _this.onSubmit = function (e) { e.preventDefault(); e.stopPropagation(); _this.props.form.submit(e); }; _this.onReset = function (e) { e.preventDefault(); e.stopPropagation(); _this.props.form.reset(e); }; _this.onKeyDown = function (e) { var _a = _this.props, onKeyDown = _a.onKeyDown, _b = _a.disableEnterSubmit, disableEnterSubmit = _b === void 0 ? true : _b; if (disableEnterSubmit && e.key === 'Enter' && e.target.tagName === 'INPUT') { e.preventDefault(); e.stopPropagation(); } onKeyDown && onKeyDown(e); }; _this.submitListener = function (e) { _this.submit(e); }; _this.resetListener = function (e) { _this.reset(e); }; return _this; } Form.prototype.reset = function (e) { var _a = this.props, form = _a.form, onReset = _a.onReset; form.resetValue(); onReset === null || onReset === void 0 ? void 0 : onReset(e); }; Form.prototype.submit = function (e) { return __awaiter(this, void 0, void 0, function () { var _a, onSubmit, form, onSubmitFail, onSubmitSuccess, scrollToError, success, fail, error_1; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.props, onSubmit = _a.onSubmit, form = _a.form, onSubmitFail = _a.onSubmitFail, onSubmitSuccess = _a.onSubmitSuccess, scrollToError = _a.scrollToError; if (!onSubmit) { return [2]; } success = function () { onSubmitSuccess && onSubmitSuccess(); form.submitSuccess(); }; fail = function (error) { onSubmitFail && onSubmitFail(error); form.submitError(); }; _b.label = 1; case 1: _b.trys.push([1, 4, , 5]); form.submitStart(); return [4, form.validate(ValidateOption.IncludeAsync | ValidateOption.IncludeChildrenRecursively | ValidateOption.IncludeUntouched)]; case 2: _b.sent(); if (!form.isValid()) { scrollToError && this.scrollToFirstError(); fail(new FormValidationError('Form validation failed')); return [2]; } return [4, onSubmit(form, e)]; case 3: _b.sent(); success(); return [3, 5]; case 4: error_1 = _b.sent(); fail(error_1); return [3, 5]; case 5: return [2]; } }); }); }; Form.prototype.scrollToFirstError = function () { var _this = this; var _a = this.props, willScrollToError = _a.willScrollToError, form = _a.form; if (typeof willScrollToError !== 'function') { this._scrollToFirstError(); } else { var p = willScrollToError(form); if (!isPromise(p)) { this._scrollToFirstError(p); } else { p.then(function (opt) { _this._scrollToFirstError(opt); }).catch(function () { }); } } }; Form.prototype._scrollToFirstError = function (options) { var scrollX = Infinity; var scrollY = Infinity; for (var i = 0; i < this.children.length; i += 1) { var child = this.children[i]; var el = child.getDOMNode(); if (!el || child.valid()) { continue; } var elementBound = el.getBoundingClientRect(); var y = elementBound.top; var x = elementBound.left; if (y < scrollY || (y === scrollY && x < scrollX)) { scrollX = x; scrollY = y; } } if (scrollX === Infinity || scrollY === Infinity) { return; } var scrollOptions = (options !== null && options !== void 0 ? options : {}); var _a = scrollOptions.offsetX, offsetX = _a === void 0 ? 0 : _a, _b = scrollOptions.offsetY, offsetY = _b === void 0 ? 0 : _b, scrollContainer = scrollOptions.scrollContainer; if (scrollContainer) { var containerBox = scrollContainer.getBoundingClientRect(); var deltaX = scrollX - containerBox.left; var deltaY = scrollY - containerBox.top; var x = scrollContainer.scrollLeft + deltaX + offsetX; var y = scrollContainer.scrollTop + deltaY + offsetY; smoothScroll(scrollContainer, x, y); } else { var _c = getScrollPosition(), x = _c.x, y = _c.y; smoothScroll(document.body, scrollX + x + offsetX, scrollY + y + offsetY); } }; Form.prototype.subscribe = function () { var form = this.props.form; this.submitSubscription = form.submit$.subscribe(this.submitListener); this.resetSubscription = form.reset$.subscribe(this.resetListener); }; Form.prototype.unsubscribe = function () { if (this.submitSubscription) { this.submitSubscription.unsubscribe(); this.submitSubscription = null; } if (this.resetSubscription) { this.resetSubscription.unsubscribe(); this.resetSubscription = null; } }; Form.prototype.componentDidMount = function () { this.subscribe(); }; Form.prototype.componentDidUpdate = function (prevProps) { if (prevProps.form !== this.props.form) { this.unsubscribe(); this.subscribe(); } }; Form.prototype.componentWillUnmount = function () { this.unsubscribe(); }; Form.prototype.render = function () { var _a = this.props, children = _a.children, _b = _a.layout, layout = _b === void 0 ? 'vertical' : _b, _c = _a.direction, direction = _c === void 0 ? 'column' : _c, className = _a.className, form = _a.form, onSubmit = _a.onSubmit, onSubmitFail = _a.onSubmitFail, onSubmitSuccess = _a.onSubmitSuccess, disableEnterSubmit = _a.disableEnterSubmit, _d = _a.disabled, disabled = _d === void 0 ? false : _d, scrollToError = _a.scrollToError, willScrollToError = _a.willScrollToError, props = __rest(_a, ["children", "layout", "direction", "className", "form", "onSubmit", "onSubmitFail", "onSubmitSuccess", "disableEnterSubmit", "disabled", "scrollToError", "willScrollToError"]); var childrenCtx = this.getChildrenContext(this.children); return (_jsx(Disabled, __assign({ value: disabled }, { children: _jsx(FormChildrenContext.Provider, __assign({ value: childrenCtx }, { children: _jsx(FormProvider, __assign({ value: form.ctx }, { children: _jsx("form", __assign({ ref: this.formRef }, props, { className: cx('zent-form-reactive', { 'zent-form-vertical': layout === 'vertical', 'zent-form-horizontal': layout === 'horizontal', 'zent-form-direction-row': direction === 'row', 'zent-form-direction-column': direction === 'column', }, className), onSubmit: this.onSubmit, onReset: this.onReset, onKeyDown: this.onKeyDown, "data-zv": '10.0.17' }, { children: children }), void 0) }), void 0) }), void 0) }), void 0)); }; Form.displayName = 'ZentForm'; Form.CombineErrors = CombineErrors; Form.useForm = useForm; Form.useField = useField; Form.useFieldArray = useFieldArray; Form.useFieldSet = useFieldSet; Form.useNamedChildModel = useNamedChildModel; Form.useFieldArrayChildModels = useFieldArrayChildModels; Form.useFieldArrayValue = useFieldArrayChildModels; Form.field = field; Form.set = set; Form.array = array; Form.form = form; Form.FieldValue = FieldValue; Form.FieldSetValue = FieldSetValue; Form.useFormValue = useFormValue; Form.useFieldValue = useFieldValue; Form.FieldValid = FieldValid; Form.useFormValid = useFormValid; Form.useFieldValid = useFieldValid; Form.useModelValue = useModelValue; Form.useModelValid = useModelValid; Form.ValidateOption = ValidateOption; Form.createAsyncValidator = createAsyncValidator; Form.isAsyncValidator = isAsyncValidator; Form.ValidateOccasion = ValidateOccasion; Form.TouchWhen = TouchWhen; return Form; }(Component)); export { Form }; var FormValidationError = (function (_super) { __extends(FormValidationError, _super); function FormValidationError(message) { var _this = _super.call(this, message) || this; _this.name = 'FormValidationError'; return _this; } return FormValidationError; }(Error)); export { FormValidationError };