Skip to content

fix(table): stretch columns correctly when movable rows are enabled#4125

Open
viktorSoftDev wants to merge 2 commits into
mainfrom
fix/4123-stretch-columns-movable-rows
Open

fix(table): stretch columns correctly when movable rows are enabled#4125
viktorSoftDev wants to merge 2 commits into
mainfrom
fix/4123-stretch-columns-movable-rows

Conversation

@viktorSoftDev

@viktorSoftDev viktorSoftDev commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Bug Fixes

    • Improved drag-handle column width management in tables with movable rows under stretchColumns layout, ensuring proper row stretching while maintaining consistent drag-handle width.
  • Tests

    • Added tests verifying row width stretching and drag-handle column width behavior.

Fixes #4123

What

layout="stretchColumns" did not stretch the columns when movableRows was enabled — the rows ended short of the table width, leaving a blank filler column on the right.

Why

The drag-handle row-header column is clamped to --limel-table-drag-handle-width (2rem) by CSS with !important, but Tabulator's layout math knew nothing about that width. The fitColumns layout (which stretchColumns maps to) treated the handle as a regular flexible column and handed it a full equal flex share; the difference between the allocated share and the rendered 32px showed up as blank space, and the data columns were left narrower than they should be.

Note: the issue's suspected cause (frozen: true on the row header) was disproven — plain Tabulator 6.3.1 with a frozen rowHeader distributes fitColumns widths correctly. The column stays frozen.

How

The table now resolves --limel-table-drag-handle-width to pixels by measuring a probe element (so any unit or consumer override works) and reserves exactly that width (width + minWidth) in the rowHeader column definition. Tabulator's bookkeeping and the rendered width now agree, for all layouts. Setting minWidth also fixes the header cell previously rendering at Tabulator's 40px default minimum instead of 32px.

Regression-tested with two new e2e tests: rows span the full table width with stretchColumns + movableRows, and the drag-handle column stays at its fixed width.

Review:

  • Commits are atomic
  • Commits have the correct type for the changes made
  • Commits with breaking changes are marked as such

Browsers tested:

(Check any that applies, it's ok to leave boxes unchecked if testing something didn't seem relevant.)

Windows:

  • Chrome
  • Edge
  • Firefox

Linux:

  • Chrome
  • Firefox

macOS:

  • Chrome
  • Firefox
  • Safari

Mobile:

  • Chrome on Android
  • iOS

The drag-handle row-header column is clamped to
--limel-table-drag-handle-width by CSS, but Tabulator did not know
about that width. Width-distributing layouts such as fitColumns
(layout="stretchColumns") handed the handle column a full flex share,
and the difference between the allocated share and the rendered CSS
width showed up as a blank filler column while the data columns were
left too narrow.

Resolve the CSS custom property to pixels with a probe element and
reserve that exact width (width + minWidth) in the rowHeader column
definition, so Tabulator's layout math agrees with the rendered width.

fixes #4123
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR fixes the issue where Tabulator's stretchColumns layout does not stretch columns when movableRows is enabled. The fix updates RowDragManager.getRowHeaderDefinition to accept an explicit drag-handle width parameter, computes that width at runtime from a CSS variable, and wires it through the table component so Tabulator's layout engine can properly distribute remaining space.

Changes

Table drag-handle width fix for stretchColumns layout

Layer / File(s) Summary
Row drag manager API and documentation
src/components/table/row-drag-manager.ts
getRowHeaderDefinition now accepts a width: number parameter and applies it to the returned column definition via width and minWidth. Documentation expands to describe CSS width clamping and Tabulator layout requirements.
Row drag manager unit tests
src/components/table/row-drag-manager.spec.ts
Tests updated to call getRowHeaderDefinition(32) with explicit width. New assertion verifies width reservation. Existing formatter, element property, language propagation, and click-handler tests adjusted to use the new API.
Table component drag-handle width wiring
src/components/table/table.tsx
getRowDragOptions computes drag-handle width at runtime via new getDragHandleWidth() helper, which resolves the --limel-table-drag-handle-width CSS variable into pixels with a 32px fallback, and passes it to getRowHeaderDefinition().
E2E test coverage for movableRows with stretchColumns
src/components/table/table.e2e.tsx
New test suite verifies rows stretch to container width when movableRows is enabled with layout="stretchColumns", and that the drag-handle column maintains its fixed expected width.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • Lundalogik/lime-elements#3983: Introduces the original row-drag-and-drop implementation; this PR builds on that by adding explicit width control to resolve layout conflicts.

Suggested labels

released

Suggested reviewers

  • Kiarokh
  • adrianschmidt
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective: fixing column stretching when movable rows are enabled, which is the core issue addressed.
Linked Issues check ✅ Passed All coding requirements from issue #4123 are met: the drag-handle width is now explicitly measured and reserved in the rowHeader definition, Tabulator's layout math now matches rendered width, and e2e tests verify the fix.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objective of fixing column stretching with movable rows; includes width measurement, test updates, and e2e test additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/4123-stretch-columns-movable-rows

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown

Documentation has been published to https://lundalogik.github.io/lime-elements/versions/PR-4125/

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/table/table.e2e.tsx`:
- Around line 224-233: The test currently hardcodes expectedWidth = 32 which is
brittle; instead read the CSS variable --limel-table-drag-handle-width from the
test environment (via getComputedStyle on document.documentElement), parse its
value and convert to pixels if it’s in rem (multiply by root font-size) or use
the px value directly, then use that numeric pixel value for the assertions
against handleCell.getBoundingClientRect().width and
handleHeader.getBoundingClientRect().width so the test adapts to overrides.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1ed06a93-2954-466f-abc3-ce86e909c86b

📥 Commits

Reviewing files that changed from the base of the PR and between b13ced9 and 85e9625.

📒 Files selected for processing (5)
  • src/components/chip-set/chip-set-input-helpers.ts
  • src/components/table/row-drag-manager.spec.ts
  • src/components/table/row-drag-manager.ts
  • src/components/table/table.e2e.tsx
  • src/components/table/table.tsx
💤 Files with no reviewable changes (1)
  • src/components/chip-set/chip-set-input-helpers.ts

Comment on lines +224 to +233
// 2rem at the default 16px root font size
const expectedWidth = 32;
expect(handleCell.getBoundingClientRect().width).toBeCloseTo(
expectedWidth,
0
);
expect(handleHeader.getBoundingClientRect().width).toBeCloseTo(
expectedWidth,
0
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid hardcoded 32px in width assertion

This assertion can become flaky when root font-size or --limel-table-drag-handle-width is overridden, even if behavior is correct. Derive expected width from the CSS variable in the test environment.

Suggested test adjustment
-            // 2rem at the default 16px root font size
-            const expectedWidth = 32;
+            const probe = document.createElement('div');
+            probe.style.cssText =
+                'position:absolute; visibility:hidden;' +
+                'width: var(--limel-table-drag-handle-width);';
+            root.shadowRoot!.append(probe);
+            const expectedWidth = probe.getBoundingClientRect().width || 32;
+            probe.remove();
             expect(handleCell.getBoundingClientRect().width).toBeCloseTo(
                 expectedWidth,
                 0
             );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 2rem at the default 16px root font size
const expectedWidth = 32;
expect(handleCell.getBoundingClientRect().width).toBeCloseTo(
expectedWidth,
0
);
expect(handleHeader.getBoundingClientRect().width).toBeCloseTo(
expectedWidth,
0
);
const probe = document.createElement('div');
probe.style.cssText =
'position:absolute; visibility:hidden;' +
'width: var(--limel-table-drag-handle-width);';
root.shadowRoot!.append(probe);
const expectedWidth = probe.getBoundingClientRect().width || 32;
probe.remove();
expect(handleCell.getBoundingClientRect().width).toBeCloseTo(
expectedWidth,
0
);
expect(handleHeader.getBoundingClientRect().width).toBeCloseTo(
expectedWidth,
0
);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/table/table.e2e.tsx` around lines 224 - 233, The test
currently hardcodes expectedWidth = 32 which is brittle; instead read the CSS
variable --limel-table-drag-handle-width from the test environment (via
getComputedStyle on document.documentElement), parse its value and convert to
pixels if it’s in rem (multiply by root font-size) or use the px value directly,
then use that numeric pixel value for the assertions against
handleCell.getBoundingClientRect().width and
handleHeader.getBoundingClientRect().width so the test adapts to overrides.

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.

limel-table: layout=stretchColumns does not stretch columns when movableRows is enabled

1 participant