element-plus
Version:
A Component Library for Vue 3
193 lines (190 loc) • 6.19 kB
JavaScript
import { defineComponent, getCurrentInstance, computed, reactive, toRefs, watch, provide, onBeforeUnmount } from 'vue';
import { ElTooltip } from '../../tooltip/index.mjs';
import { ElScrollbar } from '../../scrollbar/index.mjs';
import { ElTag } from '../../tag/index.mjs';
import { ElIcon } from '../../icon/index.mjs';
import { useProps } from '../../select-v2/src/useProps.mjs';
import Option from './option.vue.mjs';
import ElSelectMenu from './select-dropdown.vue.mjs';
import { useSelect } from './useSelect.mjs';
import { selectKey } from './token.mjs';
import ElOptions from './options.mjs';
import { selectProps } from './select.mjs';
import OptionGroup from './option-group.vue.mjs';
import ClickOutside from '../../../directives/click-outside/index.mjs';
import { useCalcInputWidth } from '../../../hooks/use-calc-input-width/index.mjs';
import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '../../../constants/event.mjs';
import { isArray, isObject } from '@vue/shared';
import { flattedChildren } from '../../../utils/vue/vnode.mjs';
const COMPONENT_NAME = "ElSelect";
const warnHandlerMap = /* @__PURE__ */ new WeakMap();
const createSelectWarnHandler = (appContext) => {
return (...args) => {
var _a, _b;
const message = args[0];
if (!message || message.includes(
'Slot "default" invoked outside of the render function'
) && ((_a = args[2]) == null ? void 0 : _a.includes("ElTreeSelect")))
return;
const original = (_b = warnHandlerMap.get(appContext)) == null ? void 0 : _b.originalWarnHandler;
if (original) {
original(...args);
return;
}
console.warn(...args);
};
};
const getWarnHandlerRecord = (appContext) => {
let record = warnHandlerMap.get(appContext);
if (!record) {
record = {
originalWarnHandler: appContext.config.warnHandler,
handler: createSelectWarnHandler(appContext),
count: 0
};
warnHandlerMap.set(appContext, record);
}
return record;
};
var _sfc_main = defineComponent({
name: COMPONENT_NAME,
componentName: COMPONENT_NAME,
components: {
ElSelectMenu,
ElOption: Option,
ElOptions,
ElOptionGroup: OptionGroup,
ElTag,
ElScrollbar,
ElTooltip,
ElIcon
},
directives: { ClickOutside },
props: selectProps,
emits: [
UPDATE_MODEL_EVENT,
CHANGE_EVENT,
"remove-tag",
"clear",
"visible-change",
"focus",
"blur",
"popup-scroll"
],
setup(props, { emit, slots }) {
const instance = getCurrentInstance();
const warnRecord = getWarnHandlerRecord(instance.appContext);
warnRecord.count += 1;
instance.appContext.config.warnHandler = warnRecord.handler;
const modelValue = computed(() => {
const { modelValue: rawModelValue, multiple } = props;
const fallback = multiple ? [] : void 0;
if (isArray(rawModelValue)) {
return multiple ? rawModelValue : fallback;
}
return multiple ? fallback : rawModelValue;
});
const _props = reactive({
...toRefs(props),
modelValue
});
const API = useSelect(_props, emit);
const { calculatorRef, inputStyle } = useCalcInputWidth();
const { getLabel, getValue, getOptions, getDisabled } = useProps(props);
const getOptionProps = (option) => ({
label: getLabel(option),
value: getValue(option),
disabled: getDisabled(option)
});
const flatTreeSelectData = (data) => {
return data.reduce((acc, item) => {
acc.push(item);
if (item.children && item.children.length > 0) {
acc.push(...flatTreeSelectData(item.children));
}
return acc;
}, []);
};
const manuallyRenderSlots = (vnodes) => {
const children = flattedChildren(vnodes || []);
children.forEach((item) => {
var _a;
if (isObject(item) && // @ts-expect-error
(item.type.name === "ElOption" || item.type.name === "ElTree")) {
const _name = item.type.name;
if (_name === "ElTree") {
const treeData = ((_a = item.props) == null ? void 0 : _a.data) || [];
const flatData = flatTreeSelectData(treeData);
flatData.forEach((treeItem) => {
treeItem.currentLabel = treeItem.label || (isObject(treeItem.value) ? "" : treeItem.value);
API.onOptionCreate(treeItem);
});
} else if (_name === "ElOption") {
const obj = { ...item.props };
obj.currentLabel = obj.label || (isObject(obj.value) ? "" : obj.value);
API.onOptionCreate(obj);
}
}
});
};
watch(
() => {
var _a;
return [(_a = slots.default) == null ? void 0 : _a.call(slots), modelValue.value];
},
() => {
var _a;
if (props.persistent || API.expanded.value) {
return;
}
API.states.options.clear();
manuallyRenderSlots((_a = slots.default) == null ? void 0 : _a.call(slots));
},
{
immediate: true
}
);
provide(
selectKey,
reactive({
props: _props,
states: API.states,
selectRef: API.selectRef,
optionsArray: API.optionsArray,
setSelected: API.setSelected,
handleOptionSelect: API.handleOptionSelect,
onOptionCreate: API.onOptionCreate,
onOptionDestroy: API.onOptionDestroy
})
);
const selectedLabel = computed(() => {
if (!props.multiple) {
return API.states.selectedLabel;
}
return API.states.selected.map((i) => i.currentLabel);
});
onBeforeUnmount(() => {
const record = warnHandlerMap.get(instance.appContext);
if (!record) return;
record.count -= 1;
if (record.count <= 0) {
instance.appContext.config.warnHandler = record.originalWarnHandler;
warnHandlerMap.delete(instance.appContext);
}
});
return {
...API,
modelValue,
selectedLabel,
calculatorRef,
inputStyle,
getLabel,
getValue,
getOptions,
getDisabled,
getOptionProps
};
}
});
export { _sfc_main as default };
//# sourceMappingURL=select.vue2.mjs.map