@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
77 lines (73 loc) • 3.04 kB
JavaScript
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);
});
};