@onesy/ui-react
Version:
UI for React
90 lines (85 loc) • 3.56 kB
JavaScript
"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;