@atlaskit/editor-plugin-panel
Version:
Panel plugin for @atlaskit/editor-core.
118 lines • 6.53 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 { akEditorTableContainerBg } from '@atlaskit/editor-shared-styles/consts';
import { fg } from '@atlaskit/platform-feature-flags';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
export const isPanel = nodeName => {
return expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? ['panel', 'panel_c1'].includes(nodeName) : nodeName === 'panel';
};
export const panelTypes = nodes => {
const {
panel,
panel_c1
} = nodes;
return expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? [panel, panel_c1] : [panel];
};
export const findPanel = (state, selection) => {
return findSelectedNodeOfType(panelTypes(state.schema.nodes))(selection || state.selection) || findParentNodeOfType(panelTypes(state.schema.nodes))(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 isCustomPanelWithColor = expValEquals('platform_editor_stricter_panelcolor_typecheck', 'isEnabled', true) ? typeof panelColor === 'string' && isCustomPanel : panelColor && isCustomPanel;
const style = [`${isCustomPanelWithColor ? `background-color: ${panelBackgroundColor};` : ''}`,
// When table-in-panel is enabled, set --table-container-bg so that table
// masking elements (sticky-header mask, column-controls wrapper) blend with
// the custom panel background instead of showing opaque white.
`${isCustomPanelWithColor && expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? `${akEditorTableContainerBg}: ${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)) {
var _oldPanelNode$node$ty;
// 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 => isPanel(node.type.name))(oldState.tr.selection);
const clonedPanelNode = oldPanelNode === null || oldPanelNode === void 0 ? void 0 : oldPanelNode.node.copy();
const panelNodeType = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? (_oldPanelNode$node$ty = oldPanelNode === null || oldPanelNode === void 0 ? void 0 : oldPanelNode.node.type) !== null && _oldPanelNode$node$ty !== void 0 ? _oldPanelNode$node$ty : schema.nodes.panel : schema.nodes.panel;
const newPanelNode = panelNodeType.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(panelTypes(newState.schema.nodes))(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));
};