UNPKG

@atlaskit/editor-plugin-panel

Version:

Panel plugin for @atlaskit/editor-core.

352 lines (350 loc) 15.7 kB
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; 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; } import React from 'react'; import { PanelType } from '@atlaskit/adf-schema'; import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics'; import { withAnalytics } from '@atlaskit/editor-common/editor-analytics'; import commonMessages, { panelMessages as messages } from '@atlaskit/editor-common/messages'; import { getPanelTypeBackgroundNoTokens } from '@atlaskit/editor-common/panel'; import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check'; import { DEFAULT_BORDER_COLOR, panelBackgroundPalette } from '@atlaskit/editor-common/ui-color'; import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils'; import { akEditorSelectedNodeClassName } from '@atlaskit/editor-shared-styles'; import CopyIcon from '@atlaskit/icon/core/copy'; import CrossCircleIcon from '@atlaskit/icon/core/cross-circle'; import DeleteIcon from '@atlaskit/icon/core/delete'; import EmojiRemoveIcon from '@atlaskit/icon/core/emoji-remove'; import StatusDiscoveryIcon from '@atlaskit/icon/core/status-discovery'; import InformationIcon from '@atlaskit/icon/core/status-information'; import SuccessIcon from '@atlaskit/icon/core/status-success'; import WarningIcon from '@atlaskit/icon/core/status-warning'; import { changePanelType, removePanel } from '../editor-actions/actions'; import { findPanel } from '../pm-plugins/utils/utils'; import { panelTypeDropdown } from './panelTypeDropdown'; export var panelIconMap = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, PanelType.INFO, { shortName: ':info:', id: 'atlassian-info' }), PanelType.NOTE, { shortName: ':note:', id: 'atlassian-note' }), PanelType.WARNING, { shortName: ':warning:', id: 'atlassian-warning' }), PanelType.ERROR, { shortName: ':cross_mark:', id: 'atlassian-cross_mark' }), PanelType.SUCCESS, { shortName: ':check_mark:', id: 'atlassian-check_mark' }), PanelType.TIP, { shortName: ':tip:', id: 'atlassian-tip' }); export var getToolbarItems = function getToolbarItems(formatMessage, panelNodeType, isCustomPanelEnabled, isCustomPanelEditable, providerFactory, hoverDecoration, editorAnalyticsAPI, activePanelType, activePanelColor, activePanelIcon, state, api) { var areAllNewToolbarFlagsDisabled = !areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar)); // TODO: ED-14403 - investigate why these titles are not getting translated for the tooltips var items = areAllNewToolbarFlagsDisabled ? [{ id: 'editor.panel.info', type: 'button', icon: InformationIcon, onClick: changePanelType(editorAnalyticsAPI)(PanelType.INFO), selected: activePanelType === PanelType.INFO, title: formatMessage(messages.info), tabIndex: null }, { id: 'editor.panel.note', type: 'button', icon: StatusDiscoveryIcon, onClick: changePanelType(editorAnalyticsAPI)(PanelType.NOTE), selected: activePanelType === PanelType.NOTE, title: formatMessage(messages.note), tabIndex: null }, { id: 'editor.panel.success', type: 'button', icon: SuccessIcon, onClick: changePanelType(editorAnalyticsAPI)(PanelType.SUCCESS), selected: activePanelType === PanelType.SUCCESS, title: formatMessage(messages.success), tabIndex: null }, { id: 'editor.panel.warning', type: 'button', icon: WarningIcon, onClick: changePanelType(editorAnalyticsAPI)(PanelType.WARNING), selected: activePanelType === PanelType.WARNING, title: formatMessage(messages.warning), tabIndex: null }, { id: 'editor.panel.error', type: 'button', icon: CrossCircleIcon, onClick: changePanelType(editorAnalyticsAPI)(PanelType.ERROR), selected: activePanelType === PanelType.ERROR, title: formatMessage(messages.error), tabIndex: null }] : [panelTypeDropdown({ activePanelType: activePanelType, editorAnalyticsAPI: editorAnalyticsAPI, formatMessage: formatMessage })].concat(_toConsumableArray(Boolean(api === null || api === void 0 ? void 0 : api.toolbar) ? [] : [{ type: 'separator' }])); if (isCustomPanelEnabled) { var changeColor = function changeColor(color) { return function (state, dispatch) { var panelNode = findPanel(state); if (panelNode === undefined) { return false; } var previousColor = panelNode.node.attrs.panelType === 'custom' ? panelNode.node.attrs.panelColor || 'none' : getPanelTypeBackgroundNoTokens(panelNode.node.attrs.panelType); var emojiInfo = panelNode.node.attrs.panelType; var panelEmoji = panelIconMap[emojiInfo]; var previousEmoji = panelEmoji ? { emoji: panelEmoji.shortName, emojiId: panelEmoji.id } : {}; if (previousColor === color) { changePanelType(editorAnalyticsAPI)(PanelType.CUSTOM, _objectSpread({ color: color }, previousEmoji), isCustomPanelEnabled)(state, dispatch); return false; } var payload = { action: ACTION.CHANGED_BACKGROUND_COLOR, actionSubject: ACTION_SUBJECT.PANEL, actionSubjectId: ACTION_SUBJECT_ID.PANEL, attributes: { newColor: color, previousColor: previousColor }, eventType: EVENT_TYPE.TRACK }; withAnalytics(editorAnalyticsAPI, payload)(changePanelType(editorAnalyticsAPI)(PanelType.CUSTOM, _objectSpread({ color: color }, previousEmoji), isCustomPanelEnabled))(state, dispatch); return false; }; }; var changeEmoji = function changeEmoji(emoji) { return function (state, dispatch) { var panelNode = findPanel(state); if (panelNode === undefined) { return false; } var previousIcon = panelNode.node.attrs.panelIcon || ''; if (previousIcon === emoji.shortName) { changePanelType(editorAnalyticsAPI)(PanelType.CUSTOM, { emoji: emoji.shortName, emojiId: emoji.id, emojiText: emoji.fallback }, true)(state, dispatch); return false; } var payload = { action: ACTION.CHANGED_ICON, actionSubject: ACTION_SUBJECT.PANEL, actionSubjectId: ACTION_SUBJECT_ID.PANEL, attributes: { newIcon: emoji.shortName, previousIcon: previousIcon }, eventType: EVENT_TYPE.TRACK }; withAnalytics(editorAnalyticsAPI, payload)(changePanelType(editorAnalyticsAPI)(PanelType.CUSTOM, { emoji: emoji.shortName, emojiId: emoji.id, emojiText: emoji.fallback }, true))(state, dispatch); return false; }; }; var removeEmoji = function removeEmoji() { return function (state, dispatch) { var panelNode = findPanel(state); if (activePanelType === PanelType.CUSTOM && !activePanelIcon) { return false; } if (panelNode === undefined) { return false; } var payload = { action: ACTION.REMOVE_ICON, actionSubject: ACTION_SUBJECT.PANEL, actionSubjectId: ACTION_SUBJECT_ID.PANEL, attributes: { icon: panelNode.node.attrs.panelIcon }, eventType: EVENT_TYPE.TRACK }; withAnalytics(editorAnalyticsAPI, payload)(changePanelType(editorAnalyticsAPI)(PanelType.CUSTOM, { emoji: undefined, emojiId: undefined, emojiText: undefined }, isCustomPanelEnabled))(state, dispatch); return false; }; }; var panelColor = activePanelType === PanelType.CUSTOM ? activePanelColor || getPanelTypeBackgroundNoTokens(PanelType.INFO) : getPanelTypeBackgroundNoTokens(activePanelType); var defaultPalette = panelBackgroundPalette.find(function (item) { return item.value === panelColor; }) || { // eslint-disable-next-line @atlassian/i18n/no-literal-string-in-object label: 'Custom', value: panelColor, border: DEFAULT_BORDER_COLOR }; if (isCustomPanelEditable) { var colorPicker = { id: 'editor.panel.colorPicker', title: formatMessage(messages.backgroundColor), isAriaExpanded: true, type: 'select', selectType: 'color', defaultValue: defaultPalette, options: panelBackgroundPalette, onChange: function onChange(option) { return changeColor(option.value); } }; var emojiPicker = { id: 'editor.panel.emojiPicker', title: formatMessage(messages.emoji), type: 'select', selectType: 'emoji', options: [], selected: activePanelType === PanelType.CUSTOM && !!activePanelIcon, onChange: function onChange(emoji) { return changeEmoji(emoji); } }; var removeEmojiButton = { id: 'editor.panel.removeEmoji', type: 'button', icon: function icon() { return /*#__PURE__*/React.createElement(EmojiRemoveIcon, { spacing: 'spacious', label: '' }); }, onClick: removeEmoji(), title: formatMessage(commonMessages.removeEmoji), disabled: activePanelIcon ? false : true }; items.push(emojiPicker, removeEmojiButton, { type: 'separator' }, colorPicker); } } if (areAllNewToolbarFlagsDisabled) { if (state) { items.push({ type: 'separator' }); items.push({ type: 'copy-button', items: [{ state: state, formatMessage: formatMessage, nodeType: panelNodeType }] }); } items.push({ type: 'separator' }, { id: 'editor.panel.delete', type: 'button', appearance: 'danger', focusEditoronEnter: true, icon: function icon() { return /*#__PURE__*/React.createElement(DeleteIcon, { spacing: 'spacious', label: '' }); }, onClick: removePanel(editorAnalyticsAPI), onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(panelNodeType, true), onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(panelNodeType, false), onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(panelNodeType, true), onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(panelNodeType, false), title: formatMessage(commonMessages.remove), tabIndex: null }); } else { var hoverDecorationProps = function hoverDecorationProps(nodeType, className) { return { onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, true, className), onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, false, className), onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, true, className), onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, false, className) }; }; // testId is required to show focus on trigger button on ESC key press // see hideOnEsc in platform/packages/editor/editor-plugin-floating-toolbar/src/ui/Dropdown.tsx var testId = 'panel-overflow-dropdown-trigger'; var overflowMenuConfig = [{ type: 'separator', fullHeight: true }, { type: 'overflow-dropdown', testId: testId, options: [_objectSpread({ title: formatMessage(commonMessages.copyToClipboard), onClick: function onClick() { var _api$core, _api$floatingToolbar; api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute( // @ts-ignore api === null || api === void 0 || (_api$floatingToolbar = api.floatingToolbar) === null || _api$floatingToolbar === void 0 ? void 0 : _api$floatingToolbar.commands.copyNode(panelNodeType, INPUT_METHOD.FLOATING_TB)); return true; }, icon: /*#__PURE__*/React.createElement(CopyIcon, { label: "" }) }, hoverDecorationProps(panelNodeType, akEditorSelectedNodeClassName)), _objectSpread({ title: formatMessage(commonMessages.delete), onClick: removePanel(editorAnalyticsAPI), icon: /*#__PURE__*/React.createElement(DeleteIcon, { label: "" }) }, hoverDecorationProps(panelNodeType))] }]; items.push.apply(items, overflowMenuConfig); } return items; }; export var getToolbarConfig = function getToolbarConfig(state, intl) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var providerFactory = arguments.length > 3 ? arguments[3] : undefined; var api = arguments.length > 4 ? arguments[4] : undefined; var formatMessage = intl.formatMessage; var panelObject = findPanel(state); if (panelObject) { var _api$decorations, _api$analytics; var nodeType = state.schema.nodes.panel; var _panelObject$node$att = panelObject.node.attrs, panelType = _panelObject$node$att.panelType, panelColor = _panelObject$node$att.panelColor, panelIcon = _panelObject$node$att.panelIcon; var isStandardPanel = function isStandardPanel(panelType) { return panelType !== PanelType.CUSTOM ? panelType : undefined; }; // force toolbar to be turned on var items = getToolbarItems(formatMessage, nodeType, options.allowCustomPanel || false, options.allowCustomPanel && options.allowCustomPanelEdit || false, providerFactory, api === null || api === void 0 || (_api$decorations = api.decorations) === null || _api$decorations === void 0 ? void 0 : _api$decorations.actions.hoverDecoration, api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, panelType, options.allowCustomPanel ? panelColor : undefined, options.allowCustomPanel ? panelIcon || isStandardPanel(panelType) : undefined, state, areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar)) ? api : undefined); var getDomRef = function getDomRef(editorView) { var domAtPos = editorView.domAtPos.bind(editorView); var element = findDomRefAtPos(panelObject.pos, domAtPos); return element; }; return { title: 'Panel floating controls', getDomRef: getDomRef, nodeType: nodeType, items: items, scrollable: true, groupLabel: formatMessage(messages.panelsGroup) }; } return; };