UNPKG

@opensig/opendesign

Version:

<p align="center"><img src="../docs/public/opendesign-logo-light.png"/></p> <h1 align="center">opendesign</h1> <p align="center">一个 Vue 3 组件库</p> <p align="center"><b>皮肤可定制,使用 TypeScript</b></p>

599 lines (598 loc) 23.2 kB
"use strict"; const vue = require("vue"); const global = require("../_utils/global.js"); const icons = require("../_utils/icons.js"); const index$5 = require("../popup/index.js"); const index$2 = require("../popover/index.js"); const index$3 = require("../dialog/index.js"); const provide$1 = require("./provide.js"); const types = require("./types.js"); const styleClass = require("../_utils/style-class.js"); const clientOnly = require("../_components/client-only.js"); const index$1 = require("../scrollbar/index.js"); const is = require("../_utils/is.js"); const SelectOption_vue_vue_type_script_setup_true_lang = require("./SelectOption.vue.js"); const slot = require("./slot.js"); const vueUtils = require("../_utils/vue-utils.js"); const provide = require("../form/provide.js"); const index = require("../locale/index.js"); const index$4 = require("../button/index.js"); const useScreen = require("../hooks/use-screen.js"); const _hoisted_1 = ["value", "placeholder"]; const _hoisted_2 = { class: "o-select-tags-wrap" }; const _hoisted_3 = ["onClick"]; const _hoisted_4 = { class: "o-select-tags" }; const _hoisted_5 = ["onClick"]; const _hoisted_6 = { class: "o-select-suffix" }; const _hoisted_7 = { class: "o-select-suffix-icon" }; const _hoisted_8 = { key: 0, class: "o-select-loading" }; const _hoisted_9 = { class: "o-select-option-wrap" }; const _hoisted_10 = { class: "o-select-empty" }; const _hoisted_11 = { class: "o-select-options-head" }; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ __name: "OSelect", props: types.selectProps, emits: ["update:modelValue", "change", "options-visible-change", "clear"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const { isPhonePad } = useScreen.useScreen(); const { t } = index.useI18n(); const selectRef = vue.ref(); const optionsRef = vue.ref(null); const isSelecting = vue.ref(false); const isResponding = vue.computed(() => { return !props.noResponsive && isPhonePad.value; }); const tagPopoverVisible = vue.ref(false); vue.watch( () => isSelecting.value, () => { if (isSelecting.value) { tagPopoverVisible.value = false; } } ); const formItemInjection = vue.inject(provide.formItemInjectKey, null); const color = vue.computed(() => { var _a; if (formItemInjection == null ? void 0 : formItemInjection.fieldResult.value) { return (_a = formItemInjection == null ? void 0 : formItemInjection.fieldResult.value) == null ? void 0 : _a.type; } else { return props.color; } }); const optionLabels = vue.ref({}); const valueList = vue.ref([]); const finalValueList = vue.ref([]); if (is.isArray(props.modelValue)) { valueList.value = [...props.modelValue]; } else if (is.isArray(props.defaultValue)) { valueList.value = [...props.defaultValue]; } else { const mrValue = props.modelValue ?? props.defaultValue; if (!is.isUndefined(mrValue)) { valueList.value = [mrValue]; } else { valueList.value = []; } } finalValueList.value = [...valueList.value]; const valueListDisplay = vue.computed(() => { if (!props.maxTagCount) { return finalValueList.value; } return finalValueList.value.slice(0, props.maxTagCount); }); const valueListFold = vue.computed(() => { if (!props.maxTagCount) { return []; } return finalValueList.value.slice(props.maxTagCount); }); const foldLabel = vue.computed(() => { if (props.foldLabel) { const tags = valueListFold.value.map((item) => ({ value: item, label: optionLabels.value[item] })); return props.foldLabel(tags); } return `+${valueListFold.value.length}...`; }); const foldTrigger = typeof props.showFoldTags === "string" ? props.showFoldTags : "hover"; const round = styleClass.getRoundClass(props, "select"); vue.watch( () => props.modelValue, (v) => { if (props.multiple) { if (is.isArray(v)) { if (!is.isArrayEqual(v, valueList.value)) { valueList.value = [...v]; } } else { valueList.value = []; } } else if (valueList.value[0] !== v) { valueList.value = [v]; } finalValueList.value = [...valueList.value]; } ); vue.watchEffect(() => { if (!isResponding.value) { finalValueList.value = [...valueList.value]; } }); const isClearable = vue.computed(() => props.clearable && !props.disabled && valueList.value.length > 0); const emitChange = (value) => { var _a, _b; if (props.multiple) { emits("change", [...value]); } else { emits("change", value[0]); } (_b = formItemInjection == null ? void 0 : (_a = formItemInjection.fieldHandlers).onChange) == null ? void 0 : _b.call(_a); }; const emitUpdateValue = (value) => { if (props.multiple) { emits("update:modelValue", [...value]); } else { emits("update:modelValue", value[0]); } }; const clearClick = (e) => { e.stopPropagation(); valueList.value = []; emits("clear", e); emitChange(valueList.value); emitUpdateValue(valueList.value); }; const beforeSelect = async (value) => { if (is.isFunction(props.beforeSelect)) { const rlt = await props.beforeSelect(value, props.multiple ? valueList.value : valueList.value[0]); return rlt; } return true; }; vue.provide(provide$1.selectOptionInjectKey, { multiple: props.multiple, selectValue: valueList, select: async (option, userSelect) => { if (userSelect) { let toValue = option.value; const rlt = await beforeSelect(option.value); if (rlt === false) { return; } if (typeof rlt !== "boolean") { toValue = rlt; } if (!props.multiple) { isSelecting.value = false; if (valueList.value[0] !== toValue) { valueList.value[0] = toValue; emitUpdateValue(valueList.value); emitChange(valueList.value); } } else { const idx = valueList.value.indexOf(toValue); if (idx > -1) { valueList.value.splice(idx, 1); } else { valueList.value.push(toValue); } if (!isResponding.value) { emitUpdateValue(valueList.value); emitChange(valueList.value); } } } else { if (optionLabels.value[option.value] !== option.label) { optionLabels.value[option.value] = option.label; } } } }); const onOptionVisibleChange = (visible) => { emits("options-visible-change", visible); }; const onRemoveTag = (value, e) => { e.stopPropagation(); const idx = valueList.value.indexOf(value); if (idx > -1) { valueList.value.splice(idx, 1); emitChange(valueList.value); emitUpdateValue(valueList.value); } }; const onFoldTagClick = (e) => { if (foldTrigger === "click") { e.stopPropagation(); } }; const beforeTagPopoverShow = () => { if (isSelecting.value) { return false; } return true; }; const onSelectClick = () => { if (isResponding.value) { if (!props.disabled) { isSelecting.value = true; } } }; const onSelectDlgChange = (visible) => { onOptionVisibleChange(visible); }; const onselectDlgCancelClick = () => { isSelecting.value = false; valueList.value = [...finalValueList.value]; }; const onselectDlgOkClick = () => { isSelecting.value = false; finalValueList.value = [...valueList.value]; emitChange(valueList.value); emitUpdateValue(valueList.value); }; return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock( "div", { ref_key: "selectRef", ref: selectRef, class: vue.normalizeClass(["o-select", [ `o-select-${color.value}`, `o-select-${props.variant}`, `o-select-${props.size || vue.unref(global.defaultSize)}`, vue.unref(round).class.value, { "is-selecting": isSelecting.value, "is-multiple": props.multiple && valueList.value.length > 0, "o-select-disabled": props.disabled, "o-select-clearable": isClearable.value, "o-select-is-loading": props.loading } ]]), style: vue.normalizeStyle(vue.unref(round).style.value), onClick: onSelectClick }, [ !props.multiple || props.multiple && valueList.value.length === 0 ? (vue.openBlock(), vue.createElementBlock("input", { key: 0, value: optionLabels.value[valueList.value[0]], type: "text", placeholder: props.placeholder, class: "o-select-input", readonly: "" }, null, 8, _hoisted_1)) : (vue.openBlock(), vue.createBlock(vue.unref(index$1.OScroller), { key: 1, class: "o-select-tags-scroller", "wrap-class": "o-select-value-list", "show-type": "hover", size: "small", "disabled-x": "" }, { default: vue.withCtx(() => [ vue.createElementVNode("div", _hoisted_2, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(valueListDisplay.value, (item) => { return vue.openBlock(), vue.createElementBlock("div", { key: item, class: "o-select-tag" }, [ vue.createTextVNode( vue.toDisplayString(optionLabels.value[item]) + " ", 1 /* TEXT */ ), vue.createElementVNode("div", { class: "o-select-tag-remove", onClick: (e) => onRemoveTag(item, e) }, [ vue.createVNode(vue.unref(icons.IconClose)) ], 8, _hoisted_3) ]); }), 128 /* KEYED_FRAGMENT */ )), _ctx.showFoldTags && valueListFold.value.length > 0 ? (vue.openBlock(), vue.createBlock(vue.unref(index$2.OPopover), { key: 0, visible: tagPopoverVisible.value, "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => tagPopoverVisible.value = $event), trigger: vue.unref(foldTrigger), class: "o-select-tag-popover", position: "bottom", "before-show": beforeTagPopoverShow }, { target: vue.withCtx(() => [ vue.createElementVNode("div", { class: "o-select-tag", onClick: onFoldTagClick }, [ vue.renderSlot(_ctx.$slots, "tag-fold", {}, () => [ vue.createTextVNode( vue.toDisplayString(foldLabel.value), 1 /* TEXT */ ) ]) ]) ]), default: vue.withCtx(() => [ vue.createElementVNode("div", _hoisted_4, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(valueListFold.value, (item) => { return vue.openBlock(), vue.createElementBlock("div", { key: item, class: "o-select-tag" }, [ vue.createTextVNode( vue.toDisplayString(optionLabels.value[item]) + " ", 1 /* TEXT */ ), vue.createElementVNode("div", { class: "o-select-tag-remove", onClick: (e) => onRemoveTag(item, e) }, [ vue.createVNode(vue.unref(icons.IconClose)) ], 8, _hoisted_5) ]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]), _: 3 /* FORWARDED */ }, 8, ["visible", "trigger"])) : vue.createCommentVNode("v-if", true) ]) ]), _: 3 /* FORWARDED */ })), vue.createElementVNode("div", _hoisted_6, [ vue.createElementVNode("div", _hoisted_7, [ props.loading ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8, [ vue.createVNode(vue.unref(icons.IconLoading), { class: "o-rotating" }) ])) : isClearable.value ? (vue.openBlock(), vue.createElementBlock("div", { key: 1, class: "o-select-clear", onClick: clearClick }, [ vue.createVNode(vue.unref(icons.IconClose), { class: "o-select-clear-icon" }) ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode( "div", { class: vue.normalizeClass(["o-select-arrow", { active: isSelecting.value }]) }, [ vue.renderSlot(_ctx.$slots, "arrow", { active: isSelecting.value }, () => [ vue.createVNode(vue.unref(icons.IconChevronDown)) ]) ], 2 /* CLASS */ ) ]), vue.renderSlot(_ctx.$slots, "suffix", { active: isSelecting.value }) ]), vue.createVNode(vue.unref(clientOnly), null, { default: vue.withCtx(() => [ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: optionsRef.value, disabled: !optionsRef.value }, [ vue.withDirectives(vue.createElementVNode( "div", _hoisted_9, [ vue.renderSlot(_ctx.$slots, "default", {}, () => [ vue.createElementVNode("div", _hoisted_10, [ vue.renderSlot(_ctx.$slots, "empty", {}, () => [ vue.createElementVNode( "span", null, vue.toDisplayString(vue.unref(t)("common.empty")), 1 /* TEXT */ ) ]) ]) ]) ], 512 /* NEED_PATCH */ ), [ [vue.vShow, optionsRef.value] ]) ], 8, ["to", "disabled"])), isResponding.value ? (vue.openBlock(), vue.createBlock(vue.unref(index$3.ODialog), { key: 0, visible: isSelecting.value, "onUpdate:visible": _cache[1] || (_cache[1] = ($event) => isSelecting.value = $event), "before-show": props.beforeOptionsShow, "before-hide": props.beforeOptionsHide, "hide-close": "", class: vue.normalizeClass(["o-select-dlg", { "is-loading": props.loading }]), "mask-close": !props.multiple, size: "small", scrollbar: false, onChange: onSelectDlgChange }, vue.createSlots({ default: vue.withCtx(() => [ vue.createVNode(SelectOption_vue_vue_type_script_setup_true_lang, { size: props.size, "wrap-class": props.optionWrapClass, loading: props.loading, class: "o-select-options-dlg", "option-title": props.optionTitle, multiple: props.multiple }, vue.createSlots({ "option-target": vue.withCtx(() => [ vue.createElementVNode( "div", { ref_key: "optionsRef", ref: optionsRef }, null, 512 /* NEED_PATCH */ ) ]), _: 2 /* DYNAMIC */ }, [ vue.renderList(vue.unref(vueUtils.filterSlots)(_ctx.$slots, vue.unref(slot).option.names), (name) => { return { name, fn: vue.withCtx(() => [ vue.renderSlot(_ctx.$slots, name) ]) }; }) ]), 1032, ["size", "wrap-class", "loading", "option-title", "multiple"]) ]), _: 2 /* DYNAMIC */ }, [ props.optionTitle ? { name: "header", fn: vue.withCtx(() => [ vue.createElementVNode( "div", _hoisted_11, vue.toDisplayString(props.optionTitle), 1 /* TEXT */ ) ]), key: "0" } : void 0, props.multiple ? { name: "actions", fn: vue.withCtx(() => [ vue.createVNode(vue.unref(index$4.OButton), { class: "o-dlg-btn", variant: "text", size: "large", onClick: onselectDlgCancelClick }, { default: vue.withCtx(() => [ vue.createTextVNode( vue.toDisplayString(vue.unref(t)("select.cancel")), 1 /* TEXT */ ) ]), _: 1 /* STABLE */ }), vue.createVNode(vue.unref(index$4.OButton), { class: "o-dlg-btn", variant: "text", size: "large", onClick: onselectDlgOkClick }, { default: vue.withCtx(() => [ vue.createTextVNode( vue.toDisplayString(vue.unref(t)("select.confirm")), 1 /* TEXT */ ) ]), _: 1 /* STABLE */ }) ]), key: "1" } : void 0 ]), 1032, ["visible", "before-show", "before-hide", "mask-close", "class"])) : (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 1 }, [ !props.disabled ? (vue.openBlock(), vue.createBlock(vue.unref(index$5.OPopup), { key: 0, visible: isSelecting.value, "onUpdate:visible": _cache[2] || (_cache[2] = ($event) => isSelecting.value = $event), "wrap-class": "o-options-popup", transition: props.transition, "unmount-on-hide": props.unmountOnHide, position: props.optionPosition, wrapper: props.optionsWrapper, target: selectRef.value, trigger: props.trigger, offset: 4, "adjust-min-width": props.optionWidthMode === "min-width", "adjust-width": props.optionWidthMode === "width", "before-show": props.beforeOptionsShow, "before-hide": props.beforeOptionsHide, onChange: onOptionVisibleChange }, { default: vue.withCtx(() => [ vue.createVNode(SelectOption_vue_vue_type_script_setup_true_lang, { size: props.size, "wrap-class": props.optionWrapClass, loading: props.loading, multiple: props.multiple }, vue.createSlots({ "option-target": vue.withCtx(() => [ vue.createElementVNode( "div", { ref_key: "optionsRef", ref: optionsRef }, null, 512 /* NEED_PATCH */ ) ]), _: 2 /* DYNAMIC */ }, [ vue.renderList(vue.unref(vueUtils.filterSlots)(_ctx.$slots, vue.unref(slot).option.names), (name) => { return { name, fn: vue.withCtx(() => [ vue.renderSlot(_ctx.$slots, name) ]) }; }) ]), 1032, ["size", "wrap-class", "loading", "multiple"]) ]), _: 3 /* FORWARDED */ }, 8, ["visible", "transition", "unmount-on-hide", "position", "wrapper", "target", "trigger", "adjust-min-width", "adjust-width", "before-show", "before-hide"])) : vue.createCommentVNode("v-if", true) ], 64 /* STABLE_FRAGMENT */ )) ]), _: 3 /* FORWARDED */ }) ], 6 /* CLASS, STYLE */ ); }; } }); module.exports = _sfc_main;