vuestic-ui
Version:
Vue 3 UI Framework
118 lines (117 loc) • 3.27 kB
JavaScript
import { computed } from "vue";
import { u as useDebounceFn } from "../../../composables/useDebounce.js";
import { u as useNumericProp } from "../../../composables/useNumericProp.js";
import { u as useEvent } from "../../../composables/useEvent.js";
const isTyping = (e) => {
const target = e.target;
if (!(target.tagName === "INPUT" || target.tagName === "TEXTAREA")) {
return false;
}
if (target.attributes.getNamedItem("readonly")) {
return false;
}
return true;
};
const isReadonlyArray = (arr) => {
return Array.isArray(arr);
};
const useNavigation = (isOpen, anchorRef, contentRef, props) => {
const normalizeTriggerName = (t) => {
t = t.replace(/-/g, "").toLowerCase();
if (t === "space") {
return " ";
}
if (t === "rightclick") {
return "contextmenu";
}
return t;
};
const normalizedTriggers = computed(() => {
if (isReadonlyArray(props.trigger)) {
return props.trigger.map((t) => normalizeTriggerName(t));
}
return [normalizeTriggerName(props.trigger)];
});
useEvent("keydown", (e) => {
if (props.disabled) {
return;
}
if (e.key === "Escape" && isOpen.value) {
isOpen.value = false;
e.preventDefault();
}
if (isTyping(e)) {
return;
}
if (normalizedTriggers.value.includes(normalizeTriggerName(e.key))) {
isOpen.value = !isOpen.value;
e.preventDefault();
}
}, anchorRef);
useEvent("keydown", (e) => {
if (props.disabled) {
return;
}
if (e.key === "Escape" && isOpen.value) {
isOpen.value = false;
e.preventDefault();
}
}, contentRef);
useEvent(["click", "contextmenu", "dblclick"], (e) => {
if (props.disabled) {
return;
}
if (isTyping(e)) {
return;
}
if (normalizedTriggers.value.includes(normalizeTriggerName(e.type))) {
e.preventDefault();
if (isOpen.value && props.closeOnAnchorClick) {
isOpen.value = false;
if (props.cursor) {
setTimeout(() => {
isOpen.value = true;
}, 16);
}
} else {
isOpen.value = true;
}
}
}, anchorRef);
useEvent(["click", "contextmenu", "dblclick"], (e) => {
if (props.closeOnContentClick) {
isOpen.value = false;
}
}, contentRef);
const { debounced: debounceHover, cancel: cancelHoverDebounce } = useDebounceFn(useNumericProp("hoverOverTimeout"));
const { debounced: debounceUnHover, cancel: cancelUnHoverDebounce } = useDebounceFn(useNumericProp("hoverOutTimeout"));
const onMouseHover = (e) => {
if (props.disabled) {
return;
}
if (!normalizedTriggers.value.includes("hover")) {
return;
}
if (e.type === "mouseleave") {
cancelHoverDebounce();
if (!props.isContentHoverable) {
isOpen.value = false;
return;
}
debounceUnHover(() => {
isOpen.value = false;
});
} else {
cancelUnHoverDebounce();
debounceHover(() => {
isOpen.value = true;
});
}
};
useEvent(["mouseleave", "mouseenter"], onMouseHover, anchorRef);
useEvent(["mouseleave", "mouseenter"], onMouseHover, contentRef);
};
export {
useNavigation as u
};
//# sourceMappingURL=useDropdownNavigation.js.map