@yuuvis/client-framework 3.12.0 → 3.13.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuuvis/client-framework",
3
- "version": "3.12.0",
3
+ "version": "3.13.0",
4
4
  "author": "OPTIMAL SYSTEMS GmbH <npm@optimal-systems.de>",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {
@@ -8,16 +8,16 @@
8
8
  "@angular/common": "^21.2.9",
9
9
  "@angular/core": "^21.2.9",
10
10
  "angular-gridster2": "^21.0.1",
11
- "@yuuvis/client-core": "^3.12.0",
12
- "@yuuvis/client-shell-core": "^3.12.0",
13
- "@yuuvis/client-components": "^3.12.0",
11
+ "@yuuvis/client-core": "^3.13.0",
12
+ "@yuuvis/client-shell-core": "^3.13.0",
13
+ "@yuuvis/client-components": "^3.13.0",
14
14
  "ng-dynamic-component": "^10.8.2",
15
15
  "modern-normalize": "^3.0.1"
16
16
  },
17
17
  "dependencies": {
18
18
  "@angular/material": "^21.2.7",
19
19
  "@ngrx/signals": "^21.1.0",
20
- "@yuuvis/material": "^3.12.0",
20
+ "@yuuvis/material": "^3.13.0",
21
21
  "@yuuvis/media-viewer": "^3.0.6",
22
22
  "angular-split": "^20.0.0",
23
23
  "vis-network": "^10.0.2",
@@ -305,6 +305,24 @@ declare class QueryListComponent<T = any> {
305
305
  * Re-evaluates automatically whenever any of the three sources change.
306
306
  */
307
307
  resultItems: _angular_core.Signal<T[]>;
308
+ /**
309
+ * Object IDs of the currently selected rows — the id-based source of truth for the
310
+ * visual selection.
311
+ *
312
+ * The inner list tracks selection by positional index, which becomes meaningless the
313
+ * moment a re-query reorders or replaces the rendered rows (the `@for` reuses/recreates
314
+ * the projected item directives, so index-based visual state points at the wrong — or
315
+ * detached — directives). When `idProperty` is set, the inner list is switched into
316
+ * `selfHandleSelection` mode and each row's `[selected]` is bound to this set instead, so
317
+ * Angular re-applies the correct selection by ID on every render — a multi-selection then
318
+ * survives sort, page changes, and refreshes. Kept in sync from every committed selection
319
+ * via `onInnerItemSelect()`.
320
+ */
321
+ selectedIds: _angular_core.WritableSignal<Set<string>>;
322
+ /** Whether this component drives the inner list's selection visuals via each row's id-based
323
+ * `[selected]` binding (and thus the inner list should not write them imperatively). Enabled
324
+ * whenever an `idProperty` is configured — the prerequisite for id-based selection. */
325
+ idSelection: _angular_core.Signal<boolean>;
308
326
  /**
309
327
  * Indicates whether a search request is currently in flight.
310
328
  *
@@ -320,6 +338,25 @@ declare class QueryListComponent<T = any> {
320
338
  constructor();
321
339
  /** Resolves the tracking key for a result item in the `@for` loop. */
322
340
  trackItem(item: T, index: number): unknown;
341
+ /**
342
+ * Whether the given row is part of the current selection, resolved by ID.
343
+ *
344
+ * Bound to each row's `[selected]` in the template so the visual selection is driven by
345
+ * {@link selectedIds} (id-based) rather than the inner list's positional state. This is
346
+ * what makes a multi-selection survive a re-query/reorder.
347
+ */
348
+ isRowSelected(item: T): boolean;
349
+ /**
350
+ * Choke point for every committed selection emitted by the inner list.
351
+ *
352
+ * Translates the positional indices into object IDs against the currently rendered
353
+ * `resultItems()` and stores them in {@link selectedIds}, then re-emits the original
354
+ * indices via `itemSelect` so existing consumers are unaffected. Keeping the id set in
355
+ * sync here (rather than in each caller) means clicks, keyboard, drag-select, and
356
+ * programmatic selection all feed the same source of truth. A no-op passthrough when no
357
+ * `idProperty` is configured (the inner list then owns the visual selection as before).
358
+ */
359
+ onInnerItemSelect(indices: number[]): void;
323
360
  /**
324
361
  * Handles a single click on a list item.
325
362
  *
@@ -341,10 +378,16 @@ declare class QueryListComponent<T = any> {
341
378
  * to trigger a secondary action (e.g. opening a detail panel or navigating to a route)
342
379
  * that is distinct from the primary single-click selection.
343
380
  *
381
+ * When a modifier key (Ctrl/Shift/Meta) is held, the double-click is instead treated as a
382
+ * selection gesture: while the user is rapidly building a multi-selection, two quick clicks
383
+ * on the same row are easily coalesced by the browser into a `dblclick`. Emitting the
384
+ * double-click action then would navigate away / open a preview and tear down the whole
385
+ * multi-selection. So we toggle selection for that item and suppress the double-click action.
386
+ *
344
387
  * Called from the template via `ClickDoubleDirective`. Not intended for external callers.
345
388
  *
346
389
  * @param idx Zero-based index of the double-clicked item.
347
- * @param event The originating mouse event (unused, kept for directive compatibility).
390
+ * @param event The originating mouse event; its modifier flags decide open-vs-select.
348
391
  */
349
392
  onItemDoubleClick(idx: number, event: MouseEvent): void;
350
393
  /**