UNPKG

@vimeo/iris

Version:
115 lines (108 loc) 5.88 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tslib_es6 = require('../../../tslib.es6-3ec409b7.js'); var React = require('react'); var styled = require('styled-components'); var polished = require('polished'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled); function Anchor(_a) { var anchor = _a.anchor, anchorToWindow = _a.anchorToWindow, attach = _a.attach, childRef = _a.childRef, children = _a.children, margin = _a.margin, style = _a.style, props = tslib_es6.__rest(_a, ["anchor", "anchorToWindow", "attach", "childRef", "children", "margin", "style"]); var _b = tslib_es6.__read(React.useState({}), 2), state = _b[0], setState = _b[1]; var onResize = React.useCallback(function () { var childElement = childRef === null || childRef === void 0 ? void 0 : childRef.current; if (!childElement) return; var viewport = anchorToWindow && windowRect(); var childRect = calcRect(childRef); var rect = viewport || calcRect(anchor, window); var _a = remPos({ attach: attach, margin: margin, rect: rect, childRect: childRect, }), top = _a.top, left = _a.left; setState(function (state) { return (tslib_es6.__assign(tslib_es6.__assign({}, state), { top: top, left: left, rect: rect, childRect: childRect })); }); }, [anchor, anchorToWindow, attach, childRef, margin]); // eslint-disable-next-line react-hooks/exhaustive-deps React.useLayoutEffect(function () { return onResize(); }, []); React.useLayoutEffect(function () { var childElement = childRef === null || childRef === void 0 ? void 0 : childRef.current; window.addEventListener('resize', onResize); window.addEventListener('scroll', onResize); childElement === null || childElement === void 0 ? void 0 : childElement.addEventListener('transitionend', onResize); return function () { window.removeEventListener('resize', onResize); window.removeEventListener('scroll', onResize); childElement === null || childElement === void 0 ? void 0 : childElement.removeEventListener('transitionend', onResize); }; }, [childRef, onResize]); React.useLayoutEffect(function () { if (!top && !left) onResize(); }); var top = state.top, left = state.left; var zIndex = useChildZIndex(children); return (React__default["default"].createElement(AnchorStyled, tslib_es6.__assign({ anchorToWindow: anchorToWindow, attach: attach, childRect: state.childRect, children: children, margin: margin, rect: state.rect, style: tslib_es6.__assign(tslib_es6.__assign({}, style), { top: top, left: left, zIndex: zIndex }) }, props))); } function useChildZIndex(children) { var _a; if ((_a = children === null || children === void 0 ? void 0 : children.ref) === null || _a === void 0 ? void 0 : _a.current) { var style = getComputedStyle(children.ref.current); var zIndex = parseInt(style.zIndex); if (zIndex > 0) return zIndex; } return 5000; } function calcRect(ref, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.scrollX, scrollX = _c === void 0 ? 0 : _c, _d = _b.scrollY, scrollY = _d === void 0 ? 0 : _d; if (ref && ref.current) { var _e = ref.current, offsetHeight = _e.offsetHeight, offsetWidth = _e.offsetWidth; var _f = ref.current.getBoundingClientRect(), x = _f.x, y = _f.y; var height = offsetHeight; var left = x + scrollX; var top_1 = y + scrollY; var width = offsetWidth; return { bottom: top_1 + height, height: height, left: left, right: left + width, top: top_1, width: width, }; } return null; } function windowRect() { return { bottom: 0, height: window.innerHeight, left: 0, right: 0, top: 0, width: window.innerWidth, }; } function remPos(_a) { var _b = tslib_es6.__read(_a.attach, 2), a = _b[0], b = _b[1], margin = _a.margin, rect = _a.rect, childRect = _a.childRect; if (!rect || !childRect) return { top: null, left: null }; var top = rect.top + rect.height * (a[0] / 100) - (childRect.height + margin * 2) * (b[0] / 100); var left = rect.left + rect.width * (a[1] / 100) - (childRect.width + margin * 2) * (b[1] / 100); return { top: polished.rem(top <= 0 ? rect.bottom : top), left: polished.rem(left <= 0 ? rect.right : left), }; } var AnchorStyled = styled__default["default"].div(templateObject_2 || (templateObject_2 = tslib_es6.__makeTemplateObject(["\n position: fixed;\n margin: ", ";\n overflow: visible;\n max-width: calc(100vw - 1.5rem) !important;\n\n ", "\n"], ["\n position: fixed;\n margin: ", ";\n overflow: visible;\n max-width: calc(100vw - 1.5rem) !important;\n\n ", "\n"])), function (p) { return polished.rem(p.margin); }, function (p) { return !p.anchorToWindow && styled.css(templateObject_1 || (templateObject_1 = tslib_es6.__makeTemplateObject(["\n position: absolute;\n\n > div {\n max-width: 100%;\n\n > div {\n max-width: 100%;\n\n > * {\n max-width: 100%;\n }\n }\n }\n "], ["\n position: absolute;\n\n > div {\n max-width: 100%;\n\n > div {\n max-width: 100%;\n\n > * {\n max-width: 100%;\n }\n }\n }\n "]))); }); var templateObject_1, templateObject_2; exports.Anchor = Anchor;