diff --git a/addon/-private/column-tree.js b/addon/-private/column-tree.js index 9c31c0c03..06810e7d0 100644 --- a/addon/-private/column-tree.js +++ b/addon/-private/column-tree.js @@ -763,8 +763,14 @@ export default EmberObject.extend({ return; } + let widthConstraint = get(this, 'widthConstraint'); let isSlackModeEnabled = get(this, 'isSlackModeEnabled'); + // For gte-container-slack, first try to expand columns to their maxWidth + if (widthConstraint === WIDTH_CONSTRAINT.GTE_CONTAINER_SLACK) { + this.expandColumnsToMax(); + } + if (isSlackModeEnabled) { this.updateSlackColumn(); } @@ -1177,4 +1183,80 @@ export default EmberObject.extend({ this.token ); }, + + /** + * Expands columns to their maxWidth when possible, while respecting container width + */ + expandColumnsToMax() { + let containerWidth = this.getContainerWidth(); + let leaves = get(this, 'root.leaves').filter(node => !get(node, 'isSlack')); + + // Calculate total fixed width from columns with explicit width + let flexibleColumns = leaves.filter(node => !get(node, 'column.width')); + let totalFixedWidth = leaves.reduce((sum, node) => { + let columnWidth = get(node, 'column.width'); + return sum + (columnWidth || 0); + }, 0); + + let remainingWidth = containerWidth - totalFixedWidth; + + // First pass: ensure all columns get at least their minWidth + let totalMinWidth = 0; + flexibleColumns.forEach(node => { + let minWidth = get(node, 'minWidth'); + totalMinWidth += minWidth; + }); + + // If we don't have space for all minWidths, set all columns to minWidth + if (remainingWidth <= totalMinWidth) { + flexibleColumns.forEach(node => { + set(node, 'width', get(node, 'minWidth')); + }); + return; + } + + // Keep track of columns that still need width allocated + let columnsNeedingWidth = [...flexibleColumns]; + let loopCount = 0; + + // Continue redistributing width until all columns are satisfied or we hit guard + while (columnsNeedingWidth.length > 0 && loopCount < LOOP_COUNT_GUARD) { + let availableWidth = remainingWidth; + columnsNeedingWidth.forEach(node => { + availableWidth -= get(node, 'minWidth'); + }); + + let equalExtraWidth = Math.floor(availableWidth / columnsNeedingWidth.length); + let columnsToRemove = []; + + // Try to set each column to minWidth + equalExtraWidth + columnsNeedingWidth.forEach(node => { + let minWidth = get(node, 'minWidth'); + let maxWidth = get(node, 'maxWidth'); + let targetWidth = minWidth + equalExtraWidth; + let width = Math.min(Math.max(targetWidth, minWidth), maxWidth); + + // If column hits a constraint, remove it from future calculations + if (width !== targetWidth) { + columnsToRemove.push(node); + remainingWidth -= width; + } + + set(node, 'width', width); + }); + + // If no columns hit constraints, we're done + if (columnsToRemove.length === 0) { + break; + } + + // Remove columns that hit constraints and continue redistributing + columnsToRemove.forEach(node => { + let index = columnsNeedingWidth.indexOf(node); + columnsNeedingWidth.splice(index, 1); + }); + + loopCount++; + } + }, }); diff --git a/tests/helpers/generate-table.js b/tests/helpers/generate-table.js index 7d61b3954..da2c86b87 100644 --- a/tests/helpers/generate-table.js +++ b/tests/helpers/generate-table.js @@ -11,7 +11,7 @@ import { export { configureTableGeneration, resetTableGenerationConfig, generateColumns, generateRows }; const fullTable = hbs` -
+