@atlaskit/editor-plugin-annotation
Version:
Annotation plugin for @atlaskit/editor-core
171 lines (170 loc) • 7.4 kB
JavaScript
import React from 'react';
import { isSSR } from '@atlaskit/editor-common/core-utils';
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { setInlineCommentDraftState, showInlineCommentForBlockNode } from './editor-commands';
import { annotationWithToDOMFix } from './nodeviews/annotationMark';
import { inlineCommentPlugin } from './pm-plugins/inline-comment';
import { keymapPlugin } from './pm-plugins/keymap';
import { buildSuppressedToolbar, buildToolbar, shouldSuppressFloatingToolbar } from './pm-plugins/toolbar';
import { getPluginState, hasAnyUnResolvedAnnotationInPage, stripNonExistingAnnotations } from './pm-plugins/utils';
import { InlineCommentView } from './ui/InlineCommentView';
import { getToolbarComponents } from './ui/toolbar-components';
export const annotationPlugin = ({
config: annotationProviders,
api
}) => {
var _api$featureFlags, _api$analytics;
const featureFlags = api === null || api === void 0 ? void 0 : (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState();
const isToolbarAIFCEnabled = Boolean(api === null || api === void 0 ? void 0 : api.toolbar);
if (isToolbarAIFCEnabled) {
var _api$toolbar;
api === null || api === void 0 ? void 0 : (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 ? void 0 : _api$toolbar.actions.registerComponents(getToolbarComponents(api, annotationProviders));
}
return {
name: 'annotation',
marks() {
return [{
name: 'annotation',
mark: annotationWithToDOMFix
}];
},
actions: {
hasAnyUnResolvedAnnotationInPage,
stripNonExistingAnnotations,
setInlineCommentDraftState: setInlineCommentDraftState(api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes),
showCommentForBlockNode: showInlineCommentForBlockNode(annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes)
},
getSharedState(editorState) {
if (!editorState) {
return undefined;
}
const pluginState = getPluginState(editorState) || undefined;
const clonedPluginState = Object.assign({}, pluginState);
clonedPluginState === null || clonedPluginState === void 0 ? true : delete clonedPluginState.featureFlagsPluginState;
return clonedPluginState;
},
pmPlugins: () => [{
name: 'annotation',
plugin: ({
dispatch
}) => {
if (annotationProviders) {
var _api$analytics2;
return inlineCommentPlugin({
dispatch,
provider: annotationProviders.inlineComment,
editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions,
featureFlagsPluginState: featureFlags,
selectCommentExperience: annotationProviders.selectCommentExperience,
viewInlineCommentTraceUFOPress: annotationProviders.viewInlineCommentTraceUFOPress,
annotationManager: annotationProviders.annotationManager,
api
});
}
return;
}
}, {
name: 'annotationKeymap',
plugin: () => {
if (annotationProviders) {
return keymapPlugin(api);
}
return;
}
}],
pluginsOptions: {
floatingToolbar(state) {
const pluginState = getPluginState(state);
const bookmark = pluginState === null || pluginState === void 0 ? void 0 : pluginState.bookmark;
if (shouldSuppressFloatingToolbar({
state,
bookmark
})) {
return buildSuppressedToolbar(state);
}
},
selectionToolbar(state, intl) {
if (isToolbarAIFCEnabled) {
return;
}
if (!annotationProviders) {
return;
}
const pluginState = getPluginState(state);
if (pluginState && pluginState.isVisible && !pluginState.bookmark && !pluginState.mouseData.isSelecting) {
var _api$analytics3;
const {
isToolbarAbove,
onCommentButtonMount,
getCanAddComments,
contentType
} = annotationProviders.inlineComment;
const toolbarConfig = buildToolbar(api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions)({
state,
intl,
isToolbarAbove,
api,
createCommentExperience: annotationProviders.createCommentExperience,
annotationManager: annotationProviders.annotationManager,
onCommentButtonMount,
getCanAddComments,
contentType
});
if (!toolbarConfig) {
return undefined;
} else {
return {
...toolbarConfig,
rank: editorExperiment('platform_editor_controls', 'variant1') ? 1 : undefined
};
}
}
}
},
contentComponent({
editorView,
dispatchAnalyticsEvent
}) {
if (!annotationProviders || !editorView || isSSR()) {
return null;
}
return /*#__PURE__*/React.createElement(AnnotationContentComponent, {
api: api,
editorView: editorView,
annotationProviders: annotationProviders,
dispatchAnalyticsEvent: dispatchAnalyticsEvent
});
}
};
};
const selector = states => {
var _states$annotationSta, _states$annotationSta2, _states$annotationSta3;
return {
isVisible: (_states$annotationSta = states.annotationState) === null || _states$annotationSta === void 0 ? void 0 : _states$annotationSta.isVisible,
selectedAnnotations: (_states$annotationSta2 = states.annotationState) === null || _states$annotationSta2 === void 0 ? void 0 : _states$annotationSta2.selectedAnnotations,
annotations: (_states$annotationSta3 = states.annotationState) === null || _states$annotationSta3 === void 0 ? void 0 : _states$annotationSta3.annotations
};
};
function AnnotationContentComponent({
api,
editorView,
annotationProviders,
dispatchAnalyticsEvent
}) {
var _api$analytics4;
const annotationState = useSharedPluginStateWithSelector(api, ['annotation'], selector);
// need to explicitly check for false as undefined is also a valid value to continue
if ((annotationState === null || annotationState === void 0 ? void 0 : annotationState.isVisible) === false) {
return null;
}
return /*#__PURE__*/React.createElement("div", {
"data-editor-popup": "true"
}, /*#__PURE__*/React.createElement(InlineCommentView, {
providers: annotationProviders,
editorView: editorView,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions,
editorAPI: api
}));
}