123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- import { ref, watch, computed, nextTick, defineComponent, createVNode as _createVNode, mergeProps as _mergeProps } from "vue";
- import { pick, extend, unitToPx, truthProp, isSameValue, makeArrayProp, preventDefault, makeStringProp, makeNumericProp, BORDER_UNSET_TOP_BOTTOM } from "../utils/index.mjs";
- import { bem, name, isOptionExist, getColumnsType, findOptionByValue, assignDefaultFields, formatCascadeColumns, getFirstEnabledOption } from "./utils.mjs";
- import { useChildren, useEventListener, useParent } from "@vant/use";
- import { useExpose } from "../composables/use-expose.mjs";
- import { Loading } from "../loading/index.mjs";
- import Column, { PICKER_KEY } from "./PickerColumn.mjs";
- import Toolbar, { pickerToolbarPropKeys, pickerToolbarProps, pickerToolbarSlots } from "./PickerToolbar.mjs";
- import { PICKER_GROUP_KEY } from "../picker-group/PickerGroup.mjs";
- const pickerSharedProps = extend({
- loading: Boolean,
- readonly: Boolean,
- allowHtml: Boolean,
- optionHeight: makeNumericProp(44),
- showToolbar: truthProp,
- swipeDuration: makeNumericProp(1e3),
- visibleOptionNum: makeNumericProp(6)
- }, pickerToolbarProps);
- const pickerProps = extend({}, pickerSharedProps, {
- columns: makeArrayProp(),
- modelValue: makeArrayProp(),
- toolbarPosition: makeStringProp("top"),
- columnsFieldNames: Object
- });
- var stdin_default = defineComponent({
- name,
- props: pickerProps,
- emits: ["confirm", "cancel", "change", "scrollInto", "clickOption", "update:modelValue"],
- setup(props, {
- emit,
- slots
- }) {
- const columnsRef = ref();
- const selectedValues = ref(props.modelValue.slice(0));
- const {
- parent
- } = useParent(PICKER_GROUP_KEY);
- const {
- children,
- linkChildren
- } = useChildren(PICKER_KEY);
- linkChildren();
- const fields = computed(() => assignDefaultFields(props.columnsFieldNames));
- const optionHeight = computed(() => unitToPx(props.optionHeight));
- const columnsType = computed(() => getColumnsType(props.columns, fields.value));
- const currentColumns = computed(() => {
- const {
- columns
- } = props;
- switch (columnsType.value) {
- case "multiple":
- return columns;
- case "cascade":
- return formatCascadeColumns(columns, fields.value, selectedValues);
- default:
- return [columns];
- }
- });
- const hasOptions = computed(() => currentColumns.value.some((options) => options.length));
- const selectedOptions = computed(() => currentColumns.value.map((options, index) => findOptionByValue(options, selectedValues.value[index], fields.value)));
- const selectedIndexes = computed(() => currentColumns.value.map((options, index) => options.findIndex((option) => option[fields.value.value] === selectedValues.value[index])));
- const setValue = (index, value) => {
- if (selectedValues.value[index] !== value) {
- const newValues = selectedValues.value.slice(0);
- newValues[index] = value;
- selectedValues.value = newValues;
- }
- };
- const getEventParams = () => ({
- selectedValues: selectedValues.value.slice(0),
- selectedOptions: selectedOptions.value,
- selectedIndexes: selectedIndexes.value
- });
- const onChange = (value, columnIndex) => {
- setValue(columnIndex, value);
- if (columnsType.value === "cascade") {
- selectedValues.value.forEach((value2, index) => {
- const options = currentColumns.value[index];
- if (!isOptionExist(options, value2, fields.value)) {
- setValue(index, options.length ? options[0][fields.value.value] : void 0);
- }
- });
- }
- nextTick(() => {
- emit("change", extend({
- columnIndex
- }, getEventParams()));
- });
- };
- const onClickOption = (currentOption, columnIndex) => {
- const params = {
- columnIndex,
- currentOption
- };
- emit("clickOption", extend(getEventParams(), params));
- emit("scrollInto", params);
- };
- const confirm = () => {
- children.forEach((child) => child.stopMomentum());
- const params = getEventParams();
- nextTick(() => {
- emit("confirm", params);
- });
- return params;
- };
- const cancel = () => emit("cancel", getEventParams());
- const renderColumnItems = () => currentColumns.value.map((options, columnIndex) => _createVNode(Column, {
- "value": selectedValues.value[columnIndex],
- "fields": fields.value,
- "options": options,
- "readonly": props.readonly,
- "allowHtml": props.allowHtml,
- "optionHeight": optionHeight.value,
- "swipeDuration": props.swipeDuration,
- "visibleOptionNum": props.visibleOptionNum,
- "onChange": (value) => onChange(value, columnIndex),
- "onClickOption": (option) => onClickOption(option, columnIndex),
- "onScrollInto": (option) => {
- emit("scrollInto", {
- currentOption: option,
- columnIndex
- });
- }
- }, {
- option: slots.option
- }));
- const renderMask = (wrapHeight) => {
- if (hasOptions.value) {
- const frameStyle = {
- height: `${optionHeight.value}px`
- };
- const maskStyle = {
- backgroundSize: `100% ${(wrapHeight - optionHeight.value) / 2}px`
- };
- return [_createVNode("div", {
- "class": bem("mask"),
- "style": maskStyle
- }, null), _createVNode("div", {
- "class": [BORDER_UNSET_TOP_BOTTOM, bem("frame")],
- "style": frameStyle
- }, null)];
- }
- };
- const renderColumns = () => {
- const wrapHeight = optionHeight.value * +props.visibleOptionNum;
- const columnsStyle = {
- height: `${wrapHeight}px`
- };
- return _createVNode("div", {
- "ref": columnsRef,
- "class": bem("columns"),
- "style": columnsStyle
- }, [renderColumnItems(), renderMask(wrapHeight)]);
- };
- const renderToolbar = () => {
- if (props.showToolbar && !parent) {
- return _createVNode(Toolbar, _mergeProps(pick(props, pickerToolbarPropKeys), {
- "onConfirm": confirm,
- "onCancel": cancel
- }), pick(slots, pickerToolbarSlots));
- }
- };
- watch(currentColumns, (columns) => {
- columns.forEach((options, index) => {
- if (options.length && !isOptionExist(options, selectedValues.value[index], fields.value)) {
- setValue(index, getFirstEnabledOption(options)[fields.value.value]);
- }
- });
- }, {
- immediate: true
- });
- let lastEmittedModelValue;
- watch(() => props.modelValue, (newValues) => {
- if (!isSameValue(newValues, selectedValues.value) && !isSameValue(newValues, lastEmittedModelValue)) {
- selectedValues.value = newValues.slice(0);
- lastEmittedModelValue = newValues.slice(0);
- }
- }, {
- deep: true
- });
- watch(selectedValues, (newValues) => {
- if (!isSameValue(newValues, props.modelValue)) {
- lastEmittedModelValue = newValues.slice(0);
- emit("update:modelValue", lastEmittedModelValue);
- }
- }, {
- immediate: true
- });
- useEventListener("touchmove", preventDefault, {
- target: columnsRef
- });
- const getSelectedOptions = () => selectedOptions.value;
- useExpose({
- confirm,
- getSelectedOptions
- });
- return () => {
- var _a, _b;
- return _createVNode("div", {
- "class": bem()
- }, [props.toolbarPosition === "top" ? renderToolbar() : null, props.loading ? _createVNode(Loading, {
- "class": bem("loading")
- }, null) : null, (_a = slots["columns-top"]) == null ? void 0 : _a.call(slots), renderColumns(), (_b = slots["columns-bottom"]) == null ? void 0 : _b.call(slots), props.toolbarPosition === "bottom" ? renderToolbar() : null]);
- };
- }
- });
- export {
- stdin_default as default,
- pickerProps,
- pickerSharedProps
- };
|