UNPKG

vuestic-ui

Version:
85 lines (84 loc) 2.95 kB
import { computed, ref } from "vue"; import { offset, flip, shift, size, useFloating, autoUpdate } from "@floating-ui/vue"; import { u as usePlacementAliases } from "../../../composables/usePlacementAliases.js"; const useDropdown = (anchorComputed, floating, target, options) => { const placementComputed = computed(() => { const { position, align } = usePlacementAliases({ placement: options.value.placement }); return `${position.value}-${align.value}`; }); const offsetComputed = computed(() => { const dropdownOffset = options.value.offset; const result = { mainAxis: 0, crossAxis: 0 }; if (Array.isArray(dropdownOffset)) { result.mainAxis = dropdownOffset[0]; result.crossAxis = dropdownOffset[1]; } if (typeof dropdownOffset === "number") { result.mainAxis = dropdownOffset; } return result; }); const middlewareComputed = computed(() => { const { autoPlacement, stickToEdges, keepAnchorWidth, verticalScrollOnOverflow } = options.value; const result = [ offset(offsetComputed.value) ]; if (autoPlacement) { result.push( // boundary doesn't work with ssr (trying to access document) flip({ boundary: target.value }) ); } if (stickToEdges) { result.push( shift() ); } if (keepAnchorWidth || verticalScrollOnOverflow) { result.push(size({ apply({ elements, availableHeight }) { if (keepAnchorWidth) { const reference = elements.reference; const availableWidth = reference.getBoundingClientRect().width; Object.assign(elements.floating.style, { // Don't set width here, because some plugin applies width 100% and it breaks layout maxWidth: `${availableWidth}px`, minWidth: `${availableWidth}px` }); } if (verticalScrollOnOverflow) { Object.assign(elements.floating.style, { maxHeight: `${availableHeight}px` }); } } })); } return result; }); const { floatingStyles, isPositioned } = typeof document === "undefined" ? { floatingStyles: {}, isPositioned: ref(false) } : useFloating(anchorComputed, floating, { placement: placementComputed, whileElementsMounted: autoUpdate, middleware: middlewareComputed, transform: true }); return { // Because floating ui by default set top and left to 0 before position calculated, dropdown jumps to the left top corner // If user wants to make focus on el as soon as Dropdown is opened, page will be scrolled on the left top corner floatingStyles: computed(() => { if (!isPositioned.value) { return { position: "fixed" }; } return floatingStyles.value; }), isPositioned }; }; export { useDropdown as u }; //# sourceMappingURL=useDropdown.js.map