@atlaskit/editor-plugin-layout
Version:
Layout plugin for @atlaskit/editor-core
177 lines (174 loc) • 7.06 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.calculateDistribution = void 0;
exports.isDistributedUniformly = isDistributedUniformly;
exports.redistributeProportionally = exports.redistributeAfterDeletion = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var roundLayoutColumnWidth = function roundLayoutColumnWidth(width) {
return Number(width.toFixed(2));
};
var sumWidths = function sumWidths(widths) {
return widths.reduce(function (sum, width) {
return sum + width;
}, 0);
};
var normaliseWidthsTotal = function normaliseWidthsTotal(widths, totalWidth, minWidth) {
var roundedWidths = widths.map(roundLayoutColumnWidth);
var remainder = roundLayoutColumnWidth(totalWidth - sumWidths(roundedWidths));
if (remainder === 0 || roundedWidths.length === 0) {
return roundedWidths;
}
var adjustmentIndex = 0;
roundedWidths.forEach(function (width, index) {
if (width > roundedWidths[adjustmentIndex]) {
adjustmentIndex = index;
}
});
var adjustedWidth = roundLayoutColumnWidth(roundedWidths[adjustmentIndex] + remainder);
if (adjustedWidth < minWidth) {
return roundedWidths;
}
return roundedWidths.map(function (width, index) {
return index === adjustmentIndex ? adjustedWidth : width;
});
};
var isValidWidth = function isValidWidth(width) {
return Number.isFinite(width) && width > 0;
};
var redistributeWithMinimumWidth = function redistributeWithMinimumWidth(_ref) {
var minWidth = _ref.minWidth,
totalWidth = _ref.totalWidth,
weights = _ref.weights;
if (weights.length * minWidth > totalWidth) {
return;
}
var widths = Array(weights.length).fill(0);
var clampedIndexes = new Set();
var remainingWidth = totalWidth;
var remainingWeight = sumWidths(weights);
var _loop = function _loop() {
var remainingWidthForPass = remainingWidth;
var remainingWeightForPass = remainingWeight;
var indexesToClamp = [];
weights.forEach(function (weight, index) {
if (clampedIndexes.has(index)) {
return;
}
var proportionalWidth = remainingWeightForPass > 0 ? weight / remainingWeightForPass * remainingWidthForPass : 0;
if (proportionalWidth < minWidth) {
indexesToClamp.push(index);
}
});
if (indexesToClamp.length === 0) {
return 1; // break
}
indexesToClamp.forEach(function (index) {
widths[index] = minWidth;
clampedIndexes.add(index);
remainingWidth -= minWidth;
remainingWeight -= weights[index];
});
};
while (clampedIndexes.size < weights.length) {
if (_loop()) break;
}
weights.forEach(function (weight, index) {
if (!clampedIndexes.has(index)) {
widths[index] = remainingWeight > 0 ? weight / remainingWeight * remainingWidth : minWidth;
}
});
return widths;
};
/**
* Returns true when the given selected columns already reflect the distribution that
* `distributeLayoutColumns` would produce — i.e. the first N-1 cols each hold
* `equalWidth` (rounded to 2 dp) and the last col absorbs the rounding remainder.
*
* This mirrors the action's "last col absorbs remainder" logic so that the UI can
* disable the option when it would be a no-op, avoiding spurious undo entries.
*/
var calculateDistribution = exports.calculateDistribution = function calculateDistribution(selectedWidths) {
var count = selectedWidths.length;
if (count < 2) {
return undefined;
}
var selectedTotal = sumWidths(selectedWidths);
var equalWidth = roundLayoutColumnWidth(selectedTotal / count);
return {
selectedTotal: selectedTotal,
equalWidth: equalWidth
};
};
function isDistributedUniformly(selectedWidths) {
var distribution = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : calculateDistribution(selectedWidths);
if (!distribution || selectedWidths.length < 2) {
return false;
}
var selectedTotal = distribution.selectedTotal,
equalWidth = distribution.equalWidth;
var lastColWidth = roundLayoutColumnWidth(selectedTotal - equalWidth * (selectedWidths.length - 1));
return selectedWidths.slice(0, -1).every(function (width) {
return width === equalWidth;
}) && selectedWidths[selectedWidths.length - 1] === lastColWidth;
}
var redistributeAfterDeletion = exports.redistributeAfterDeletion = function redistributeAfterDeletion(currentWidths, removeIndex, minWidth) {
if (currentWidths.length === 0 || removeIndex < 0 || removeIndex >= currentWidths.length || !isValidWidth(minWidth)) {
return currentWidths;
}
if (currentWidths.some(function (width) {
return !isValidWidth(width);
})) {
return currentWidths.filter(function (_, i) {
return i !== removeIndex;
});
}
var remainingWidths = currentWidths.filter(function (_, i) {
return i !== removeIndex;
});
if (remainingWidths.length === 0) {
return remainingWidths;
}
var currentTotalWidth = sumWidths(currentWidths);
var targetTotalWidth = Math.round(currentTotalWidth) === 100 ? 100 : currentTotalWidth;
var redistributed = redistributeWithMinimumWidth({
weights: remainingWidths,
totalWidth: targetTotalWidth,
minWidth: minWidth
});
if (!redistributed) {
var equalWidth = roundLayoutColumnWidth(targetTotalWidth / remainingWidths.length);
return normaliseWidthsTotal(Array(remainingWidths.length).fill(equalWidth), targetTotalWidth, minWidth);
}
return normaliseWidthsTotal(redistributed, targetTotalWidth, minWidth);
};
var redistributeProportionally = exports.redistributeProportionally = function redistributeProportionally(currentWidths, insertIndex, maxColumns, minWidth) {
if (currentWidths.length === 0 || !Number.isInteger(maxColumns) || maxColumns <= 0 || currentWidths.length >= maxColumns || insertIndex < 0 || insertIndex > currentWidths.length || !isValidWidth(minWidth) || currentWidths.some(function (width) {
return !isValidWidth(width);
})) {
return currentWidths;
}
var currentTotalWidth = sumWidths(currentWidths);
if (!isValidWidth(currentTotalWidth)) {
return currentWidths;
}
var targetTotalWidth = Math.round(currentTotalWidth) === 100 ? 100 : currentTotalWidth;
var newColumnWidth = Math.max(minWidth, roundLayoutColumnWidth(targetTotalWidth / (currentWidths.length + 1)));
var existingColumnsTotalWidth = targetTotalWidth - newColumnWidth;
if (existingColumnsTotalWidth < currentWidths.length * minWidth) {
return currentWidths;
}
var redistributedExistingWidths = redistributeWithMinimumWidth({
weights: currentWidths,
totalWidth: existingColumnsTotalWidth,
minWidth: minWidth
});
if (!redistributedExistingWidths) {
return currentWidths;
}
var nextWidths = (0, _toConsumableArray2.default)(redistributedExistingWidths);
nextWidths.splice(insertIndex, 0, newColumnWidth);
return normaliseWidthsTotal(nextWidths, targetTotalWidth, minWidth);
};