ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
599 lines (520 loc) • 21.6 kB
JavaScript
import { createVNode as _createVNode, isVNode as _isVNode } from "vue";
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var __rest = this && this.__rest || function (s, e) {
var t = {};
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
}
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
import { inject, provide, defineComponent, computed, nextTick } from 'vue';
import cloneDeep from 'lodash-es/cloneDeep';
import PropTypes from '../_util/vue-types';
import classNames from '../_util/classNames';
import { getTransitionProps, Transition } from '../_util/transition';
import Row from '../grid/Row';
import Col from '../grid/Col';
import hasProp, { findDOMNode, getComponent, getOptionProps, getEvents, isValidElement, getSlot } from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin';
import { defaultConfigProvider } from '../config-provider';
import { cloneElement } from '../_util/vnode';
import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled';
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled';
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
import { validateRules as _validateRules } from './utils/validateUtil';
import { getNamePath } from './utils/valueUtil';
import { toArray } from './utils/typeUtil';
import { warning } from '../vc-util/warning';
import find from 'lodash-es/find';
import { tuple } from '../_util/type';
function _isSlot(s) {
return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !_isVNode(s);
}
var iconMap = {
success: CheckCircleFilled,
warning: ExclamationCircleFilled,
error: CloseCircleFilled,
validating: LoadingOutlined
};
function getPropByPath(obj, namePathList, strict) {
var tempObj = obj;
var keyArr = namePathList;
var i = 0;
try {
for (var len = keyArr.length; i < len - 1; ++i) {
if (!tempObj && !strict) break;
var key = keyArr[i];
if (key in tempObj) {
tempObj = tempObj[key];
} else {
if (strict) {
throw Error('please transfer a valid name path to form item!');
}
break;
}
}
if (strict && !tempObj) {
throw Error('please transfer a valid name path to form item!');
}
} catch (error) {
console.error('please transfer a valid name path to form item!');
}
return {
o: tempObj,
k: keyArr[i],
v: tempObj ? tempObj[keyArr[i]] : undefined
};
}
export var FormItemProps = {
id: PropTypes.string,
htmlFor: PropTypes.string,
prefixCls: PropTypes.string,
label: PropTypes.VNodeChild,
help: PropTypes.VNodeChild,
extra: PropTypes.VNodeChild,
labelCol: {
type: Object
},
wrapperCol: {
type: Object
},
hasFeedback: PropTypes.looseBool.def(false),
colon: PropTypes.looseBool,
labelAlign: PropTypes.oneOf(tuple('left', 'right')),
prop: {
type: [String, Number, Array]
},
name: {
type: [String, Number, Array]
},
rules: PropTypes.oneOfType([Array, Object]),
autoLink: PropTypes.looseBool.def(true),
required: PropTypes.looseBool,
validateFirst: PropTypes.looseBool,
validateStatus: PropTypes.oneOf(tuple('', 'success', 'warning', 'error', 'validating')),
validateTrigger: {
type: [String, Array]
},
messageVariables: {
type: Object
}
};
export default defineComponent({
name: 'AFormItem',
mixins: [BaseMixin],
inheritAttrs: false,
__ANT_NEW_FORM_ITEM: true,
props: FormItemProps,
setup: function setup(props) {
var FormContext = inject('FormContext', {});
var fieldName = computed(function () {
return props.name || props.prop;
});
var namePath = computed(function () {
var val = fieldName.value;
return getNamePath(val);
});
var fieldId = computed(function () {
var id = props.id;
if (id) {
return id;
} else if (!namePath.value.length) {
return undefined;
} else {
var formName = FormContext.name;
var mergedId = namePath.value.join('_');
return formName ? "".concat(formName, "_").concat(mergedId) : mergedId;
}
});
var fieldValue = computed(function () {
var model = FormContext.model;
if (!model || !fieldName.value) {
return;
}
return getPropByPath(model, namePath.value, true).v;
});
var mergedValidateTrigger = computed(function () {
var validateTrigger = props.validateTrigger !== undefined ? props.validateTrigger : FormContext.validateTrigger;
validateTrigger = validateTrigger === undefined ? 'change' : validateTrigger;
return toArray(validateTrigger);
});
var getRules = function getRules() {
var formRules = FormContext.rules;
var selfRules = props.rules;
var requiredRule = props.required !== undefined ? {
required: !!props.required,
trigger: mergedValidateTrigger.value
} : [];
var prop = getPropByPath(formRules, namePath.value);
formRules = formRules ? prop.o[prop.k] || prop.v : [];
var rules = [].concat(selfRules || formRules || []);
if (find(rules, function (rule) {
return rule.required;
})) {
return rules;
} else {
return rules.concat(requiredRule);
}
};
var isRequired = computed(function () {
var rules = getRules();
var isRequired = false;
if (rules && rules.length) {
rules.every(function (rule) {
if (rule.required) {
isRequired = true;
return false;
}
return true;
});
}
return isRequired || props.required;
});
return {
isFormItemChildren: inject('isFormItemChildren', false),
configProvider: inject('configProvider', defaultConfigProvider),
FormContext: FormContext,
fieldId: fieldId,
fieldName: fieldName,
namePath: namePath,
isRequired: isRequired,
getRules: getRules,
fieldValue: fieldValue,
mergedValidateTrigger: mergedValidateTrigger
};
},
data: function data() {
warning(!hasProp(this, 'prop'), "`prop` is deprecated. Please use `name` instead.");
return {
validateState: this.validateStatus,
validateMessage: '',
validateDisabled: false,
validator: {},
helpShow: false,
errors: [],
initialValue: undefined
};
},
watch: {
validateStatus: function validateStatus(val) {
this.validateState = val;
}
},
created: function created() {
provide('isFormItemChildren', true);
},
mounted: function mounted() {
if (this.fieldName) {
var addField = this.FormContext.addField;
addField && addField(this);
this.initialValue = cloneDeep(this.fieldValue);
}
},
beforeUnmount: function beforeUnmount() {
var removeField = this.FormContext.removeField;
removeField && removeField(this);
},
methods: {
getNamePath: function getNamePath() {
var fieldName = this.fieldName;
var _this$FormContext$pre = this.FormContext.prefixName,
prefixName = _this$FormContext$pre === void 0 ? [] : _this$FormContext$pre;
return fieldName !== undefined ? [].concat(_toConsumableArray(prefixName), _toConsumableArray(this.namePath)) : [];
},
validateRules: function validateRules(options) {
var _this = this;
var _this$$props = this.$props,
_this$$props$validate = _this$$props.validateFirst,
validateFirst = _this$$props$validate === void 0 ? false : _this$$props$validate,
messageVariables = _this$$props.messageVariables;
var _ref = options || {},
triggerName = _ref.triggerName;
var namePath = this.getNamePath();
var filteredRules = this.getRules();
if (triggerName) {
filteredRules = filteredRules.filter(function (rule) {
var trigger = rule.trigger;
if (!trigger && !_this.mergedValidateTrigger.length) {
return true;
}
var triggerList = toArray(trigger || _this.mergedValidateTrigger);
return triggerList.includes(triggerName);
});
}
if (!filteredRules.length) {
return Promise.resolve();
}
var promise = _validateRules(namePath, this.fieldValue, filteredRules, options, validateFirst, messageVariables);
this.validateState = 'validating';
this.errors = [];
promise.catch(function (e) {
return e;
}).then(function () {
var errors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
if (_this.validateState === 'validating') {
_this.validateState = errors.length ? 'error' : 'success';
_this.validateMessage = errors[0];
_this.errors = errors;
}
});
return promise;
},
onFieldBlur: function onFieldBlur() {
this.validateRules({
triggerName: 'blur'
});
},
onFieldChange: function onFieldChange() {
if (this.validateDisabled) {
this.validateDisabled = false;
return;
}
this.validateRules({
triggerName: 'change'
});
},
clearValidate: function clearValidate() {
this.validateState = '';
this.validateMessage = '';
this.validateDisabled = false;
},
resetField: function resetField() {
var _this2 = this;
this.validateState = '';
this.validateMessage = '';
var model = this.FormContext.model || {};
var value = this.fieldValue;
var prop = getPropByPath(model, this.namePath, true);
this.validateDisabled = true;
if (Array.isArray(value)) {
prop.o[prop.k] = [].concat(this.initialValue);
} else {
prop.o[prop.k] = this.initialValue;
} // reset validateDisabled after onFieldChange triggered
nextTick(function () {
_this2.validateDisabled = false;
});
},
getHelpMessage: function getHelpMessage() {
var help = getComponent(this, 'help');
return this.validateMessage || help;
},
onLabelClick: function onLabelClick() {
var id = this.fieldId;
if (!id) {
return;
}
var formItemNode = findDOMNode(this);
var control = formItemNode.querySelector("[id=\"".concat(id, "\"]"));
if (control && control.focus) {
control.focus();
}
},
onHelpAnimEnd: function onHelpAnimEnd(_key, helpShow) {
this.helpShow = helpShow;
if (!helpShow) {
this.$forceUpdate();
}
},
renderHelp: function renderHelp(prefixCls) {
var _this3 = this;
var help = this.getHelpMessage();
var children = help ? _createVNode("div", {
"class": "".concat(prefixCls, "-explain"),
"key": "help"
}, _isSlot(help) ? help : {
default: function _default() {
return [help];
}
}) : null;
if (children) {
this.helpShow = !!children;
}
var transitionProps = getTransitionProps('show-help', {
onAfterEnter: function onAfterEnter() {
return _this3.onHelpAnimEnd('help', true);
},
onAfterLeave: function onAfterLeave() {
return _this3.onHelpAnimEnd('help', false);
}
});
return _createVNode(Transition, _objectSpread(_objectSpread({}, transitionProps), {}, {
"key": "help"
}), _isSlot(children) ? children : {
default: function _default() {
return [children];
}
});
},
renderExtra: function renderExtra(prefixCls) {
var extra = getComponent(this, 'extra');
return extra ? _createVNode("div", {
"class": "".concat(prefixCls, "-extra")
}, _isSlot(extra) ? extra : {
default: function _default() {
return [extra];
}
}) : null;
},
renderValidateWrapper: function renderValidateWrapper(prefixCls, c1, c2, c3) {
var validateStatus = this.validateState;
var classes = "".concat(prefixCls, "-item-control");
if (validateStatus) {
classes = classNames("".concat(prefixCls, "-item-control"), {
'has-feedback': validateStatus && this.hasFeedback,
'has-success': validateStatus === 'success',
'has-warning': validateStatus === 'warning',
'has-error': validateStatus === 'error',
'is-validating': validateStatus === 'validating'
});
}
var IconNode = validateStatus && iconMap[validateStatus];
var icon = this.hasFeedback && IconNode ? _createVNode("span", {
"class": "".concat(prefixCls, "-item-children-icon")
}, [_createVNode(IconNode, null, null)]) : null;
return _createVNode("div", {
"class": classes
}, [_createVNode("span", {
"class": "".concat(prefixCls, "-item-children")
}, [c1, icon]), c2, c3]);
},
renderWrapper: function renderWrapper(prefixCls, children) {
var _ref2 = this.isFormItemChildren ? {} : this.FormContext,
contextWrapperCol = _ref2.wrapperCol;
var wrapperCol = this.wrapperCol;
var mergedWrapperCol = wrapperCol || contextWrapperCol || {};
var style = mergedWrapperCol.style,
id = mergedWrapperCol.id,
restProps = __rest(mergedWrapperCol, ["style", "id"]);
var className = classNames("".concat(prefixCls, "-item-control-wrapper"), mergedWrapperCol.class);
var colProps = _extends(_extends({}, restProps), {
class: className,
key: 'wrapper',
style: style,
id: id
});
return _createVNode(Col, colProps, _isSlot(children) ? children : {
default: function _default() {
return [children];
}
});
},
renderLabel: function renderLabel(prefixCls) {
var _slot;
var _classNames;
var _this$FormContext = this.FormContext,
vertical = _this$FormContext.vertical,
contextLabelAlign = _this$FormContext.labelAlign,
contextLabelCol = _this$FormContext.labelCol,
contextColon = _this$FormContext.colon;
var labelAlign = this.labelAlign,
labelCol = this.labelCol,
colon = this.colon,
fieldId = this.fieldId,
htmlFor = this.htmlFor;
var label = getComponent(this, 'label');
var required = this.isRequired;
var mergedLabelCol = labelCol || contextLabelCol || {};
var mergedLabelAlign = labelAlign || contextLabelAlign;
var labelClsBasic = "".concat(prefixCls, "-item-label");
var labelColClassName = classNames(labelClsBasic, mergedLabelAlign === 'left' && "".concat(labelClsBasic, "-left"), mergedLabelCol.class);
var labelColClass = mergedLabelCol.class,
labelColStyle = mergedLabelCol.style,
labelColId = mergedLabelCol.id,
restProps = __rest(mergedLabelCol, ["class", "style", "id"]);
var labelChildren = label; // Keep label is original where there should have no colon
var computedColon = colon === true || contextColon !== false && colon !== false;
var haveColon = computedColon && !vertical; // Remove duplicated user input colon
if (haveColon && typeof label === 'string' && label.trim() !== '') {
labelChildren = label.replace(/[::]\s*$/, '');
}
var labelClassName = classNames((_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-item-required"), required), _defineProperty(_classNames, "".concat(prefixCls, "-item-no-colon"), !computedColon), _classNames));
var colProps = _extends(_extends({}, restProps), {
class: labelColClassName,
key: 'label',
style: labelColStyle,
id: labelColId
});
return label ? _createVNode(Col, colProps, _isSlot(_slot = _createVNode("label", {
"for": htmlFor || fieldId,
"class": labelClassName,
"title": typeof label === 'string' ? label : '',
"onClick": this.onLabelClick
}, _isSlot(labelChildren) ? labelChildren : {
default: function _default() {
return [labelChildren];
}
})) ? _slot : {
default: function _default() {
return [_slot];
}
}) : null;
},
renderChildren: function renderChildren(prefixCls, child) {
return [this.renderLabel(prefixCls), this.renderWrapper(prefixCls, this.renderValidateWrapper(prefixCls, child, this.renderHelp(prefixCls), this.renderExtra(prefixCls)))];
},
renderFormItem: function renderFormItem(child) {
var _itemClassName;
var customizePrefixCls = this.$props.prefixCls;
var _a = this.$attrs,
className = _a.class,
restProps = __rest(_a, ["class"]);
var getPrefixCls = this.configProvider.getPrefixCls;
var prefixCls = getPrefixCls('form', customizePrefixCls);
var children = this.renderChildren(prefixCls, child);
var itemClassName = (_itemClassName = {}, _defineProperty(_itemClassName, className, className), _defineProperty(_itemClassName, "".concat(prefixCls, "-item"), true), _defineProperty(_itemClassName, "".concat(prefixCls, "-item-with-help"), this.helpShow), _itemClassName);
return _createVNode(Row, _objectSpread({
"class": classNames(itemClassName),
"key": "row"
}, restProps), _isSlot(children) ? children : {
default: function _default() {
return [children];
}
});
}
},
render: function render() {
var _this4 = this;
var _getOptionProps = getOptionProps(this),
autoLink = _getOptionProps.autoLink;
var children = getSlot(this);
var firstChildren = children[0];
if (this.fieldName && autoLink && isValidElement(firstChildren)) {
var originalEvents = getEvents(firstChildren);
var originalBlur = originalEvents.onBlur;
var originalChange = originalEvents.onChange;
firstChildren = cloneElement(firstChildren, _extends(_extends({}, this.fieldId ? {
id: this.fieldId
} : undefined), {
onBlur: function onBlur() {
originalBlur && originalBlur.apply(void 0, arguments);
_this4.onFieldBlur();
},
onChange: function onChange() {
if (Array.isArray(originalChange)) {
for (var i = 0, l = originalChange.length; i < l; i++) {
originalChange[i].apply(originalChange, arguments);
}
} else if (originalChange) {
originalChange.apply(void 0, arguments);
}
_this4.onFieldChange();
}
}));
}
return this.renderFormItem([firstChildren, children.slice(1)]);
}
});