@triniwiz/nativescript-pager
Version:
A Carousel/Pager plugin for NativeScript
187 lines (186 loc) • 8.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PagerItem = exports.Pager = exports._PagerItem = exports._Pager = void 0;
const React = require("react");
const __1 = require("../");
const react_nativescript_1 = require("react-nativescript");
(0, react_nativescript_1.registerElement)('pager', () => require('../').Pager);
(0, react_nativescript_1.registerElement)('pagerItem', () => require('../').PagerItem);
const react_nativescript_2 = require("react-nativescript");
class _Pager extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.argsViewToRootKeyAndRef = new Map();
this.roots = new Set();
this.defaultOnItemLoading = (args) => {
const { logLevel, onCellRecycle, onCellFirstLoad } = this.props._debug;
const { items, itemTemplateSelector } = this.props;
const item = _Pager.isItemsSource(items) ? items.getItem(args.index) : items[args.index];
const template = itemTemplateSelector
? typeof itemTemplateSelector === "string"
? itemTemplateSelector
: itemTemplateSelector(item, args.index, items)
: null;
const cellFactory = template === null
? this.props.cellFactory
: this.props.cellFactories
? this.props.cellFactories.get(template).cellFactory
: this.props.cellFactory;
if (typeof cellFactory === "undefined") {
console.warn(`Pager: No cell factory found, given template ${template}!`);
return;
}
let view = args.view;
if (!view) {
const rootKeyAndRef = this.renderNewRoot(item, cellFactory);
args.view = rootKeyAndRef.nativeView;
/* Here we're re-using the ref - I assume this is best practice. If not, we can make a new one on each update instead. */
this.argsViewToRootKeyAndRef.set(args.view, rootKeyAndRef);
if (onCellFirstLoad)
onCellFirstLoad(rootKeyAndRef.nativeView);
}
else {
console.log(`[Pager] existing view: `, view);
if (onCellRecycle)
onCellRecycle(view);
const { rootKey, nativeView } = this.argsViewToRootKeyAndRef.get(view);
if (typeof rootKey === "undefined") {
console.error(`Unable to find root key that args.view corresponds to!`, view);
return;
}
if (!nativeView) {
console.error(`Unable to find ref that args.view corresponds to!`, view);
return;
}
// args.view = null;
(0, react_nativescript_2.render)(
// @ts-ignore
cellFactory(item), null, () => {
// console.log(`Rendered into cell! detachedRootRef:`);
}, rootKey);
}
};
this.renderNewRoot = (item, cellFactory) => {
const node = this.getNativeView();
if (!node) {
throw new Error("Unable to get ref to Pager");
}
console.log(`[Pager] no existing view.`);
const rootKey = `Pager-${node._domId}-${this.roots.size.toString()}`;
const root = new react_nativescript_2.NSVRoot();
(0, react_nativescript_2.render)(
// @ts-ignore
cellFactory(item), root, () => {
// console.log(`Rendered into cell! ref:`);
}, rootKey);
this.roots.add(rootKey);
return {
rootKey,
nativeView: root.baseRef.nativeView
};
};
this.state = {
nativeCells: {},
nativeCellToItemIndex: new Map(),
itemIndexToNativeCell: props._debug.logLevel === "debug" ? new Map() : undefined,
};
}
getNativeView() {
const ref = (this.props.forwardedRef || this.myRef);
return ref.current ? ref.current.nativeView : null;
}
componentDidMount() {
const node = this.getNativeView();
if (!node) {
console.warn(`React ref to NativeScript View lost, so unable to set item templates.`);
return;
}
/* NOTE: does not support updating of this.props.cellFactories upon Props update. */
if (this.props.cellFactories) {
const itemTemplates = [];
this.props.cellFactories.forEach((info, key) => {
const { placeholderItem, cellFactory } = info;
itemTemplates.push({
key,
createView: () => {
console.log(`[Pager] item template "${key}"`);
const rootKeyAndRef = this.renderNewRoot(placeholderItem, cellFactory);
this.argsViewToRootKeyAndRef.set(rootKeyAndRef.nativeView, rootKeyAndRef);
return rootKeyAndRef.nativeView;
},
});
});
node.itemTemplates = itemTemplates;
}
}
componentWillUnmount() {
this.roots.forEach(root => (0, react_nativescript_2.unmountComponentAtNode)(root));
}
static isItemsSource(arr) {
// Same implementation as: https://github.com/NativeScript/NativeScript/blob/b436ecde3605b695a0ffa1757e38cc094e2fe311/tns-core-modules/ui/list-picker/list-picker-common.ts#L74
return typeof arr.getItem === "function";
}
render() {
console.log(`Pager's render()`);
const _a = this.props, {
// Only used by the class component; not the JSX element.
forwardedRef, children, _debug, cellFactories, cellFactory } = _a, rest = __rest(_a, ["forwardedRef", "children", "_debug", "cellFactories", "cellFactory"]);
return (
// React.createElement('pager',{
// className: 'pager-group',
// ...rest,
// ref: forwardedRef || this.myRef,
// onItemLoading: this.defaultOnItemLoading
// }, children)
// @ts-ignore
React.createElement("pager", Object.assign({}, rest, { onItemLoading: this.defaultOnItemLoading, ref: forwardedRef || this.myRef, children: children })));
}
}
exports._Pager = _Pager;
_Pager.defaultProps = {
_debug: {
logLevel: "info",
onCellFirstLoad: undefined,
onCellRecycle: undefined,
},
};
class _PagerItem extends React.Component {
constructor() {
super(...arguments);
this.myRef = React.createRef();
this.item = new __1.PagerItem();
}
componentDidMount() {
const { forwardedRef } = this.props;
const view = (forwardedRef || this.myRef).current.nativeView;
const parent = view && view.parent ? view.parent : null;
if (parent) {
// remove parent
parent._removeView(view);
// add to item;
this.item.addChild(view);
// @ts-ignore
parent._addChildFromBuilder('PagerItem', this.item);
}
}
render() {
const _a = this.props, { forwardedRef, children } = _a,
// view, /* We disallow this at the typings level. */
rest = __rest(_a, ["forwardedRef", "children"]);
return React.createElement('pagerItem', Object.assign(Object.assign({}, rest), { ref: forwardedRef || this.myRef }), children);
}
}
exports._PagerItem = _PagerItem;
exports.Pager = React.forwardRef(
//@ts-ignore
(props, ref) => {
//@ts-ignore
return React.createElement(_Pager, Object.assign({}, props, { forwardedRef: ref }));
});
exports.PagerItem = React.forwardRef(
//@ts-ignore
(props, ref) => {
//@ts-ignore
return React.createElement(_PagerItem, Object.assign({}, props, { forwardedRef: ref }));
});