UNPKG

@atlaskit/editor-plugin-breakout

Version:

Breakout plugin for @atlaskit/editor-core

278 lines (276 loc) 14.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.breakoutPlugin = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _react = _interopRequireWildcard(require("react")); var _adfSchema = require("@atlaskit/adf-schema"); var _hooks = require("@atlaskit/editor-common/hooks"); var _safePlugin = require("@atlaskit/editor-common/safe-plugin"); var _styles = require("@atlaskit/editor-common/styles"); var _usePluginStateEffect = require("@atlaskit/editor-common/use-plugin-state-effect"); var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector"); var _editorSharedStyles = require("@atlaskit/editor-shared-styles"); var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); var _experiments = require("@atlaskit/tmp-editor-statsig/experiments"); var _pluginKey = require("./pm-plugins/plugin-key"); var _resizingPlugin = require("./pm-plugins/resizing-plugin"); var _findBreakoutNode = require("./pm-plugins/utils/find-breakout-node"); var _getBreakoutMode = require("./pm-plugins/utils/get-breakout-mode"); var _GuidelineLabel = require("./ui/GuidelineLabel"); var _LayoutButton = _interopRequireDefault(require("./ui/LayoutButton")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var BreakoutView = /*#__PURE__*/(0, _createClass2.default)(function BreakoutView( /** * Note: this is actually a PMMark -- however our version * of the prosemirror and prosemirror types mean using PMNode * is not problematic. */ mark, view, appearance) { (0, _classCallCheck2.default)(this, BreakoutView); var dom = document.createElement('div'); var contentDOM = document.createElement('div'); contentDOM.className = _styles.BreakoutCssClassName.BREAKOUT_MARK_DOM; contentDOM.setAttribute('data-testid', 'ak-editor-breakout-mark-dom'); dom.className = _styles.BreakoutCssClassName.BREAKOUT_MARK; dom.setAttribute('data-layout', mark.attrs.mode); dom.setAttribute('data-testid', 'ak-editor-breakout-mark'); dom.appendChild(contentDOM); dom.style.transform = 'none'; dom.style.display = 'flex'; dom.style.justifyContent = 'center'; contentDOM.style.transition = "min-width 0.5s ".concat(_editorSharedStyles.akEditorSwoopCubicBezier); if ((0, _experiments.editorExperiment)('advanced_layouts', true)) { if (mark.attrs.width) { contentDOM.style.minWidth = "min(".concat(mark.attrs.width, "px, calc(100cqw - var(--ak-editor--breakout-full-page-guttering-padding)))"); } else { // original breakout algorithm is in calcBreakoutWidth from platform/packages/editor/editor-common/src/utils/breakout.ts if (mark.attrs.mode === 'full-width') { contentDOM.style.minWidth = "max(var(--ak-editor--line-length), min(var(--ak-editor--full-width-layout-width), calc(100cqw - var(--ak-editor--breakout-full-page-guttering-padding))))"; } if (mark.attrs.mode === 'wide') { if (appearance && appearance === 'full-width' && (0, _experiments.editorExperiment)('single_column_layouts', true) && true) { contentDOM.style.minWidth = "min(var(--ak-editor--breakout-wide-layout-width), calc(100cqw - var(--ak-editor--breakout-full-page-guttering-padding)))"; } else { contentDOM.style.minWidth = "max(var(--ak-editor--line-length), min(var(--ak-editor--breakout-wide-layout-width), calc(100cqw - var(--ak-editor--breakout-full-page-guttering-padding))))"; } } } } else { // original breakout algorithm is in calcBreakoutWidth from platform/packages/editor/editor-common/src/utils/breakout.ts if (mark.attrs.mode === 'full-width') { contentDOM.style.minWidth = "max(var(--ak-editor--line-length), min(var(--ak-editor--full-width-layout-width), calc(100cqw - var(--ak-editor--breakout-full-page-guttering-padding))))"; } if (mark.attrs.mode === 'wide') { contentDOM.style.minWidth = "max(var(--ak-editor--line-length), min(var(--ak-editor--breakout-wide-layout-width), calc(100cqw - var(--ak-editor--breakout-full-page-guttering-padding))))"; } } this.dom = dom; this.mark = mark; this.view = view; this.contentDOM = contentDOM; }); function shouldPluginStateUpdate(newBreakoutNode, currentBreakoutNode) { if (newBreakoutNode && currentBreakoutNode) { return newBreakoutNode !== currentBreakoutNode; } return newBreakoutNode || currentBreakoutNode ? true : false; } function createPlugin(api, _ref, appearance) { var dispatch = _ref.dispatch; return new _safePlugin.SafePlugin({ state: { init: function init() { return { breakoutNode: undefined, activeGuidelineKey: undefined }; }, apply: function apply(tr, pluginState) { var breakoutNode = (0, _findBreakoutNode.findSupportedNodeForBreakout)(tr.selection); if (shouldPluginStateUpdate(breakoutNode, pluginState.breakoutNode)) { var nextPluginState = _objectSpread(_objectSpread({}, pluginState), {}, { breakoutNode: breakoutNode }); dispatch(_pluginKey.pluginKey, nextPluginState); return nextPluginState; } return pluginState; } }, key: _pluginKey.pluginKey, props: { nodeViews: { // Note: When we upgrade to prosemirror 1.27.2 -- we should // move this to markViews. // See the following link for more details: // https://prosemirror.net/docs/ref/#view.EditorProps.nodeViews. breakout: function breakout(mark, view) { return new BreakoutView(mark, view, appearance); } } } }); } var LayoutButtonWrapper = function LayoutButtonWrapper(_ref2) { var api = _ref2.api, editorView = _ref2.editorView, boundariesElement = _ref2.boundariesElement, scrollableElement = _ref2.scrollableElement, mountPoint = _ref2.mountPoint; var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['editorViewMode', 'editorDisabled', 'blockControls'], function (states) { var _states$blockControls, _states$blockControls2, _states$editorViewMod, _states$editorDisable; return { isDragging: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.isDragging, isPMDragging: (_states$blockControls2 = states.blockControlsState) === null || _states$blockControls2 === void 0 ? void 0 : _states$blockControls2.isPMDragging, mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode, editorDisabled: (_states$editorDisable = states.editorDisabledState) === null || _states$editorDisable === void 0 ? void 0 : _states$editorDisable.editorDisabled }; }), editorDisabled = _useSharedPluginState.editorDisabled, isDragging = _useSharedPluginState.isDragging, isPMDragging = _useSharedPluginState.isPMDragging, mode = _useSharedPluginState.mode; var _useState = (0, _react.useState)(false), _useState2 = (0, _slicedToArray2.default)(_useState, 2), breakoutNodePresent = _useState2[0], setBreakoutNodePresent = _useState2[1]; var _useState3 = (0, _react.useState)((0, _expValEquals.expValEquals)('platform_editor_hydratable_ui', 'isEnabled', true) && !editorView ? undefined : // Remove ! during platform_editor_hydratable_ui cleanup // eslint-disable-next-line @typescript-eslint/no-non-null-assertion (0, _getBreakoutMode.getBreakoutMode)(editorView.state)), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), breakoutMode = _useState4[0], setBreakoutMode = _useState4[1]; (0, _usePluginStateEffect.usePluginStateEffect)(api, ['breakout'], function (_ref3) { var breakoutState = _ref3.breakoutState; if ((0, _expValEquals.expValEquals)('platform_editor_hydratable_ui', 'isEnabled', true) && !editorView) { return; } if (breakoutState !== null && breakoutState !== void 0 && breakoutState.breakoutNode && !breakoutNodePresent) { setBreakoutNodePresent(true); } if (!(breakoutState !== null && breakoutState !== void 0 && breakoutState.breakoutNode) && breakoutNodePresent) { setBreakoutNodePresent(false); } // Remove ! during platform_editor_hydratable_ui cleanup // eslint-disable-next-line @typescript-eslint/no-non-null-assertion var nextBreakoutMode = (0, _getBreakoutMode.getBreakoutMode)(editorView.state); if (nextBreakoutMode !== breakoutMode) { setBreakoutMode(nextBreakoutMode); } }); var interactionState = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(api, 'interaction.interactionState'); if (interactionState === 'hasNotHadInteraction') { return null; } if (isDragging || isPMDragging) { if ((0, _experiments.editorExperiment)('advanced_layouts', true)) { return null; } } var isViewMode = mode === 'view'; var isEditMode = mode === 'edit'; return !isViewMode && editorDisabled === false ? /*#__PURE__*/_react.default.createElement(_LayoutButton.default, { editorView: editorView, mountPoint: mountPoint, boundariesElement: boundariesElement, scrollableElement: scrollableElement, isLivePage: isEditMode, isBreakoutNodePresent: breakoutNodePresent, breakoutMode: breakoutMode, api: api }) : null; }; var breakoutPlugin = exports.breakoutPlugin = function breakoutPlugin(_ref4) { var options = _ref4.config, api = _ref4.api; return { name: 'breakout', pmPlugins: function pmPlugins() { if ((0, _expValEquals.expValEquals)('platform_editor_breakout_resizing', 'isEnabled', true)) { return [{ name: 'breakout-resizing', plugin: function plugin(_ref5) { var getIntl = _ref5.getIntl, nodeViewPortalProviderAPI = _ref5.nodeViewPortalProviderAPI; return (0, _resizingPlugin.createResizingPlugin)(api, getIntl, nodeViewPortalProviderAPI, options); } }]; } return [{ name: 'breakout', plugin: function plugin(props) { return createPlugin(api, props, options === null || options === void 0 ? void 0 : options.appearance); } }]; }, marks: function marks() { return [{ name: 'breakout', mark: _adfSchema.breakout }]; }, getSharedState: function getSharedState(editorState) { if (!editorState) { return { breakoutNode: undefined }; } if ((0, _expValEquals.expValEquals)('platform_editor_breakout_resizing', 'isEnabled', true)) { var resizingPluginState = _resizingPlugin.resizingPluginKey.getState(editorState); if (!resizingPluginState) { return { breakoutNode: undefined, activeGuidelineKey: undefined }; } return resizingPluginState; } var pluginState = _pluginKey.pluginKey.getState(editorState); if (!pluginState) { return { breakoutNode: undefined }; } return pluginState; }, contentComponent: function contentComponent(_ref6) { var editorView = _ref6.editorView, popupsMountPoint = _ref6.popupsMountPoint, popupsBoundariesElement = _ref6.popupsBoundariesElement, popupsScrollableElement = _ref6.popupsScrollableElement; if (!editorView) { return null; } if ((0, _expValEquals.expValEquals)('platform_editor_breakout_resizing', 'isEnabled', true)) { return /*#__PURE__*/_react.default.createElement(_GuidelineLabel.GuidelineLabel, { api: api, editorView: editorView, mountPoint: popupsMountPoint, boundariesElement: popupsBoundariesElement, scrollableElement: popupsScrollableElement }); } // This is a bit crappy, but should be resolved once we move to a static schema. if (options && !options.allowBreakoutButton) { return null; } return /*#__PURE__*/_react.default.createElement(LayoutButtonWrapper, { api: api, mountPoint: popupsMountPoint, editorView: editorView, boundariesElement: popupsBoundariesElement, scrollableElement: popupsScrollableElement }); } }; };