You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
383 lines
10 KiB
383 lines
10 KiB
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
// Utils
|
|
import { createNamespace } from '../utils';
|
|
import { preventDefault } from '../utils/dom/event';
|
|
import { BORDER_UNSET_TOP_BOTTOM } from '../utils/constant';
|
|
import { pickerProps, DEFAULT_ITEM_HEIGHT } from './shared';
|
|
import { unitToPx } from '../utils/format/unit'; // Components
|
|
|
|
import Loading from '../loading';
|
|
import PickerColumn from './PickerColumn';
|
|
|
|
var _createNamespace = createNamespace('picker'),
|
|
createComponent = _createNamespace[0],
|
|
bem = _createNamespace[1],
|
|
t = _createNamespace[2];
|
|
|
|
export default createComponent({
|
|
props: _extends({}, pickerProps, {
|
|
defaultIndex: {
|
|
type: [Number, String],
|
|
default: 0
|
|
},
|
|
columns: {
|
|
type: Array,
|
|
default: function _default() {
|
|
return [];
|
|
}
|
|
},
|
|
toolbarPosition: {
|
|
type: String,
|
|
default: 'top'
|
|
},
|
|
valueKey: {
|
|
type: String,
|
|
default: 'text'
|
|
}
|
|
}),
|
|
data: function data() {
|
|
return {
|
|
children: [],
|
|
formattedColumns: []
|
|
};
|
|
},
|
|
computed: {
|
|
itemPxHeight: function itemPxHeight() {
|
|
return this.itemHeight ? unitToPx(this.itemHeight) : DEFAULT_ITEM_HEIGHT;
|
|
},
|
|
dataType: function dataType() {
|
|
var columns = this.columns;
|
|
var firstColumn = columns[0] || {};
|
|
|
|
if (firstColumn.children) {
|
|
return 'cascade';
|
|
}
|
|
|
|
if (firstColumn.values) {
|
|
return 'object';
|
|
}
|
|
|
|
return 'text';
|
|
}
|
|
},
|
|
watch: {
|
|
columns: {
|
|
handler: 'format',
|
|
immediate: true
|
|
}
|
|
},
|
|
methods: {
|
|
format: function format() {
|
|
var columns = this.columns,
|
|
dataType = this.dataType;
|
|
|
|
if (dataType === 'text') {
|
|
this.formattedColumns = [{
|
|
values: columns
|
|
}];
|
|
} else if (dataType === 'cascade') {
|
|
this.formatCascade();
|
|
} else {
|
|
this.formattedColumns = columns;
|
|
}
|
|
},
|
|
formatCascade: function formatCascade() {
|
|
var formatted = [];
|
|
var cursor = {
|
|
children: this.columns
|
|
};
|
|
|
|
while (cursor && cursor.children) {
|
|
var _cursor$defaultIndex;
|
|
|
|
var _cursor = cursor,
|
|
children = _cursor.children;
|
|
var defaultIndex = (_cursor$defaultIndex = cursor.defaultIndex) != null ? _cursor$defaultIndex : +this.defaultIndex;
|
|
|
|
while (children[defaultIndex] && children[defaultIndex].disabled) {
|
|
if (defaultIndex < children.length - 1) {
|
|
defaultIndex++;
|
|
} else {
|
|
defaultIndex = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
formatted.push({
|
|
values: cursor.children,
|
|
className: cursor.className,
|
|
defaultIndex: defaultIndex
|
|
});
|
|
cursor = children[defaultIndex];
|
|
}
|
|
|
|
this.formattedColumns = formatted;
|
|
},
|
|
emit: function emit(event) {
|
|
var _this = this;
|
|
|
|
if (this.dataType === 'text') {
|
|
this.$emit(event, this.getColumnValue(0), this.getColumnIndex(0));
|
|
} else {
|
|
var values = this.getValues(); // compatible with old version of wrong parameters
|
|
// should be removed in next major version
|
|
// see: https://github.com/youzan/vant/issues/5905
|
|
|
|
if (this.dataType === 'cascade') {
|
|
values = values.map(function (item) {
|
|
return item[_this.valueKey];
|
|
});
|
|
}
|
|
|
|
this.$emit(event, values, this.getIndexes());
|
|
}
|
|
},
|
|
onCascadeChange: function onCascadeChange(columnIndex) {
|
|
var cursor = {
|
|
children: this.columns
|
|
};
|
|
var indexes = this.getIndexes();
|
|
|
|
for (var i = 0; i <= columnIndex; i++) {
|
|
cursor = cursor.children[indexes[i]];
|
|
}
|
|
|
|
while (cursor && cursor.children) {
|
|
columnIndex++;
|
|
this.setColumnValues(columnIndex, cursor.children);
|
|
cursor = cursor.children[cursor.defaultIndex || 0];
|
|
}
|
|
},
|
|
onChange: function onChange(columnIndex) {
|
|
var _this2 = this;
|
|
|
|
if (this.dataType === 'cascade') {
|
|
this.onCascadeChange(columnIndex);
|
|
}
|
|
|
|
if (this.dataType === 'text') {
|
|
this.$emit('change', this, this.getColumnValue(0), this.getColumnIndex(0));
|
|
} else {
|
|
var values = this.getValues(); // compatible with old version of wrong parameters
|
|
// should be removed in next major version
|
|
// see: https://github.com/youzan/vant/issues/5905
|
|
|
|
if (this.dataType === 'cascade') {
|
|
values = values.map(function (item) {
|
|
return item[_this2.valueKey];
|
|
});
|
|
}
|
|
|
|
this.$emit('change', this, values, columnIndex);
|
|
}
|
|
},
|
|
// get column instance by index
|
|
getColumn: function getColumn(index) {
|
|
return this.children[index];
|
|
},
|
|
// @exposed-api
|
|
// get column value by index
|
|
getColumnValue: function getColumnValue(index) {
|
|
var column = this.getColumn(index);
|
|
return column && column.getValue();
|
|
},
|
|
// @exposed-api
|
|
// set column value by index
|
|
setColumnValue: function setColumnValue(index, value) {
|
|
var column = this.getColumn(index);
|
|
|
|
if (column) {
|
|
column.setValue(value);
|
|
|
|
if (this.dataType === 'cascade') {
|
|
this.onCascadeChange(index);
|
|
}
|
|
}
|
|
},
|
|
// @exposed-api
|
|
// get column option index by column index
|
|
getColumnIndex: function getColumnIndex(columnIndex) {
|
|
return (this.getColumn(columnIndex) || {}).currentIndex;
|
|
},
|
|
// @exposed-api
|
|
// set column option index by column index
|
|
setColumnIndex: function setColumnIndex(columnIndex, optionIndex) {
|
|
var column = this.getColumn(columnIndex);
|
|
|
|
if (column) {
|
|
column.setIndex(optionIndex);
|
|
|
|
if (this.dataType === 'cascade') {
|
|
this.onCascadeChange(columnIndex);
|
|
}
|
|
}
|
|
},
|
|
// @exposed-api
|
|
// get options of column by index
|
|
getColumnValues: function getColumnValues(index) {
|
|
return (this.children[index] || {}).options;
|
|
},
|
|
// @exposed-api
|
|
// set options of column by index
|
|
setColumnValues: function setColumnValues(index, options) {
|
|
var column = this.children[index];
|
|
|
|
if (column) {
|
|
column.setOptions(options);
|
|
}
|
|
},
|
|
// @exposed-api
|
|
// get values of all columns
|
|
getValues: function getValues() {
|
|
return this.children.map(function (child) {
|
|
return child.getValue();
|
|
});
|
|
},
|
|
// @exposed-api
|
|
// set values of all columns
|
|
setValues: function setValues(values) {
|
|
var _this3 = this;
|
|
|
|
values.forEach(function (value, index) {
|
|
_this3.setColumnValue(index, value);
|
|
});
|
|
},
|
|
// @exposed-api
|
|
// get indexes of all columns
|
|
getIndexes: function getIndexes() {
|
|
return this.children.map(function (child) {
|
|
return child.currentIndex;
|
|
});
|
|
},
|
|
// @exposed-api
|
|
// set indexes of all columns
|
|
setIndexes: function setIndexes(indexes) {
|
|
var _this4 = this;
|
|
|
|
indexes.forEach(function (optionIndex, columnIndex) {
|
|
_this4.setColumnIndex(columnIndex, optionIndex);
|
|
});
|
|
},
|
|
// @exposed-api
|
|
confirm: function confirm() {
|
|
this.children.forEach(function (child) {
|
|
return child.stopMomentum();
|
|
});
|
|
this.emit('confirm');
|
|
},
|
|
cancel: function cancel() {
|
|
this.emit('cancel');
|
|
},
|
|
genTitle: function genTitle() {
|
|
var h = this.$createElement;
|
|
var titleSlot = this.slots('title');
|
|
|
|
if (titleSlot) {
|
|
return titleSlot;
|
|
}
|
|
|
|
if (this.title) {
|
|
return h("div", {
|
|
"class": ['van-ellipsis', bem('title')]
|
|
}, [this.title]);
|
|
}
|
|
},
|
|
genCancel: function genCancel() {
|
|
var h = this.$createElement;
|
|
return h("button", {
|
|
"attrs": {
|
|
"type": "button"
|
|
},
|
|
"class": bem('cancel'),
|
|
"on": {
|
|
"click": this.cancel
|
|
}
|
|
}, [this.slots('cancel') || this.cancelButtonText || t('cancel')]);
|
|
},
|
|
genConfirm: function genConfirm() {
|
|
var h = this.$createElement;
|
|
return h("button", {
|
|
"attrs": {
|
|
"type": "button"
|
|
},
|
|
"class": bem('confirm'),
|
|
"on": {
|
|
"click": this.confirm
|
|
}
|
|
}, [this.slots('confirm') || this.confirmButtonText || t('confirm')]);
|
|
},
|
|
genToolbar: function genToolbar() {
|
|
var h = this.$createElement;
|
|
|
|
if (this.showToolbar) {
|
|
return h("div", {
|
|
"class": bem('toolbar')
|
|
}, [this.slots() || [this.genCancel(), this.genTitle(), this.genConfirm()]]);
|
|
}
|
|
},
|
|
genColumns: function genColumns() {
|
|
var h = this.$createElement;
|
|
var itemPxHeight = this.itemPxHeight;
|
|
var wrapHeight = itemPxHeight * this.visibleItemCount;
|
|
var frameStyle = {
|
|
height: itemPxHeight + "px"
|
|
};
|
|
var columnsStyle = {
|
|
height: wrapHeight + "px"
|
|
};
|
|
var maskStyle = {
|
|
backgroundSize: "100% " + (wrapHeight - itemPxHeight) / 2 + "px"
|
|
};
|
|
return h("div", {
|
|
"class": bem('columns'),
|
|
"style": columnsStyle,
|
|
"on": {
|
|
"touchmove": preventDefault
|
|
}
|
|
}, [this.genColumnItems(), h("div", {
|
|
"class": bem('mask'),
|
|
"style": maskStyle
|
|
}), h("div", {
|
|
"class": [BORDER_UNSET_TOP_BOTTOM, bem('frame')],
|
|
"style": frameStyle
|
|
})]);
|
|
},
|
|
genColumnItems: function genColumnItems() {
|
|
var _this5 = this;
|
|
|
|
var h = this.$createElement;
|
|
return this.formattedColumns.map(function (item, columnIndex) {
|
|
var _item$defaultIndex;
|
|
|
|
return h(PickerColumn, {
|
|
"attrs": {
|
|
"readonly": _this5.readonly,
|
|
"valueKey": _this5.valueKey,
|
|
"allowHtml": _this5.allowHtml,
|
|
"className": item.className,
|
|
"itemHeight": _this5.itemPxHeight,
|
|
"defaultIndex": (_item$defaultIndex = item.defaultIndex) != null ? _item$defaultIndex : +_this5.defaultIndex,
|
|
"swipeDuration": _this5.swipeDuration,
|
|
"visibleItemCount": _this5.visibleItemCount,
|
|
"initialOptions": item.values
|
|
},
|
|
"scopedSlots": {
|
|
option: _this5.$scopedSlots.option
|
|
},
|
|
"on": {
|
|
"change": function change() {
|
|
_this5.onChange(columnIndex);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
},
|
|
render: function render(h) {
|
|
return h("div", {
|
|
"class": bem()
|
|
}, [this.toolbarPosition === 'top' ? this.genToolbar() : h(), this.loading ? h(Loading, {
|
|
"class": bem('loading')
|
|
}) : h(), this.slots('columns-top'), this.genColumns(), this.slots('columns-bottom'), this.toolbarPosition === 'bottom' ? this.genToolbar() : h()]);
|
|
}
|
|
}); |