Skip to content

Conversation

andreynering
Copy link
Member

@andreynering andreynering commented May 22, 2025

fix(table): do not print final empty row when overflow

Before

ExtraEmptyRow-Before

After

ExtraEmptyRow-After

fix(table): fix headers with custom vertical padding

Note that we're still always truncating headers to 1 line, but now we're respecting any custom vertical padding.

Before

ExtraPaddingHeader-Before

After

ExtraPaddingHeader-After

Long Headers

ExtraPaddingHeader-LongHeaders

fix(table): fix rendering for bordered cells

Before

BorderedCells-Before

After

BorderedCells-After

fix(table): fix horizontal shrink with outline borders only

Before

ShrinkOutlineBorders-Before

After

ShrinkOutlineBorders-After

fix(table): fix layout for tables with inner borders only

Before

InnerBordersOnly-Before

After

InnerBordersOnly-After

feat(table): rework height rendering logic to fix related bugs

I suggest to checkout and take a look at the golden files at table/testdata/TestTableHeightShrink to understand the fixes done here.

In short, the behavior was unreliable before, in particular when BorderRow(true) was set or when cell had custom margin / padding.

@andreynering andreynering self-assigned this May 22, 2025
@andreynering andreynering force-pushed the v2-table-fixes branch 3 times, most recently from 6a1fbe8 to 70aaeac Compare May 23, 2025 20:35
Comment on lines 461 to 473
if printedRows+rowHeight+btoi(isHeader && r.borderHeader)+btoi(r.borderBottom)+btoi(!isHeader && !isLastRow)+btoi(!isLastRow && r.borderRow) > r.tableHeight {
return i - btoi(hasHeaders)
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this line looks complex, but it's a result of extensive testing and debugging, so we're covered (even by unit tests).

I can consider separating it into variables if you think it'd help.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I improved this slightly since, but still open to opinions if you have.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one ended up being a small regression due to being tricky.

In theory the intended behavior is debatable, but I'm open to work on restoring the previous behavior.

In short, the previous behavior was forcing the table to show more records than asked if yOffset is too high. (For example, if the user asked to offset 90 out of 100 total rows, we'll still show more then 10 records if we're space "height" available for it).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I was actually able to restore the previous behavior and also fix some edge cases (but not all).

@andreynering andreynering marked this pull request as ready for review May 28, 2025 16:38
@andreynering andreynering requested a review from bashbunni May 28, 2025 17:49
@andreynering
Copy link
Member Author

Hey @Broderick-Westrope,

Just an update from charmbracelet/bubbles#601 (review) to let you know that your tests helped us to identify many bugs on table rendering and I have fixed them here.

This will be ported over to the Bubbles' Table component because it'll soon use this under the hood.

Copy link
Member

@meowgorithm meowgorithm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incredible work, @andreynering. This LGTM. Just to have it documented, how is the table API changing in this PR?

@andreynering
Copy link
Member Author

Just to have it documented, how is the table API changing in this PR?

These functions were exposed as public because they're needed on my Bubbles PR:

  • func DataToMatrix(data Data) (rows [][]string)
  • func (t *Table) GetData() Data
  • func (t *Table) GetHeaders() []string
  • func (t *Table) GetBorderTop() bool
  • func (t *Table) GetBorderBottom() bool
  • func (t *Table) GetBorderLeft() bool
  • func (t *Table) GetBorderRight() bool
  • func (t *Table) GetBorderHeader() bool
  • func (t *Table) GetBorderColumn() bool
  • func (t *Table) GetBorderRow() bool
  • func (t *Table) GetHeight() int
  • func (t *Table) GetYOffset() int
  • func (t *Table) FirstVisibleRowIndex() int
  • func (t *Table) LastVisibleRowIndex() int
  • func (t *Table) VisibleRows() int

Copy link
Member

@bashbunni bashbunni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NICE. Confirmed all test results look good, code is way tidier, and all of the table examples run 👌

@bashbunni
Copy link
Member

We should probably also document that headers don't wrap in the README(?)

@meowgorithm
Copy link
Member

Good call. I’d document it in the GoDocs.

@andreynering andreynering merged commit 946081c into v2-exp Jun 3, 2025
13 checks passed
@andreynering andreynering deleted the v2-table-fixes branch June 3, 2025 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants