@atlaskit/editor-plugin-copy-button
Version:
editor-plugin-copy-button for @atlaskit/editor-core
103 lines (100 loc) • 4.29 kB
JavaScript
import commonMessages from '@atlaskit/editor-common/messages';
import CopyIcon from '@atlaskit/icon/core/copy';
import { createToolbarCopyCommandForMark, createToolbarCopyCommandForNode, getProvideMarkVisualFeedbackForCopyButtonCommand, removeMarkVisualFeedbackForCopyButtonCommand, resetCopiedState } from '../pm-plugins/commands';
import { copyButtonPluginKey } from '../pm-plugins/plugin-key';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isSeparator(item) {
return (item === null || item === void 0 ? void 0 : item.type) === 'separator';
}
function isNodeOptions(options) {
return 'nodeType' in options && options.nodeType !== undefined;
}
/**
* Performs the actions after a copy operation.
* - Sets the copied state in the editor state
* - Announces the copied message to the user
*/
export const afterCopy = api => message => {
var _api$accessibilityUti;
api === null || api === void 0 ? void 0 : api.core.actions.execute(({
tr
}) => {
return tr.setMeta(copyButtonPluginKey, {
copied: true
}).setMeta('scrollIntoView', false);
});
api === null || api === void 0 ? void 0 : (_api$accessibilityUti = api.accessibilityUtils) === null || _api$accessibilityUti === void 0 ? void 0 : _api$accessibilityUti.actions.ariaNotify(message, {
priority: 'important'
});
};
export function getCopyButtonConfig(options, hoverDecoration, editorAnalyticsApi, api) {
const {
state,
formatMessage,
onMouseEnter,
onMouseLeave,
onFocus,
onBlur
} = options;
const copyButtonState = copyButtonPluginKey.getState(state);
let buttonActionHandlers;
if (isNodeOptions(options)) {
const {
onClick
} = options;
buttonActionHandlers = {
onClick: createToolbarCopyCommandForNode(options.nodeType, editorAnalyticsApi, api, formatMessage(commonMessages.copiedToClipboard)),
// Note for future changes: these two handlers should perform
// the same action.
onMouseEnter: onMouseEnter || (hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(options.nodeType, true, 'ak-editor-selected-node')),
onFocus: onFocus || (hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(options.nodeType, true, 'ak-editor-selected-node')),
// Note for future changes: these two handlers should perform
// the same action.
onMouseLeave: resetCopiedState(options.nodeType, hoverDecoration, onMouseLeave),
onBlur: resetCopiedState(options.nodeType, hoverDecoration, onBlur)
};
if (onClick) {
buttonActionHandlers.onClick = (editorState, dispatch, editorView) => {
if (onClick(editorState, dispatch, editorView)) {
afterCopy(api)(formatMessage(commonMessages.copiedToClipboard));
return true;
}
return false;
};
}
} else {
buttonActionHandlers = {
onClick: createToolbarCopyCommandForMark(options.markType, editorAnalyticsApi),
onMouseEnter: getProvideMarkVisualFeedbackForCopyButtonCommand(options.markType),
onFocus: getProvideMarkVisualFeedbackForCopyButtonCommand(options.markType),
onMouseLeave: removeMarkVisualFeedbackForCopyButtonCommand,
onBlur: removeMarkVisualFeedbackForCopyButtonCommand
};
}
return {
id: 'editor.floatingToolbar.copy',
type: 'button',
appearance: 'subtle',
icon: CopyIcon,
title: formatMessage(copyButtonState !== null && copyButtonState !== void 0 && copyButtonState.copied ? commonMessages.copiedToClipboard : commonMessages.copyToClipboard),
...buttonActionHandlers,
hideTooltipOnClick: false,
tabIndex: null
};
}
/**
* Process floatingToolbar items for copyButton
*/
export const processCopyButtonItems = (editorAnalyticsApi, api) => _state => {
return (items, hoverDecoration) => items.flatMap(item => {
switch (item.type) {
case 'copy-button':
if (item !== null && item !== void 0 && item.hidden) {
return [];
}
return item === null || item === void 0 ? void 0 : item.items.map(copyButtonItem => isSeparator(copyButtonItem) ? copyButtonItem : getCopyButtonConfig(copyButtonItem, hoverDecoration, editorAnalyticsApi, api));
default:
return [item];
}
});
};