birdpaper-ui
Version:
一个通用的 vue3 UI组件库。A common vue3 UI component library.
101 lines (100 loc) • 2.98 kB
JavaScript
import { defineComponent, ref, computed, provide, watch } from "vue";
import { selectInjectionKey } from "./type.js";
import { vClickOutside } from "../../directives/clickOutside.js";
import BpInput from "../../input/src/input.vue.js";
import { IconCloseLine, IconArrowDownSLine, IconArrowUpSLine } from "birdpaper-icon";
import { getAllElements } from "../../utils/dom.js";
import { useSelect } from "./select.js";
const _sfc_main = defineComponent({
name: "Select",
components: { BpInput, IconCloseLine },
directives: { clickOutside: vClickOutside },
props: {
/** 绑定值 Binding value */
modelValue: { type: [String, Number], default: "" },
/** 是否禁用 Disabled or not */
disabled: { type: Boolean, default: false },
/** 占位提示文字 The placeholder text */
placeholder: { type: String, default: "" },
/** 是否允许清空 Clearable or not */
clearable: { type: Boolean, default: false }
},
emits: ["update:modelValue", "change"],
setup(props, { emit, slots }) {
const name = "bp-select";
const inpRef = ref();
const showClear = ref(false);
const hasOptions = computed(() => {
var _a;
const children = getAllElements((_a = slots.default) == null ? void 0 : _a.call(slots), true).filter((item) => item.type["name"] === "BpOption");
return children.length !== 0;
});
const { currentSelect, valueMap, isFocus } = useSelect(slots);
provide(selectInjectionKey, {
modelValue: props.modelValue,
currentSelect,
onSelect: (v, payload) => {
currentSelect.value = v;
currentSelect.label = payload.label;
emit("update:modelValue", currentSelect.value);
emit("change", currentSelect.value);
isFocus.value = false;
}
});
const clsName = computed(() => {
let cls = [name];
if (isFocus.value)
cls.push(`${name}-focus`);
if (props.disabled)
cls.push(`${name}-disabled`);
return cls;
});
const setValue = () => {
currentSelect.value = props.modelValue;
currentSelect.label = valueMap.value[currentSelect.value];
};
const handleMouseEnter = () => {
if (!props.clearable)
return;
showClear.value = true;
};
const handleMouseLeave = () => {
if (!props.clearable)
return;
showClear.value = false;
};
const handleClear = () => {
currentSelect.value = "";
currentSelect.label = "";
};
watch(
() => valueMap.value,
() => setValue(),
{
immediate: true,
deep: true
}
);
watch(
() => props.modelValue,
() => setValue()
);
return {
name,
inpRef,
hasOptions,
currentSelect,
isFocus,
clsName,
handleMouseEnter,
handleMouseLeave,
showClear,
handleClear,
IconArrowDownSLine,
IconArrowUpSLine
};
}
});
export {
_sfc_main as default
};