@coreui/vue-pro
Version:
UI Components Library for Vue.js
111 lines (107 loc) • 3.43 kB
JavaScript
;
var vue = require('vue');
var usePopper = require('./usePopper.js');
var isRTL = require('../utils/isRTL.js');
const useDropdownWithPopper = (popperConfig) => {
// References to the dropdown elements
const dropdownRefElement = vue.ref(null);
const dropdownMenuElement = vue.ref(null);
// Reactive state to control dropdown visibility
const isOpen = vue.ref(false);
// Popper.js integration
const { popper, initPopper, destroyPopper } = usePopper.usePopper();
// Computed Popper configuration based on RTL and user-provided settings
const _popperConfig = vue.computed(() => ({
placement: (isRTL.default(dropdownRefElement.value) ? 'bottom-end' : 'bottom-start'),
modifiers: [
{
name: 'preventOverflow',
options: {
boundary: 'clippingParents',
},
},
{
name: 'offset',
options: {
offset: [0, 2],
},
},
],
...popperConfig,
}));
// Methods to control dropdown state
const closeDropdown = () => {
isOpen.value = false;
};
const openDropdown = () => {
isOpen.value = true;
};
const toggleDropdown = () => {
isOpen.value = !isOpen.value;
};
const updatePopper = () => {
if (popper) {
popper.update();
}
};
// Event handlers
const handleKeyUp = (event) => {
if (event.key === 'Escape') {
isOpen.value = false;
return;
}
if (event.key === 'Tab') {
const activeElement = document.activeElement;
if (dropdownRefElement.value?.contains(activeElement) ||
dropdownMenuElement.value?.contains(activeElement)) {
return;
}
isOpen.value = false;
}
};
const handleMouseUp = (event) => {
const target = event.target;
if (dropdownMenuElement.value?.contains(target) || dropdownRefElement.value?.contains(target)) {
return;
}
isOpen.value = false;
};
// Utility functions to manage event listeners
const addEventListeners = () => {
window.addEventListener('mouseup', handleMouseUp);
window.addEventListener('keyup', handleKeyUp);
};
const removeEventListeners = () => {
window.removeEventListener('mouseup', handleMouseUp);
window.removeEventListener('keyup', handleKeyUp);
};
// Watcher to handle side effects when `isOpen` changes
vue.watch(isOpen, (open) => {
if (open) {
addEventListeners();
if (dropdownRefElement.value && dropdownMenuElement.value) {
initPopper(dropdownRefElement.value, dropdownMenuElement.value, _popperConfig.value);
}
}
else {
removeEventListeners();
destroyPopper();
}
});
// Cleanup on component unmount
vue.onUnmounted(() => {
removeEventListeners();
destroyPopper();
});
return {
dropdownRefElement,
dropdownMenuElement,
isOpen,
closeDropdown,
openDropdown,
toggleDropdown,
updatePopper,
};
};
exports.useDropdownWithPopper = useDropdownWithPopper;
//# sourceMappingURL=useDropdownWithPopper.js.map