@zambon-dev/library 1.6.1 → 1.6.3

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,35 @@ 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.3] - 2026-09-20
27
+
28
+ ### Fixed
29
+
30
+ - Declared `ngx-resize-observer` and `rxjs` in `peerDependencies`. `DataGridRowComponent` imports
31
+ `ngx-resize-observer` at runtime, but the package was never declared, so installing
32
+ `@zambon-dev/library` on its own left the dependency unresolved.
33
+ - Added a README to the published package.
34
+
35
+ ## [1.6.2] - 2026-09-20
36
+
37
+ ### Fixed
38
+
39
+ - **A `lib-data-grid` column with no room from the start no longer drags its heading out of line.**
40
+ 1.6.1 removes the heading of a collapsed column, but only once that column had measured a real
41
+ width at some point. A column that never has any room does not, so it kept a heading over nothing
42
+ and pushed every column to its right along -- up to 263px on a fourteen-column screen, which is
43
+ the same drift 1.6.1 set out to remove.
44
+
45
+ Whether a zero is believable is now settled by the row rather than by what the column measured
46
+ before: if the row has a width the layout is live, so a column reporting zero really has
47
+ collapsed.
48
+
49
+ - **`lib-data-grid` headings no longer stay behind after you revisit a tab.** Re-activating a
50
+ detached tab puts the grid back in the page with its horizontal scroll at the start again, and no
51
+ scroll event follows to say so, so the headings kept the offset they had when you left: on a grid
52
+ scrolled 300px every heading sat 300px away from its column. The header now reconciles with the
53
+ body whenever the grid is re-measured, which is what re-inserting it triggers.
54
+
26
55
  ## [1.6.1] - 2026-09-19
27
56
 
28
57
  ### Fixed
@@ -48,6 +77,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
48
77
  the body does not have. Measured in a running application the drift is zero across every column,
49
78
  at rest and scrolled.
50
79
 
80
+ A column that declares no `size` is laid out as `minmax(0, 1fr)`, which is free to collapse. If
81
+ one of yours does, its heading now goes with it rather than staying behind as a label over
82
+ nothing. Give such a column a real minimum -- `size: 'minmax(8rem, 1fr)'` -- to keep both on
83
+ screen.
84
+
51
85
  ## [1.6.0] - 2026-09-16
52
86
 
53
87
  ### Added
@@ -290,7 +324,9 @@ config options and the `getUserProfile()` method still exist but are no longer c
290
324
  available via [GitHub Releases](https://github.com/RicardoZambon/ZLibraries/releases) and the
291
325
  `library-v*` tags.
292
326
 
293
- [Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/library-v1.6.1...HEAD
327
+ [Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/library-v1.6.3...HEAD
328
+ [1.6.3]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.3
329
+ [1.6.2]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.2
294
330
  [1.6.1]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.1
295
331
  [1.6.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.0
296
332
  [1.5.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.5.0
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # @zambon-dev/library
2
+
3
+ Angular UI components and shared presentation utilities for Zambon applications.
4
+
5
+ This is the presentation layer of [ZLibraries](https://github.com/RicardoZambon/ZLibraries). It has no
6
+ knowledge of authentication, routing shells or backend contracts — those live in
7
+ [`@zambon-dev/framework`](https://www.npmjs.com/package/@zambon-dev/framework) and
8
+ [`@zambon-dev/shared`](https://www.npmjs.com/package/@zambon-dev/shared), both of which build on this package.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @zambon-dev/library
14
+ ```
15
+
16
+ ### Peer dependencies
17
+
18
+ All peers must be present in the consuming application:
19
+
20
+ | Package | Range |
21
+ | --- | --- |
22
+ | `@angular/cdk` | `^19.1.5` |
23
+ | `@angular/common` | `^19.1.0` |
24
+ | `@angular/core` | `^19.1.0` |
25
+ | `@angular/forms` | `^19.1.0` |
26
+ | `@angular/router` | `^19.1.0` |
27
+ | `@ngx-translate/core` | `^16.0.4` |
28
+ | `ngx-resize-observer` | `^3.0.0` |
29
+ | `rxjs` | `^7.8.0` |
30
+
31
+ ## Usage
32
+
33
+ Every component is standalone, so import only what a given component needs:
34
+
35
+ ```ts
36
+ import { Component } from '@angular/core';
37
+ import { DataGridComponent, FormInputComponent } from '@zambon-dev/library';
38
+
39
+ @Component({
40
+ selector: 'app-customers',
41
+ imports: [DataGridComponent, FormInputComponent],
42
+ templateUrl: './customers.component.html',
43
+ })
44
+ export class CustomersComponent {}
45
+ ```
46
+
47
+ `LibraryModule` is also exported for applications that are still NgModule-based, and re-exports every
48
+ component, directive and pipe listed below.
49
+
50
+ ## Styles
51
+
52
+ The package ships SCSS that the components expect. Import it once, at the application root:
53
+
54
+ ```scss
55
+ @use '@zambon-dev/library/styles' as library;
56
+ ```
57
+
58
+ That entry point resolves to `styles/variables.scss` and is also reachable as
59
+ `@zambon-dev/library/styles/variables`.
60
+
61
+ ## What's included
62
+
63
+ **Components** — `BaseComponent`, `CatalogSelectComponent`, `DataGridComponent`, `DataGridRowComponent`,
64
+ `FormInputComponent`, `FormInputGroupComponent`, `FormGroupComponent`, `GroupAccordionComponent`,
65
+ `GroupContainerComponent`, `GroupScrollSpyComponent`, `ModalComponent`, `MultiEditorComponent`,
66
+ `MultiSelectComponent`, `MultiSelectResultGridComponent`, `SidebarComponent`, `RibbonComponent`,
67
+ `RibbonButtonComponent`, `RibbonGroupComponent`
68
+
69
+ **Directives** — `ScrollSpyDirective`
70
+
71
+ **Pipes** — `EnumTranslatePipe`, `ReplacePipe`, `ReplaceManyPipe`
72
+
73
+ Helpers, models, configuration providers, services and validators are exported from the package root as well.
74
+
75
+ ## Documentation
76
+
77
+ Component behaviour and variants are documented as Storybook stories alongside the source. To browse them:
78
+
79
+ ```bash
80
+ npm run storybook:library
81
+ ```
82
+
83
+ ## Contributing
84
+
85
+ See the [workspace README](https://github.com/RicardoZambon/ZLibraries#readme) for the development setup,
86
+ and [CHANGELOG.md](./CHANGELOG.md) for release history.
87
+
88
+ ## License
89
+
90
+ MIT © Ricardo Zambon
@@ -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
  }