@atlaskit/editor-plugin-insert-block
Version:
Insert block plugin for @atlaskit/editor-core
849 lines (836 loc) • 46.7 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
import _extends from "@babel/runtime/helpers/extends";
var _templateObject;
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
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) { _defineProperty(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; }
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
/* eslint-disable @atlaskit/ui-styling-standard/no-imported-style-values */
/**
* @jsxRuntime classic
* @jsx jsx
*/
import React from 'react';
/* eslint-disable @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports */
import { css, jsx } from '@emotion/react';
import { injectIntl } from 'react-intl';
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
import { buttonGroupStyle, separatorStyles, wrapperStyle } from '@atlaskit/editor-common/styles';
import { Popup, TableSelectorPopup } from '@atlaskit/editor-common/ui';
import { ToolbarButton } from '@atlaskit/editor-common/ui-menu';
import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners as withOuterListeners } from '@atlaskit/editor-common/ui-react';
import { akEditorMenuZIndex } from '@atlaskit/editor-shared-styles';
import { EmojiPicker as AkEmojiPicker } from '@atlaskit/emoji/picker';
// Ignored via go/ees005
// eslint-disable-next-line import/no-namespace
import { fg } from '@atlaskit/platform-feature-flags';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { LINK_BUTTON_KEY } from '../toolbar-components/hooks/filterDropdownItems';
import { BlockInsertMenu } from './block-insert-menu';
import { createItems } from './create-items';
// Ignored via go/ees005
// eslint-disable-next-line import/no-named-as-default
/**
* Checks if an element is detached (i.e. not in the current document)
*/
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage -- Existing DOM check surfaced by this mechanical PR.
var isDetachedElement = function isDetachedElement(el) {
return !document.body.contains(el);
};
var TABLE_SELECTOR_STRING = 'table selector';
// TODO: ED-26959 - Jenga team will create a component for a split button using this css
var getHoverStyles = function getHoverStyles(selector) {
return "&:hover ".concat(selector, " {\n background: ", "var(--ds-background-neutral-subtle-hovered, #0515240F)", ";\n\n &:hover {\n background: ", "var(--ds-background-neutral-hovered, #0B120E24)", ";\n }\n }");
};
var EmojiPicker = function EmojiPicker(props) {
var setOutsideClickTargetRef = React.useContext(OutsideClickTargetRefContext);
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
return jsx(AkEmojiPicker, _extends({
onPickerRef: setOutsideClickTargetRef
}, props));
};
var EmojiPickerWithListeners = withOuterListeners(EmojiPicker);
export var tableButtonWrapper = function tableButtonWrapper(_ref) {
var isTableSelectorOpen = _ref.isTableSelectorOpen,
isButtonDisabled = _ref.isButtonDisabled;
return (// eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression -- Needs manual remediation due to mixins
css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n\t\tdisplay: flex;\n\t\t", "\n\t\t", "\n\n .table-toolbar-btn {\n\t\t\tborder-top-right-radius: ", ";\n\t\t\tborder-bottom-right-radius: ", ";\n\t\t\tmargin-right: ", ";\n\t\t\tpadding: ", ";\n\t\t\t& > span {\n\t\t\t\tmin-width: 16px;\n\t\t\t\tmargin: ", ";\n\t\t\t}\n\t\t}\n\t\t.table-selector-toolbar-btn {\n\t\t\tpadding: ", ";\n\t\t\t& > span {\n\t\t\t\tmargin: ", ";\n\t\t\t\twidth: 16px !important;\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: center;\n\t\t\t}\n\n\t\t\tborder-top-left-radius: ", " !important;\n\t\t\tborder-bottom-left-radius: ", " !important;\n\t\t}\n\t"])), !isTableSelectorOpen && !isButtonDisabled && getHoverStyles('.table-selector-toolbar-btn'), !isTableSelectorOpen && !isButtonDisabled && getHoverStyles('.table-toolbar-btn'), "var(--ds-radius-large, 0px)", "var(--ds-radius-large, 0px)", "var(--ds-space-025, 2px)", "var(--ds-space-0, 0px)", "var(--ds-space-0, 0px)", "var(--ds-space-0, 0px)", "var(--ds-space-0, 0px)", "var(--ds-radius-large, 0px)", "var(--ds-radius-large, 0px)")
);
};
// eslint-disable-next-line @repo/internal/react/no-class-components
export var ToolbarInsertBlock = /*#__PURE__*/function (_React$PureComponent) {
function ToolbarInsertBlock() {
var _this;
_classCallCheck(this, ToolbarInsertBlock);
for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
_args[_key] = arguments[_key];
}
_this = _callSuper(this, ToolbarInsertBlock, [].concat(_args));
_defineProperty(_this, "tableButtonRef", /*#__PURE__*/React.createRef());
_defineProperty(_this, "tableSelectorButtonRef", /*#__PURE__*/React.createRef());
_defineProperty(_this, "state", {
isPlusMenuOpen: false,
emojiPickerOpen: false,
isOpenedByKeyboard: false,
buttons: [],
dropdownItems: [],
isTableSelectorOpen: false,
isTableSelectorOpenedByKeyboard: false
});
_defineProperty(_this, "onOpenChange", function (attrs) {
var state = {
isPlusMenuOpen: attrs.isPlusMenuOpen,
emojiPickerOpen: _this.state.emojiPickerOpen
};
if (_this.state.emojiPickerOpen && !attrs.open) {
state.emojiPickerOpen = false;
}
_this.setState(state, function () {
var dispatchAnalyticsEvent = _this.props.dispatchAnalyticsEvent;
if (!dispatchAnalyticsEvent) {
return;
}
var isPlusMenuOpen = _this.state.isPlusMenuOpen;
if (isPlusMenuOpen) {
return dispatchAnalyticsEvent({
action: ACTION.OPENED,
actionSubject: ACTION_SUBJECT.PLUS_MENU,
eventType: EVENT_TYPE.UI
});
}
return dispatchAnalyticsEvent({
action: ACTION.CLOSED,
actionSubject: ACTION_SUBJECT.PLUS_MENU,
eventType: EVENT_TYPE.UI
});
});
});
_defineProperty(_this, "togglePlusMenuVisibility", function (event) {
var isPlusMenuOpen = _this.state.isPlusMenuOpen;
var pluginInjectionApi = _this.props.pluginInjectionApi;
if (pluginInjectionApi && fg('platform_editor_ease_of_use_metrics')) {
pluginInjectionApi.core.actions.execute(function (_ref2) {
var tr = _ref2.tr;
if (isPlusMenuOpen) {
var _pluginInjectionApi$m;
(_pluginInjectionApi$m = pluginInjectionApi.metrics) === null || _pluginInjectionApi$m === void 0 || _pluginInjectionApi$m.commands.startActiveSessionTimer()({
tr: tr
});
} else {
var _pluginInjectionApi$m2;
(_pluginInjectionApi$m2 = pluginInjectionApi.metrics) === null || _pluginInjectionApi$m2 === void 0 || _pluginInjectionApi$m2.commands.handleIntentToStartEdit({
shouldStartTimer: false,
shouldPersistActiveSession: true
})({
tr: tr
});
}
return tr;
});
}
_this.onOpenChange({
isPlusMenuOpen: !isPlusMenuOpen
});
if ((event === null || event === void 0 ? void 0 : event.key) === 'Escape') {
var _ref3;
(_ref3 = _this.plusButtonRef || _this.dropdownButtonRef) === null || _ref3 === void 0 || (_ref3 = _ref3.deref()) === null || _ref3 === void 0 || _ref3.focus();
}
});
_defineProperty(_this, "toggleEmojiPicker", function () {
var inputMethod = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : INPUT_METHOD.TOOLBAR;
_this.setState(function (prevState) {
return {
emojiPickerOpen: !prevState.emojiPickerOpen
};
}, function () {
if (_this.state.emojiPickerOpen) {
var dispatchAnalyticsEvent = _this.props.dispatchAnalyticsEvent;
if (dispatchAnalyticsEvent) {
dispatchAnalyticsEvent({
action: ACTION.OPENED,
actionSubject: ACTION_SUBJECT.PICKER,
actionSubjectId: ACTION_SUBJECT_ID.PICKER_EMOJI,
attributes: {
inputMethod: inputMethod
},
eventType: EVENT_TYPE.UI
});
}
}
});
});
_defineProperty(_this, "handleEmojiPressEscape", function () {
var _this$emojiButtonRef;
_this.toggleEmojiPicker(INPUT_METHOD.KEYBOARD);
(_this$emojiButtonRef = _this.emojiButtonRef) === null || _this$emojiButtonRef === void 0 || (_this$emojiButtonRef = _this$emojiButtonRef.deref()) === null || _this$emojiButtonRef === void 0 || _this$emojiButtonRef.focus();
});
_defineProperty(_this, "handleEmojiClickOutside", function (e) {
// Ignore click events for detached elements.
// Workaround for FS-1322 - where two onClicks fire - one when the upload button is
// still in the document, and one once it's detached. Does not always occur, and
// may be a side effect of a react render optimisation
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
if (e.target && !isDetachedElement(e.target)) {
_this.toggleEmojiPicker(INPUT_METHOD.TOOLBAR);
}
});
_defineProperty(_this, "getToolbarButtonTestId", function (btn) {
var buttonTestIds = {
media: 'media-attachment-toolbar-button'
};
return buttonTestIds[btn.value.name] || String(btn.content);
});
_defineProperty(_this, "handleToolbarRef", function (buttonName) {
return function (ref) {
if (!ref) {
return;
}
switch (buttonName) {
case 'emoji':
_this.emojiButtonRef = new WeakRef(ref);
break;
case 'media':
_this.mediaButtonRef = new WeakRef(ref);
break;
}
};
});
_defineProperty(_this, "handlePlusButtonRef", function (ref) {
if (ref) {
_this.plusButtonRef = new WeakRef(ref);
}
});
_defineProperty(_this, "handleDropDownButtonRef", function (ref) {
if (ref) {
_this.dropdownButtonRef = new WeakRef(ref);
}
});
_defineProperty(_this, "toggleTableSelector", function () {
var _inputMethod = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : INPUT_METHOD.TOOLBAR;
_this.setState(function (prevState) {
return {
isTableSelectorOpen: !prevState.isTableSelectorOpen
};
});
});
_defineProperty(_this, "handleSelectedTableSize", function (rowsCount, colsCount) {
_this.insertTableWithSize(INPUT_METHOD.TOOLBAR, rowsCount, colsCount)();
_this.toggleTableSelector();
});
_defineProperty(_this, "handleTableSelectorPressEscape", function () {
var _this$tableSelectorBu;
_this.toggleTableSelector(INPUT_METHOD.KEYBOARD);
(_this$tableSelectorBu = _this.tableSelectorButtonRef.current) === null || _this$tableSelectorBu === void 0 || _this$tableSelectorBu.focus();
});
_defineProperty(_this, "handleTableSelectorClickOutside", function (e) {
// Ignore click events for detached elements.
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
if (e.target && !isDetachedElement(e.target)) {
_this.toggleTableSelector(INPUT_METHOD.TOOLBAR);
}
});
_defineProperty(_this, "handleClick", function () {
_this.togglePlusMenuVisibility();
});
_defineProperty(_this, "handleOpenByKeyboard", function (event) {
if (event.key === 'Enter' || event.key === ' ') {
_this.setState(_objectSpread(_objectSpread({}, _this.state), {}, {
isOpenedByKeyboard: true
}));
event.preventDefault();
_this.togglePlusMenuVisibility();
}
});
_defineProperty(_this, "handleTableSelectorOpenByKeyboard", function (event) {
if (event.key === 'Enter' || event.key === ' ') {
_this.setState({
isTableSelectorOpenedByKeyboard: true
});
}
});
_defineProperty(_this, "toggleLinkPanel", function (inputMethod) {
var _pluginInjectionApi$c, _pluginInjectionApi$c2, _pluginInjectionApi$h;
var pluginInjectionApi = _this.props.pluginInjectionApi;
return (_pluginInjectionApi$c = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c2 = pluginInjectionApi.core) === null || _pluginInjectionApi$c2 === void 0 ? void 0 : _pluginInjectionApi$c2.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$h = pluginInjectionApi.hyperlink) === null || _pluginInjectionApi$h === void 0 ? void 0 : _pluginInjectionApi$h.commands.showLinkToolbar(inputMethod))) !== null && _pluginInjectionApi$c !== void 0 ? _pluginInjectionApi$c : false;
});
_defineProperty(_this, "insertMention", function (inputMethod) {
var _pluginInjectionApi$m3, _pluginInjectionApi$m4;
var _this$props = _this.props,
editorView = _this$props.editorView,
pluginInjectionApi = _this$props.pluginInjectionApi;
if (!editorView) {
return true;
}
var pluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$m3 = pluginInjectionApi.mention) === null || _pluginInjectionApi$m3 === void 0 ? void 0 : _pluginInjectionApi$m3.sharedState.currentState();
if (pluginState && pluginState.canInsertMention === false) {
return false;
}
return Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$m4 = pluginInjectionApi.mention) === null || _pluginInjectionApi$m4 === void 0 || (_pluginInjectionApi$m4 = _pluginInjectionApi$m4.actions) === null || _pluginInjectionApi$m4 === void 0 ? void 0 : _pluginInjectionApi$m4.openTypeAhead(inputMethod));
});
_defineProperty(_this, "insertTable", function (inputMethod) {
var _this$props2 = _this.props,
pluginInjectionApi = _this$props2.pluginInjectionApi,
editorView = _this$props2.editorView;
var state = editorView.state,
dispatch = editorView.dispatch;
// workaround to solve race condition where cursor is not placed correctly inside table
queueMicrotask(function () {
var _pluginInjectionApi$t, _pluginInjectionApi$t2, _pluginInjectionApi$t3;
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$t = pluginInjectionApi.table) === null || _pluginInjectionApi$t === void 0 || (_pluginInjectionApi$t2 = (_pluginInjectionApi$t3 = _pluginInjectionApi$t.actions).insertTable) === null || _pluginInjectionApi$t2 === void 0 || _pluginInjectionApi$t2.call(_pluginInjectionApi$t3, {
action: ACTION.INSERTED,
actionSubject: ACTION_SUBJECT.DOCUMENT,
actionSubjectId: ACTION_SUBJECT_ID.TABLE,
attributes: {
inputMethod: inputMethod
},
eventType: EVENT_TYPE.TRACK
})(state, dispatch);
});
});
_defineProperty(_this, "insertTableWithSize", function (inputMethod, rowsCount, colsCount) {
return function () {
var pluginInjectionApi = _this.props.pluginInjectionApi;
// workaround to solve race condition where cursor is not placed correctly inside table
queueMicrotask(function () {
var _pluginInjectionApi$c3, _pluginInjectionApi$t4;
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c3 = pluginInjectionApi.core) === null || _pluginInjectionApi$c3 === void 0 || _pluginInjectionApi$c3.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$t4 = pluginInjectionApi.table) === null || _pluginInjectionApi$t4 === void 0 ? void 0 : _pluginInjectionApi$t4.commands.insertTableWithSize(rowsCount, colsCount, INPUT_METHOD.PICKER));
});
};
});
_defineProperty(_this, "createDate", function (inputMethod) {
var _pluginInjectionApi$c4, _pluginInjectionApi$d;
var pluginInjectionApi = _this.props.pluginInjectionApi;
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c4 = pluginInjectionApi.core) === null || _pluginInjectionApi$c4 === void 0 || _pluginInjectionApi$c4.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$d = pluginInjectionApi.date) === null || _pluginInjectionApi$d === void 0 || (_pluginInjectionApi$d = _pluginInjectionApi$d.commands) === null || _pluginInjectionApi$d === void 0 ? void 0 : _pluginInjectionApi$d.insertDate({
inputMethod: inputMethod
}));
return true;
});
_defineProperty(_this, "createPlaceholderText", function () {
var _pluginInjectionApi$p;
var _this$props3 = _this.props,
editorView = _this$props3.editorView,
pluginInjectionApi = _this$props3.pluginInjectionApi;
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$p = pluginInjectionApi.placeholderText) === null || _pluginInjectionApi$p === void 0 || _pluginInjectionApi$p.actions.showPlaceholderFloatingToolbar(editorView.state, editorView.dispatch);
return true;
});
_defineProperty(_this, "insertLayoutColumns", function (inputMethod) {
var _pluginInjectionApi$l;
var _this$props4 = _this.props,
editorView = _this$props4.editorView,
pluginInjectionApi = _this$props4.pluginInjectionApi;
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$l = pluginInjectionApi.layout) === null || _pluginInjectionApi$l === void 0 || _pluginInjectionApi$l.actions.insertLayoutColumns(inputMethod)(editorView.state, editorView.dispatch);
return true;
});
_defineProperty(_this, "createStatus", function (inputMethod) {
var _pluginInjectionApi$c5, _pluginInjectionApi$s;
var pluginInjectionApi = _this.props.pluginInjectionApi;
return Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c5 = pluginInjectionApi.core) === null || _pluginInjectionApi$c5 === void 0 ? void 0 : _pluginInjectionApi$c5.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$s = pluginInjectionApi.status) === null || _pluginInjectionApi$s === void 0 || (_pluginInjectionApi$s = _pluginInjectionApi$s.commands) === null || _pluginInjectionApi$s === void 0 ? void 0 : _pluginInjectionApi$s.insertStatus(inputMethod)));
});
_defineProperty(_this, "openMediaPicker", function (inputMethod) {
var _this$props5 = _this.props,
onShowMediaPicker = _this$props5.onShowMediaPicker,
dispatchAnalyticsEvent = _this$props5.dispatchAnalyticsEvent;
if (onShowMediaPicker) {
var _this$mediaButtonRef, _this$props$popupsMou, _this$props$popupsMou2;
var ref = (_this$mediaButtonRef = _this.mediaButtonRef) === null || _this$mediaButtonRef === void 0 ? void 0 : _this$mediaButtonRef.deref();
var args = ref ? {
ref: ref,
mountPoint: (_this$props$popupsMou = _this.props.popupsMountPoint) !== null && _this$props$popupsMou !== void 0 ? _this$props$popupsMou : ref
} : undefined;
var argsWithUpdatedMountPoint = ref !== null && ref !== void 0 && ref.parentElement ? {
ref: ref,
mountPoint: (_this$props$popupsMou2 = _this.props.popupsMountPoint) !== null && _this$props$popupsMou2 !== void 0 ? _this$props$popupsMou2 : ref.parentElement
} : undefined;
onShowMediaPicker(fg('platform_editor_nov_a11y_fixes') ? argsWithUpdatedMountPoint : args);
if (dispatchAnalyticsEvent) {
dispatchAnalyticsEvent({
action: ACTION.OPENED,
actionSubject: ACTION_SUBJECT.PICKER,
actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
attributes: {
inputMethod: inputMethod
},
eventType: EVENT_TYPE.UI
});
}
}
return true;
});
_defineProperty(_this, "insertTaskDecision", function (name, inputMethod) {
return function () {
var _pluginInjectionApi$t5, _pluginInjectionApi$t6;
var _this$props6 = _this.props,
_this$props6$editorVi = _this$props6.editorView,
state = _this$props6$editorVi.state,
dispatch = _this$props6$editorVi.dispatch,
pluginInjectionApi = _this$props6.pluginInjectionApi;
var listType = name === 'action' ? 'taskList' : 'decisionList';
return (_pluginInjectionApi$t5 = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$t6 = pluginInjectionApi.taskDecision) === null || _pluginInjectionApi$t6 === void 0 ? void 0 : _pluginInjectionApi$t6.actions.insertTaskDecision(listType, inputMethod)(state, dispatch)) !== null && _pluginInjectionApi$t5 !== void 0 ? _pluginInjectionApi$t5 : false;
};
});
_defineProperty(_this, "insertHorizontalRule", function (inputMethod) {
var _pluginInjectionApi$r, _pluginInjectionApi$r2;
var _this$props7 = _this.props,
_this$props7$editorVi = _this$props7.editorView,
state = _this$props7$editorVi.state,
dispatch = _this$props7$editorVi.dispatch,
pluginInjectionApi = _this$props7.pluginInjectionApi;
return (_pluginInjectionApi$r = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$r2 = pluginInjectionApi.rule) === null || _pluginInjectionApi$r2 === void 0 ? void 0 : _pluginInjectionApi$r2.actions.insertHorizontalRule(inputMethod)(state, dispatch)) !== null && _pluginInjectionApi$r !== void 0 ? _pluginInjectionApi$r : false;
});
_defineProperty(_this, "insertExpand", function () {
var _pluginInjectionApi$e, _pluginInjectionApi$e2;
var _this$props8 = _this.props,
_this$props8$editorVi = _this$props8.editorView,
state = _this$props8$editorVi.state,
dispatch = _this$props8$editorVi.dispatch,
pluginInjectionApi = _this$props8.pluginInjectionApi;
return (_pluginInjectionApi$e = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$e2 = pluginInjectionApi.expand) === null || _pluginInjectionApi$e2 === void 0 ? void 0 : _pluginInjectionApi$e2.actions.insertExpand(state, dispatch)) !== null && _pluginInjectionApi$e !== void 0 ? _pluginInjectionApi$e : false;
});
_defineProperty(_this, "insertBlockType", function (itemName) {
return function () {
var _this$props9 = _this.props,
editorView = _this$props9.editorView,
onInsertBlockType = _this$props9.onInsertBlockType;
var state = editorView.state,
dispatch = editorView.dispatch;
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
onInsertBlockType(itemName)(state, dispatch);
return true;
};
});
_defineProperty(_this, "handleSelectedEmoji", function (emojiId) {
var _pluginInjectionApi$c6, _pluginInjectionApi$e3;
var pluginInjectionApi = _this.props.pluginInjectionApi;
_this.props.editorView.focus();
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c6 = pluginInjectionApi.core) === null || _pluginInjectionApi$c6 === void 0 || _pluginInjectionApi$c6.actions.execute((_pluginInjectionApi$e3 = pluginInjectionApi.emoji) === null || _pluginInjectionApi$e3 === void 0 ? void 0 : _pluginInjectionApi$e3.commands.insertEmoji(emojiId, INPUT_METHOD.PICKER));
_this.toggleEmojiPicker();
return true;
});
_defineProperty(_this, "onItemActivated", function (_ref4) {
var item = _ref4.item,
inputMethod = _ref4.inputMethod;
var _this$props0 = _this.props,
editorView = _this$props0.editorView,
handleImageUpload = _this$props0.handleImageUpload,
expandEnabled = _this$props0.expandEnabled;
// need to do this before inserting nodes so scrollIntoView works properly
if (!editorView.hasFocus()) {
editorView.focus();
}
switch (item.value.name) {
case LINK_BUTTON_KEY:
_this.toggleLinkPanel(inputMethod);
break;
case 'table':
_this.insertTable(inputMethod);
break;
case 'table selector':
_this.toggleTableSelector(inputMethod);
break;
case 'image upload':
if (handleImageUpload) {
var state = editorView.state,
dispatch = editorView.dispatch;
handleImageUpload()(state, dispatch);
}
break;
case 'media':
_this.openMediaPicker(inputMethod);
break;
case 'mention':
_this.insertMention(inputMethod);
break;
case 'emoji':
_this.toggleEmojiPicker(inputMethod);
break;
case 'codeblock':
case 'blockquote':
case 'panel':
_this.insertBlockType(item.value.name)();
break;
case 'action':
case 'decision':
_this.insertTaskDecision(item.value.name, inputMethod)();
break;
case 'horizontalrule':
_this.insertHorizontalRule(inputMethod);
break;
case 'date':
_this.createDate(inputMethod);
break;
case 'placeholder text':
_this.createPlaceholderText();
break;
case 'layout':
_this.insertLayoutColumns(inputMethod);
break;
case 'status':
_this.createStatus(inputMethod);
break;
// https://product-fabric.atlassian.net/browse/ED-8053
// @ts-ignore: OK to fallthrough to default
case 'expand':
if (expandEnabled) {
_this.insertExpand();
break;
}
// eslint-disable-next-line no-fallthrough
default:
if (item && item.onClick) {
item.onClick();
break;
}
}
_this.setState({
isPlusMenuOpen: false
});
});
_defineProperty(_this, "insertToolbarMenuItem", function (btn) {
return _this.onItemActivated({
item: btn,
inputMethod: INPUT_METHOD.TOOLBAR
});
});
_defineProperty(_this, "insertInsertMenuItem", function (_ref5) {
var item = _ref5.item;
return _this.onItemActivated({
item: item,
inputMethod: INPUT_METHOD.INSERT_MENU
});
});
return _this;
}
_inherits(ToolbarInsertBlock, _React$PureComponent);
return _createClass(ToolbarInsertBlock, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
// If number of visible buttons changed, close emoji picker and table selector
if (prevProps.buttons !== this.props.buttons) {
this.setState({
emojiPickerOpen: false,
isTableSelectorOpen: false
});
}
if (this.state.isOpenedByKeyboard) {
var _this$dropdownButtonR;
var downArrowEvent = new KeyboardEvent('keydown', {
bubbles: true,
key: 'ArrowDown'
});
(_this$dropdownButtonR = this.dropdownButtonRef) === null || _this$dropdownButtonR === void 0 || (_this$dropdownButtonR = _this$dropdownButtonR.deref()) === null || _this$dropdownButtonR === void 0 || _this$dropdownButtonR.dispatchEvent(downArrowEvent);
this.setState(_objectSpread(_objectSpread({}, this.state), {}, {
isOpenedByKeyboard: false
}));
}
if (this.state.isTableSelectorOpen) {
this.setState({
isTableSelectorOpenedByKeyboard: false
});
}
if (this.props.showElementBrowser !== prevProps.showElementBrowser) {
this.handleClick();
this.setState(_objectSpread(_objectSpread({}, this.state), {}, {
isPlusMenuOpen: this.props.showElementBrowser
}));
}
}
}, {
key: "renderPopup",
value: function renderPopup() {
var _this2 = this;
var emojiPickerOpen = this.state.emojiPickerOpen;
var _this$props1 = this.props,
popupsMountPoint = _this$props1.popupsMountPoint,
popupsBoundariesElement = _this$props1.popupsBoundariesElement,
popupsScrollableElement = _this$props1.popupsScrollableElement,
emojiProvider = _this$props1.emojiProvider;
var dropdownEmoji = this.state.dropdownItems.some(function (_ref6) {
var name = _ref6.value.name;
return name === 'emoji';
});
var dropDownButtonRef = this.plusButtonRef;
var ref = dropdownEmoji ? dropDownButtonRef : this.emojiButtonRef;
if (!emojiPickerOpen || !ref || !emojiProvider) {
return null;
}
var onUnmount = function onUnmount() {
requestAnimationFrame(function () {
var _this2$props$pluginIn;
return (_this2$props$pluginIn = _this2.props.pluginInjectionApi) === null || _this2$props$pluginIn === void 0 || (_this2$props$pluginIn = _this2$props$pluginIn.core) === null || _this2$props$pluginIn === void 0 || (_this2$props$pluginIn = _this2$props$pluginIn.actions) === null || _this2$props$pluginIn === void 0 ? void 0 : _this2$props$pluginIn.focus();
});
};
return jsx(Popup, {
target: ref.deref(),
fitHeight: 350,
fitWidth: 350
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
offset: [0, 3],
mountTo: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
scrollableElement: popupsScrollableElement,
onUnmount: onUnmount,
focusTrap: true,
zIndex: akEditorMenuZIndex
}, jsx(EmojiPickerWithListeners, {
emojiProvider: emojiProvider,
onSelection: this.handleSelectedEmoji,
handleClickOutside: this.handleEmojiClickOutside,
handleEscapeKeydown: this.handleEmojiPressEscape
}));
}
}, {
key: "renderTableSelectorPopup",
value: function renderTableSelectorPopup() {
var _this$tableButtonRef$;
var _this$state = this.state,
isTableSelectorOpen = _this$state.isTableSelectorOpen,
isTableSelectorOpenedByKeyboard = _this$state.isTableSelectorOpenedByKeyboard;
var _this$props10 = this.props,
popupsMountPoint = _this$props10.popupsMountPoint,
popupsBoundariesElement = _this$props10.popupsBoundariesElement,
popupsScrollableElement = _this$props10.popupsScrollableElement,
pluginInjectionApi = _this$props10.pluginInjectionApi;
var ref = (_this$tableButtonRef$ = this.tableButtonRef.current) !== null && _this$tableButtonRef$ !== void 0 ? _this$tableButtonRef$ : undefined;
if (!isTableSelectorOpen) {
return null;
}
// We use focusTrap in the Popup. When we insert a table via popup,
// the popup closes, focusTrap gets destroyed and the popup detaches.
// The focus gets set to the body element. onUnmount method sets focus on the editor right before the
// Popup will be unmounted to ensure that the new table has a selection with a blinking cursor.
// So we can start typing right away.
var onUnmount = function onUnmount() {
var _pluginInjectionApi$c7;
return pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c7 = pluginInjectionApi.core) === null || _pluginInjectionApi$c7 === void 0 || (_pluginInjectionApi$c7 = _pluginInjectionApi$c7.actions) === null || _pluginInjectionApi$c7 === void 0 ? void 0 : _pluginInjectionApi$c7.focus();
};
return jsx(TableSelectorPopup, {
allowOutsideSelection: true,
target: ref,
onUnmount: onUnmount,
onSelection: this.handleSelectedTableSize,
popupsMountPoint: popupsMountPoint,
popupsBoundariesElement: popupsBoundariesElement,
popupsScrollableElement: popupsScrollableElement,
handleClickOutside: this.handleTableSelectorClickOutside,
handleEscapeKeydown: this.handleTableSelectorPressEscape,
isOpenedByKeyboard: isTableSelectorOpenedByKeyboard
});
}
}, {
key: "render",
value: function render() {
var _this3 = this,
_tableButton,
_tableButton2,
_tableButton3,
_tableButton4,
_tableButton5,
_tableButton6,
_tableButton7,
_tableSelectorButton,
_tableSelectorButton2,
_tableSelectorButton3,
_tableSelectorButton4,
_tableSelectorButton5,
_tableSelectorButton6,
_this$props$isDisable,
_this$plusButtonRef,
_this$props$pluginInj;
var _this$state2 = this.state,
buttons = _this$state2.buttons,
dropdownItems = _this$state2.dropdownItems,
emojiPickerOpen = _this$state2.emojiPickerOpen,
isTableSelectorOpen = _this$state2.isTableSelectorOpen;
var _this$props11 = this.props,
isDisabled = _this$props11.isDisabled,
isReducedSpacing = _this$props11.isReducedSpacing,
editorAppearance = _this$props11.editorAppearance;
var isFullPageAppearance = ['full-page', 'full-width'].includes(editorAppearance !== null && editorAppearance !== void 0 ? editorAppearance : '');
var isTableButtonVisible = buttons.some(function (_ref7) {
var value = _ref7.value;
return value.name === 'table';
});
var isTableSizeVisible = buttons.some(function (_ref8) {
var value = _ref8.value;
return value.name === 'table selector';
});
if (buttons.length === 0 && dropdownItems.length === 0) {
return null;
}
var toolbarButtons = [];
var tableSelectorButton;
var tableButton;
// Seperate table buttons from toolbar buttons
var _iterator = _createForOfIteratorHelper(buttons),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var btn = _step.value;
if (btn.value.name === TABLE_SELECTOR_STRING) {
tableSelectorButton = btn;
} else if (btn.value.name === 'table' && this.props.tableSelectorSupported) {
tableButton = btn;
} else {
toolbarButtons.push(btn);
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return jsx("span", {
css:
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values
buttonGroupStyle
}, toolbarButtons.map(function (btn) {
return jsx(ToolbarButton, {
item: btn,
testId: _this3.getToolbarButtonTestId(btn),
ref: _this3.handleToolbarRef(btn.value.name),
key: btn.value.name,
spacing: isReducedSpacing ? 'none' : 'default',
disabled: isDisabled || btn.isDisabled,
iconBefore: btn.elemBefore,
selected: btn.value.name === 'emoji' && emojiPickerOpen || btn.isActive,
title: btn.title,
"aria-label": btn['aria-label'],
"aria-haspopup": btn['aria-haspopup'],
"aria-keyshortcuts": btn['aria-keyshortcuts'],
onItemClick: _this3.insertToolbarMenuItem
});
}), this.props.tableSelectorSupported && (isTableButtonVisible || isTableSizeVisible) && jsx("div", {
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
css: tableButtonWrapper({
isTableSelectorOpen: isTableSelectorOpen,
isButtonDisabled: (_tableButton = tableButton) === null || _tableButton === void 0 ? void 0 : _tableButton.isDisabled
})
}, isTableButtonVisible && jsx(ToolbarButton
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/design-system/no-unsafe-style-overrides -- Ignored via go/DSP-18766
, {
className: "table-toolbar-btn",
item: tableButton,
ref: this.tableButtonRef,
testId: String((_tableButton2 = tableButton) === null || _tableButton2 === void 0 ? void 0 : _tableButton2.content),
key: (_tableButton3 = tableButton) === null || _tableButton3 === void 0 ? void 0 : _tableButton3.value.name,
spacing: isReducedSpacing ? 'none' : 'default',
disabled: isDisabled || ((_tableButton4 = tableButton) === null || _tableButton4 === void 0 ? void 0 : _tableButton4.isDisabled),
iconBefore: (_tableButton5 = tableButton) === null || _tableButton5 === void 0 ? void 0 : _tableButton5.elemBefore,
selected: ((_tableButton6 = tableButton) === null || _tableButton6 === void 0 ? void 0 : _tableButton6.isActive) || isTableSelectorOpen,
title: (_tableButton7 = tableButton) === null || _tableButton7 === void 0 ? void 0 : _tableButton7.title,
"aria-label": tableButton ? tableButton['aria-label'] : undefined,
"aria-haspopup": tableButton ? tableButton['aria-haspopup'] : undefined,
"aria-keyshortcuts": tableButton ? tableButton['aria-keyshortcuts'] : undefined,
onItemClick: this.insertToolbarMenuItem
}), isTableButtonVisible && jsx(ToolbarButton
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/design-system/no-unsafe-style-overrides -- Ignored via go/DSP-18766
, {
className: "table-selector-toolbar-btn",
item: tableSelectorButton,
testId: String((_tableSelectorButton = tableSelectorButton) === null || _tableSelectorButton === void 0 ? void 0 : _tableSelectorButton.content),
key: (_tableSelectorButton2 = tableSelectorButton) === null || _tableSelectorButton2 === void 0 ? void 0 : _tableSelectorButton2.value.name,
ref: this.tableSelectorButtonRef,
spacing: isReducedSpacing ? 'none' : 'default',
disabled: isDisabled || ((_tableSelectorButton3 = tableSelectorButton) === null || _tableSelectorButton3 === void 0 ? void 0 : _tableSelectorButton3.isDisabled),
iconBefore: (_tableSelectorButton4 = tableSelectorButton) === null || _tableSelectorButton4 === void 0 ? void 0 : _tableSelectorButton4.elemBefore,
selected: ((_tableSelectorButton5 = tableSelectorButton) === null || _tableSelectorButton5 === void 0 ? void 0 : _tableSelectorButton5.isActive) || isTableSelectorOpen,
title: (_tableSelectorButton6 = tableSelectorButton) === null || _tableSelectorButton6 === void 0 ? void 0 : _tableSelectorButton6.title,
"aria-label": tableSelectorButton ? tableSelectorButton['aria-label'] : undefined,
"aria-haspopup": tableSelectorButton ? tableSelectorButton['aria-haspopup'] : undefined,
"aria-keyshortcuts": tableSelectorButton ? tableSelectorButton['aria-keyshortcuts'] : undefined,
onItemClick: this.insertToolbarMenuItem,
onKeyDown: this.handleTableSelectorOpenByKeyboard
})), jsx("span", {
css: wrapperStyle
}, this.renderPopup(), this.renderTableSelectorPopup(), jsx(BlockInsertMenu, {
popupsMountPoint: this.props.popupsMountPoint,
popupsBoundariesElement: this.props.popupsBoundariesElement,
popupsScrollableElement: this.props.popupsScrollableElement,
disabled: (_this$props$isDisable = this.props.isDisabled) !== null && _this$props$isDisable !== void 0 ? _this$props$isDisable : false,
editorView: this.props.editorView,
spacing: this.props.isReducedSpacing ? 'none' : 'default',
label: this.props.intl.formatMessage(messages.insertMenu),
open: this.state.isPlusMenuOpen,
plusButtonRef: (_this$plusButtonRef = this.plusButtonRef) === null || _this$plusButtonRef === void 0 ? void 0 : _this$plusButtonRef.deref(),
items: this.state.dropdownItems,
onRef: this.handleDropDownButtonRef,
onPlusButtonRef: this.handlePlusButtonRef,
onClick: this.handleClick,
onKeyDown: this.handleOpenByKeyboard,
onInsert: this.insertInsertMenuItem,
togglePlusMenuVisibility: this.togglePlusMenuVisibility,
showElementBrowserLink: this.props.showElementBrowserLink || false,
pluginInjectionApi: this.props.pluginInjectionApi,
isFullPageAppearance: isFullPageAppearance
})), (!((_this$props$pluginInj = this.props.pluginInjectionApi) !== null && _this$props$pluginInj !== void 0 && _this$props$pluginInj.primaryToolbar) && this.props.showSeparator || isFullPageAppearance && editorExperiment('platform_editor_controls', 'variant1')) && /* eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage */
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
jsx("span", {
css: separatorStyles
}));
}
}], [{
key: "getDerivedStateFromProps",
value: function getDerivedStateFromProps(props, state) {
var _props$pluginInjectio, _props$pluginInjectio2, _props$pluginInjectio3;
var _createItems = createItems({
isTypeAheadAllowed: props.isTypeAheadAllowed,
tableSupported: props.tableSupported,
tableSelectorSupported: props.tableSelectorSupported,
mediaUploadsEnabled: props.mediaUploadsEnabled,
mediaSupported: props.mediaSupported,
isEditorOffline: props.isEditorOffline,
imageUploadSupported: props.imageUploadSupported,
imageUploadEnabled: props.imageUploadEnabled,
mentionsSupported: props.mentionsSupported,
mentionsDisabled: props.mentionsDisabled,
actionSupported: props.actionSupported,
decisionSupported: props.decisionSupported,
linkSupported: props.linkSupported,
linkDisabled: props.linkDisabled,
emojiDisabled: props.emojiDisabled,
hasEmojiPlugin: !!((_props$pluginInjectio = props.pluginInjectionApi) !== null && _props$pluginInjectio !== void 0 && _props$pluginInjectio.emoji),
hasMentionsPlugin: !!((_props$pluginInjectio2 = props.pluginInjectionApi) !== null && _props$pluginInjectio2 !== void 0 && _props$pluginInjectio2.mention),
hasMediaPlugin: !!((_props$pluginInjectio3 = props.pluginInjectionApi) !== null && _props$pluginInjectio3 !== void 0 && _props$pluginInjectio3.media),
nativeStatusSupported: props.nativeStatusSupported,
dateEnabled: props.dateEnabled,
placeholderTextEnabled: props.placeholderTextEnabled,
horizontalRuleEnabled: props.horizontalRuleEnabled,
layoutSectionEnabled: props.layoutSectionEnabled,
expandEnabled: props.expandEnabled,
showElementBrowserLink: props.showElementBrowserLink,
emojiProvider: props.emojiProvider,
availableWrapperBlockTypes: props.availableWrapperBlockTypes,
insertMenuItems: props.insertMenuItems,
schema: props.editorView.state.schema,
numberOfButtons: props.buttons,
formatMessage: props.intl.formatMessage
}),
_createItems2 = _slicedToArray(_createItems, 2),
buttons = _createItems2[0],
dropdownItems = _createItems2[1];
return _objectSpread(_objectSpread({}, state), {}, {
buttons: buttons,
dropdownItems: dropdownItems
});
}
}]);
}(React.PureComponent);
// eslint-disable-next-line @typescript-eslint/ban-types
var _default_1 = injectIntl(ToolbarInsertBlock);
export default _default_1;