@moxy/next-layout
Version:
Add persistent and nested layouts to your Next.js projects in a declarative way
101 lines (79 loc) • 4.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.isComponentWrapped = exports.getInitialLayoutTree = void 0;
var _react = _interopRequireWildcard(require("react"));
var _hoistNonReactStatics = _interopRequireDefault(require("hoist-non-react-statics"));
var _useObjectState = _interopRequireDefault(require("./util/use-object-state"));
var _context = _interopRequireDefault(require("./util/context"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const toFunction = fn => typeof fn === 'function' ? fn : () => fn;
const getInitialLayoutTreeSymbol = Symbol('getInitialLayoutTreeSymbol');
const withLayout = (mapLayoutStateToLayoutTree, mapPropsToInitialLayoutState) => {
const shouldInjectSetLayoutState = typeof mapLayoutStateToLayoutTree === 'function';
mapLayoutStateToLayoutTree = toFunction(mapLayoutStateToLayoutTree);
mapPropsToInitialLayoutState = toFunction(mapPropsToInitialLayoutState);
return Component => {
const WithLayout = (0, _react.forwardRef)((_props, ref) => {
const {
pageKey,
props
} = (0, _react.useMemo)(() => {
const {
pageKey,
...props
} = _props;
return {
pageKey,
props
};
}, [_props]);
const initialLayoutStateRef = (0, _react.useRef)();
if (!initialLayoutStateRef.current) {
initialLayoutStateRef.current = mapPropsToInitialLayoutState(props);
}
const layoutProviderValue = (0, _react.useContext)(_context.default); // Check if <LayoutTree /> was not added to the app (missing provider).
if (process.env.NODE_ENV !== 'production' && !layoutProviderValue) {
throw new Error('It seems you forgot to include <LayoutTree /> in your app');
}
const {
updateLayoutTree,
Component: ProviderComponent,
pageKey: providerPageKey
} = layoutProviderValue;
const [layoutState, setLayoutState] = (0, _useObjectState.default)(initialLayoutStateRef.current);
(0, _react.useEffect)(() => {
if (layoutState !== initialLayoutStateRef.current && ProviderComponent === WithLayout && providerPageKey === pageKey) {
updateLayoutTree(mapLayoutStateToLayoutTree(layoutState));
}
}, [layoutState, updateLayoutTree, ProviderComponent, providerPageKey, pageKey]);
return (0, _react.useMemo)(() => /*#__PURE__*/_react.default.createElement(Component, Object.assign({
ref: ref
}, shouldInjectSetLayoutState ? {
setLayoutState
} : {}, props)), [ref, setLayoutState, props]);
});
const getInitialLayoutTree = props => {
const layoutState = mapPropsToInitialLayoutState(props);
return mapLayoutStateToLayoutTree(layoutState);
};
Object.defineProperty(WithLayout, getInitialLayoutTreeSymbol, {
value: getInitialLayoutTree
});
WithLayout.displayName = `WithLayout(${Component.displayName || Component.name || 'Component'})`;
(0, _hoistNonReactStatics.default)(WithLayout, Component);
return WithLayout;
};
};
const getInitialLayoutTree = (Component, pageProps) => {
var _Component$getInitial;
return (_Component$getInitial = Component[getInitialLayoutTreeSymbol]) === null || _Component$getInitial === void 0 ? void 0 : _Component$getInitial.call(Component, pageProps);
};
exports.getInitialLayoutTree = getInitialLayoutTree;
const isComponentWrapped = Component => !!Component[getInitialLayoutTreeSymbol];
exports.isComponentWrapped = isComponentWrapped;
var _default = withLayout;
exports.default = _default;
;