UNPKG

@arco-design/web-vue

Version:

Arco Design Vue 2.0: A Vue.js 3 UI Library

195 lines (194 loc) 5.22 kB
import { ref, watch, nextTick, provide, reactive } from "vue"; import { getRelativeRect } from "../../_utils/dom.js"; import { useOptions } from "./use-options.js"; import { getKeyDownHandler, KEYBOARD_KEY } from "../../_utils/keyboard.js"; import { selectInjectionKey } from "../context.js"; const useSelect = ({ multiple, options, extraOptions, inputValue, filterOption, showExtraOptions, component, valueKey, fieldNames, loading, popupVisible, valueKeys, dropdownRef, optionRefs, virtualListRef, onSelect, onPopupVisibleChange, enterToOpen = true, defaultActiveFirstOption }) => { const { validOptions, optionInfoMap, validOptionInfos, enabledOptionKeys, getNextSlotOptionIndex, addSlotOptionInfo, removeSlotOptionInfo } = useOptions({ options, extraOptions, inputValue, filterOption, showExtraOptions, valueKey, fieldNames }); const activeKey = ref(); watch(enabledOptionKeys, (enabledKeys) => { if (!activeKey.value || !enabledKeys.includes(activeKey.value)) { activeKey.value = enabledKeys[0]; } }); const setActiveKey = (key) => { activeKey.value = key; }; const getNextActiveKey = (direction) => { const _length = enabledOptionKeys.value.length; if (_length === 0) { return void 0; } if (!activeKey.value) { if (direction === "down") { return enabledOptionKeys.value[0]; } return enabledOptionKeys.value[_length - 1]; } const activeIndex = enabledOptionKeys.value.indexOf(activeKey.value); const nextIndex = (_length + activeIndex + (direction === "up" ? -1 : 1)) % _length; return enabledOptionKeys.value[nextIndex]; }; const scrollIntoView = (key) => { var _a, _b; if (virtualListRef == null ? void 0 : virtualListRef.value) { virtualListRef.value.scrollTo({ key }); } const optionInfo = optionInfoMap.get(key); const wrapperEle = (_a = dropdownRef == null ? void 0 : dropdownRef.value) == null ? void 0 : _a.wrapperRef; const optionEle = (_b = optionRefs == null ? void 0 : optionRefs.value[key]) != null ? _b : optionInfo == null ? void 0 : optionInfo.ref; if (!wrapperEle || !optionEle) { return; } if (wrapperEle.scrollHeight === wrapperEle.offsetHeight) { return; } const optionRect = getRelativeRect(optionEle, wrapperEle); const wrapperScrollTop = wrapperEle.scrollTop; if (optionRect.top < 0) { wrapperEle.scrollTo(0, wrapperScrollTop + optionRect.top); } else if (optionRect.bottom < 0) { wrapperEle.scrollTo(0, wrapperScrollTop - optionRect.bottom); } }; watch(popupVisible, (visible) => { var _a; if (visible) { const current = valueKeys.value[valueKeys.value.length - 1]; let _activeKey = ((_a = defaultActiveFirstOption == null ? void 0 : defaultActiveFirstOption.value) != null ? _a : true) ? enabledOptionKeys.value[0] : void 0; if (enabledOptionKeys.value.includes(current)) { _activeKey = current; } if (_activeKey !== activeKey.value) { activeKey.value = _activeKey; } nextTick(() => { if (activeKey.value) { scrollIntoView(activeKey.value); } }); } }); const handleKeyDown = getKeyDownHandler( /* @__PURE__ */ new Map([ [ KEYBOARD_KEY.ENTER, (e) => { if (!(loading == null ? void 0 : loading.value) && !e.isComposing) { if (popupVisible.value) { if (activeKey.value) { onSelect(activeKey.value, e); e.preventDefault(); } } else if (enterToOpen) { onPopupVisibleChange(true); e.preventDefault(); } } } ], [ KEYBOARD_KEY.ESC, (e) => { if (popupVisible.value) { onPopupVisibleChange(false); e.preventDefault(); } } ], [ KEYBOARD_KEY.ARROW_DOWN, (e) => { if (popupVisible.value) { const next = getNextActiveKey("down"); if (next) { activeKey.value = next; scrollIntoView(next); } e.preventDefault(); } } ], [ KEYBOARD_KEY.ARROW_UP, (e) => { if (popupVisible.value) { const next = getNextActiveKey("up"); if (next) { activeKey.value = next; scrollIntoView(next); } e.preventDefault(); } } ] ]) ); provide( selectInjectionKey, reactive({ multiple, valueKey, inputValue, filterOption, component, valueKeys, activeKey, setActiveKey, onSelect, getNextSlotOptionIndex, addSlotOptionInfo, removeSlotOptionInfo }) ); return { validOptions, optionInfoMap, validOptionInfos, enabledOptionKeys, activeKey, setActiveKey, addSlotOptionInfo, removeSlotOptionInfo, getNextActiveKey, scrollIntoView, handleKeyDown }; }; export { useSelect };