UNPKG

bootstrap-vue-3

Version:

Early (but lovely) implementation of Vue 3, Bootstrap 5 and Typescript

120 lines (100 loc) 4.08 kB
import {AnimationFrame, DOCUMENT} from '../types/safeTypes' import {HAS_WINDOW_SUPPORT} from '../utils/env' import {Comment, Slot, VNode} from 'vue' import {from as arrayFrom} from './array' import {toString} from './stringUtils' export const isElement = (el: HTMLElement): boolean => !!(el && el.nodeType === Node.ELEMENT_NODE) export const getBCR = (el: HTMLElement) => (isElement(el) ? el.getBoundingClientRect() : null) export const getActiveElement = (excludes = []): Element | null => { const {activeElement} = document return activeElement && !excludes.some((el: HTMLElement) => el === activeElement) ? activeElement : null } export const isActiveElement = (el: HTMLElement): boolean => isElement(el) && el === getActiveElement() export const attemptFocus = (el: HTMLElement, options = {}): boolean => { try { el.focus(options) } catch (e) { console.error(e) } return isActiveElement(el) } // Attempt to blur an element, and return `true` if successful export const attemptBlur = (el: HTMLElement): boolean => { try { el.blur() } catch (e) { console.error(e) } return !isActiveElement(el) } export const getStyle = (el: HTMLElement, prop: string) => prop && isElement(el) ? el.getAttribute(prop) || null : null export const contains = (parent: Node, child: Node): boolean => parent.contains(child) export const isVisible = (el: HTMLElement): boolean => { //if (!isElement(el) || !el.parentNode || !contains(DOCUMENT.body, el)) { // Note this can fail for shadow dom elements since they // are not a direct descendant of document.body //return false //} if (getStyle(el, 'display') === 'none') { // We do this check to help with vue-test-utils when using v-show /* istanbul ignore next */ return false } // All browsers support getBoundingClientRect(), except JSDOM as it returns all 0's for values :( // So any tests that need isVisible will fail in JSDOM // Except when we override the getBCR prototype in some tests const bcr = getBCR(el) return !!(bcr && bcr.height > 0 && bcr.width > 0) } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const isEmptySlot = (slot: Slot | undefined, data?: any) => !slot || slot(data).filter((vnode: VNode) => vnode.type !== Comment).length < 1 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const offset = (el: HTMLElement) => { const _offset = {top: 0, left: 0} if (!isElement(el) || el.getClientRects().length === 0) { return _offset } const bcr = getBCR(el) if (bcr) { const win = el.ownerDocument.defaultView _offset.top = bcr.top + (win?.pageYOffset || 0) _offset.left = bcr.left + (win?.pageXOffset || 0) } return _offset } // Select a single element, returns `null` if not found export const select = (selector: any, root: any) => (isElement(root) ? root : DOCUMENT).querySelector(selector) || null export const selectAll = (selector: any, root: any) => arrayFrom((isElement(root) ? root : DOCUMENT).querySelectorAll(selector)) export const getAttr = (el: HTMLElement, attr: string): string | null => attr && isElement(el) ? el.getAttribute(attr) : null export const setAttr = (el: HTMLElement, attr: string, value: string): void => { if (attr && isElement(el)) { el.setAttribute(attr, value) } } // Remove an attribute from an element export const removeAttr = (el: HTMLElement, attr: string): void => { if (attr && isElement(el)) { el.removeAttribute(attr) } } export const isTag = (tag: any, name: any): boolean => toString(tag).toLowerCase() === toString(name).toLowerCase() export const requestAF: AnimationFrame = HAS_WINDOW_SUPPORT ? window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || // Fallback, but not a true polyfill // Only needed for Opera Mini /* istanbul ignore next */ ((cb) => setTimeout(cb, 16)) : (cb) => setTimeout(cb, 0)