igniteui-react-core
Version:
Ignite UI React Core.
104 lines (103 loc) • 4 kB
JavaScript
import * as React from "react";
export class ContentChildrenManager {
getChildren(propChildren) {
let children = [];
React.Children.forEach(propChildren, (ch) => {
let key = this._getPropsKey(ch);
if (key === undefined) {
throw new Error("each child must have a unique key or name property");
}
if (typeof ch.type === "string") {
// this is a HTML element, not a React Component
children.push(React.cloneElement(ch, {
key: key
}));
}
else if (!ch.props.name) {
children.push(React.cloneElement(ch, {
key: key,
name: key,
ref: this.getChildRef,
originalRef: ch.ref
}));
}
else {
children.push(React.cloneElement(ch, {
key: key,
ref: this.getChildRef,
originalRef: ch.ref
}));
}
});
this._contentChildren = children;
let prevActual = this._contentChildrenActual;
this._contentChildrenActual = [];
let prevMap = this._contentChildrenMap;
let prevUnresolved = this._contentChildrenUnresolvedSet;
this._contentChildrenUnresolvedSet = new Set();
this._contentChildrenMap = new Map();
this._contentChildrenUnresolved = 0;
if (this._contentChildren) {
this._contentChildren.map((ch, i) => {
let key = this._getPropsKey(ch);
var unresolved = prevUnresolved.has(key);
if (prevMap && prevMap.has(key) && !unresolved) {
this._contentChildrenActual[i] = prevActual[prevMap.get(key)];
}
else {
this._contentChildrenActual[i] = null;
this._contentChildrenUnresolvedSet.add(key);
this._contentChildrenUnresolved++;
}
this._contentChildrenMap.set(key, i);
});
}
return children;
}
getChildRef(child) {
//console.log(child);
this.trackChild(child);
}
constructor(getPropsKey, getKey, updateContentChildren) {
this._contentChildren = null;
this._contentChildrenActual = null;
this._contentChildrenMap = null;
this._contentChildrenUnresolvedSet = null;
this._contentChildrenUnresolved = 0;
this.getChildRef = this.getChildRef.bind(this);
this._getPropsKey = getPropsKey;
this._getKey = getKey;
this._updateContentChildren = updateContentChildren;
this._contentChildrenUnresolvedSet = new Set();
}
get contentChildrenActual() {
return this._contentChildrenActual;
}
trackChild(child) {
var _a;
if (child === null) {
return;
}
let name = this._getKey(child);
let index = this._contentChildrenMap.get(name);
// resolve any refs from content child.
const contentChild = this._contentChildren[index];
const ref = (_a = contentChild === null || contentChild === void 0 ? void 0 : contentChild.props) === null || _a === void 0 ? void 0 : _a.originalRef;
if (ref && typeof ref === 'function') {
// user has set a callback function.
ref(child);
}
else if (ref && ref.hasOwnProperty('current')) {
// user has set a useRef object.
ref.current = child;
}
if (this._contentChildrenActual[index] === null) {
this._contentChildrenActual[index] = child;
this._contentChildrenUnresolvedSet.delete(name);
this._contentChildrenUnresolved--;
if (this._contentChildrenUnresolved <= 0) {
this._updateContentChildren();
}
}
}
}