@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
199 lines (188 loc) • 10.7 kB
JavaScript
import { getParentNodeWidth, getTableContainerWidth, layoutToWidth } from '@atlaskit/editor-common/node-width';
import { calcTableWidth } from '@atlaskit/editor-common/styles';
import { calcTableColumnWidths } from '@atlaskit/editor-common/utils';
import { akEditorFullWidthLayoutWidth, akEditorGutterPaddingDynamic, akEditorTableNumberColumnWidth, akEditorGutterPaddingReduced, akEditorFullPageNarrowBreakout } from '@atlaskit/editor-shared-styles';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { hasTableBeenResized, hasTableColumnBeenResized } from './colgroup';
import { MAX_SCALING_PERCENT, MAX_SCALING_PERCENT_TABLES_WITH_FIXED_COLUMN_WIDTHS_OPTION, TABLE_MAX_WIDTH, TABLE_FULL_WIDTH } from './consts';
// Translates named layouts in number values.
export function getLayoutSize(tableLayout) {
var containerWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var options = arguments.length > 2 ? arguments[2] : undefined;
var isFullWidthModeEnabled = options.isFullWidthModeEnabled;
if (isFullWidthModeEnabled) {
var padding = akEditorGutterPaddingDynamic();
if (containerWidth <= akEditorFullPageNarrowBreakout && editorExperiment('platform_editor_preview_panel_responsiveness', true, {
exposure: true
})) {
padding = akEditorGutterPaddingReduced;
}
return containerWidth ? Math.min(containerWidth - padding * 2, akEditorFullWidthLayoutWidth) : akEditorFullWidthLayoutWidth;
}
var calculatedTableWidth = calcTableWidth(tableLayout, containerWidth, true);
if (calculatedTableWidth !== 'inherit') {
return calculatedTableWidth;
}
return layoutToWidth[tableLayout] || containerWidth;
}
// Does the current position point at a cell.
export function pointsAtCell($pos) {
return $pos.parent.type.spec.tableRole === 'row' && $pos.nodeAfter;
}
// Get the current col width, handles colspan.
export function currentColWidth(view, cellPos, _ref) {
var colspan = _ref.colspan,
colwidth = _ref.colwidth;
var width = colwidth && colwidth[colwidth.length - 1];
if (width) {
return width;
}
// Not fixed, read current width from DOM
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
var domWidth = view.domAtPos(cellPos + 1).node.offsetWidth;
var parts = colspan || 0;
if (colwidth) {
for (var i = 0; i < (colspan || 0); i++) {
if (colwidth[i]) {
domWidth -= colwidth[i];
parts--;
}
}
}
return domWidth / parts;
}
export var getTableMaxWidth = function getTableMaxWidth(_ref2) {
var table = _ref2.table,
tableStart = _ref2.tableStart,
state = _ref2.state,
layout = _ref2.layout,
getEditorContainerWidth = _ref2.getEditorContainerWidth;
var containerWidth = getEditorContainerWidth();
var parentWidth = getParentNodeWidth(tableStart, state, containerWidth);
var maxWidth = parentWidth || table.attrs.width || getLayoutSize(layout, containerWidth.width, {});
if (table.attrs.isNumberColumnEnabled) {
maxWidth -= akEditorTableNumberColumnWidth;
}
return maxWidth;
};
/**
*
* @param table
* @returns calculated width of <table /> element derived from sum of colwidths on tableCell or tableHeader nodes or falls back to container width
*/
export var getTableElementWidth = function getTableElementWidth(table) {
if (hasTableBeenResized(table)) {
// TODO: ED-26961 - is there a scenario where ADF columns are SMALLER than container width?
return calcTableColumnWidths(table).reduce(function (sum, width) {
return sum + width;
}, 0);
}
return getTableContainerElementWidth(table);
};
export var getTableContainerElementWidth = function getTableContainerElementWidth(table) {
return getTableContainerWidth(table);
};
// eslint-disable-next-line jsdoc/require-example
/**
* This function is used to set the max width for table resizer container.
* @param isCommentEditor Whether the editor is in comment mode.
* @param isChromelessEditor Whether the editor is chromeless.
* @param isTableScalingEnabled Whether table scaling is enabled.
* @returns The CSS max-width value
*/
export var getTableResizerContainerMaxWidthInCSS = function getTableResizerContainerMaxWidthInCSS(isCommentEditor, isChromelessEditor, isTableScalingEnabled) {
var maxResizerWidthForNonCommentEditor = isTableScalingEnabled ? "min(calc(100cqw - calc(var(--ak-editor--large-gutter-padding) * 2)), ".concat(expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true) ? TABLE_MAX_WIDTH : TABLE_FULL_WIDTH, "px)") : "min(calc(100cqw - calc(var(--ak-editor--large-gutter-padding) * 2) - var(--ak-editor--resizer-handle-spacing)), ".concat(expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true) ? TABLE_MAX_WIDTH : TABLE_FULL_WIDTH, "px)");
return isCommentEditor || isChromelessEditor ? '100%' : maxResizerWidthForNonCommentEditor;
};
// eslint-disable-next-line jsdoc/require-example
/**
* This function is used in NodeView for TableResizer to set the max width for table resizer container
* @param node The ProseMirror node representing the table.
* @param isCommentEditor Whether the editor is in comment mode.
* @param isChromelessEditor Whether the editor is chromeless.
* @returns The CSS max-width value for the table resizer container.
*/
export var getTableResizerItemWidth = function getTableResizerItemWidth(node, isCommentEditor, isChromelessEditor) {
var tableWidthAttribute = getTableContainerWidth(node);
if (!node.attrs.width && (isCommentEditor || isChromelessEditor)) {
// width undefined would make .resizer-item width to be `auto`
return undefined;
}
return tableWidthAttribute;
};
// eslint-disable-next-line jsdoc/require-example
/**
* This function is used to set the CSS width value for the table resizer-item.
* Because comment and chromeless editors don't have container-type: inline-size set,
* we need to calculate the width based on the table node width.
* If the table node width is not set, it will return 'auto'.
* This is used in table toDOM
* @param node The ProseMirror node representing the table.
* @param isCommentEditor Whether the editor is in comment mode.
* @param isChromelessEditor Whether the editor is chromeless.
* @returns The CSS width value for the table container.
*/
export var getTableResizerItemWidthInCSS = function getTableResizerItemWidthInCSS(node, isCommentEditor, isChromelessEditor) {
var tableWidthAttribute = getTableResizerItemWidth(node, isCommentEditor, isChromelessEditor);
return tableWidthAttribute ? "".concat(tableWidthAttribute, "px") : 'auto';
};
// eslint-disable-next-line jsdoc/require-example
/**
* This function is used to set the table width --ak-editor-table-width CSS property for full page editor.
* Which is applied to the table resizer container.
* For Full page appearance, we don't need to use containerWidth from JS, as we can use cqw value.
* So we set dynamic containerWidth from JS to CSS property.
* @param node The ProseMirror node representing the table.
* @param isCommentEditor Whether the editor is in comment mode.
* @param isChromelessEditor Whether the editor is chromeless.
* @param isTableScalingEnabled Whether table scaling is enabled.
* @param tableWidthFromJS The width of the container element. In toDOM it'd be undefined, but will have a value from nodeView.
* @returns The CSS width value for the table.
*/
export var getTableResizerContainerForFullPageWidthInCSS = function getTableResizerContainerForFullPageWidthInCSS(node, isTableScalingEnabled) {
var tableWidth = getTableContainerElementWidth(node);
// for full page appearance
if (isTableScalingEnabled) {
return "min(calc(100cqw - calc(var(--ak-editor--large-gutter-padding) * 2)), ".concat(tableWidth, "px)");
}
return "min(calc(100cqw - calc(var(--ak-editor--large-gutter-padding) * 2) - var(--ak-editor--resizer-handle-spacing)), ".concat(tableWidth, "px)");
};
export var getTableScalingPercent = function getTableScalingPercent(table, tableRef, shouldUseIncreasedScalingPercent) {
var _tableRef$parentEleme;
var maxScalingPercent = shouldUseIncreasedScalingPercent ? MAX_SCALING_PERCENT_TABLES_WITH_FIXED_COLUMN_WIDTHS_OPTION : MAX_SCALING_PERCENT;
var tableWidth = getTableContainerElementWidth(table);
var renderWidth = (tableRef === null || tableRef === void 0 || (_tableRef$parentEleme = tableRef.parentElement) === null || _tableRef$parentEleme === void 0 ? void 0 : _tableRef$parentEleme.clientWidth) || tableWidth;
// minus 1 here to avoid any 1px scroll in Firefox
var scalePercent = (renderWidth - 1) / tableWidth;
scalePercent = Math.max(scalePercent, 1 - maxScalingPercent);
return Math.min(scalePercent, 1);
};
// This function is used to default and full-width tables in Comment/Chromeless editors
// These tables don't have node.attrs.width set. Their pm-table-wrapper width depend on the editor container width.
// actual table node width can be calculated as sum of colwidth values if table's columns were resized.
// If colwidth are not set, table columns are not resized, they all are equal widths.
export var getScalingPercentForTableWithoutWidth = function getScalingPercentForTableWithoutWidth(table, tableRef) {
// are table columns resized
if (hasTableColumnBeenResized(table)) {
var _tableRef$parentEleme2;
var tableWidth = calcTableColumnWidths(table).reduce(function (sum, width) {
return sum + width;
}, 0);
var renderWidth = (tableRef === null || tableRef === void 0 || (_tableRef$parentEleme2 = tableRef.parentElement) === null || _tableRef$parentEleme2 === void 0 ? void 0 : _tableRef$parentEleme2.clientWidth) || tableWidth;
// minus 1 here to avoid any 1px scroll in Firefox
return (renderWidth - 1) / tableWidth;
}
// When table cols are not resized and table width is not set,
// tableWidth is equal to renderWidth
return 1;
};
export var getStaticTableScalingPercent = function getStaticTableScalingPercent(table, tableRenderWidth, shouldUseIncreasedScalingPercent) {
var maxScalingPercent = shouldUseIncreasedScalingPercent ? MAX_SCALING_PERCENT_TABLES_WITH_FIXED_COLUMN_WIDTHS_OPTION : MAX_SCALING_PERCENT;
var tableWidth = getTableContainerElementWidth(table);
// minus 1 here to avoid any 1px scroll in Firefox
var scalePercent = (tableRenderWidth - 1) / tableWidth;
scalePercent = Math.max(scalePercent, 1 - maxScalingPercent);
return Math.min(scalePercent, 1);
};