Files
dc/client/src/app/editor/utils/refreshGridAfterContainerResize.ts
T
dc ba4ddb06d3
Build / Build-and-ng-test (pull_request) Successful in 6m28s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m1s
Build / Build-and-test-development (pull_request) Successful in 31m39s
test(editor): cover the resize observer wiring, not just the helper
The helper-only spec passes even if the observer goes back to calling
updateSettings() - which is the regression the helper exists to prevent.
Move the observer into refreshGridAfterContainerResize.ts so a spec can
drive a real container resize through it, and assert that the resize
reaches refreshDimensions() without any settings call. Verified by
re-injecting the old wiring: the spec fails with 'Expected spy
updateSettings not to have been called', and passes once it is removed.

Also corrects the helper's claim about what refreshDimensions() measures:
it compares rootElement.getBoundingClientRect() with the last measured
size, and both grids take their height from a viewport-derived calc(), so
a resize that matters is a width or viewport change.
2026-11-01 23:27:41 +00:00

54 lines
2.1 KiB
TypeScript

import Handsontable from 'handsontable'
/**
* Re-measures a grid after its container changed size (sidebar toggle, modal
* open/close, window resize).
*
* Deliberately does NOT call `updateSettings()`. Any settings call while a
* multi-column sort is active corrupts formula cell references into `#REF!` -
* that is the bug `updateSettingsSortSafe()` exists for - and the workaround
* (clear the sort, apply, re-apply the sort) re-sorts the data underneath an
* open cell editor, so typing can land on a different row than the one being
* edited. A container resize has no business changing settings at all:
* `refreshDimensions()` measures `rootElement.getBoundingClientRect()` and
* compares it with the last measured size, re-running `adjustElementsSize()`
* and a render only when the box actually moved. Both grids take their height
* from a viewport-derived `calc()` setting (editor.component.ts:203), so a
* container resize that matters to the grid is a width change or a viewport
* change - both of which move that box. It also fires
* `beforeRefreshDimensions` / `afterRefreshDimensions` for anything that needs
* to react.
*/
export function refreshGridAfterContainerResize(
hot: Handsontable | null | undefined
): void {
if (!hot || hot.isDestroyed) return
hot.refreshDimensions()
}
/**
* Watches a grid's container and re-measures the grid whenever its box changes
* (sidebar toggle, modal open/close, window resize).
*
* The observer lives here rather than in the component so the wiring is
* covered by a spec: what matters is not that `refreshDimensions()` is called
* but that a resize never reaches `updateSettings()`.
*
* Returns the observer so the caller can disconnect it on destroy.
*/
export function observeGridContainerResize(
hot: Handsontable | null | undefined,
container: HTMLElement | null | undefined
): ResizeObserver | undefined {
if (!hot || !container || typeof ResizeObserver === 'undefined') {
return undefined
}
const observer = new ResizeObserver(() => {
requestAnimationFrame(() => refreshGridAfterContainerResize(hot))
})
observer.observe(container)
return observer
}