@amaui/ui-react
Version:
UI for React
81 lines (80 loc) • 3.73 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const utils_1 = require("@amaui/utils");
const useVisible = (props) => {
const { element, visibleDefault, options, addClasses, classes = {
in: 'amaui-visible'
}, addStyles, styles } = props;
const [response, setResponse] = react_1.default.useState({ visible: visibleDefault !== undefined ? visibleDefault : false });
const [root, setRoot] = react_1.default.useState();
const refs = {
root: react_1.default.useRef(root),
response: react_1.default.useRef(response),
addClasses: react_1.default.useRef(addClasses),
classes: react_1.default.useRef(classes),
addStyles: react_1.default.useRef(addStyles),
styles: react_1.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_1.default.useEffect(() => {
const rootNew = element;
setRoot(rootNew);
refs.root.current = rootNew;
}, [element]);
const method = react_1.default.useCallback((entries) => {
entries.forEach(entry => {
var _a, _b, _c;
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) {
const visibleClass = ((_a = refs.classes.current) === null || _a === void 0 ? void 0 : _a.in) || 'amaui-visible';
if (responseNew.visible)
target.classList.add(visibleClass);
else
target.classList.remove(visibleClass);
}
// styles
if (refs.addStyles.current) {
const visibleStyles = ((_b = refs.styles.current) === null || _b === void 0 ? void 0 : _b.in) || {};
const notVisibleStyles = ((_c = refs.styles.current) === null || _c === void 0 ? void 0 : _c.out) || {};
if (responseNew.visible)
Object.keys(visibleStyles).forEach(item => target.style[item] = visibleStyles[item]);
else
Object.keys(notVisibleStyles).forEach(item => target.style[item] = notVisibleStyles[item]);
}
setResponse(responseNew);
});
}, []);
react_1.default.useEffect(() => {
if (!((0, utils_1.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_1.hash)(options === null || options === void 0 ? void 0 : options.threshold)]);
return response;
};
useVisible.displayName = 'amaui-UseVisible';
exports.default = useVisible;
;