@atlaskit/editor-plugin-panel
Version:
Panel plugin for @atlaskit/editor-core.
103 lines • 5.26 kB
JavaScript
import { PanelType } from '@atlaskit/adf-schema';
import { PanelSharedCssClassName } from '@atlaskit/editor-common/panel';
import { hexToEditorBackgroundPaletteColor } from '@atlaskit/editor-palette';
import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
import { findParentNode, findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
import { fg } from '@atlaskit/platform-feature-flags';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
export const findPanel = (state, selection) => {
const {
panel
} = state.schema.nodes;
return findSelectedNodeOfType(panel)(selection || state.selection) || findParentNodeOfType(panel)(selection || state.selection);
};
export const panelAttrsToDom = (attrs, allowCustomPanel) => {
const {
panelColor,
panelType,
panelIcon,
panelIconId,
panelIconText
} = attrs;
const isCustomPanel = panelType === PanelType.CUSTOM && allowCustomPanel;
const hasIcon = !isCustomPanel || !!panelIcon || !!panelIconId;
const tokenColor = expValEquals('platform_editor_stricter_panelcolor_typecheck', 'isEnabled', true) ? typeof panelColor === 'string' && hexToEditorBackgroundPaletteColor(panelColor) : panelColor && hexToEditorBackgroundPaletteColor(panelColor);
const panelBackgroundColor = tokenColor || panelColor;
const style = [`${(expValEquals('platform_editor_stricter_panelcolor_typecheck', 'isEnabled', true) ? typeof panelColor === 'string' && isCustomPanel : panelColor && isCustomPanel) ? `background-color: ${panelBackgroundColor};` : ''}`, `${!hasIcon && !fg('platform_editor_nested_dnd_styles_changes') ? `padding-left: 12px;padding-right: 12px;` : ''}`].join('');
let panelAttrs = {
class: `${PanelSharedCssClassName.prefix}${!hasIcon && fg('platform_editor_nested_dnd_styles_changes') ? ` ${PanelSharedCssClassName.noIcon}` : ''}`,
'data-panel-type': panelType || PanelType.INFO,
'data-testid': 'panel-node-view',
style
};
if (panelColor && isCustomPanel) {
panelAttrs = {
...panelAttrs,
'data-panel-color': panelColor,
'data-panel-icon-id': panelIconId,
'data-panel-icon-text': panelIconText
};
}
// Required for parseDOM to correctly parse custom panel when NodeView DOM is copied directly
// Schema's parseDOM expects data-panel-icon on all custom panels, not just ones with color
if (isCustomPanel) {
panelAttrs = {
...panelAttrs,
'data-panel-icon': panelIcon
};
}
if (fg('platform_editor_adf_with_localid')) {
panelAttrs = {
...panelAttrs,
'data-local-id': attrs.localId
};
}
const iconDiv = ['div',
// EDITOR-266 This fixes an issue in LCM where if you have nested panels
// The icon colour will be overridden by the parent panel style, this is used to create a more specific css selector
{
class: PanelSharedCssClassName.icon,
'data-panel-type': panelType || PanelType.INFO
}];
const contentDiv = ['div', {
class: PanelSharedCssClassName.content
}, 0];
if (hasIcon) {
return ['div', panelAttrs, iconDiv, contentDiv];
} else {
return ['div', panelAttrs, contentDiv];
}
};
export const handleCut = (newState, oldState) => {
const newTr = newState.tr;
const {
schema
} = newState.doc.type;
if (panelContentCheck(newState, oldState)) {
// Create a panel using oldState with an empty paragraph node
// and insert it in the same location when panel previously existed
const emptyParagraph = schema.nodes.paragraph.create();
const oldPanelNode = findParentNode(node => node.type.name === 'panel')(oldState.tr.selection);
const clonedPanelNode = oldPanelNode === null || oldPanelNode === void 0 ? void 0 : oldPanelNode.node.copy();
const newPanelNode = schema.nodes.panel.create({
...(clonedPanelNode === null || clonedPanelNode === void 0 ? void 0 : clonedPanelNode.attrs)
}, emptyParagraph);
const endPos = oldState.tr.selection.$from.pos;
if (oldPanelNode) {
newTr.insert(oldPanelNode.pos, newPanelNode).setSelection(new TextSelection(newTr.doc.resolve(endPos)));
return newTr;
}
}
};
export const panelContentCheck = (newState, oldState) => {
// The following fuctions checks if *
// a. old selection is a NodeSelection.
// b. parent element a panel and does it have only one child
// c. parent node has a decision list and that decision list only has one decision item
// OR old selection is a codeblock OR old selection is a rule
const isNodeSelection = oldState.tr.selection instanceof NodeSelection;
const isNodeTypeRuleOrCodeBlock = isNodeSelection && ['codeBlock', 'rule'].includes(oldState.tr.selection.node.type.name);
const isParentTypePanel = findParentNodeOfType(newState.schema.nodes.panel)(oldState.tr.selection);
const isparentTypeDecision = findParentNodeOfType(newState.schema.nodes.decisionList)(oldState.tr.selection);
return Boolean(isNodeSelection && (isParentTypePanel === null || isParentTypePanel === void 0 ? void 0 : isParentTypePanel.node.childCount) === 1 && ((isparentTypeDecision === null || isparentTypeDecision === void 0 ? void 0 : isparentTypeDecision.node.childCount) === 1 || isNodeTypeRuleOrCodeBlock));
};