zmp-react
Version:
Build full featured iOS & Android apps using ZMP & React
260 lines (219 loc) • 8.49 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
/* eslint-disable no-nested-ternary */
import React, { forwardRef, useRef, useImperativeHandle, useState } from 'react';
import { useIsomorphicLayoutEffect } from '../shared/use-isomorphic-layout-effect';
import { classNames, getExtraAttrs, noUndefinedProps, emit, getRouterId } from '../shared/utils';
import { colorClasses } from '../shared/mixins';
import { zmpready, zmprouters, zmp, zmpevents } from '../shared/zmp';
import { useTab } from '../shared/use-tab';
import { useAsyncComponent } from '../shared/use-async-component';
import { getRouterInitialComponent } from '../shared/get-router-initial-component';
import { RouterContext } from '../shared/router-context';
var View = /*#__PURE__*/forwardRef(function (props, ref) {
var className = props.className,
id = props.id,
style = props.style,
children = props.children,
_props$init = props.init,
init = _props$init === void 0 ? true : _props$init,
main = props.main,
tab = props.tab,
tabActive = props.tabActive,
url = props.url,
_props$browserHistory = props.browserHistoryInitialMatch,
browserHistoryInitialMatch = _props$browserHistory === void 0 ? true : _props$browserHistory,
initRouterOnTabShow = props.initRouterOnTabShow;
var childrenArray = React.Children.toArray(children);
var initialPageComponent = childrenArray.filter(function (c) {
return c.props && c.props.initialPage;
})[0];
var restChildren = childrenArray.filter(function (c) {
return !c.props || !c.props.initialPage;
});
var shouldInitRouter = React.useMemo(function () {
return !(initRouterOnTabShow && tab && !tabActive);
}, []);
var extraAttrs = getExtraAttrs(props);
var _zmpView = useRef(null);
var elRef = useRef(null);
var routerData = useRef(null);
var initialPage;
var initialRoute;
var onViewInit = function onViewInit(view) {
emit(props, 'viewInit', view);
if (!init) {
routerData.current.instance = view;
_zmpView.current = routerData.current.instance;
}
};
if (zmp && !_zmpView.current && init) {
var routerId = getRouterId();
_zmpView.current = zmp.views.create(elRef.current, _extends({
routerId: routerId,
init: false
}, noUndefinedProps(props), {
browserHistoryInitialMatch: browserHistoryInitialMatch,
on: {
init: onViewInit
}
}));
routerData.current = {
routerId: routerId,
instance: _zmpView.current
};
zmprouters.views.push(routerData.current);
if (shouldInitRouter && _zmpView.current && _zmpView.current.router && (url || main)) {
var initialData = getRouterInitialComponent(_zmpView.current.router, initialPageComponent);
initialPage = initialData.initialPage;
initialRoute = initialData.initialRoute;
}
}
var _useState = useState(initialPage ? [initialPage] : []),
pages = _useState[0],
_setPages = _useState[1];
var onResize = function onResize(view, width) {
emit(props, 'viewResize', width);
};
var onSwipeBackMove = function onSwipeBackMove(data) {
var swipeBackData = data;
emit(props, 'swipeBackMove', swipeBackData);
};
var onSwipeBackBeforeChange = function onSwipeBackBeforeChange(data) {
var swipeBackData = data;
emit(props, 'swipeBackBeforeChange', swipeBackData);
};
var onSwipeBackAfterChange = function onSwipeBackAfterChange(data) {
var swipeBackData = data;
emit(props, 'swipeBackAfterChange', swipeBackData);
};
var onSwipeBackBeforeReset = function onSwipeBackBeforeReset(data) {
var swipeBackData = data;
emit(props, 'swipeBackBeforeReset', swipeBackData);
};
var onSwipeBackAfterReset = function onSwipeBackAfterReset(data) {
var swipeBackData = data;
emit(props, 'swipeBackAfterReset', swipeBackData);
};
useImperativeHandle(ref, function () {
return {
el: elRef.current,
zmpView: function zmpView() {
return _zmpView.current;
}
};
});
var onMount = function onMount() {
zmpready(function () {
if (_zmpView.current) {
routerData.current.el = elRef.current;
routerData.current.pages = pages;
routerData.current.setPages = function (newPages) {
_setPages([].concat(newPages));
};
if (initialPage && initialPage.isAsync && !initialPage.initialComponent) {
initialPage.component().then(function () {
setTimeout(function () {
_zmpView.current.init(elRef.current);
if (initialPage) {
initialPage.el = _zmpView.current.router.currentPageEl;
if (initialRoute && initialRoute.route && initialRoute.route.keepAlive) {
initialRoute.route.keepAliveData = {
pageEl: initialPage.el
};
}
}
}, 100);
});
} else {
_zmpView.current.init(elRef.current);
if (initialPage) {
initialPage.el = _zmpView.current.router.currentPageEl;
if (initialRoute && initialRoute.route && initialRoute.route.keepAlive) {
initialRoute.route.keepAliveData = {
pageEl: initialPage.el
};
}
}
}
} else {
var _routerId = getRouterId();
routerData.current = {
el: elRef.current,
routerId: _routerId,
pages: pages,
instance: _zmpView.current,
setPages: function setPages(newPages) {
_setPages([].concat(newPages));
}
};
zmprouters.views.push(routerData.current);
routerData.current.instance = zmp.views.create(elRef.current, _extends({
routerId: _routerId
}, noUndefinedProps(props), {
browserHistoryInitialMatch: browserHistoryInitialMatch,
on: {
init: onViewInit
}
}));
_zmpView.current = routerData.current.instance;
}
if (!init) return;
_zmpView.current.on('resize', onResize);
_zmpView.current.on('swipebackMove', onSwipeBackMove);
_zmpView.current.on('swipebackBeforeChange', onSwipeBackBeforeChange);
_zmpView.current.on('swipebackAfterChange', onSwipeBackAfterChange);
_zmpView.current.on('swipebackBeforeReset', onSwipeBackBeforeReset);
_zmpView.current.on('swipebackAfterReset', onSwipeBackAfterReset);
});
};
var onDestroy = function onDestroy() {
if (_zmpView.current) {
_zmpView.current.off('resize', onResize);
_zmpView.current.off('swipebackMove', onSwipeBackMove);
_zmpView.current.off('swipebackBeforeChange', onSwipeBackBeforeChange);
_zmpView.current.off('swipebackAfterChange', onSwipeBackAfterChange);
_zmpView.current.off('swipebackBeforeReset', onSwipeBackBeforeReset);
_zmpView.current.off('swipebackAfterReset', onSwipeBackAfterReset);
if (_zmpView.current.destroy) _zmpView.current.destroy();
_zmpView.current = null;
}
zmprouters.views.splice(zmprouters.views.indexOf(routerData.current), 1);
routerData.current = null;
};
useIsomorphicLayoutEffect(function () {
onMount();
return onDestroy;
}, []);
useIsomorphicLayoutEffect(function () {
if (routerData.current && zmp) {
zmpevents.emit('viewRouterDidUpdate', routerData.current);
}
});
useTab(elRef, props);
var classes = classNames(className, 'view', {
'view-main': main,
'tab-active': tabActive,
tab: tab
}, colorClasses(props));
return /*#__PURE__*/React.createElement("div", _extends({
id: id,
style: style,
className: classes,
ref: elRef
}, extraAttrs), restChildren, pages.map(function (_ref) {
var PageComponent = _ref.component,
pageId = _ref.id,
pageProps = _ref.props,
isAsync = _ref.isAsync,
initialComponent = _ref.initialComponent;
return /*#__PURE__*/React.createElement(RouterContext.Provider, {
key: pageId,
value: {
router: pageProps.zmprouter,
route: pageProps.zmproute
}
}, initialComponent ? /*#__PURE__*/React.cloneElement(initialComponent, _extends({}, pageProps)) : isAsync ? useAsyncComponent(PageComponent, pageProps) : /*#__PURE__*/React.createElement(PageComponent, pageProps));
}));
});
View.displayName = 'zmp-view';
export default View;