Can't make use of columns' autowidth when using a component in its header

We have encountered an issue where certain grid columns cannot be resized smaller, even when their content has a reduced width. This happens with columns with a custom Component header.

After investigating, we discovered that the problem lies in the default initial width of the header component and its input fields. The default width affects the internal call to recalculateColumnWidths(), which computes column widths (when autowidth = true) by taking the maximum between the content width across different rows and the header width. Since the default header width is considered, columns that should be able to shrink remain wider than expected.

I have developed a simple view that replicates this behavior:

public class TestView extends VerticalLayout {

  public TestView() {
    setSpacing(false);
    setSizeFull();
    getStyle().set("text-align", "center");

    H2 header = new H2("Testing column auto-widths with custom headers");
    header.addClassNames(Margin.Bottom.MEDIUM);
    add(header);

    Grid<List<String>> grid = new Grid<>();
    grid.setItems(Arrays.asList(Arrays.asList("Short", "", "", "Tiny", "Short", "Shorter"),
        Arrays.asList("Example", "A bit longer text", "Short", "xxs", "Short", "short"),
        Arrays.asList("Test", "Short", "Another long content example", "Tiny",
            "Different width test", "Medium"),
        Arrays.asList("Sample", "Extra long text here", "Short", "Expl", "Medium text",
            "Short"),
        Arrays.asList("Row 5", "Short", "Very very long text example", "Test",
            "Another medium content", "Example"),
        Arrays.asList("Sixth", "Small", "Extra content here", "Short", "Testing width", "Ltext"),
        Arrays.asList("Extra", "Another one", "Short content", "Medium", "More text to test",
            "Shgort")));

    grid.addThemeVariants(GridVariant.LUMO_COLUMN_BORDERS);
    grid.setWidth("900px");
    
    Column<List<String>> col1 = grid.addColumn(row -> row.get(0));
    col1.setTextAlign(ColumnTextAlign.START);
    col1.setAutoWidth(false);
    col1.setHeader(createCustomHeader("Column 1 /w fixed width"));
    col1.setWidth("200px");

    Column<List<String>> col2 = grid.addColumn(row -> row.get(1));
    col2.setTextAlign(ColumnTextAlign.START);
    col2.setAutoWidth(true);
    col2.setHeader(createCustomHeader("Col 2"));

    Column<List<String>> col3 = grid.addColumn(row -> row.get(2));
    col3.setTextAlign(ColumnTextAlign.START);
    col3.setAutoWidth(true);
    col3.setHeader(createCustomHeader("The third column with long label"));

    Column<List<String>> col4 = grid.addColumn(row -> row.get(3));
    col4.setTextAlign(ColumnTextAlign.START);
    col4.setAutoWidth(true);
    col4.setHeader(createCustomHeader("Column 4"));

    Column<List<String>> col5 = grid.addColumn(row -> row.get(4));
    col5.setTextAlign(ColumnTextAlign.START);
    col5.setAutoWidth(true);
    col5.setHeader(createCustomHeader("Column 5"));

    Column<List<String>> col6 = grid.addColumn(row -> row.get(5));
    col6.setTextAlign(ColumnTextAlign.START);
    col6.setAutoWidth(true);
    col6.setHeader(createCustomHeader("Column 6 has a long label"));

    add(grid);
  }

  private Component createCustomHeader(String headerText) {
    TextField textField = new TextField();
    textField.setPlaceholder("Filter");
    textField.setWidth("100%"); // try setting a small, fixed width

    Span label = new Span(headerText);
    label.getStyle().set("font-weight", "bold");

    VerticalLayout headerLayout = new VerticalLayout(label, textField);
    headerLayout.setPadding(false);
    headerLayout.setSpacing(false);
    headerLayout.setAlignItems(Alignment.START);

    return headerLayout;
  }
}

Note that in the createCustomHeader method, if we set the textfield’s width to “100%”, the column will never shrink. However, if we set a fixed, small width like “65px”, the column will correctly shrink.
Some screenshots:

With textfield’s width set to “100%”, the columns 4 and 6 won’t shrink as expected.

If a smaller fixed width is set, columns shrink, but the textfield won’t take all the available horizontal space in the header.

Actual expected behavior, with the columns shrinking and textfields expanding with the column’s calculated width as max-width. I managed to get this result by changing each textfield’s width indvidually with chrome devtools, after the view was completely loaded.

Has anyone else experienced this issue? Is there a recommended way to handle this scenario?