UNPKG

@smart-react-components/ui

Version:
214 lines (203 loc) 7.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateCSSTransitionClasses = exports.calculatePosition = void 0; const types_1 = require("../types"); const dom_1 = require("./dom"); /** * Calculates the box and arrow position based on X axis. */ const calculatePositionBasedOnXAxis = (triggerRect, boxRect, headerRect, pos, space, windowWidth, windowHeight) => { var _a; const [arrowWidth, arrowHeight] = getArrowSize(pos); let left; let arrowLeft; let overflow; if (pos === types_1.Position.RIGHT) { left = triggerRect.left + triggerRect.width + space + arrowWidth; overflow = Math.abs(Math.min(windowWidth - (left + boxRect.width), 0)); arrowLeft = (arrowWidth - 2) * -1; } else { left = triggerRect.left - (boxRect.width + arrowWidth + space); overflow = Math.abs(Math.min(left, 0)); arrowLeft = boxRect.width - 2; } const top = headerRect ? (triggerRect.top + (triggerRect.height / 2) - (headerRect.height + (arrowHeight / 2))) : (triggerRect.top + (triggerRect.height / 2) - (boxRect.height / 2)); const arrowTop = (_a = headerRect === null || headerRect === void 0 ? void 0 : headerRect.height) !== null && _a !== void 0 ? _a : ((boxRect.height - arrowHeight) / 2); const isArrowInHeader = headerRect && arrowTop + (arrowHeight * 2) < headerRect.height; if (top < 0) { overflow += Math.abs(top); } else { overflow += Math.abs(Math.min(windowHeight - (top + boxRect.height), 0)); } return { arrowStyle: ` left: ${arrowLeft}px; top: ${arrowTop}px; `, isArrowInHeader, overflow, pos, style: ` left: ${left}px; top: ${top}px; `, }; }; /** * Calculates the box and arrow position based on Y axis. */ const calculatePositionBasedOnYAxis = (triggerRect, boxRect, headerRect, pos, space, windowWidth, windowHeight) => { const [arrowWidth, arrowHeight] = getArrowSize(pos); let arrowTop; let top; let overflow; if (pos === types_1.Position.TOP) { top = triggerRect.top - (boxRect.height + arrowHeight + space); overflow = Math.abs(Math.min(top, 0)); arrowTop = boxRect.height - 1; } else { top = triggerRect.top + triggerRect.height + space + arrowHeight; overflow = Math.abs(Math.min(windowHeight - (top + boxRect.height), 0)); arrowTop = (arrowHeight - 1) * -1; } const left = (triggerRect.left) + (triggerRect.width / 2) - (boxRect.width / 2); const arrowLeft = (boxRect.width / 2) - (arrowWidth / 2); if (left < 0) { overflow += Math.abs(left); } else { overflow += Math.abs(Math.min(windowWidth - (left + boxRect.width), 0)); } return { arrowStyle: ` left: ${arrowLeft}px; top: ${arrowTop}px; `, isArrowInHeader: headerRect && pos === types_1.Position.BOTTOM, overflow, pos, style: ` left: ${left}px; top: ${top}px; `, }; }; /** * Calculates the box and arrow position. */ const calculatePosition = (triggerEl, boxEl, headerEl, arrowEl, position, space) => { if (!boxEl) { return; } const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; const triggerRect = Object.assign(Object.assign({}, triggerEl.getBoundingClientRect()), (0, dom_1.calculateShownPart)(triggerEl)); if (triggerRect.width <= 0 || triggerRect.height <= 0) { boxEl.setAttribute('style', 'pointer-events: none; visibility: hidden;'); return; } boxEl.removeAttribute('style'); const boxRect = boxEl.getBoundingClientRect(); const headerRect = headerEl === null || headerEl === void 0 ? void 0 : headerEl.getBoundingClientRect(); let result; for (let i = 0, p; i < 4; i++) { switch (i) { case 0: p = position; break; case 1: case 3: if (p & (types_1.Position.LEFT | types_1.Position.TOP)) { p <<= 1; } else { p >>= 1; } break; case 2: if (p & (types_1.Position.LEFT | types_1.Position.RIGHT)) { p = types_1.Position.TOP; } else { p = types_1.Position.LEFT; } break; } const r = p & (types_1.Position.LEFT | types_1.Position.RIGHT) ? calculatePositionBasedOnXAxis(triggerRect, boxRect, headerRect, p, space, windowWidth, windowHeight) : calculatePositionBasedOnYAxis(triggerRect, boxRect, headerRect, p, space, windowWidth, windowHeight); if (!result || r.overflow < result.overflow) { result = r; } if (result.overflow === 0) { break; } } boxEl.setAttribute('style', result.style); boxEl.setAttribute('data-src-position', String(result.pos)); arrowEl.setAttribute('style', result.arrowStyle); arrowEl.setAttribute('viewBox', getArrowViewBox(result.pos)); arrowEl.setAttribute('data-src-position', String(result.pos)); arrowEl.setAttribute('data-arrow-header', String(result.isArrowInHeader)); }; exports.calculatePosition = calculatePosition; /** * Generates CSS transition classes. */ const generateCSSTransitionClasses = (key, duration) => ` &.src-${key}-show-active, &.src-${key}-hide-active { transition: ${duration}ms 0s ease-in-out; transition-property: transform, opacity; } &.src-${key}-show { opacity: 0; &[data-src-position="${types_1.Position.LEFT}"] { transform: translateX(-30px); } &[data-src-position="${types_1.Position.RIGHT}"] { transform: translateX(30px); } &[data-src-position="${types_1.Position.TOP}"] { transform: translateY(-30px); } &[data-src-position="${types_1.Position.BOTTOM}"] { transform: translateY(-30px); } } &.src-${key}-show-active { opacity: 1; &[data-src-position="${types_1.Position.LEFT}"], &[data-src-position="${types_1.Position.RIGHT}"] { transform: translateX(0); } &[data-src-position="${types_1.Position.TOP}"], &[data-src-position="${types_1.Position.BOTTOM}"] { transform: translateY(0); } } &.src-${key}-hide { opacity: 1; &[data-src-position="${types_1.Position.LEFT}"], &[data-src-position="${types_1.Position.RIGHT}"] { transform: translateX(0); } &[data-src-position="${types_1.Position.TOP}"], &[data-src-position="${types_1.Position.BOTTOM}"] { transform: translateY(0); } } &.src-${key}-hide-active { opacity: 0; &[data-src-position="${types_1.Position.LEFT}"] { transform: translateX(-30px); } &[data-src-position="${types_1.Position.RIGHT}"] { transform: translateX(30px); } &[data-src-position="${types_1.Position.TOP}"] { transform: translateY(-30px); } &[data-src-position="${types_1.Position.BOTTOM}"] { transform: translateY(-30px); } } `; exports.generateCSSTransitionClasses = generateCSSTransitionClasses; /** * Returns width and height attributes depending on position */ const getArrowSize = (position) => position & (types_1.Position.LEFT | types_1.Position.RIGHT) ? [10, 15] : [15, 10]; /** * Returns viewBox attribute depending on position */ const getArrowViewBox = (position) => position & (types_1.Position.LEFT | types_1.Position.RIGHT) ? '0 0 252.8 378.5' : '0 0 377.3 251.9';