UNPKG

shineout

Version:

Shein 前端组件库

412 lines (337 loc) 14.7 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose"; import _createClass from "@babel/runtime/helpers/createClass"; import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import React from 'react'; import immer from 'immer'; import { Component } from '../component'; import { promiseAll, isSameError } from '../utils/errors'; import shallowEqual from '../utils/shallowEqual'; import { filterProps } from '../utils/objects'; import { getUidStr } from '../utils/uid'; import { isArray } from '../utils/is'; import _validate from '../utils/validate'; import { FORCE_PASS, ERROR_TYPE, IGNORE_VALIDATE, errorSubscribe, IGNORE_BIND } from '../Datum/types'; import { formConsumer } from './formContext'; import { itemConsumer } from './Item'; import { fieldSetConsumer } from './FieldSet'; var types = ['formDatum', 'disabled', 'combineRules', 'size']; var tryValue = function tryValue(val, def) { return val === undefined ? def : val; }; var beforeValueChange = function beforeValueChange(fn) { return function (value, datum) { if (!fn) return value; var newValue = fn(value, datum); return newValue === undefined ? value : newValue; }; }; export default (function (Origin) { var InputableInner = /*#__PURE__*/ function (_Component) { _inheritsLoose(InputableInner, _Component); function InputableInner(props) { var _this; _this = _Component.call(this, props) || this; _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "itemName", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "lastValue", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "updateTimer", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "datum", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "lastError", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "errorChange", void 0); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "customValidate", void 0); var formDatum = props.formDatum, name = props.name, defaultValue = props.defaultValue; _this.state = { error: undefined, value: props.value || defaultValue }; _this.itemName = getUidStr(); _this.handleChange = _this.handleChange.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleUpdate = _this.handleUpdate.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleDatumBind = _this.handleDatumBind.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleError = _this.handleError.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.validate = _this.validate.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.validateHook = _this.validateHook.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.lastValue = formDatum && name ? formDatum.get(name) || {} : {}; return _this; } var _proto = InputableInner.prototype; _proto.componentDidMount = function componentDidMount() { var _this2 = this; _Component.prototype.componentDidMount.call(this); // @ts-ignore var readOnly = this.props.readOnly; var _this$props = this.props, onChange = _this$props.onChange, disabled = _this$props.disabled; if ('value' in this.props && !onChange && disabled !== true && readOnly !== true) { console.error('warning: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly` or `disabled`'); } var _this$props2 = this.props, formDatum = _this$props2.formDatum, name = _this$props2.name, defaultValue = _this$props2.defaultValue, bindInputToItem = _this$props2.bindInputToItem, popover = _this$props2.popover; if (formDatum && name) { if (Array.isArray(name)) { var dv = defaultValue || []; name.forEach(function (n, i) { return formDatum.bind(n, _this2.handleUpdate, dv[i], _this2.validate); }); // @ts-ignore this.state.value = name.map(function (n) { return formDatum.get(n); }); formDatum.subscribe(errorSubscribe(this.errorName), this.handleUpdate); } else { formDatum.bind(name, this.handleUpdate, defaultValue, this.validate); // @ts-ignore this.state.value = formDatum.get(name); } this.lastValue = this.state.value; } if (bindInputToItem && name && !popover) bindInputToItem(this.errorName); }; _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { var skip = [].concat(this.props.scuSkip || [], ['formDatum']); var isFormDatum = this.props.formDatum && this.props.name; if (isFormDatum) skip.push('value'); var options = { skip: skip, deep: ['data', 'defaultValue', 'datum', 'name', 'rule', 'style'] }; if (!isFormDatum && !shallowEqual(this.getValue(), nextState.value)) return true; return !(shallowEqual(nextProps, this.props, options) && shallowEqual(nextState, this.state)); }; _proto.componentWillUnmount = function componentWillUnmount() { _Component.prototype.componentWillUnmount.call(this); var _this$props3 = this.props, formDatum = _this$props3.formDatum, name = _this$props3.name, unbindInputFromItem = _this$props3.unbindInputFromItem, reserveAble = _this$props3.reserveAble; clearTimeout(this.updateTimer); if (formDatum && name) { formDatum.unbind(name, this.handleUpdate, reserveAble); if (Array.isArray(name)) { formDatum.unsubscribe(errorSubscribe(this.errorName), this.handleUpdate); formDatum.setError(this.errorName); } } if (unbindInputFromItem && name) unbindInputFromItem(this.errorName); }; _proto.getValue = function getValue() { var _this$props4 = this.props, formDatum = _this$props4.formDatum, name = _this$props4.name, value = _this$props4.value, defaultValue = _this$props4.defaultValue; if (formDatum && name) { if (Array.isArray(name)) { var dv = defaultValue || []; return name.map(function (n, i) { return tryValue(formDatum.get(n), dv[i]); }); } return tryValue(formDatum.get(name), defaultValue); } var hasValue = 'value' in this.props || 'checked' in this.props; return !hasValue ? this.state.value : value; }; _proto.getError = function getError() { var _this$props5 = this.props, formDatum = _this$props5.formDatum, name = _this$props5.name, error = _this$props5.error; if ('error' in this.props) { return error; } if (formDatum && name) { return formDatum.getError(this.errorName); } return this.state.error; }; _proto.handleDatumBind = function handleDatumBind(datum) { this.datum = datum; }; _proto.handleError = function handleError(error) { var _this$props6 = this.props, formDatum = _this$props6.formDatum, name = _this$props6.name, onItemError = _this$props6.onItemError, onError = _this$props6.onError; if (formDatum && name) { if (!isSameError(error, formDatum.getError(this.errorName, true))) { formDatum.setError(this.errorName, error, true); } } else { this.setState({ error: error }); } var hasError = error !== undefined; this.errorChange = hasError !== this.lastError; this.lastError = hasError; if (onError) onError(error); if (onItemError && !name) onItemError(this.itemName, error); }; _proto.validateHook = function validateHook(customValidate) { this.customValidate = customValidate; }; _proto.validate = function validate(value, data, type) { var _this3 = this; var _this$props7 = this.props, name = _this$props7.name, formDatum = _this$props7.formDatum, combineRules = _this$props7.combineRules, bind = _this$props7.bind; var names = Array.isArray(name) ? name : [name]; var validates = []; var validateProps = filterProps(this.props, function (v) { return typeof v === 'string' || typeof v === 'number'; }); if (this.datum) { var datumValue = this.datum.formatValue(value); value = this.datum.limit === 1 ? datumValue[0] : datumValue; // @ts-ignore validateProps.type = 'array'; } if (type === FORCE_PASS || value === FORCE_PASS) { this.handleError(); return Promise.resolve(true); } if (value === undefined || Array.isArray(name)) value = this.getValue(); if (!Array.isArray(name)) value = [value]; if (this.customValidate) validates.push(this.customValidate()); if (formDatum && bind && type !== IGNORE_BIND) { // console.error(new Error('Use "bind" props to combine validate is not recommend. Use Form "groups" props instead.')) formDatum.validateFields(bind, IGNORE_BIND).catch(function () {}); } if (!data && formDatum) data = formDatum.getValue(); var rules = this.props.rules; names.forEach(function (n, i) { if (formDatum && combineRules) { rules = combineRules(n, rules); } if (isArray(rules) && rules.length > 0) { validates.push(_validate(value[i], data, rules, validateProps)); } }); return promiseAll(validates).then(function (res) { _this3.handleError(res === true ? undefined : res); return res; }).catch(function (e) { _this3.handleError(e); return e; }); }; _proto.handleChange = function handleChange(value) { var _this4 = this; var _this$props8 = this.props, formDatum = _this$props8.formDatum, name = _this$props8.name, fieldSetValidate = _this$props8.fieldSetValidate, onChange = _this$props8.onChange, filterSameChange = _this$props8.filterSameChange; var currentValue = this.getValue(); for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } if ((args.length === 0 || filterSameChange) && shallowEqual(value, currentValue)) { return; } var beforeChange = beforeValueChange(this.props.beforeChange); if (formDatum && name) { value = beforeChange(value, formDatum); formDatum.set(name, value); formDatum.removeFormError(this.errorName); } else { value = beforeChange(value, undefined); this.setState({ value: value }, function () { _this4.validate(value).catch(function () {}); }); } if (onChange) onChange.apply(void 0, [value].concat(args)); if (fieldSetValidate) fieldSetValidate(true); }; _proto.handleUpdate = function handleUpdate(value, sn, type) { var _this5 = this; if (type === ERROR_TYPE) { if (!isSameError(value, this.state.error)) this.setState({ error: value }); return; } var _this$props9 = this.props, name = _this$props9.name, onChange = _this$props9.onChange, forceChangeOnValueSet = _this$props9.forceChangeOnValueSet; var newValue = !Array.isArray(name) ? value : immer(this.getValue(), function (draft) { name.forEach(function (n, i) { if (n === sn) draft[i] = value; }); }); if (!this.errorChange && shallowEqual(newValue, this.lastValue)) return; this.lastValue = newValue; if (type === FORCE_PASS) { this.handleError(); this.setState({ error: undefined }); this.forceUpdate(); return; } if (onChange && forceChangeOnValueSet) onChange(newValue); if (type !== IGNORE_VALIDATE) { if (this.updateTimer) clearTimeout(this.updateTimer); this.updateTimer = setTimeout(function () { _this5.validate(newValue, undefined, type).catch(function () {}); }, 0); } this.forceUpdate(); }; _proto.render = function render() { var _this$props10 = this.props, formDatum = _this$props10.formDatum, value = _this$props10.value, required = _this$props10.required, bind = _this$props10.bind, onItemError = _this$props10.onItemError, bindInputToItem = _this$props10.bindInputToItem, unbindInputFromItem = _this$props10.unbindInputFromItem, scuSkip = _this$props10.scuSkip, defaultValue = _this$props10.defaultValue, rules = _this$props10.rules, reserveAble = _this$props10.reserveAble, other = _objectWithoutPropertiesLoose(_this$props10, ["formDatum", "value", "required", "bind", "onItemError", "bindInputToItem", "unbindInputFromItem", "scuSkip", "defaultValue", "rules", "reserveAble"]); return React.createElement(Origin, _extends({}, other, { formDatum: formDatum, error: this.getError(), value: this.getValue(), onChange: this.handleChange, onDatumBind: this.handleDatumBind, validateHook: this.validateHook })); }; _createClass(InputableInner, [{ key: "errorName", get: function get() { var name = this.props.name; return Array.isArray(name) ? name.join('|') : name; } }]); return InputableInner; }(Component); _defineProperty(InputableInner, "defaultProps", { rules: [], scuSkip: ['onChange', 'rules'] }); var WithFiledSetConsumer = fieldSetConsumer(InputableInner); var WidthItemConsumer = itemConsumer(WithFiledSetConsumer); var WidthFormConsumer = formConsumer(types)(WidthItemConsumer); return WidthFormConsumer; });