@platform/react
Version:
React refs and helpers.
114 lines (113 loc) • 4.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResizeObserver = exports.DEFAULT = void 0;
var ramda_1 = require("ramda");
var rxjs_1 = require("rxjs");
var operators_1 = require("rxjs/operators");
var RECT = {
x: -1,
y: -1,
width: -1,
height: -1,
top: -1,
right: -1,
bottom: -1,
left: -1,
};
exports.DEFAULT = { RECT: RECT };
var ResizeObserver = function (el) {
var root$ = new rxjs_1.Subject();
var dispose$ = new rxjs_1.Subject();
var items = [];
var findByTarget = function (el) { return items.find(function (item) { return item.element.target === el; }); };
var createItem = function (target) {
var item$ = new rxjs_1.Subject();
var dispose$ = new rxjs_1.Subject();
var dispose = function () {
items = items.filter(function (item) { return item.element.target !== target; });
item$.complete();
dispose$.next();
dispose$.complete();
dom.unobserve(target);
};
api.dispose$.subscribe(function () { return dispose(); });
var rect = exports.DEFAULT.RECT;
var $ = item$.pipe((0, operators_1.takeUntil)(dispose$), (0, operators_1.observeOn)(rxjs_1.animationFrameScheduler));
var element = {
$: $,
target: target,
dispose$: dispose$.asObservable(),
get rect() {
return rect;
},
refresh: function () {
var rect = target.getBoundingClientRect();
item.next(toSizeEvent(target, rect));
return rect;
},
dispose: dispose,
};
var item = { element: element, next: function (e) { return item$.next(e); } };
item$
.pipe((0, operators_1.filter)(function (e) { return e.type === 'ResizeObserver/size'; }), (0, operators_1.map)(function (e) { return e; }), (0, operators_1.distinctUntilChanged)(function (prev, next) { return (0, ramda_1.equals)(prev.payload.rect, next.payload.rect); }))
.subscribe(function (e) {
rect = e.payload.rect;
root$.next(e);
});
dom.observe(target);
items.push(item);
return item;
};
var toSizeEvent = function (target, rect) {
var x = rect.x, y = rect.y, width = rect.width, height = rect.height, top = rect.top, right = rect.right, bottom = rect.bottom, left = rect.left;
return {
type: 'ResizeObserver/size',
payload: {
target: target,
rect: { x: x, y: y, width: width, height: height, top: top, right: right, bottom: bottom, left: left },
},
};
};
var dom = new window.ResizeObserver(function (entries) {
entries.forEach(function (e) {
var target = e.target;
var item = findByTarget(target);
if (item) {
var event_1 = toSizeEvent(item.element.target, e.contentRect);
item.next(event_1);
}
});
});
var api = {
$: root$.pipe((0, operators_1.takeUntil)(dispose$)),
dispose$: dispose$.asObservable(),
get elements() {
return items.map(function (item) { return item.element; });
},
dispose: function () {
items.forEach(function (item) { return item.element.dispose(); });
dom.disconnect();
dispose$.next();
dispose$.complete();
},
watch: function (target) {
var _a;
return ((_a = findByTarget(target)) === null || _a === void 0 ? void 0 : _a.element) || createItem(target).element;
},
unwatch: function (target) {
var _a;
(_a = findByTarget(target)) === null || _a === void 0 ? void 0 : _a.element.dispose();
},
refresh: function (target) {
var _a;
if (target)
(_a = findByTarget(target)) === null || _a === void 0 ? void 0 : _a.element.refresh();
if (!target)
api.elements.forEach(function (el) { return el.refresh(); });
},
};
if (el)
api.watch(el);
return api;
};
exports.ResizeObserver = ResizeObserver;