Skip to content

feat: build the footer row lazily when createFooterRow is enabled at runtime - #1269

Merged
6pac merged 2 commits into
masterfrom
feat/runtime-footer-row-enable
Aug 9, 2026
Merged

feat: build the footer row lazily when createFooterRow is enabled at runtime#1269
6pac merged 2 commits into
masterfrom
feat/runtime-footer-row-enable

Conversation

@6pac-ai

@6pac-ai 6pac-ai commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

⚠️ Merge order: this PR assumes #1266 and #1267 are merged first (and pairs naturally with #1268). It has no textual conflicts with them, but it was authored and validated against a master that includes them — please land those before this one.

The bug (Q2 in discussion #1247)

Footer-row DOM was built only in the init path, and internal_setOptions never created it — so setOptions({ createFooterRow: true }) on a live grid flowed into setColumnscreateColumnFooter, dereferenced the undefined _footerRowL, and threw, leaving the grid with a half-mutated options state.

The change (the 'support it' resolution from the triage)

internal_setOptions now materializes the footer DOM when the flag flips true. materializeFooterRow() is the single construction path shared with init — the init path's inline footer block is replaced by a call to the same method (R-before-L scroller order, spacers, columns containers, hidden when !showFooterRow), so the two paths cannot drift. On an already-initialized grid it also binds the footer contextmenu/click/scroll handlers; during init those stay bound in finishInitialization, exactly as before. In the runtime path it runs before setScroller (which selects the footer scroll container) and before setColumns (which populates footer cells), so the existing pipeline completes the job with no further special-casing.

Runtime disable hides the footer rather than destroying it — symmetric with showFooterRow — and setFooterRowVisibility works on a runtime-built footer exactly as on an init-built one.

Test

cypress/e2e/quirk-runtime-footer-enable.cy.tsself-hosting (harness via cy.intercept; no example-page dependency). Enable on a live grid → no throw, scrollers visible, one footer cell and one onFooterRowCellRendered per column, getFooterRow() returns the element, setFooterRowVisibility(false) hides it. Verified to fail pre-fix (TypeError: Cannot read properties of undefined) and pass with the fix; footer + composite-editor + frozen suites ran 27/27 as a regression gate.

One review note: an earlier draft asserted setOptions({ showFooterRow: false }) hides the footer — dropped because master never supported visibility toggling via setOptions for init-built footers either; setFooterRowVisibility is the supported API and is what the spec exercises.

⚠️ Temporary example page

examples/example-quirk-runtime-footer-enable.html is a human-review repro (enable + toggle buttons with a live readout) intended to be deleted before merge — the cypress test is fully independent of it.

(Quirks-triage remaining-items wave: see discussion #1247; siblings #1266, #1267, #1268.)

…runtime

Footer-row DOM was built only in the init path and internal_setOptions
never created it, so setOptions({ createFooterRow: true }) on a live grid
flowed into setColumns -> createColumnFooter, dereferenced the undefined
_footerRowL and threw - leaving the grid with a half-mutated options
state.

internal_setOptions now materializes the footer DOM when the flag flips
true: materializeFooterRow() mirrors the init construction (R-before-L
scroller order, spacers, columns containers, hide when !showFooterRow)
and binds the footer contextmenu/click/scroll handlers on an
already-initialized grid. It runs before setScroller (which selects the
footer scroll container) and before setColumns (which populates footer
cells), so the normal pipeline completes the job. Disabling
createFooterRow at runtime hides the footer rather than destroying it,
symmetric with showFooterRow; setFooterRowVisibility works on the
runtime-built footer as on an init-built one.

Adds a permanent SELF-HOSTING regression test (cypress/e2e/quirk-runtime-
footer-enable.cy.ts): enable on a live grid -> no throw, scrollers
visible, one footer cell and one onFooterRowCellRendered per column,
getFooterRow() returns the element, setFooterRowVisibility(false) hides.
Verified to fail pre-fix (TypeError: Cannot read properties of undefined)
and pass with the fix; footer + composite-editor + frozen suites ran
27/27 as a regression gate.

NOTE: examples/example-quirk-runtime-footer-enable.html is a TEMPORARY
human-review repro page intended to be deleted before merge - the cypress
test does not depend on it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ghiscoding

Copy link
Copy Markdown
Collaborator

replicated on my side and all my tests passed, so it seems valid and ready to merge

The init path's inline footer-row construction is replaced by a call to
materializeFooterRow(), making it the single construction path so the two
cannot drift. The initialized guard keeps event binding unchanged: during
init the handlers are still bound in finishInitialization; on a live grid
the method binds them itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@6pac

6pac commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Actually, I thought it was a bit much repeating all of the footer materialising code for the after init case.
I asked Claude to refactor it to use materializeFooterRow() in the init case as well.

@ghiscoding

Copy link
Copy Markdown
Collaborator

ok that's a bit weird that in that case it ended up with even more loc after the refactor. A quick look at it, looks ok though

@6pac

6pac commented Aug 9, 2026

Copy link
Copy Markdown
Owner

From what I can see the refactor dropped 17 lines from slick.grid.ts (+51 -20 after vs +48 before). May have increased the tests LOC?

Anyway, wiil merge!

@6pac
6pac merged commit a73d083 into master Aug 9, 2026
4 checks passed
@6pac
6pac deleted the feat/runtime-footer-row-enable branch August 9, 2026 23:36
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.

3 participants