UNPKG

@coreui/vue-pro

Version:

UI Components Library for Vue.js

110 lines (99 loc) 3.1 kB
import { defineComponent, h, onMounted, nextTick, ref, PropType, Ref } from 'vue' import { CSpinner } from '../spinner' const CElementCover = defineComponent({ name: 'CElementCover', props: { /** * Array of custom boundaries. Use to create custom cover area (instead of parent element area). Area is defined by four sides: 'top', 'bottom', 'right', 'left'. If side is not defined by any custom boundary it is equal to parent element boundary. Each custom boundary is object with keys: * - sides (array) - select boundaries of element to define boundaries. Sides names: 'top', 'bottom', 'right', 'left'. * - query (string) - query used to get element which define boundaries. Search will be done only inside parent element, by parent.querySelector(query) function. [docs] * * @type {sides: string[], query: string}[] */ boundaries: Array as PropType<{ sides: string[]; query: string }[]>, /** * Opacity of the cover. [docs] * * @type number */ opacity: { type: Number, default: 0.4, }, }, /** * Location for custom content. * * @slot default */ setup(props, { slots }) { const elementCoverRef = ref() as Ref<HTMLElement> const customBoundaries = ref({}) const getCustomBoundaries = () => { if (!props.boundaries || elementCoverRef === null) { return {} } const parent = elementCoverRef.value.parentElement if (!parent) { return {} } const parentCoords: {[key: string]: any} = parent.getBoundingClientRect() const customBoundaries: {[key: string]: string} = {} props.boundaries.forEach(({ sides, query }) => { const element = parent.querySelector(query) if (!element || !sides) { return } const coords: {[key: string]: any} = element.getBoundingClientRect() sides.forEach((side) => { const sideMargin = Math.abs(coords[side] - parentCoords[side]) customBoundaries[side] = `${sideMargin}px` }) }) return customBoundaries } const containerCoords = { top: 0, left: 0, right: 0, bottom: 0, } const coverStyles = { ...containerCoords, position: 'absolute', 'z-index': 2, 'background-color': `rgba(255,255,255,${props.opacity})`, } onMounted(() => { nextTick(() => { customBoundaries.value = getCustomBoundaries() }) }) return () => h( 'div', { style: { ...coverStyles, ...customBoundaries.value }, ref: elementCoverRef, }, h( 'div', { style: { position: 'absolute', top: '50%', left: '50%', transform: 'translateX(-50%) translateY(-50%)', }, }, slots.default ? slots.default() : h(CSpinner, { variant: 'grow', color: 'primary', }), ), ) }, }) export { CElementCover }