@zambon-dev/library 1.6.1 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -23,6 +23,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
23
23
 
24
24
  ### ⚠ Breaking Changes / Migration
25
25
 
26
+ ## [1.6.2] - 2026-09-20
27
+
28
+ ### Fixed
29
+
30
+ - **A `lib-data-grid` column with no room from the start no longer drags its heading out of line.**
31
+ 1.6.1 removes the heading of a collapsed column, but only once that column had measured a real
32
+ width at some point. A column that never has any room does not, so it kept a heading over nothing
33
+ and pushed every column to its right along -- up to 263px on a fourteen-column screen, which is
34
+ the same drift 1.6.1 set out to remove.
35
+
36
+ Whether a zero is believable is now settled by the row rather than by what the column measured
37
+ before: if the row has a width the layout is live, so a column reporting zero really has
38
+ collapsed.
39
+
40
+ - **`lib-data-grid` headings no longer stay behind after you revisit a tab.** Re-activating a
41
+ detached tab puts the grid back in the page with its horizontal scroll at the start again, and no
42
+ scroll event follows to say so, so the headings kept the offset they had when you left: on a grid
43
+ scrolled 300px every heading sat 300px away from its column. The header now reconciles with the
44
+ body whenever the grid is re-measured, which is what re-inserting it triggers.
45
+
26
46
  ## [1.6.1] - 2026-09-19
27
47
 
28
48
  ### Fixed
@@ -48,6 +68,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
48
68
  the body does not have. Measured in a running application the drift is zero across every column,
49
69
  at rest and scrolled.
50
70
 
71
+ A column that declares no `size` is laid out as `minmax(0, 1fr)`, which is free to collapse. If
72
+ one of yours does, its heading now goes with it rather than staying behind as a label over
73
+ nothing. Give such a column a real minimum -- `size: 'minmax(8rem, 1fr)'` -- to keep both on
74
+ screen.
75
+
51
76
  ## [1.6.0] - 2026-09-16
52
77
 
53
78
  ### Added
@@ -290,7 +315,8 @@ config options and the `getUserProfile()` method still exist but are no longer c
290
315
  available via [GitHub Releases](https://github.com/RicardoZambon/ZLibraries/releases) and the
291
316
  `library-v*` tags.
292
317
 
293
- [Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/library-v1.6.1...HEAD
318
+ [Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/library-v1.6.2...HEAD
319
+ [1.6.2]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.2
294
320
  [1.6.1]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.1
295
321
  [1.6.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.0
296
322
  [1.5.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.5.0
@@ -2215,7 +2215,7 @@ class DataGridRowComponent extends BaseComponent {
2215
2215
  dataGridDataset = inject(DataGridDataset);
2216
2216
  selected = false;
2217
2217
  _rowData;
2218
- hasMeasured = {};
2218
+ elementRef = inject(ElementRef);
2219
2219
  //#endregion
2220
2220
  //#region Properties
2221
2221
  get rowData() {
@@ -2224,6 +2224,9 @@ class DataGridRowComponent extends BaseComponent {
2224
2224
  get columns() {
2225
2225
  return this.dataGridDataset.columns;
2226
2226
  }
2227
+ get isLaidOut() {
2228
+ return (this.elementRef.nativeElement?.getBoundingClientRect().width ?? 0) > 0;
2229
+ }
2227
2230
  get isRowDataSelected() {
2228
2231
  return this.dataGridDataset.isKeySelected(this.rowKey);
2229
2232
  }
@@ -2250,14 +2253,16 @@ class DataGridRowComponent extends BaseComponent {
2250
2253
  //#region Event handlers
2251
2254
  onResize(colIndex, event) {
2252
2255
  const width = event.contentRect.width;
2253
- // The very first callback can arrive before the grid is laid out and reports zero for every
2254
- // column; taking that at face value would pin the heading at zero. Once a column has measured
2255
- // something real, a later zero is believable -- that is a 1fr column collapsing, and the
2256
- // heading has to collapse with it or every column to its right sits under the wrong one.
2257
- if (width <= 0 && !this.hasMeasured[colIndex]) {
2256
+ // A zero means one of two very different things. Before the grid is laid out every column
2257
+ // reports zero, and taking that at face value would pin every heading at zero. Once the row
2258
+ // itself has a width the layout is live, and a zero is then the real thing: a 1fr column
2259
+ // collapsed for want of room, whose heading has to collapse with it or every column to its
2260
+ // right sits under the wrong one. Asking the row -- rather than remembering whether this
2261
+ // column once measured something -- also covers a column that is born collapsed and never
2262
+ // measures anything else.
2263
+ if (width <= 0 && !this.isLaidOut) {
2258
2264
  return;
2259
2265
  }
2260
- this.hasMeasured[colIndex] = true;
2261
2266
  // Reported on every change, not just the first. The body lays the columns out as a CSS grid of
2262
2267
  // minmax(x, min-content), so a column is only as wide as the content currently rendered --
2263
2268
  // which virtual scrolling keeps changing. Measuring once and latching left the header copying
@@ -2489,6 +2494,7 @@ class DataGridComponent extends BaseComponent {
2489
2494
  this.headerRightMargin = this.bodyElement.nativeElement.clientWidth - viewportWidth;
2490
2495
  }
2491
2496
  this.viewport?.checkViewportSize();
2497
+ this.syncHeaderScroll();
2492
2498
  this.changeDetectorRef.detectChanges();
2493
2499
  });
2494
2500
  this.ngZone.runOutsideAngular(() => {
@@ -2520,6 +2526,15 @@ class DataGridComponent extends BaseComponent {
2520
2526
  }
2521
2527
  //#endregion
2522
2528
  //#region Private methods
2529
+ syncHeaderScroll() {
2530
+ // Re-inserting the viewport into the DOM -- which is what re-activating a detached tab does --
2531
+ // puts its scroll position back to zero without firing a scroll event, so nothing tells the
2532
+ // header to come back with it and the headings sit at an offset the body no longer has.
2533
+ const scrollLeft = this.viewport?.elementRef?.nativeElement?.scrollLeft ?? 0;
2534
+ if (this.headerScrollLeft !== scrollLeft) {
2535
+ this.headerScrollLeft = scrollLeft;
2536
+ }
2537
+ }
2523
2538
  trackByFn(index, item) {
2524
2539
  return item.key;
2525
2540
  }