@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
141 lines (140 loc) • 6.9 kB
JavaScript
import classNames from 'classnames';
import kebabCase from 'lodash/kebabCase';
import { table, tableWithNestedTable } from '@atlaskit/adf-schema/tableNodes';
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
import { isTableInContentMode } from '@atlaskit/editor-common/table';
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { generateColgroupFromNode, getResizerMinWidth } from '../pm-plugins/table-resizing/utils/colgroup';
import { TABLE_MAX_WIDTH } from '../pm-plugins/table-resizing/utils/consts';
import { getTableResizerContainerMaxWidthInCSS, getTableResizerContainerForFullPageWidthInCSS, getTableResizerItemWidthInCSS } from '../pm-plugins/table-resizing/utils/misc';
import { isContentModeSupported } from '../pm-plugins/utils/tableMode/is-content-mode-supported';
import { TableCssClassName as ClassName } from '../types';
import { getAlignmentStyle } from './table-container-styles';
export const tableNodeSpecWithFixedToDOM = config => {
const tableNode = config.isNestingSupported ? tableWithNestedTable : table;
return {
...tableNode,
toDOM: node => {
const isFullPageEditor = !config.isChromelessEditor && !config.isCommentEditor;
const isInContentMode = isTableInContentMode({
tableNode: node,
isSupported: isContentModeSupported({
allowColumnResizing: config.allowColumnResizing,
allowTableResizing: config.tableResizingEnabled,
isFullPageEditor
}),
isTableNested: config.isNested
});
const alignmentStyle = Object.entries(getAlignmentStyle(node.attrs.layout)).map(([k, v]) => `${kebabCase(k)}: ${kebabCase(v)}`).join(';');
const tableMinWidth = getResizerMinWidth(node);
const attrs = {
'data-number-column': node.attrs.isNumberColumnEnabled,
'data-layout': node.attrs.layout,
'data-autosize': node.attrs.__autoSize,
'data-table-local-id': node.attrs.localId,
'data-table-width': node.attrs.width,
'data-ssr-placeholder': `table-${node.attrs.localId}`,
'data-ssr-placeholder-replace': `table-${node.attrs.localId}`,
'data-table-display-mode': node.attrs.displayMode
};
if (isInContentMode) {
attrs['data-initial-width-mode'] = 'content';
}
// This would be used for table scaling in colgroup CSS
// cqw, or px is well supported
const resizableTableWidth = isFullPageEditor ? getTableResizerContainerForFullPageWidthInCSS(node, config.isTableScalingEnabled) : `calc(100cqw - calc(var(--ak-editor--large-gutter-padding) * 2))`;
let colgroup = '';
if (config.allowColumnResizing) {
colgroup = ['colgroup', {}, ...generateColgroupFromNode(node, config.isCommentEditor, config.isChromelessEditor, config.isNested, config.isTableScalingEnabled, config.shouldUseIncreasedScalingPercent)];
}
const overflowShadows = isExperimentEnabled('platform_editor_table_css_overflow_shadow') ? [['div', {
contenteditable: 'false',
'aria-hidden': 'true',
'data-vc-nvs': 'true',
'data-table-overflow-shadow': 'start'
}], ['div', {
contenteditable: 'false',
'aria-hidden': 'true',
'data-vc-nvs': 'true',
'data-table-overflow-shadow': 'end'
}]] : [];
const roundedTableCornerMasks = expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? [['div', {
contenteditable: 'false',
'aria-hidden': 'true',
class: ClassName.TABLE_CORNER_MASK,
'data-corner': 'left'
}], ['div', {
contenteditable: 'false',
'aria-hidden': 'true',
class: ClassName.TABLE_CORNER_MASK,
'data-corner': 'right'
}]] : [];
const tableContainerDiv = ['div', {
class: 'pm-table-container',
'data-number-column': node.attrs.isNumberColumnEnabled,
'data-layout': node.attrs.layout,
'data-testid': 'table-container'
}, ['div', {
class: 'pm-table-sticky-sentinel-top',
'data-testid': 'sticky-sentinel-top'
}], ['div', {
class: 'pm-table-row-controls-wrapper'
}, ['div']], ['div', {
class: classNames(ClassName.TABLE_NODE_WRAPPER, {
[ClassName.TABLE_SCROLL_INLINE_SHADOW]: isExperimentEnabled('platform_editor_table_css_overflow_shadow')
})
}, ...roundedTableCornerMasks, ['table', attrs, colgroup, ['tbody', 0]]], ...overflowShadows, ['div', {
class: 'pm-table-sticky-sentinel-bottom',
'data-testid': 'sticky-sentinel-bottom'
}], ['div', {
contenteditable: 'false',
class: 'pm-table-left-border',
'data-with-numbered-table': node.attrs.isNumberColumnEnabled,
'data-testid': 'table-left-border'
}], ['div', {
contenteditable: 'false',
class: 'pm-table-right-border',
'data-testid': 'table-right-border'
}]];
if (!config.tableResizingEnabled || config.isNested) {
return ['div', {
class: 'tableView-content-wrap',
'data-prosemirror-initial-toDOM-render': 'true',
style: convertToInlineCss({
'--ak-editor-table-width': resizableTableWidth
})
}, tableContainerDiv];
}
const tableResizingDiv = ['div', {
'data-testid': 'table-alignment-container',
style: alignmentStyle
}, ['div', {
class: 'pm-table-resizer-container',
style: convertToInlineCss({
'--ak-editor-table-gutter-padding': config.isTableScalingEnabled ? 'calc(var(--ak-editor--large-gutter-padding) * 2)' : 'calc(var(--ak-editor--large-gutter-padding) * 2 - var(--ak-editor-resizer-handle-spacing))',
'--ak-editor-table-width': isInContentMode ? 'max-content' : resizableTableWidth,
width: `var(--ak-editor-table-width)`
})
}, ['div', {
class: 'resizer-item display-handle',
style: convertToInlineCss({
position: 'relative',
userSelect: 'auto',
boxSizing: 'border-box',
'--ak-editor-table-max-width': `${TABLE_MAX_WIDTH}px`,
'--ak-editor-table-min-width': `${tableMinWidth}px`,
minWidth: 'var(--ak-editor-table-min-width)',
maxWidth: getTableResizerContainerMaxWidthInCSS(config.isCommentEditor, config.isChromelessEditor, config.isTableScalingEnabled),
width: isInContentMode ? 'auto' : getTableResizerItemWidthInCSS(node, config.isCommentEditor, config.isChromelessEditor)
})
}, ['span', {
class: 'resizer-hover-zone'
}, tableContainerDiv]]]];
return ['div', {
class: 'tableView-content-wrap',
'data-prosemirror-initial-toDOM-render': 'true'
}, tableResizingDiv];
}
};
};