@opentiny/vue-renderless
Version:
An enterprise-class UI component library, support both Vue.js 2 and Vue.js 3, as well as PC and mobile.
1,367 lines • 51.5 kB
JavaScript
import {
__spreadProps,
__spreadValues
} from "../chunk-G2ADBYYC.js";
import { find } from "@opentiny/utils";
import { getObj, isEqual } from "@opentiny/utils";
import { isKorean } from "@opentiny/utils";
import { scrollIntoView } from "@opentiny/utils";
import { PopupManager } from "@opentiny/utils";
import { debounce } from "@opentiny/utils";
import { getDataset } from "@opentiny/utils";
import { Memorize } from "@opentiny/utils";
import { isEmptyObject } from "@opentiny/utils";
import { addResizeListener, removeResizeListener } from "@opentiny/utils";
import { extend } from "@opentiny/utils";
import { BROWSER_NAME } from "@opentiny/utils";
import { browserInfo } from "@opentiny/utils";
import { isNull } from "@opentiny/utils";
import { fastdom } from "@opentiny/utils";
import { deepClone } from "../picker-column";
import { escapeRegexpString } from "../option";
import { isServer } from "@opentiny/utils";
const handleComposition = ({ api, nextTick, state }) => (event) => {
const text = event.target.value;
if (event.type === "compositionend") {
state.isOnComposition = false;
const isChange = false;
const isInput = true;
nextTick(() => api.handleQueryChange(text, isChange, isInput));
} else {
const lastCharacter = text[text.length - 1] || "";
state.isOnComposition = !isKorean(lastCharacter);
}
};
const showTip = ({ props, state, vm }) => (show) => {
if (!props.showOverflowTooltip) {
return;
}
let overflow;
if (!show) {
clearTimeout(state.tipTimer);
state.tipTimer = setTimeout(() => {
state.showTip = state.tipHover;
}, vm.$refs.popover.closeDelay);
} else {
if (!props.multiple) {
const reference = vm.$refs.reference.$el;
overflow = reference.querySelector("input").scrollWidth > reference.scrollWidth;
} else {
overflow = vm.$refs.tags.scrollHeight > vm.$refs.tags.getBoundingClientRect().height;
}
state.showTip = show && overflow && !!state.tips && !state.visible;
}
};
const defaultOnQueryChange = ({ props, state, constants, api, nextTick }) => (value, isInput) => {
if (props.remote && (typeof props.remoteMethod === "function" || typeof props.initQuery === "function")) {
state.hoverIndex = -1;
props.remoteMethod && props.remoteMethod(value, props.extraQueryParams);
} else if (typeof props.filterMethod === "function") {
props.filterMethod(value);
state.selectEmitter.emit(constants.COMPONENT_NAME.OptionGroup, constants.EVENT_NAME.queryChange);
} else {
api.queryChange(value, isInput);
}
setFilteredSelectCls(nextTick, state, props);
api.getOptionIndexArr();
state.magicKey = state.magicKey > 0 ? -1 : 1;
};
const queryChange = ({ props, state, constants }) => (value, isInput) => {
if (props.optimization && isInput) {
const filterDatas = state.initDatas.filter((item) => new RegExp(escapeRegexpString(value), "i").test(item.label));
state.datas = filterDatas;
} else {
state.selectEmitter.emit(constants.EVENT_NAME.queryChange, value);
}
};
const setFilteredSelectCls = (nextTick, state, props) => {
nextTick(() => {
if (props.multiple && props.showAlloption && props.filterable && state.query && !props.remote) {
const filterSelectedVal = state.options.filter((item) => item.state.visible && item.state.itemSelected).map((opt) => opt.value);
const visibleOptions = state.options.filter((item) => item.state.visible);
if (filterSelectedVal.length === visibleOptions.length) {
state.filteredSelectCls = "checked-sur";
} else if (filterSelectedVal.length === 0) {
state.filteredSelectCls = "check";
} else {
state.filteredSelectCls = "halfselect";
}
}
});
};
const handleQueryChange = ({ api, constants, nextTick, props, vm, state }) => (value, isChange = false, isInput = false) => {
if (state.previousQuery === value && !isChange || state.isOnComposition) {
return;
}
if (state.previousQuery === null && !isChange && (typeof props.filterMethod === "function" || typeof props.remoteMethod === "function" || typeof props.initQuery === "function")) {
state.previousQuery = value;
return;
}
state.query = value;
state.previousQuery = value;
window.requestAnimationFrame(() => {
if (state.visible) {
state.selectEmitter.emit(constants.EVENT_NAME.updatePopper);
state.showWarper = true;
}
});
state.hoverIndex = -1;
if (props.multiple && props.filterable && !props.shape) {
nextTick(() => {
const length = vm.$refs.input.value.length * 15 + 20;
state.inputLength = state.collapseTags ? Math.min(50, length) : length;
api.managePlaceholder();
api.resetInputHeight();
});
}
state.triggerSearch = true;
api.defaultOnQueryChange(value, isInput);
};
const scrollToOption = ({ vm, constants }) => (option) => {
const target = Array.isArray(option) && option[0] && option[0].state ? option[0].state.el : option.state ? option.state.el : "";
if (vm.$refs.popper && target) {
const menu = vm.$refs.popper.$el.querySelector(constants.CLASS.SelectDropdownWrap);
setTimeout(() => scrollIntoView(menu, target));
}
vm.$refs.scrollbar && vm.$refs.scrollbar.handleScroll();
};
const handleMenuEnter = ({ api, nextTick, state, props }) => () => {
if (!props.optimization) {
nextTick(() => api.scrollToOption(state.selected));
}
};
const emitChange = ({ emit, props, state, constants }) => (value, changed) => {
if (state.device === "mb" && props.multiple && !changed)
return;
if (!isEqual(props.modelValue, state.compareValue)) {
emit("change", value);
}
};
const directEmitChange = ({ emit, props, state }) => (value, key) => {
if (state.device === "mb" && props.multiple)
return;
emit("change", value, key);
};
const getOption = ({ props, state, api }) => (value) => {
let option;
const isObject = Object.prototype.toString.call(value).toLowerCase() === "[object object]";
const isNull2 = Object.prototype.toString.call(value).toLowerCase() === "[object null]";
const isUndefined = Object.prototype.toString.call(value).toLowerCase() === "[object undefined]";
if (state.cachedOptions.length !== 0) {
for (let i = state.cachedOptions.length - 1; i >= 0; i--) {
const cachedOption = state.cachedOptions[i];
const isEqual2 = isObject ? getObj(cachedOption.value, props.valueKey) === getObj(value, props.valueKey) : cachedOption.value === value;
if (isEqual2) {
option = cachedOption;
break;
}
}
if (option) {
return option;
}
} else if (!isEmptyObject(state.selected)) {
return state.selected;
}
if (props.optimization) {
option = api.getSelectedOption(value);
if (option) {
return { value: option.value, currentLabel: option.label || option.currentLabel };
}
option = state.datas.find((v) => getObj(v, props.valueKey) === value);
if (option) {
return { value: option.value, currentLabel: option.label || option.currentLabel };
}
}
const label = !isObject && !isNull2 && !isUndefined && !props.clearNoMatchValue ? value : "";
let newOption = { value, currentLabel: label };
if (props.multiple) {
newOption.hitState = false;
}
return newOption;
};
const getSelectedOption = ({ props, state }) => (value) => {
let option;
if (props.multiple) {
option = state.selected.find((v) => getObj(v, props.valueKey) === value);
} else {
if (!isEmptyObject(state.selected) && getObj(state.selected, props.valueKey) === value) {
option = state.selected;
}
}
return option;
};
const getOptionOfSetSelected = ({ api, props }) => {
const option = api.getOption(props.modelValue) || {};
if (!option.state) {
option.state = {};
}
if (option.created) {
option.createdLabel = option.state.currentLabel;
option.createdSelected = true;
} else {
option.createdSelected = false;
}
if (!option.state.currentLabel) {
api.clearNoMatchValue("");
}
return option;
};
const getResultOfSetSelected = ({ state, api, props }) => {
let result = [];
const newModelValue = [];
if (Array.isArray(state.modelValue)) {
state.modelValue.forEach((value) => {
const option = api.getOption(value);
if (!props.clearNoMatchValue || props.clearNoMatchValue && option.label) {
result.push(option);
newModelValue.push(value);
}
});
}
api.clearNoMatchValue(newModelValue);
return result;
};
const setSelected = ({ api, nextTick, props, vm, state }) => () => {
if (!props.multiple) {
const option = getOptionOfSetSelected({ api, props });
state.selected = option;
state.selectedLabel = option.state.currentLabel || option.currentLabel;
props.filterable && !props.shape && (state.query = state.selectedLabel);
} else {
const result = getResultOfSetSelected({ state, props, api });
state.selectCls = result.length ? result.length === state.options.length ? "checked-sur" : "halfselect" : "check";
if (!vm.$slots.panel) {
state.selected = result;
}
state.selected.length && (state.selectedLabel = "");
state.tips = state.selected.map((item) => item.state ? item.state.currentLabel : item.currentLabel).join(",");
setFilteredSelectCls(nextTick, state, props);
nextTick(api.resetInputHeight);
}
};
const getPluginOption = ({ props, state }) => (value) => {
const isRemote = props.filterable && props.remote && (typeof props.remoteMethod === "function" || typeof props.initQuery === "function");
const { textField, valueField } = props;
const sourceData = isRemote ? state.remoteData : state.gridData;
const selNode = find(sourceData, (item) => item[valueField] === value);
const items = [];
if (selNode) {
selNode.currentLabel = selNode[textField];
items.push(selNode);
}
return items;
};
const toggleCheckAll = ({ api, state }) => (filtered) => {
let value = [];
const enabledValues = state.options.filter((op) => !op.state.disabled && !op.state.groupDisabled && !op.required && op.state.visible).map((op) => op.value);
if (filtered) {
if (state.filteredSelectCls === "check" || state.filteredSelectCls === "halfselect") {
value = [.../* @__PURE__ */ new Set([...state.modelValue, ...enabledValues])];
} else {
value = state.modelValue.filter((val) => !enabledValues.includes(val));
}
} else {
if (state.selectCls === "check") {
value = enabledValues;
} else if (state.selectCls === "halfselect") {
const unchecked = state.options.filter((item) => !item.state.disabled && item.state.selectCls === "check");
unchecked.length ? value = enabledValues : value = [];
} else if (state.selectCls === "checked-sur") {
value = [];
}
}
const requiredValue = state.options.filter((op) => op.required).map((op) => op.value);
const disabledSelectedValues = state.options.filter((op) => (op.state.disabled || op.state.groupDisabled) && op.state.selectCls === "checked-sur").map((op) => op.value);
value = [...value, ...requiredValue, ...disabledSelectedValues];
api.setSoftFocus();
state.isSilentBlur = true;
api.updateModelValue(value);
api.directEmitChange(value);
};
const handleFocus = ({ emit, props, state }) => (event) => {
if (!state.softFocus) {
if (props.automaticDropdown || props.filterable) {
state.visible = true;
state.softFocus = true;
}
emit("focus", event);
} else {
if (state.searchSingleCopy && state.selectedLabel) {
emit("focus", event);
}
state.softFocus = false;
}
};
const focus = ({ vm, state }) => () => {
if (!state.softFocus) {
vm.$refs.reference.focus();
}
};
const blur = ({ vm, state }) => () => {
state.visible = false;
vm.$refs.reference.blur();
};
const handleBlur = ({ constants, dispatch, emit, state, designConfig }) => (event) => {
var _a;
clearTimeout(state.timer);
state.timer = setTimeout(() => {
var _a2;
if (state.isSilentBlur) {
state.isSilentBlur = false;
} else {
emit("blur", event);
}
if ((_a2 = designConfig == null ? void 0 : designConfig.state) == null ? void 0 : _a2.delayBlur) {
dispatch(constants.COMPONENT_NAME.FormItem, constants.EVENT_NAME.formBlur, event.target.value);
}
}, 200);
if (!((_a = designConfig == null ? void 0 : designConfig.state) == null ? void 0 : _a.delayBlur)) {
dispatch(constants.COMPONENT_NAME.FormItem, constants.EVENT_NAME.formBlur, event.target.value);
}
state.softFocus = false;
};
const handleClearClick = (api) => (event) => {
api.deleteSelected(event);
};
const doDestroy = (vm) => () => {
var _a;
if ((_a = vm == null ? void 0 : vm.$refs) == null ? void 0 : _a.popper) {
vm.$refs.popper.doDestroy();
}
};
const handleClose = (state) => () => {
state.visible = false;
};
const toggleLastOptionHitState = ({ state }) => (hit) => {
if (!Array.isArray(state.selected)) {
return;
}
const option = state.selected[state.selected.length - 1];
if (!option) {
return;
}
if (option.required) {
return true;
}
const hitTarget = option.state || option;
if (hit === true || hit === false) {
hitTarget.hitState = hit;
return hit;
}
hitTarget.hitState = !hitTarget.hitState;
return hitTarget.hitState;
};
const deletePrevTag = ({ api, state }) => (event) => {
if (event.target.value.length <= 0 && !api.toggleLastOptionHitState()) {
const value = state.modelValue.slice();
value.pop();
state.compareValue = deepClone(value);
api.updateModelValue(value);
api.emitChange(value);
}
};
const managePlaceholder = ({ vm, state }) => () => {
if (state.currentPlaceholder !== "") {
state.currentPlaceholder = vm.$refs.input.value ? "" : state.cachedPlaceHolder;
}
};
const resetInputState = ({ api, vm, state }) => (event) => {
if (event.keyCode !== 8) {
api.toggleLastOptionHitState(false);
}
state.inputLength = vm.$refs.input.value.length * 15 + 20;
api.resetInputHeight();
};
const resetInputHeight = ({ constants, nextTick, props, vm, state, api, designConfig }) => () => {
if (state.collapseTags && !props.filterable) {
return;
}
nextTick(() => {
var _a, _b;
if (!vm.$refs.reference) {
return;
}
let input = vm.$refs.reference.type === "text" && vm.$refs.reference.$el.querySelector("input");
const tags = vm.$refs.tags;
const limitText = vm.$refs.reference.$el.querySelector("span.tiny-select__limit-txt");
if (!input) {
return;
}
if (!state.isDisplayOnly && (props.hoverExpand || props.clickExpand) && !props.disabled) {
api.calcCollapseTags();
}
const sizeInMap = (designConfig == null ? void 0 : designConfig.state.initialInputHeight) || state.initialInputHeight || 32;
const noSelected = state.selected.length === 0;
const spacingHeight = (_b = (_a = designConfig == null ? void 0 : designConfig.state) == null ? void 0 : _a.spacingHeight) != null ? _b : constants.SPACING_HEIGHT;
if (!state.isDisplayOnly) {
if (!noSelected && tags) {
fastdom.measure(() => {
const tagsClientHeight = tags.clientHeight;
fastdom.mutate(() => {
input.style.height = Math.max(tagsClientHeight + spacingHeight, sizeInMap) + "px";
});
});
} else {
input.style.height = noSelected ? sizeInMap + "px" : Math.max(0, sizeInMap) + "px";
}
} else {
input.style.height = "auto";
}
if (limitText && props.multipleLimit) {
const { width, marginLeft, marginRight } = getComputedStyle(limitText);
vm.$refs.tags.style.paddingRight = `${Math.ceil(
parseFloat(width) + parseFloat(marginLeft) + parseFloat(marginRight)
)}px`;
}
if (state.visible && state.emptyText !== false) {
state.selectEmitter.emit(constants.EVENT_NAME.updatePopper, true);
}
});
};
const resetHoverIndex = ({ props, state }) => () => {
if (!props.showOverflowTooltip) {
state.hoverIndex = -1;
} else if (!props.multiple) {
state.hoverIndex = state.options.indexOf(state.selected);
} else {
if (state.selected.length > 0) {
state.hoverIndex = Math.min.apply(
null,
state.selected.map((item) => state.options.indexOf(item))
);
} else {
state.hoverIndex = -1;
}
}
};
const resetDatas = ({ props, state }) => () => {
if (props.optimization && !props.remote && !props.filterMethod) {
state.datas = state.initDatas;
}
};
const handleOptionSelect = ({ api, nextTick, props, vm, state }) => (option, byClick) => {
state.memorize && state.memorize.updateByKey(option[state.memorize._dataKey] || option.value);
if (props.multiple) {
const value = (state.modelValue || []).slice();
const optionIndex = api.getValueIndex(value, option.value);
if (optionIndex > -1) {
value.splice(optionIndex, 1);
} else if (state.multipleLimit <= 0 || value.length < state.multipleLimit) {
value.push(option.value);
}
state.compareValue = deepClone(value);
api.updateModelValue(value);
api.emitChange(value);
if (option.created) {
const isChange = false;
const isInput = true;
state.query = "";
api.handleQueryChange("", isChange, isInput);
state.inputLength = 20;
}
if (props.filterable) {
vm.$refs.input.focus();
}
if (props.autoClose) {
state.visible = false;
}
} else {
state.compareValue = deepClone(option.value);
api.updateModelValue(option.value);
api.emitChange(option.value);
if (option.created) {
state.createdSelected = true;
state.createdLabel = option.value;
}
state.visible = false;
}
state.isSilentBlur = byClick;
api.setSoftFocus();
if (state.visible) {
return;
}
nextTick(() => {
api.scrollToOption(option);
});
};
const initValue = ({ state }) => (vm) => {
const isExist = state.initValue.find((val) => val === vm.value);
!isExist && state.initValue.push(vm.value);
};
const setSoftFocus = ({ vm, state }) => () => {
state.softFocus = true;
const input = vm.$refs.input || vm.$refs.reference;
if (input) {
input.focus();
}
state.softFocus = false;
};
const getValueIndex = (props) => (arr = [], value = null) => {
const isObject = Object.prototype.toString.call(value).toLowerCase() === "[object object]";
if (!isObject) {
return arr.indexOf(value);
} else {
const valueKey = props.valueKey;
let index = -1;
arr.some((item, i) => {
if (getObj(item, valueKey) === getObj(value, valueKey)) {
index = i;
return true;
}
return false;
});
return index;
}
};
const toggleMenu = ({ vm, state, props, api }) => (e) => {
if (props.keepFocus && state.visible && props.filterable) {
return;
}
const event = e || window.event;
const enterCode = 13;
const nodeName = event.target && event.target.nodeName;
const toggleVisible = props.ignoreEnter ? event.keyCode !== enterCode && nodeName === "INPUT" : true;
if (!props.displayOnly) {
event.stopPropagation();
}
if (!state.selectDisabled) {
toggleVisible && !state.softFocus && (state.visible = !state.visible);
state.softFocus = false;
if (state.visible) {
if (!(props.filterable && props.shape)) {
const dom = vm.$refs.input || vm.$refs.reference;
(dom == null ? void 0 : dom.focus) && dom.focus();
api.setOptionHighlight();
}
}
}
};
const selectOption = ({ api, state, props }) => (e) => {
if (!state.visible || props.hideDrop) {
api.toggleMenu(e);
} else {
let option = "";
if (state.query || props.remote) {
option = state.options.find((item) => item.state.index === state.hoverValue);
} else {
option = state.options[state.hoverIndex];
}
option && api.handleOptionSelect(option);
}
};
const deleteSelected = ({ api, emit, props, state }) => (event) => {
event && event.stopPropagation();
let selectedValue = [];
if (props.multiple) {
const requireOptions = state.options.filter((opt) => opt.required && opt.value);
selectedValue = state.modelValue.slice().filter((v) => requireOptions.find((opt) => opt.value === v));
}
const value = props.multiple ? selectedValue : "";
state.showTip = false;
state.compareValue = deepClone(value);
api.updateModelValue(value, true);
api.emitChange(value, true);
state.visible = false;
emit("clear");
};
const deleteTag = ({ api, constants, emit, props, state, nextTick, vm }) => (event, tag) => {
if (tag.required)
return;
const index = state.selected.indexOf(tag);
if (index > -1 && !state.selectDisabled) {
const value = state.modelValue.slice();
value.splice(index, 1);
state.compareValue = deepClone(value);
api.updateModelValue(value);
api.emitChange(value);
emit(constants.EVENT_NAME.removeTag, tag[props.valueField]);
nextTick(() => state.key++);
}
event && event.stopPropagation();
};
const onInputChange = ({ api, props, state, constants, nextTick }) => () => {
if (!props.delay) {
if (props.filterable && state.query !== state.selectedLabel) {
const isChange = false;
const isInput = true;
state.query = state.selectedLabel;
api.handleQueryChange(state.query, isChange, isInput);
nextTick(() => {
state.selectEmitter.emit(constants.EVENT_NAME.updatePopper);
});
}
} else {
api.debouncRquest();
}
nextTick(() => {
state.selectEmitter.emit(constants.EVENT_NAME.updatePopper);
});
};
const onOptionDestroy = (state) => (index) => {
if (index > -1) {
state.optionsCount--;
state.filteredOptionsCount--;
state.options.splice(index, 1);
}
};
const resetInputWidth = ({ vm, state }) => () => {
if (vm.$refs.reference && vm.$refs.reference.$el) {
state.inputWidth = vm.$refs.reference.$el.getBoundingClientRect().width;
}
};
const handleResize = ({ api, props, state }) => () => {
api.resetInputWidth();
if (props.multiple && !state.isDisplayOnly) {
api.resetInputHeight();
}
};
const setOptionHighlight = (state) => () => {
for (let i = 0; i < state.options.length; ++i) {
const option = state.options[i];
if (!option.disabled && !option.groupDisabled && !option.state.created && option.state.visible && option.state.itemSelected) {
state.hoverIndex = i;
break;
}
}
};
const checkDefaultFirstOption = (state) => () => {
state.hoverIndex = -1;
let hasCreated = false;
const visibleOptions = state.options.filter((item) => item.visible && item.state.visible);
for (let i = visibleOptions.length - 1; i >= 0; i--) {
if (visibleOptions[i].created) {
hasCreated = true;
state.hoverIndex = i;
state.hoverValue = state.optionIndexArr[i];
break;
}
}
if (hasCreated) {
return;
}
for (let i = 0; i < visibleOptions.length; i++) {
const option = visibleOptions[i];
if (state.query) {
if (!option.disabled && !option.groupDisabled && option.state.visible && option.visible) {
state.hoverIndex = i;
state.hoverValue = state.optionIndexArr[i];
break;
}
} else {
if (option.itemSelected) {
state.hoverIndex = i;
state.hoverValue = state.optionIndexArr[i];
break;
}
}
}
};
const getValueKey = (props) => (item) => {
if (!item)
return;
if (Object.prototype.toString.call(item.value).toLowerCase() !== "[object object]") {
return item.value || item[props.valueField];
}
return getObj(item.value, props.valueKey);
};
const navigateOptions = ({ api, state, props, nextTick }) => (direction) => {
const { optimization } = props;
if (optimization) {
return;
}
const len = state.options.filter((item) => item.visible && item.state.visible).length;
if (!state.visible) {
state.visible = true;
return;
}
if (len === 0 || state.filteredOptionsCount === 0) {
return;
}
state.disabledOptionHover = true;
setTimeout(() => {
state.disabledOptionHover = false;
}, 100);
if (state.hoverIndex < -1 || state.hoverIndex >= len) {
state.hoverIndex = 0;
}
if (!state.optionsAllDisabled) {
if (direction === "next") {
state.hoverIndex++;
if (state.hoverIndex === len) {
state.hoverIndex = 0;
}
} else if (direction === "prev") {
state.hoverIndex--;
if (state.hoverIndex < 0) {
state.hoverIndex = len - 1;
}
}
let option = {};
state.hoverValue = state.optionIndexArr[state.hoverIndex];
if (state.query || props.remote) {
option = state.options.find((item) => item.state.index === state.hoverValue);
} else {
option = state.options[state.hoverIndex];
}
if (option.disabled === true || option.groupDisabled === true || !option.state.visible || option.state.limitReached) {
api.navigateOptions(direction);
}
nextTick(() => api.scrollToOption(state.hoverIndex === -9 ? {} : option || {}));
}
};
const emptyFlag = ({ props, state }) => () => {
if (props.optimization) {
if (props.allowCreate) {
return state.query === "" && state.datas.length === 0;
} else {
return state.datas.length === 0;
}
} else {
return state.options.length === 0;
}
};
const recycleScrollerHeight = ({ state, props, recycle }) => () => {
const { ITEM_HEIGHT, SAFE_MARGIN, SAAS_HEIGHT, AURORA_HEIGHT } = recycle;
let length = state.datas.length;
if (state.showNewOption) {
length += 1;
}
if (length === 0 || props.loading) {
return 0;
} else if (length < 6) {
return length * ITEM_HEIGHT + (state.isSaaSTheme ? SAFE_MARGIN * 2 : 0);
} else {
return state.isSaaSTheme ? SAAS_HEIGHT : AURORA_HEIGHT;
}
};
const emptyText = ({ I18N, props, state, t, isMobileFirstMode }) => () => {
if (props.loading) {
return props.loadingText || t(I18N.loading);
}
if (props.remote && state.query === "" && props.renderType) {
return remoteEmptyText(props, state);
}
if (props.remote && state.query === "" && state.emptyFlag && !state.triggerSearch) {
return props.shape === "filter" || isMobileFirstMode ? "" : false;
}
if (props.filterable && state.query && (props.remote && state.emptyFlag || !state.options.some((option) => option.visible && option.state.visible))) {
return props.noMatchText || t(I18N.noMatch);
}
if (state.emptyFlag) {
return props.noDataText || t(I18N.noData);
}
return null;
};
const remoteEmptyText = function(props, state) {
if (props.multiple) {
return state.selected.length > 0 || state.remoteData.length >= 0;
}
return state.selected[props.valueField] || state.remoteData.length >= 0;
};
const watchValue = ({ api, constants, dispatch, props, vm, state }) => (value, oldValue) => {
if (props.multiple) {
api.resetInputHeight();
if (value && value.length > 0 || vm.$refs.input && state.query !== "") {
state.currentPlaceholder = "";
} else {
state.currentPlaceholder = state.cachedPlaceHolder;
}
if (props.filterable && !props.reserveKeyword) {
!props.searchable && (state.query = "");
}
}
api.setSelected();
!state.isClickChoose && api.initQuery({ init: true }).then(() => api.setSelected());
state.isClickChoose = false;
if (props.filterable && !props.multiple) {
state.inputLength = 20;
}
if (state.completed && !isEqual(value, oldValue)) {
dispatch(constants.COMPONENT_NAME.FormItem, constants.EVENT_NAME.formChange, value);
}
props.optimization && optmzApis.setValueIndex({ props, state });
};
const calcOverFlow = ({ vm, props, state }) => (height) => {
if (props.multiple && props.showOverflowTooltip) {
state.overflow = false;
const tagDom = vm.$refs.tags;
const tags = tagDom.querySelectorAll('[data-tag="tiny-tag"]');
if (tags.length) {
tagDom.scrollTo && tagDom.scrollTo({ top: 0 });
let { x, width } = tags[0].getBoundingClientRect();
if (width >= tagDom.getBoundingClientRect().width) {
state.overflow = 0;
} else {
for (let i = 1; i < tags.length; i++) {
let tx = tags[i].getBoundingClientRect().x;
if (tx === x) {
state.overflow = i - 1;
break;
}
}
}
}
vm.$refs.select.style.height = vm.$refs.select.style.height || height;
vm.$refs.reference.$el.style.position = "absolute";
const inputWidth = vm.$refs.select.getBoundingClientRect().width;
const position = state.visible ? "absolute" : "";
state.selectFiexd = {
height,
position,
width: inputWidth + "px",
zIndex: PopupManager.nextZIndex()
};
state.inputWidth = inputWidth;
}
};
const postOperOfToVisible = ({ props, state, constants }) => {
if (props.multiple) {
return;
}
if (state.selected) {
if (props.filterable && props.allowCreate && state.createdSelected && state.createdLabel) {
state.selectedLabel = state.createdLabel;
} else {
state.selectedLabel = state.selected.state.currentLabel || state.selected.currentLabel;
}
if (props.filterable) {
state.query = state.selectedLabel;
}
if (props.filterable) {
state.currentPlaceholder = state.cachedPlaceHolder;
}
}
};
const toVisible = ({ constants, state, props, vm, api, nextTick }) => () => {
state.selectEmitter.emit(constants.EVENT_NAME.destroyPopper);
props.remote && props.dropOnlySearch && (state.showWarper = false);
if (vm.$refs.input) {
vm.$refs.input.blur();
}
state.query = "";
state.selectedLabel = "";
state.inputLength = 20;
state.previousQuery !== state.query && api.initQuery().then(() => api.setSelected());
state.previousQuery = null;
api.resetHoverIndex();
api.resetDatas();
nextTick(() => {
if (vm.$refs.input && vm.$refs.input.value === "" && state.selected.length === 0) {
state.currentPlaceholder = state.cachedPlaceHolder;
}
});
postOperOfToVisible({ props, state, constants });
};
const toHide = ({ constants, state, props, vm, api }) => () => {
const { filterable, remote, remoteConfig, shape, multiple, valueField } = props;
state.selectEmitter.emit(constants.COMPONENT_NAME.SelectDropdown, constants.EVENT_NAME.updatePopper);
if (filterable) {
state.query = remote || shape ? "" : state.selectedLabel;
const isChange = remote && remoteConfig.autoSearch && (state.firstAutoSearch || remoteConfig.clearData);
state.firstAutoSearch = false;
api.handleQueryChange(state.query, isChange);
if (multiple) {
vm.$refs.input.focus();
} else {
if (!remote) {
state.selectEmitter.emit(constants.EVENT_NAME.queryChange, "");
state.selectEmitter.emit(constants.COMPONENT_NAME.OptionGroup, constants.EVENT_NAME.queryChange);
}
if (state.selectedLabel && !shape) {
state.currentPlaceholder = state.selectedLabel;
state.selectedLabel = "";
}
}
}
};
const watchVisible = ({ api, constants, emit, state, vm, props }) => (value) => {
if ((props.filterable || props.remote) && !value) {
vm.$refs.reference.blur();
}
if (api.onCopying()) {
return;
}
if (value && props.multiple && state.device === "mb") {
state.selectedCopy = state.selected.slice();
}
setTimeout(() => {
if (!value && !state.selectedLabel) {
state.cachedOptions.forEach((item) => {
item.state.visible = true;
});
}
}, 200);
value ? api.toHide() : api.toVisible();
emit(constants.EVENT_NAME.visibleChange, value);
setTimeout(() => {
state.selectEmitter.emit(constants.EVENT_NAME.updatePopper);
if (value && vm.$refs.scrollbar) {
if (props.optimization) {
optmzApis.setScrollTop({ refs: vm.$refs, state });
vm.$refs.scrollbar.updateVisibleItems(true, true);
} else {
vm.$refs.scrollbar.handleScroll();
}
}
}, props.updateDelay);
if (!value && props.shape === "filter") {
state.softFocus = false;
}
};
const watchOptions = ({ api, constants, nextTick, parent, props, state }) => () => {
if (typeof window === "undefined") {
return;
}
nextTick(() => {
state.selectEmitter.emit(constants.EVENT_NAME.updatePopper);
});
if (props.multiple) {
api.resetInputHeight();
}
nextTick(() => {
if (parent.$el.querySelector("input") !== document.activeElement) {
api.setSelected();
}
});
api.getOptionIndexArr();
};
const getOptionIndexArr = ({ props, state, api }) => () => {
setTimeout(() => {
state.optionIndexArr = api.queryVisibleOptions().map((item) => Number(item.getAttribute("data-index")));
if (props.defaultFirstOption && (props.filterable || props.remote) && state.filteredOptionsCount) {
if (props.optimization) {
optmzApis.checkDefaultFirstOption({ state });
} else {
api.checkDefaultFirstOption();
}
}
});
};
const queryVisibleOptions = ({ props, vm, isMobileFirstMode }) => () => {
if (props.optimization) {
return optmzApis.queryVisibleOptions(vm, isMobileFirstMode);
} else {
return vm.$refs.scrollbar ? Array.from(vm.$refs.scrollbar.$el.querySelectorAll('[data-index]:not([style*="display: none"])')) : [];
}
};
const handleCopyClick = ({ parent, props, state }) => () => {
const input = document.createElement("input");
input.style.height = 0;
input.style.border = "none";
input.style.position = "absolute";
parent.$el.appendChild(input);
input.value = state.selected.map((item) => item.state ? item.state.currentLabel : item.currentLabel).join(props.textSplit);
input.select();
document.execCommand("copy");
parent.$el.removeChild(input);
};
const debouncRquest = ({ api, state, props }) => debounce(props.delay, () => {
if (props.filterable && state.query !== state.selectedLabel) {
const isChange = false;
const isInput = true;
state.query = state.selectedLabel;
api.handleQueryChange(state.query, isChange, isInput);
}
});
const getChildValue = () => (data, key) => {
const ids = [];
const getChild = (nodes) => {
nodes.forEach((node) => {
ids.push(node.data[key]);
if (node.childNodes.length > 0) {
getChild(node.childNodes);
}
});
};
getChild(data);
return ids;
};
const watchPropsOption = ({ constants, parent, props, state }) => () => {
const dataset = {
dataset: props.options || props.dataset,
service: parent.$service
};
getDataset(dataset).then((data) => {
let sortData = data.slice();
if (props.multiple) {
const requiredData = [];
sortData = sortData.filter((item) => {
if (item.required) {
requiredData.push(item);
return false;
}
return true;
});
sortData = requiredData.concat(sortData);
}
if (props.cacheOp && props.cacheOp.key) {
state.memorize = new Memorize(props.cacheOp);
state.datas = state.memorize.assemble(sortData.slice());
} else {
state.datas = sortData;
state.initDatas = sortData;
}
});
};
const onMouseenterNative = ({ state }) => () => {
state.inputHovering = true;
if (state.searchSingleCopy && state.selectedLabel) {
state.softFocus = true;
}
};
const onMouseleaveNative = ({ state }) => (e) => {
if (e.target === e.currentTarget)
return;
state.inputHovering = false;
if (state.searchSingleCopy && state.selectedLabel) {
state.softFocus = false;
}
};
const onCopying = ({ state, vm }) => () => {
return state.searchSingleCopy && state.selectedLabel && vm.$refs.reference && vm.$refs.reference.hasSelection && vm.$refs.reference.hasSelection();
};
const watchHoverIndex = ({ state }) => (value) => {
if (value === -1 || value === -9) {
state.hoverValue = -1;
} else {
state.hoverValue = state.optionIndexArr[value];
}
};
const handleDropdownClick = ({ vm, state, props, emit }) => ($event) => {
if (props.allowCopy && vm.$refs.reference) {
vm.$refs.reference.$el.querySelector("input").selectionEnd = 0;
}
state.softFocus = false;
emit("dropdown-click", $event);
};
const handleEnterTag = ({ state }) => ($event, key) => {
const target = $event.target;
if (target && target.scrollWidth > target.offsetWidth) {
state.tooltipContent = __spreadProps(__spreadValues({}, state.tooltipContent), { [key]: target.innerText });
}
};
const calcCollapseTags = ({ state, vm, props }) => () => {
if (state.inputHovering && !props.clickExpand) {
return state.isHidden = true;
}
const tags = vm.$refs.tags;
const collapseTag = tags && tags.querySelector('[data-tag="tags-collapse"]');
if (!collapseTag || !tags) {
return;
}
const { width: tagsContentWidth, paddingLeft, paddingRight } = window.getComputedStyle(tags);
const tagsWidth = parseFloat(tagsContentWidth) - parseFloat(paddingLeft) - parseFloat(paddingRight);
const { width: collapseTagContentWidth, marginRight } = collapseTag && window.getComputedStyle(collapseTag);
const collapseTagWidth = collapseTag && parseFloat(collapseTagContentWidth) + parseFloat(marginRight);
const tagList = Array.from(tags.querySelectorAll('[data-tag="tiny-tag"]'));
let [dom, idx, currentRowWidth, currentTagIndex] = [null, 0, 0, 0];
for (let rowNum = 0; rowNum < props.maxVisibleRows; rowNum++) {
currentRowWidth = 0;
let currentTagWidth = 0;
for (currentTagIndex; currentTagIndex < tagList.length; currentTagIndex++) {
const tag = tagList[currentTagIndex];
if (tag !== collapseTag) {
const { width: tagContentWidth, marginRight: marginRight2, marginLeft } = tag && window.getComputedStyle(tag);
currentTagWidth = parseFloat(tagContentWidth) + parseFloat(marginRight2) + parseFloat(marginLeft);
currentRowWidth += currentTagWidth;
}
if (tag !== collapseTag && currentRowWidth > tagsWidth) {
if (!dom && rowNum === props.maxVisibleRows - 1) {
if (currentRowWidth - currentTagWidth + collapseTagWidth < tagsWidth) {
dom = tag;
idx = currentTagIndex;
} else {
dom = tagList[currentTagIndex - 1];
idx = currentTagIndex - 1;
}
}
break;
}
}
if (currentTagIndex === tagList.length - 1) {
break;
}
}
if (idx === 0) {
state.exceedMaxVisibleRow = false;
state.showCollapseTag = false;
return state.isHidden = true;
}
if (dom) {
dom.before(collapseTag);
state.isHidden = false;
} else {
state.isHidden = true;
}
state.collapseTagsLength = tagList.length - idx;
state.exceedMaxVisibleRow = true;
state.toHideIndex = idx;
};
const watchInputHover = ({ vm }) => (newVal) => {
const [inputHovering, visible] = newVal;
if (!inputHovering && !visible) {
const tags = vm.$refs.tags;
const content = vm.$refs["tags-content"];
tags && content && tags.scrollTo({ top: content });
}
};
const initQuery = ({ props, state, constants, vm }) => ({ init } = {}) => {
const isRemote = props.filterable && props.remote && (typeof props.remoteMethod === "function" || typeof props.initQuery === "function");
let selected;
if (isRemote && props.initQuery) {
let initData = props.initQuery(props.modelValue, props.extraQueryParams, !!init);
if (initData.then) {
return new Promise((resolve) => {
initData.then((selected2) => {
state.remoteData = selected2;
resolve(selected2);
});
});
}
selected = initData;
state.remoteData = selected;
}
return Promise.resolve(selected);
};
const mounted = ({ api, parent, state, props, vm, designConfig }) => () => {
var _a;
const parentEl = parent.$el;
const inputEl = parentEl.querySelector('input[data-tag="tiny-input-inner"]');
const inputClientRect = inputEl && inputEl.getBoundingClientRect() || {};
if (inputEl === document.activeElement) {
document.activeElement.blur();
}
state.completed = true;
const defaultSizeMap = { medium: 40, default: 32, small: 28, mini: 24 };
const sizeMap = ((_a = designConfig == null ? void 0 : designConfig.state) == null ? void 0 : _a.sizeMap) || defaultSizeMap;
if (props.multiple && Array.isArray(props.modelValue) && props.modelValue.length > 0) {
state.currentPlaceholder = "";
}
state.initialInputHeight = state.isDisplayOnly ? sizeMap[state.selectSize || "default"] : inputClientRect.height || sizeMap[state.selectSize];
addResizeListener(parentEl, api.handleResize);
if (vm.$refs.tags) {
addResizeListener(vm.$refs.tags, api.resetInputHeight);
}
if (props.remote && props.multiple) {
api.resetInputHeight();
}
state.inputWidth = inputClientRect.width;
api.initQuery({ init: true }).then(() => api.setSelected());
if (props.dataset) {
api.watchPropsOption();
}
};
const unMount = ({ api, parent, vm, state }) => () => {
if (parent.$el && api.handleResize) {
removeResizeListener(parent.$el, api.handleResize);
}
if (vm.$refs.tags) {
removeResizeListener(vm.$refs.tags, api.resetInputHeight);
}
state.popperElm = null;
};
const optmzApis = {
exist: (val, multiple) => multiple ? Array.isArray(val) && val.length : val,
getValueIndex: (props) => {
const { options, valueField, modelValue, multiple } = props;
const contain = (val, arr) => Array.isArray(arr) && ~arr.indexOf(val);
const equal = (val, opt) => multiple ? contain(opt[valueField], [val]) : opt[valueField] === val;
let start = 0;
if (optmzApis.exist(modelValue, multiple) && options) {
const lastVal = multiple ? modelValue[modelValue.length - 1] : modelValue;
for (let i = 0; i < options.length; i++) {
if (!equal(lastVal, options[i]))
continue;
return i;
}
}
return start;
},
queryVisibleOptions: (vm, isMobileFirstMode) => {
const querySelectKey = isMobileFirstMode ? ".cursor-not-allowed" : ".is-disabled";
return Array.from(
vm.$refs.scrollbar.$el.querySelectorAll(
'.tiny-recycle-scroller__slot, .tiny-recycle-scroller__item-view:not([style*="transform: translateY(-9999px) translateX(0px)"])'
)
).map((item) => item.querySelector(`[data-tag="tiny-option"]:not(${querySelectKey})`)).filter((v) => v);
},
setScrollTop: ({ refs, state }) => {
const { optimizeStore } = state;
refs.scrollbar.scrollToItem(optimizeStore.valueIndex);
},
setValueIndex: ({ props, state }) => {
state.optimizeStore.valueIndex = optmzApis.getValueIndex(props);
},
natural: (val) => val < 0 ? 0 : val,
checkDefaultFirstOption: ({ state }) => {
state.hoverIndex = 0;
state.hoverValue = state.optionIndexArr[0];
}
};
const computeOptimizeOpts = ({ props, designConfig }) => () => {
const { optimization } = props;
const baseOpts = (designConfig == null ? void 0 : designConfig.baseOpts) ? designConfig.baseOpts : { gt: 20, rSize: 10, optionHeight: 30, limit: 20 };
let optOpts;
if (optimization) {
if (typeof optimization === "boolean") {
optOpts = extend(true, {}, baseOpts);
} else {
optOpts = extend(true, {}, baseOpts, optimization);
}
return optOpts;
}
};
const watchOptimizeOpts = ({ props, state }) => () => {
const { optimizeOpts, optimizeStore } = state;
if (optimizeOpts) {
if (props.optimization) {
optimizeStore.valueIndex = optmzApis.getValueIndex(props);
}
}
};
const computeCollapseTags = (props) => () => props.collapseTags;
const computeMultipleLimit = ({ props, state }) => () => {
const { multipleLimit, multiple, optimization } = props;
const { optimizeOpts } = state;
return optmzApis.natural(multiple && optimization ? multipleLimit || optimizeOpts.limit : multipleLimit);
};
const updateModelValue = ({ props, emit, state }) => (value, needUpdate) => {
state.isClickChoose = true;
if (state.device === "mb" && props.multiple && !needUpdate) {
state.modelValue = value;
} else {
emit("update:modelValue", value);
}
};
const getLabelSlotValue = ({ props, state }) => (item) => {
const datas = state.datas;
const value = item.state ? item.state.currentValue : item.value;
const data = datas.find((data2) => data2.value === value);
const obj = __spreadProps(__spreadValues({}, data), {
label: item.state ? item.state.currentLabel : item.currentLabel,
value
});
return obj;
};
const computedTagsStyle = ({ props, parent, state, vm }) => () => {
const isReadonly = props.disabled || (parent.form || {}).disabled || props.displayOnly;
let tagsStyle = {
"max-width": isReadonly ? "" : state.inputWidth - state.inputPaddingRight + "px",
width: "100%"
};
if (props.clickExpand && !state.exceedMaxVisibleRow || state.visible) {
Object.assign(tagsStyle, { height: "auto" });
}
if (props.clickExpand && state.exceedMaxVisibleRow && !state.showCollapseTag) {
const tags = vm.$refs.tags;
const { paddingTop: tagsPaddingTop, paddingBottom: tagsPaddingBottom } = window.getComputedStyle(tags);
const tagsPaddingVertical = parseFloat(tagsPaddingTop) + parseFloat(tagsPaddingBottom);
const tag = tags == null ? void 0 : tags.querySelector('[data-tag="tiny-tag"]');
if (tag) {
const { height: tagHeight, marginTop, marginBottom } = window.getComputedStyle(tag);
const rowHeight = (parseFloat(tagHeight) + parseFloat(marginTop) + parseFloat(marginBottom)) * props.maxVisibleRows;
Object.assign(tagsStyle, { "height": `${rowHeight + tagsPaddingVertical}px` });
}
}
return tagsStyle;
};
const computedReadonly = ({ props, state }) => () => state.device === "mb" || props.readonly || !props.filterable || props.multiple || browserInfo.name !== BROWSER_NAME.IE && browserInfo.name !== BROWSER_NAME.Edge && !state.visible;
const computedShowClose = ({ props, state }) => () => props.clearable && !state.selectDisabled && (state.inputHovering || props.multiple && state.visible) && (props.multiple ? Array.isArray(props.modelValue) && props.modelValue.length > 0 : !isNull(props.modelValue) && props.modelValue !== "");
const computedCollapseTagSize = (state) => () => state.selectSize;
const computedShowNewOption = ({ props, state }) => () => {
const query = state.device === "mb" ? state.queryValue : state.query;
return props.filterable && props.allowCreate && query && !state.options.filter((option) => !option.created).some((option) => option.state.currentLabel === state.query);
};
const computedShowCopy = ({ props, state }) => () => props.multiple && props.copyable && state.inputHovering && state.selected.length;
const computedOptionsAllDisabled = (state) => () => state.options.filter((option) => option.visible).every((option) => option.disabled);
const computedDisabledTooltipContent = (state) => () => state.selected.map((item) => item.state ? item.state.currentLabel : item.currentLabel).join("\uFF1B");
const computedSelectDisabled = ({ props, parent }) => () => props.disabled || (parent.form || {}).disabled || props.displayOnly || (parent.form || {}).displayOnly;
const computedIsExpand = ({ props, state }) => () => {
const hoverExpanded = (state.selectHover || state.visible) && props.hoverExpand && !props.disabled;
const clickExpanded = props.clickExpand && state.exceedMaxVisibleRow && state.showCollapseTag;
return hoverExpanded || clickExpanded;
};
const watchInitValue = ({ props, emit }) => (value) => {
if (props.multiple) {
let modelValue = props.modelValue.slice();
value.forEach((val) => {
modelValue = modelValue.filter((item) => item !== val);
});
emit("update:modelValue", value.concat(modelValue));
}
};
const watchShowClose = ({ nextTick, state, parent }) => () => {
if (isServer)
return;
nextTick(() => {
const parentEl = parent.$el;
const inputEl = parentEl.querySelector('input[data-tag="tiny-input-inner"]');
if (inputEl) {
const { paddingRight } = getComputedStyle(inputEl);
const COPY_ICON_WIDTH = 16;
state.inputPaddingRight = parseFloat(paddingRight) + COPY_ICON_WIDTH;
}
});
};
const computedShowTagText = ({ state }) => () => state.isDisplayOnly;
const isTagClosable = () => (item) => !item.required;
const computedGetIcon = ({ designConfig, props }) => () => {
return props.dropdownIcon ? { icon: props.dropdownIcon } : {
icon: (designConfig == null ? void 0 : designConfig.icons.dropdownIcon) || "icon-delta-down",
isDefault: true
};
};
const computedGetTagType = ({ designConfig, props }) => () => {
var _a;
if (((_a = designConfig == null ? void 0 : designConfig.props) == null ? void 0 : _a.tagType) && !props.tagType) {
return designConfig.props.tagType;
}
return props.tagType;
};
const clearSearchText = ({ state, api }) => () => {
state.query = "";
state.previousQuery = void 0;
api.handleQueryChange(state.query);
};
const clearNoMatchValue = ({ props, emit }) => (newModelValue) => {
if (!props.clearNoMatchValue) {
return;
}
if (props.multiple && props.modelValue.length !== newModelValue.length || !props.multiple && props.modelValue !== newModelValue) {
emit("update:modelValue", newModelValue);
}
};
const handleDebouncedQueryChange = ({ state, api }) => debounce(state.debounce, (value) => {
api.handleQueryChange(value);
});
const onClickCollapseTag = ({ state, props, nextTick, api }) => (event) => {
event.stopPropagation();
if (props.clickExpand && !props.disabled && !state.isDisplayOnly) {
state.showCollapseTag = !state.showCollapseTag;
nextTick(api.resetInputHeight);
}
};
const updateSelectedData = ({ state }) => (data) => {
state.selected = data;
};
const hidePanel = ({ state }) => () => {
state.visible = false;
};
export {
blur,
calcCollapseTags,
calcOverFlow,
checkDefaultFirstOption,
clearNoMatchValue,
clearSearchText,
computeCollapseTags,
computeMultipleLimit,
computeOptimizeOpts,
computedCollapseTagSize,
computedDisabledTooltipContent,
computedGetIcon,
computedGetTagType,
computedIsExpand,
computedOptionsAllDisabled,
computedReadonly,
computedSe