UNPKG

@onesy/ui-react

Version:
90 lines (85 loc) 3.56 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireDefault(require("react")); var _utils = require("@onesy/utils"); const useVisible = props => { const { element, visibleDefault, options, addClasses, classes = { in: 'onesy-visible' }, addStyles, styles } = props; const [response, setResponse] = _react.default.useState({ visible: visibleDefault !== undefined ? visibleDefault : false }); const [root, setRoot] = _react.default.useState(); const refs = { root: _react.default.useRef(root), response: _react.default.useRef(response), addClasses: _react.default.useRef(addClasses), classes: _react.default.useRef(classes), addStyles: _react.default.useRef(addStyles), styles: _react.default.useRef(styles) }; refs.root.current = root; refs.response.current = response; refs.addClasses.current = addClasses; refs.classes.current = classes; refs.addStyles.current = addStyles; refs.styles.current = styles; // Root _react.default.useEffect(() => { const rootNew = element; setRoot(rootNew); refs.root.current = rootNew; }, [element]); const method = entries => { entries.forEach(entry => { const properties = ['boundingClientRect', 'intersectionRatio', 'intersectionRect', 'isIntersecting', 'isVisible', 'rootBounds', 'target', 'time']; const responseNew = { visible: !!entry.isIntersecting, percentage: entry.intersectionRatio }; properties.forEach(property => responseNew[property] = entry[property]); const target = entry.target; // classes if (refs.addClasses.current) { var _refs$classes$current; const visibleClass = ((_refs$classes$current = refs.classes.current) === null || _refs$classes$current === void 0 ? void 0 : _refs$classes$current.in) || 'onesy-visible'; if (responseNew.visible) target.classList.add(visibleClass);else target.classList.remove(visibleClass); } // styles if (refs.addStyles.current) { var _refs$styles$current, _refs$styles$current2; const visibleStyles = ((_refs$styles$current = refs.styles.current) === null || _refs$styles$current === void 0 ? void 0 : _refs$styles$current.in) || {}; const notVisibleStyles = ((_refs$styles$current2 = refs.styles.current) === null || _refs$styles$current2 === void 0 ? void 0 : _refs$styles$current2.out) || {}; if (responseNew.visible) Object.keys(visibleStyles).forEach(item => target.style[item] = visibleStyles[item]);else Object.keys(notVisibleStyles).forEach(item_0 => target.style[item_0] = notVisibleStyles[item_0]); } setResponse(responseNew); }); }; _react.default.useEffect(() => { if (!((0, _utils.isEnvironment)('browser') && 'IntersectionObserver' in window)) return; // Add new observer listener const observer = new IntersectionObserver(method, options); if (root) { observer.observe(root); } return () => { // Clean up observer.disconnect(); }; }, [root, options === null || options === void 0 ? void 0 : options.root, options === null || options === void 0 ? void 0 : options.rootMargin, (0, _utils.hash)(options === null || options === void 0 ? void 0 : options.threshold)]); return response; }; useVisible.displayName = 'onesy-UseVisible'; var _default = exports.default = useVisible;