UNPKG

@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
"use strict"; 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;