"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.CanvasContainer = CanvasContainer;
exports.CanvasPanel = CanvasPanel;
exports.CanvasWrapper = exports.useCanvasContext = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _framerMotion = require("framer-motion");

var _react = _interopRequireWildcard(require("react"));

var _Flex = require("../Flex");

var _useWindowResize2 = require("../hooks/useWindowResize");

var _Modal = require("../Modal");

var _PseudoBox = require("../PseudoBox");

var _ThemeProvider = require("../ThemeProvider");

var _router = require("../utils/router");

var _styles = _interopRequireDefault(require("./styles"));

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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; }

var __jsx = _react["default"].createElement;

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

var CanvasContext = /*#__PURE__*/(0, _react.createContext)(null);

var useCanvasContext = function useCanvasContext() {
  var context = (0, _react.useContext)(CanvasContext);

  if (context == null) {
    throw new Error('This component must be used within the `CanvasWrapper` ');
  }

  return context;
};

exports.useCanvasContext = useCanvasContext;
var MotionPanel = (0, _framerMotion.motion)(_PseudoBox.PseudoBox);

var getPanels = function getPanels(panels) {
  var panelList = Object.keys(panels).map(function (panelKey) {
    return _objectSpread(_objectSpread({}, panels[panelKey]), {}, {
      name: panelKey
    });
  }).filter(function (p) {
    return p;
  });
  var leftPanels = panelList.filter(function (panel) {
    return panel.position === 'left';
  });
  var rightPanels = panelList.filter(function (panel) {
    return panel.position === 'right';
  });
  return {
    leftPanels: leftPanels,
    rightPanels: rightPanels
  };
};

var isWithinRange = function isWithinRange(width, range) {
  if (width && (range === null || range === void 0 ? void 0 : range.length) === 2 && width >= range[0] && width < range[1]) {
    return true;
  }

  return false;
};

function CanvasContainer(props) {
  var _useState = (0, _react.useState)(props.initialCanvasState),
      panels = _useState[0],
      setPanels = _useState[1];

  var _useTheme = (0, _ThemeProvider.useTheme)(),
      zIndices = _useTheme.zIndices;

  var styles = (0, _styles["default"])(_objectSpread({}, props));

  var updatePanel = function updatePanel(name, update) {
    setPanels(function ($prev) {
      return _objectSpread(_objectSpread({}, $prev), {}, (0, _defineProperty2["default"])({}, name, _objectSpread(_objectSpread({}, $prev[name] || {}), update)));
    });
  };

  var togglePanel = function togglePanel(name) {
    setPanels(function ($prev) {
      var panel = $prev[name];

      if (!panel) {
        return null;
      }

      return _objectSpread(_objectSpread({}, $prev), {}, (0, _defineProperty2["default"])({}, name, _objectSpread(_objectSpread({}, panel), {}, {
        // if desktop and panel can be minified, minify rather than hiding
        // if mobile, skip minifiable and either show or hide
        isVisible: !panel.isMinifiable ? !(panel !== null && panel !== void 0 && panel.isVisible) : panel === null || panel === void 0 ? void 0 : panel.isVisible,
        isMinified: panel.isMinifiable ? !(panel !== null && panel !== void 0 && panel.isMinified) : false
      })));
    });
  };

  var addPanel = function addPanel(name, update) {
    setPanels(function ($prev) {
      return _objectSpread(_objectSpread({}, $prev), {}, (0, _defineProperty2["default"])({}, name, update($prev[name] || {})));
    });
  };

  var removePanel = function removePanel(name) {
    var deletePanel = function deletePanel() {
      setPanels(function ($prev) {
        var newPanelList = _objectSpread({}, $prev);

        delete newPanelList[name];
        return newPanelList;
      });
    }; // TODO: look into cleaner way of doing this
    // Hide the panel first to keep close animation, then delete from the panels object.


    updatePanel(name, {
      isVisible: false
    });
    setTimeout(function () {
      deletePanel();
    }, 400);
  };

  var renderPanel = function renderPanel(panel, i) {
    if (!panel || !(panel && panel.render)) return null;
    var name = panel.name,
        ref = panel.ref,
        children = panel.children,
        isVisible = panel.isVisible,
        type = panel.type,
        bg = panel.bg,
        isOverlay = panel.isOverlay,
        _panel$p = panel.p,
        p = _panel$p === void 0 ? 'canvas.spacing' : _panel$p,
        renderProps = panel.renderProps,
        overflow = panel.overflow,
        overflowY = panel.overflowY,
        panelProps = (0, _objectWithoutProperties2["default"])(panel, ["name", "ref", "children", "isVisible", "type", "bg", "isOverlay", "p", "renderProps", "overflow", "overflowY"]);
    var animateTo = isVisible && (panelProps.isMinified ? 'minified' : 'visible') || 'hidden';
    var zIndex = i;

    var panelStyleProps = _objectSpread(_objectSpread({}, styles.panel), styles.getPanelStyle({
      width: panelProps.width || panelProps.w,
      minifiedWidth: panelProps.minifiedWidth,
      position: panelProps.position,
      bg: bg,
      isOverlay: isOverlay,
      name: name,
      zIndex: zIndex
    }));

    return __jsx(_Flex.Flex, {
      zIndex: (isVisible && isOverlay ? zIndices.panel : 1) + zIndex,
      key: name,
      overflow: overflow,
      overflowY: overflowY
    }, __jsx(MotionPanel, (0, _extends2["default"])({
      key: "motion-".concat(panel.name),
      initial: animateTo,
      animate: animateTo
    }, panelStyleProps, {
      transition: {
        type: 'spring',
        duration: 0.5,
        bounce: 0
      } // _track={{ backgroundColor: 'black' }}

    }), __jsx(_Flex.Flex, (0, _extends2["default"])({
      ref: ref,
      direction: "column",
      minH: "100%",
      h: "100%",
      p: p
    }, panelProps, {
      width: "100%"
    }), panel.render(_objectSpread({
      isMinified: panelProps.isMinified,
      isVisible: isVisible
    }, renderProps)))), isVisible && isOverlay && __jsx(_Modal.ModalOverlay, {
      zIndex: 1,
      onClick: function onClick() {
        return togglePanel(name);
      }
    }));
  };

  var _getPanels = getPanels(panels),
      leftPanels = _getPanels.leftPanels,
      rightPanels = _getPanels.rightPanels;

  return __jsx(CanvasContext.Provider, {
    value: {
      panels: panels,
      addPanel: addPanel,
      setPanels: setPanels,
      updatePanel: updatePanel,
      togglePanel: togglePanel,
      removePanel: removePanel
    }
  }, props.header, __jsx(_Flex.Flex, (0, _extends2["default"])({
    h: "100%"
  }, styles.style), leftPanels.sort(function (a, b) {
    return a.priority - b.priority;
  }).map(function (panel, i) {
    return renderPanel(panel, i);
  }), props.children, rightPanels.sort(function (a, b) {
    return a.priority - b.priority;
  }).map(function (panel, i) {
    return renderPanel(panel, i);
  })));
}

var renderPanels = function renderPanels(_ref) {
  var _ref$panels = _ref.panels,
      panels = _ref$panels === void 0 ? [] : _ref$panels,
      _ref$children = _ref.children,
      children = _ref$children === void 0 ? null : _ref$children,
      _ref$windowWidth = _ref.windowWidth,
      windowWidth = _ref$windowWidth === void 0 ? 0 : _ref$windowWidth,
      renderPanelsProps = (0, _objectWithoutProperties2["default"])(_ref, ["panels", "children", "windowWidth"]);
  return __jsx(_Flex.Flex, null, panels.map(function (canvas, i) {
    var name = canvas.name,
        render = canvas.render,
        renderProps = canvas.renderProps,
        rest = (0, _objectWithoutProperties2["default"])(canvas, ["name", "render", "renderProps"]);
    return __jsx(CanvasPanel, (0, _extends2["default"])({
      name: name,
      key: name,
      borderRight: "1px",
      borderColor: "border",
      windowWidth: windowWidth
    }, renderPanelsProps, rest), function (props) {
      return __jsx(_react["default"].Fragment, null, render(_objectSpread({
        children: null,
        renderProps: renderProps
      }, props)));
    });
  }));
};

var CanvasWrapper = function CanvasWrapper(props) {
  var initialCanvasState = props.initialCanvasState,
      children = props.children,
      header = props.header,
      rest = (0, _objectWithoutProperties2["default"])(props, ["initialCanvasState", "children", "header"]);

  var _useWindowResize = (0, _useWindowResize2.useWindowResize)(),
      windowWidth = _useWindowResize.windowWidth;

  return __jsx(CanvasContainer, {
    initialCanvasState: initialCanvasState,
    header: header
  }, __jsx(CanvasContext.Consumer, null, function (_ref2) {
    var panels = _ref2.panels;
    var canvasPanels = Object.keys(panels).length > 0 && panels;

    if (!canvasPanels) {
      return children;
    }

    var _getPanels2 = getPanels(canvasPanels),
        leftPanels = _getPanels2.leftPanels,
        rightPanels = _getPanels2.rightPanels;

    return __jsx(_react["default"].Fragment, null, (leftPanels === null || leftPanels === void 0 ? void 0 : leftPanels.length) > 0 && renderPanels({
      panels: leftPanels,
      windowWidth: windowWidth
    }), __jsx(_Flex.Flex, (0, _extends2["default"])({
      direction: "column",
      flexGrow: 1,
      minH: "100%",
      h: "100%",
      width: "100%",
      bg: "pageBg"
    }, rest), children), (rightPanels === null || rightPanels === void 0 ? void 0 : rightPanels.length) > 0 && renderPanels({
      panels: rightPanels,
      windowWidth: windowWidth
    }));
  }));
};

exports.CanvasWrapper = CanvasWrapper;

function CanvasPanel(_ref3) {
  var name = _ref3.name,
      children = _ref3.children,
      _ref3$type = _ref3.type,
      type = _ref3$type === void 0 ? 'inline' : _ref3$type,
      ranges = _ref3.ranges,
      windowWidth = _ref3.windowWidth,
      rest = (0, _objectWithoutProperties2["default"])(_ref3, ["name", "children", "type", "ranges", "windowWidth"]);

  var _useCanvasContext = useCanvasContext(),
      updatePanel = _useCanvasContext.updatePanel;

  var _useRouter = (0, _router.useRouter)(),
      pathname = _useRouter.pathname;

  var ref = /*#__PURE__*/(0, _react.createRef)();
  var currentWindowWidth = Math.max(1, windowWidth);
  var isOverlay = isWithinRange(currentWindowWidth, ranges === null || ranges === void 0 ? void 0 : ranges.isOverlay);
  var isMinifiable = !isOverlay && isWithinRange(currentWindowWidth, ranges === null || ranges === void 0 ? void 0 : ranges.allowMinify);
  var isMinified = isMinifiable && isWithinRange(currentWindowWidth, ranges === null || ranges === void 0 ? void 0 : ranges.defaultMinified);
  var isVisible = false;

  if (isOverlay && ranges.defaultVisible) {
    isVisible = false;
  } else {
    isVisible = isWithinRange(currentWindowWidth, ranges === null || ranges === void 0 ? void 0 : ranges.defaultVisible);
  }

  (0, _react.useEffect)(function () {
    // Set the canvas panel's default values
    updatePanel(name, _objectSpread({
      name: name,
      ref: ref,
      render: children,
      type: type,
      ranges: ranges
    }, rest)); // remove panel
    // return () => {
    //     removePanel(name);
    // };
  }, []);
  (0, _react.useEffect)(function () {
    updatePanel(name, {
      isMinifiable: isMinifiable,
      isMinified: isMinified,
      isVisible: isVisible,
      isOverlay: isOverlay
    });
  }, [isMinifiable, isMinified, isVisible, isOverlay]);
  (0, _react.useEffect)(function () {
    // when a link is clicked and route changes, close overlay canvases
    if (isOverlay) {
      updatePanel(name, {
        isVisible: false
      });
    }
  }, [pathname]);
  return null;
}
//# sourceMappingURL=Canvas.js.map