UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

77 lines (73 loc) 3.04 kB
import { tableCellMinWidth } from '@atlaskit/editor-common/styles'; import { akEditorGutterPaddingDynamic } from '@atlaskit/editor-shared-styles'; import { EVEN_SHARE_RATIO } from './constants'; export var sumWidths = function sumWidths(widths) { return widths.reduce(function (sum, width) { return sum + width; }, 0); }; // 2px absorbs sub-pixel rounding in `getRenderedColgroupColumnWidths`. var SUB_PIXEL_ROUNDING_ALLOWANCE = 2; /** * Clamps each desired width to `[tableCellMinWidth, MAX × evenShare]`. Greedy * columns (paragraphs) hit the ceiling and wrap; small columns stay at their * natural width. Leftover canvas budget grows ceiling-hitters up to their * desired; overflow reclaims from ceiling-hitters only. */ export var distributeByEvenShareRatio = function distributeByEvenShareRatio(desiredWidths, editorContainerWidth) { if (desiredWidths.length === 0 || !isFinite(editorContainerWidth) || editorContainerWidth <= 0) { return desiredWidths; } var usableWidth = Math.max(editorContainerWidth - akEditorGutterPaddingDynamic() * 2, tableCellMinWidth * desiredWidths.length); var evenShare = usableWidth / desiredWidths.length; var ceiling = EVEN_SHARE_RATIO.MAX * evenShare; var isCompactColumn = function isCompactColumn(width) { return width <= ceiling; }; var desiredCeil = desiredWidths.map(function (desired) { return Math.max(tableCellMinWidth, Math.ceil(desired) + SUB_PIXEL_ROUNDING_ALLOWANCE); }); var capped = desiredCeil.map(function (desired) { return isCompactColumn(desired) ? desired : Math.min(ceiling, desired); }); var sum = sumWidths(capped); // Underflow: grow non-protected ceiling-hitters into the leftover, up to their desired. if (sum < usableWidth) { var leftover = usableWidth - sum; var growthHeadroom = capped.map(function (width, index) { return !isCompactColumn(desiredCeil[index]) && width >= ceiling ? Math.max(desiredCeil[index] - width, 0) : 0; }); var totalHeadroom = sumWidths(growthHeadroom); if (totalHeadroom > 0) { var totalGrowth = Math.min(leftover, totalHeadroom); return capped.map(function (width, index) { var headroom = growthHeadroom[index]; if (headroom <= 0) { return width; } return width + headroom / totalHeadroom * totalGrowth; }); } return capped; } if (sum === usableWidth) { return capped; } // Overflow: reclaim from non-protected ceiling-hitters only. var overage = sum - usableWidth; var slacks = capped.map(function (width, index) { return !isCompactColumn(desiredCeil[index]) && width >= ceiling ? Math.max(width - tableCellMinWidth, 0) : 0; }); var totalSlack = sumWidths(slacks); if (totalSlack <= 0) { return capped; } return capped.map(function (width, index) { var slack = slacks[index]; if (slack <= 0) { return width; } var share = slack / totalSlack * Math.min(overage, totalSlack); return Math.max(width - share, tableCellMinWidth); }); };