first
This commit is contained in:
635
node_modules/vant/es/field/index.js
generated
vendored
Normal file
635
node_modules/vant/es/field/index.js
generated
vendored
Normal file
@ -0,0 +1,635 @@
|
||||
import _mergeJSXProps2 from "@vue/babel-helper-vue-jsx-merge-props";
|
||||
import _mergeJSXProps from "@vue/babel-helper-vue-jsx-merge-props";
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
// Utils
|
||||
import { resetScroll } from '../utils/dom/reset-scroll';
|
||||
import { formatNumber } from '../utils/format/number';
|
||||
import { preventDefault } from '../utils/dom/event';
|
||||
import { getRootScrollTop, setRootScrollTop } from '../utils/dom/scroll';
|
||||
import { isDef, addUnit, isObject, isPromise, isFunction, createNamespace } from '../utils'; // Components
|
||||
|
||||
import Icon from '../icon';
|
||||
import Cell from '../cell';
|
||||
import { cellProps } from '../cell/shared';
|
||||
|
||||
var _createNamespace = createNamespace('field'),
|
||||
createComponent = _createNamespace[0],
|
||||
bem = _createNamespace[1];
|
||||
|
||||
export default createComponent({
|
||||
inheritAttrs: false,
|
||||
provide: function provide() {
|
||||
return {
|
||||
vanField: this
|
||||
};
|
||||
},
|
||||
inject: {
|
||||
vanForm: {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
props: _extends({}, cellProps, {
|
||||
name: String,
|
||||
rules: Array,
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
autosize: [Boolean, Object],
|
||||
leftIcon: String,
|
||||
rightIcon: String,
|
||||
clearable: Boolean,
|
||||
formatter: Function,
|
||||
maxlength: [Number, String],
|
||||
labelWidth: [Number, String],
|
||||
labelClass: null,
|
||||
labelAlign: String,
|
||||
inputAlign: String,
|
||||
placeholder: String,
|
||||
errorMessage: String,
|
||||
errorMessageAlign: String,
|
||||
showWordLimit: Boolean,
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: ''
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
},
|
||||
error: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
colon: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
clearTrigger: {
|
||||
type: String,
|
||||
default: 'focus'
|
||||
},
|
||||
formatTrigger: {
|
||||
type: String,
|
||||
default: 'onChange'
|
||||
}
|
||||
}),
|
||||
data: function data() {
|
||||
return {
|
||||
focused: false,
|
||||
validateFailed: false,
|
||||
validateMessage: ''
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: function value() {
|
||||
this.updateValue(this.value);
|
||||
this.resetValidation();
|
||||
this.validateWithTrigger('onChange');
|
||||
this.$nextTick(this.adjustSize);
|
||||
}
|
||||
},
|
||||
mounted: function mounted() {
|
||||
this.updateValue(this.value, this.formatTrigger);
|
||||
this.$nextTick(this.adjustSize);
|
||||
|
||||
if (this.vanForm) {
|
||||
this.vanForm.addField(this);
|
||||
}
|
||||
},
|
||||
beforeDestroy: function beforeDestroy() {
|
||||
if (this.vanForm) {
|
||||
this.vanForm.removeField(this);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showClear: function showClear() {
|
||||
var readonly = this.getProp('readonly');
|
||||
|
||||
if (this.clearable && !readonly) {
|
||||
var hasValue = isDef(this.value) && this.value !== '';
|
||||
var trigger = this.clearTrigger === 'always' || this.clearTrigger === 'focus' && this.focused;
|
||||
return hasValue && trigger;
|
||||
}
|
||||
},
|
||||
showError: function showError() {
|
||||
if (this.error !== null) {
|
||||
return this.error;
|
||||
}
|
||||
|
||||
if (this.vanForm && this.vanForm.showError && this.validateFailed) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
listeners: function listeners() {
|
||||
return _extends({}, this.$listeners, {
|
||||
blur: this.onBlur,
|
||||
focus: this.onFocus,
|
||||
input: this.onInput,
|
||||
click: this.onClickInput,
|
||||
keypress: this.onKeypress
|
||||
});
|
||||
},
|
||||
labelStyle: function labelStyle() {
|
||||
var labelWidth = this.getProp('labelWidth');
|
||||
|
||||
if (labelWidth) {
|
||||
return {
|
||||
width: addUnit(labelWidth)
|
||||
};
|
||||
}
|
||||
},
|
||||
formValue: function formValue() {
|
||||
if (this.children && (this.$scopedSlots.input || this.$slots.input)) {
|
||||
return this.children.value;
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// @exposed-api
|
||||
focus: function focus() {
|
||||
if (this.$refs.input) {
|
||||
this.$refs.input.focus();
|
||||
}
|
||||
},
|
||||
// @exposed-api
|
||||
blur: function blur() {
|
||||
if (this.$refs.input) {
|
||||
this.$refs.input.blur();
|
||||
}
|
||||
},
|
||||
runValidator: function runValidator(value, rule) {
|
||||
return new Promise(function (resolve) {
|
||||
var returnVal = rule.validator(value, rule);
|
||||
|
||||
if (isPromise(returnVal)) {
|
||||
return returnVal.then(resolve);
|
||||
}
|
||||
|
||||
resolve(returnVal);
|
||||
});
|
||||
},
|
||||
isEmptyValue: function isEmptyValue(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return !value.length;
|
||||
}
|
||||
|
||||
if (value === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !value;
|
||||
},
|
||||
runSyncRule: function runSyncRule(value, rule) {
|
||||
if (rule.required && this.isEmptyValue(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rule.pattern && !rule.pattern.test(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
getRuleMessage: function getRuleMessage(value, rule) {
|
||||
var message = rule.message;
|
||||
|
||||
if (isFunction(message)) {
|
||||
return message(value, rule);
|
||||
}
|
||||
|
||||
return message;
|
||||
},
|
||||
runRules: function runRules(rules) {
|
||||
var _this = this;
|
||||
|
||||
return rules.reduce(function (promise, rule) {
|
||||
return promise.then(function () {
|
||||
if (_this.validateFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
var value = _this.formValue;
|
||||
|
||||
if (rule.formatter) {
|
||||
value = rule.formatter(value, rule);
|
||||
}
|
||||
|
||||
if (!_this.runSyncRule(value, rule)) {
|
||||
_this.validateFailed = true;
|
||||
_this.validateMessage = _this.getRuleMessage(value, rule);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rule.validator) {
|
||||
return _this.runValidator(value, rule).then(function (result) {
|
||||
if (result === false) {
|
||||
_this.validateFailed = true;
|
||||
_this.validateMessage = _this.getRuleMessage(value, rule);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, Promise.resolve());
|
||||
},
|
||||
validate: function validate(rules) {
|
||||
var _this2 = this;
|
||||
|
||||
if (rules === void 0) {
|
||||
rules = this.rules;
|
||||
}
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
if (!rules) {
|
||||
resolve();
|
||||
}
|
||||
|
||||
_this2.resetValidation();
|
||||
|
||||
_this2.runRules(rules).then(function () {
|
||||
if (_this2.validateFailed) {
|
||||
resolve({
|
||||
name: _this2.name,
|
||||
message: _this2.validateMessage
|
||||
});
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
validateWithTrigger: function validateWithTrigger(trigger) {
|
||||
if (this.vanForm && this.rules) {
|
||||
var defaultTrigger = this.vanForm.validateTrigger === trigger;
|
||||
var rules = this.rules.filter(function (rule) {
|
||||
if (rule.trigger) {
|
||||
return rule.trigger === trigger;
|
||||
}
|
||||
|
||||
return defaultTrigger;
|
||||
});
|
||||
|
||||
if (rules.length) {
|
||||
this.validate(rules);
|
||||
}
|
||||
}
|
||||
},
|
||||
resetValidation: function resetValidation() {
|
||||
if (this.validateFailed) {
|
||||
this.validateFailed = false;
|
||||
this.validateMessage = '';
|
||||
}
|
||||
},
|
||||
updateValue: function updateValue(value, trigger) {
|
||||
if (trigger === void 0) {
|
||||
trigger = 'onChange';
|
||||
}
|
||||
|
||||
value = isDef(value) ? String(value) : ''; // native maxlength have incorrect line-break counting
|
||||
// see: https://github.com/vant-ui/vant/issues/5033
|
||||
|
||||
var maxlength = this.maxlength;
|
||||
|
||||
if (isDef(maxlength) && value.length > maxlength) {
|
||||
if (this.value && this.value.length === +maxlength) {
|
||||
value = this.value;
|
||||
} else {
|
||||
value = value.slice(0, maxlength);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.type === 'number' || this.type === 'digit') {
|
||||
var isNumber = this.type === 'number';
|
||||
value = formatNumber(value, isNumber, isNumber);
|
||||
}
|
||||
|
||||
if (this.formatter && trigger === this.formatTrigger) {
|
||||
value = this.formatter(value);
|
||||
}
|
||||
|
||||
var input = this.$refs.input;
|
||||
|
||||
if (input && value !== input.value) {
|
||||
input.value = value;
|
||||
}
|
||||
|
||||
if (value !== this.value) {
|
||||
this.$emit('input', value);
|
||||
}
|
||||
},
|
||||
onInput: function onInput(event) {
|
||||
// not update v-model when composing
|
||||
if (event.target.composing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateValue(event.target.value);
|
||||
},
|
||||
onFocus: function onFocus(event) {
|
||||
this.focused = true;
|
||||
this.$emit('focus', event); // https://github.com/vant-ui/vant/issues/9715
|
||||
|
||||
this.$nextTick(this.adjustSize); // readonly not work in legacy mobile safari
|
||||
|
||||
/* istanbul ignore if */
|
||||
|
||||
if (this.getProp('readonly')) {
|
||||
this.blur();
|
||||
}
|
||||
},
|
||||
onBlur: function onBlur(event) {
|
||||
if (this.getProp('readonly')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.focused = false;
|
||||
this.updateValue(this.value, 'onBlur');
|
||||
this.$emit('blur', event);
|
||||
this.validateWithTrigger('onBlur');
|
||||
this.$nextTick(this.adjustSize);
|
||||
resetScroll();
|
||||
},
|
||||
onClick: function onClick(event) {
|
||||
this.$emit('click', event);
|
||||
},
|
||||
onClickInput: function onClickInput(event) {
|
||||
this.$emit('click-input', event);
|
||||
},
|
||||
onClickLeftIcon: function onClickLeftIcon(event) {
|
||||
this.$emit('click-left-icon', event);
|
||||
},
|
||||
onClickRightIcon: function onClickRightIcon(event) {
|
||||
this.$emit('click-right-icon', event);
|
||||
},
|
||||
onClear: function onClear(event) {
|
||||
preventDefault(event);
|
||||
this.$emit('input', '');
|
||||
this.$emit('clear', event);
|
||||
},
|
||||
onKeypress: function onKeypress(event) {
|
||||
var ENTER_CODE = 13;
|
||||
|
||||
if (event.keyCode === ENTER_CODE) {
|
||||
var submitOnEnter = this.getProp('submitOnEnter');
|
||||
|
||||
if (!submitOnEnter && this.type !== 'textarea') {
|
||||
preventDefault(event);
|
||||
} // trigger blur after click keyboard search button
|
||||
|
||||
|
||||
if (this.type === 'search') {
|
||||
this.blur();
|
||||
}
|
||||
}
|
||||
|
||||
this.$emit('keypress', event);
|
||||
},
|
||||
adjustSize: function adjustSize() {
|
||||
var input = this.$refs.input;
|
||||
|
||||
if (!(this.type === 'textarea' && this.autosize) || !input) {
|
||||
return;
|
||||
}
|
||||
|
||||
var scrollTop = getRootScrollTop();
|
||||
input.style.height = 'auto';
|
||||
var height = input.scrollHeight;
|
||||
|
||||
if (isObject(this.autosize)) {
|
||||
var _this$autosize = this.autosize,
|
||||
maxHeight = _this$autosize.maxHeight,
|
||||
minHeight = _this$autosize.minHeight;
|
||||
|
||||
if (maxHeight) {
|
||||
height = Math.min(height, maxHeight);
|
||||
}
|
||||
|
||||
if (minHeight) {
|
||||
height = Math.max(height, minHeight);
|
||||
}
|
||||
}
|
||||
|
||||
if (height) {
|
||||
input.style.height = height + 'px'; // https://github.com/vant-ui/vant/issues/9178
|
||||
|
||||
setRootScrollTop(scrollTop);
|
||||
}
|
||||
},
|
||||
genInput: function genInput() {
|
||||
var h = this.$createElement;
|
||||
var type = this.type;
|
||||
var disabled = this.getProp('disabled');
|
||||
var readonly = this.getProp('readonly');
|
||||
var inputSlot = this.slots('input');
|
||||
var inputAlign = this.getProp('inputAlign');
|
||||
|
||||
if (inputSlot) {
|
||||
return h("div", {
|
||||
"class": bem('control', [inputAlign, 'custom']),
|
||||
"on": {
|
||||
"click": this.onClickInput
|
||||
}
|
||||
}, [inputSlot]);
|
||||
}
|
||||
|
||||
var inputProps = {
|
||||
ref: 'input',
|
||||
class: bem('control', inputAlign),
|
||||
domProps: {
|
||||
value: this.value
|
||||
},
|
||||
attrs: _extends({}, this.$attrs, {
|
||||
name: this.name,
|
||||
disabled: disabled,
|
||||
readonly: readonly,
|
||||
placeholder: this.placeholder
|
||||
}),
|
||||
on: this.listeners,
|
||||
// add model directive to skip IME composition
|
||||
directives: [{
|
||||
name: 'model',
|
||||
value: this.value
|
||||
}]
|
||||
};
|
||||
|
||||
if (type === 'textarea') {
|
||||
return h("textarea", _mergeJSXProps([{}, inputProps]));
|
||||
}
|
||||
|
||||
var inputType = type;
|
||||
var inputMode; // type="number" is weird in iOS, and can't prevent dot in Android
|
||||
// so use inputmode to set keyboard in modern browsers
|
||||
|
||||
if (type === 'number') {
|
||||
inputType = 'text';
|
||||
inputMode = 'decimal';
|
||||
}
|
||||
|
||||
if (type === 'digit') {
|
||||
inputType = 'tel';
|
||||
inputMode = 'numeric';
|
||||
}
|
||||
|
||||
return h("input", _mergeJSXProps2([{
|
||||
"attrs": {
|
||||
"type": inputType,
|
||||
"inputmode": inputMode
|
||||
}
|
||||
}, inputProps]));
|
||||
},
|
||||
genLeftIcon: function genLeftIcon() {
|
||||
var h = this.$createElement;
|
||||
var showLeftIcon = this.slots('left-icon') || this.leftIcon;
|
||||
|
||||
if (showLeftIcon) {
|
||||
return h("div", {
|
||||
"class": bem('left-icon'),
|
||||
"on": {
|
||||
"click": this.onClickLeftIcon
|
||||
}
|
||||
}, [this.slots('left-icon') || h(Icon, {
|
||||
"attrs": {
|
||||
"name": this.leftIcon,
|
||||
"classPrefix": this.iconPrefix
|
||||
}
|
||||
})]);
|
||||
}
|
||||
},
|
||||
genRightIcon: function genRightIcon() {
|
||||
var h = this.$createElement;
|
||||
var slots = this.slots;
|
||||
var showRightIcon = slots('right-icon') || this.rightIcon;
|
||||
|
||||
if (showRightIcon) {
|
||||
return h("div", {
|
||||
"class": bem('right-icon'),
|
||||
"on": {
|
||||
"click": this.onClickRightIcon
|
||||
}
|
||||
}, [slots('right-icon') || h(Icon, {
|
||||
"attrs": {
|
||||
"name": this.rightIcon,
|
||||
"classPrefix": this.iconPrefix
|
||||
}
|
||||
})]);
|
||||
}
|
||||
},
|
||||
genWordLimit: function genWordLimit() {
|
||||
var h = this.$createElement;
|
||||
|
||||
if (this.showWordLimit && this.maxlength) {
|
||||
var count = (this.value || '').length;
|
||||
return h("div", {
|
||||
"class": bem('word-limit')
|
||||
}, [h("span", {
|
||||
"class": bem('word-num')
|
||||
}, [count]), "/", this.maxlength]);
|
||||
}
|
||||
},
|
||||
genMessage: function genMessage() {
|
||||
var h = this.$createElement;
|
||||
|
||||
if (this.vanForm && this.vanForm.showErrorMessage === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
var message = this.errorMessage || this.validateMessage;
|
||||
|
||||
if (message) {
|
||||
var errorMessageAlign = this.getProp('errorMessageAlign');
|
||||
return h("div", {
|
||||
"class": bem('error-message', errorMessageAlign)
|
||||
}, [message]);
|
||||
}
|
||||
},
|
||||
getProp: function getProp(key) {
|
||||
if (isDef(this[key])) {
|
||||
return this[key];
|
||||
}
|
||||
|
||||
if (this.vanForm && isDef(this.vanForm[key])) {
|
||||
return this.vanForm[key];
|
||||
}
|
||||
},
|
||||
genLabel: function genLabel() {
|
||||
var h = this.$createElement;
|
||||
var colon = this.getProp('colon') ? ':' : '';
|
||||
|
||||
if (this.slots('label')) {
|
||||
return [this.slots('label'), colon];
|
||||
}
|
||||
|
||||
if (this.label) {
|
||||
return h("span", [this.label + colon]);
|
||||
}
|
||||
}
|
||||
},
|
||||
render: function render() {
|
||||
var _bem;
|
||||
|
||||
var h = arguments[0];
|
||||
var slots = this.slots;
|
||||
var disabled = this.getProp('disabled');
|
||||
var labelAlign = this.getProp('labelAlign');
|
||||
var scopedSlots = {
|
||||
icon: this.genLeftIcon
|
||||
};
|
||||
var Label = this.genLabel();
|
||||
|
||||
if (Label) {
|
||||
scopedSlots.title = function () {
|
||||
return Label;
|
||||
};
|
||||
}
|
||||
|
||||
var extra = this.slots('extra');
|
||||
|
||||
if (extra) {
|
||||
scopedSlots.extra = function () {
|
||||
return extra;
|
||||
};
|
||||
}
|
||||
|
||||
return h(Cell, {
|
||||
"attrs": {
|
||||
"icon": this.leftIcon,
|
||||
"size": this.size,
|
||||
"center": this.center,
|
||||
"border": this.border,
|
||||
"isLink": this.isLink,
|
||||
"required": this.required,
|
||||
"clickable": this.clickable,
|
||||
"titleStyle": this.labelStyle,
|
||||
"valueClass": bem('value'),
|
||||
"titleClass": [bem('label', labelAlign), this.labelClass],
|
||||
"arrowDirection": this.arrowDirection
|
||||
},
|
||||
"scopedSlots": scopedSlots,
|
||||
"class": bem((_bem = {
|
||||
error: this.showError,
|
||||
disabled: disabled
|
||||
}, _bem["label-" + labelAlign] = labelAlign, _bem['min-height'] = this.type === 'textarea' && !this.autosize, _bem)),
|
||||
"on": {
|
||||
"click": this.onClick
|
||||
}
|
||||
}, [h("div", {
|
||||
"class": bem('body')
|
||||
}, [this.genInput(), this.showClear && h(Icon, {
|
||||
"attrs": {
|
||||
"name": "clear"
|
||||
},
|
||||
"class": bem('clear'),
|
||||
"on": {
|
||||
"touchstart": this.onClear
|
||||
}
|
||||
}), this.genRightIcon(), slots('button') && h("div", {
|
||||
"class": bem('button')
|
||||
}, [slots('button')])]), this.genWordLimit(), this.genMessage()]);
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user