ngwr 15.2.0 → 15.3.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.
Files changed (99) hide show
  1. package/alert/styles/_index.scss +13 -5
  2. package/fesm2022/ngwr-alert.mjs +2 -2
  3. package/fesm2022/ngwr-alert.mjs.map +1 -1
  4. package/fesm2022/ngwr-breadcrumbs.mjs +18 -2
  5. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  6. package/fesm2022/ngwr-hotkey.mjs +23 -1
  7. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  8. package/fesm2022/ngwr-i18n-ar.mjs +2 -0
  9. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  10. package/fesm2022/ngwr-i18n-cs.mjs +2 -0
  11. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  12. package/fesm2022/ngwr-i18n-de.mjs +2 -0
  13. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  14. package/fesm2022/ngwr-i18n-en.mjs +2 -0
  15. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  16. package/fesm2022/ngwr-i18n-es.mjs +2 -0
  17. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  18. package/fesm2022/ngwr-i18n-fr.mjs +2 -0
  19. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  20. package/fesm2022/ngwr-i18n-he.mjs +2 -0
  21. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  22. package/fesm2022/ngwr-i18n-hi.mjs +2 -0
  23. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  24. package/fesm2022/ngwr-i18n-id.mjs +2 -0
  25. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  26. package/fesm2022/ngwr-i18n-it.mjs +2 -0
  27. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  28. package/fesm2022/ngwr-i18n-ja.mjs +2 -0
  29. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  30. package/fesm2022/ngwr-i18n-ko.mjs +2 -0
  31. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  32. package/fesm2022/ngwr-i18n-nl.mjs +2 -0
  33. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  34. package/fesm2022/ngwr-i18n-pl.mjs +2 -0
  35. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  36. package/fesm2022/ngwr-i18n-pt.mjs +2 -0
  37. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  38. package/fesm2022/ngwr-i18n-ru.mjs +2 -0
  39. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  40. package/fesm2022/ngwr-i18n-sv.mjs +2 -0
  41. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  42. package/fesm2022/ngwr-i18n-tr.mjs +2 -0
  43. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  44. package/fesm2022/ngwr-i18n-uk.mjs +2 -0
  45. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  46. package/fesm2022/ngwr-i18n-vi.mjs +2 -0
  47. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  48. package/fesm2022/ngwr-i18n-zh-tw.mjs +2 -0
  49. package/fesm2022/ngwr-i18n-zh-tw.mjs.map +1 -1
  50. package/fesm2022/ngwr-i18n-zh.mjs +2 -0
  51. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  52. package/fesm2022/ngwr-pagination.mjs +3 -0
  53. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  54. package/fesm2022/ngwr-pipes.mjs +5 -2
  55. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  56. package/fesm2022/ngwr-schema-form.mjs +3 -0
  57. package/fesm2022/ngwr-schema-form.mjs.map +1 -1
  58. package/fesm2022/ngwr-select-testing.mjs +16 -0
  59. package/fesm2022/ngwr-select-testing.mjs.map +1 -1
  60. package/fesm2022/ngwr-select.mjs +218 -38
  61. package/fesm2022/ngwr-select.mjs.map +1 -1
  62. package/fesm2022/ngwr-statistic.mjs +9 -5
  63. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  64. package/fesm2022/ngwr-version.mjs +1 -1
  65. package/fesm2022/ngwr-version.mjs.map +1 -1
  66. package/i18n/ar.json +2 -0
  67. package/i18n/cs.json +2 -0
  68. package/i18n/de.json +2 -0
  69. package/i18n/en.json +2 -0
  70. package/i18n/es.json +2 -0
  71. package/i18n/fr.json +2 -0
  72. package/i18n/he.json +2 -0
  73. package/i18n/hi.json +2 -0
  74. package/i18n/id.json +2 -0
  75. package/i18n/it.json +2 -0
  76. package/i18n/ja.json +2 -0
  77. package/i18n/ko.json +2 -0
  78. package/i18n/nl.json +2 -0
  79. package/i18n/pl.json +2 -0
  80. package/i18n/pt.json +2 -0
  81. package/i18n/ru.json +2 -0
  82. package/i18n/sv.json +2 -0
  83. package/i18n/tr.json +2 -0
  84. package/i18n/uk.json +2 -0
  85. package/i18n/vi.json +2 -0
  86. package/i18n/zh-TW.json +2 -0
  87. package/i18n/zh.json +2 -0
  88. package/llms-full.txt +3 -3
  89. package/package.json +1 -1
  90. package/schematics/use/symbol-map.json +1 -0
  91. package/select/styles/_index.scss +23 -1
  92. package/skills/ngwr/references/catalog.md +1 -1
  93. package/types/ngwr-alert.d.ts +3 -1
  94. package/types/ngwr-breadcrumbs.d.ts +15 -0
  95. package/types/ngwr-hotkey.d.ts +14 -2
  96. package/types/ngwr-select-testing.d.ts +9 -0
  97. package/types/ngwr-select.d.ts +133 -2
  98. package/types/ngwr-sidebar.d.ts +1 -1
  99. package/types/ngwr-version.d.ts +1 -1
@@ -144,6 +144,15 @@ export declare class WrSelectHarness extends ComponentHarness {
144
144
  removeChip(label: string): Promise<void>;
145
145
  /** The "no results" message, or `null` when the panel is showing options. */
146
146
  getNoResultsText(): Promise<string | null>;
147
+ /** The error row's text after a failed load, retry label included, or `null` while there is none. */
148
+ getLoadErrorText(): Promise<string | null>;
149
+ /**
150
+ * Runs a failed load again: Enter in the field where the field names the error
151
+ * row as active, which works for a `wrSelectLoadError` template too, else a
152
+ * click on the default Try again button (under `freeText`, where Enter commits
153
+ * the text). Throws when no retry is on offer.
154
+ */
155
+ retryLoad(): Promise<void>;
147
156
  /** Whether the panel is showing its async loading row. */
148
157
  isLoading(): Promise<boolean>;
149
158
  /** Move keyboard focus to the select. */
@@ -118,6 +118,28 @@ interface WrSelectContext {
118
118
  /** Register an option; returns an unregister function. */
119
119
  registerOption(reg: WrSelectOptionRegistration): () => void;
120
120
  }
121
+ /**
122
+ * @license
123
+ *
124
+ * Use of this source code is governed by an MIT-style license that can be
125
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
126
+ */
127
+ /** Template context of `<ng-template wrSelectLoadError>`. */
128
+ interface WrSelectLoadErrorContext<E = unknown> {
129
+ /** What the loader threw or rejected with: `let-error`. */
130
+ readonly $implicit: E;
131
+ /** The query whose load failed. */
132
+ readonly query: string;
133
+ /**
134
+ * A retry is on offer: `retryable` is set and nothing else is in the panel. Draw
135
+ * the retry control only while it is, the way the default row does.
136
+ */
137
+ readonly canRetry: boolean;
138
+ /** Runs the load again for that query, while `canRetry` and no retry is in flight. */
139
+ readonly retry: () => void;
140
+ /** A retry is in flight, so the template can draw a loader. */
141
+ readonly retrying: boolean;
142
+ }
121
143
  /**
122
144
  * Behavior mode for `<wr-select>`. The component is the unified
123
145
  * combobox primitive — every shape (single, multi, type-to-search,
@@ -145,6 +167,42 @@ type WrSelectTagValidator = (value: string, existing: readonly string[]) => bool
145
167
  type WrSelectSearchLoader<T> = (query: string) => Observable<readonly T[]> | Promise<readonly T[]> | readonly T[];
146
168
  /** Control size for `<wr-select>` — shares the `--wr-control-*` contract. */
147
169
  type WrSelectSize = 'sm' | 'md' | 'lg';
170
+ /**
171
+ * Replaces what a failed `[loader]` shows in the panel: the message, the retry
172
+ * button, a loader while the retry runs, any text of the app's own. Declare it as
173
+ * a DIRECT child of `<wr-select>`. The context carries the error, the query that
174
+ * failed, `canRetry`, `retry()` and `retrying`.
175
+ *
176
+ * **It draws inside the error row, and that row is an option of the listbox**,
177
+ * since the panel element is the listbox and may own nothing else. So the
178
+ * template holds nothing focusable: a `<button>` inside an option is nested
179
+ * interactive content. Draw a retry the way the default does, a `<span>` with
180
+ * the `.wr-btn` classes and `(click)="retry()"`, inside `@if (canRetry)`. The
181
+ * select's `retryable` decides `canRetry`, and lets Enter in the field reach it.
182
+ *
183
+ * @example
184
+ * ```html
185
+ * <wr-select mode="search" retryable [loader]="search">
186
+ * <ng-template wrSelectLoadError let-error let-canRetry="canRetry" let-retry="retry" let-retrying="retrying">
187
+ * <p>Search is offline: {{ error.message }}</p>
188
+ * @if (canRetry) {
189
+ * <span class="wr-btn wr-btn--sm" (click)="retry()">{{ retrying ? 'Retrying…' : 'Retry' }}</span>
190
+ * }
191
+ * </ng-template>
192
+ * </wr-select>
193
+ * ```
194
+ */
195
+ export declare class WrSelectLoadError<E = SafeAny> {
196
+ readonly template: TemplateRef<WrSelectLoadErrorContext<E>>;
197
+ /**
198
+ * Types the template's `let-` variables under `strictTemplates`. `E` defaults
199
+ * to `SafeAny` for the reason `WrOptionLeading` gives: nothing infers the error
200
+ * type, and narrowed to `unknown`, `error.message` would not compile.
201
+ */
202
+ static ngTemplateContextGuard<E>(_dir: WrSelectLoadError<E>, _ctx: unknown): _ctx is WrSelectLoadErrorContext<E>;
203
+ static ɵfac: i0.ɵɵFactoryDeclaration<WrSelectLoadError<any>, never>;
204
+ static ɵdir: i0.ɵɵDirectiveDeclaration<WrSelectLoadError<any>, "ng-template[wrSelectLoadError]", never, {}, {}, never, never, true, never>;
205
+ }
148
206
  interface SelectedChip {
149
207
  readonly value: unknown;
150
208
  readonly label: string;
@@ -430,8 +488,27 @@ export declare class WrSelect implements FormValueControl<unknown>, WrSelectCont
430
488
  readonly noResultsText: import("@angular/core").InputSignal<string | null>;
431
489
  /** Search mode: text shown while the async loader is in flight. Falls back to `select.loading`. */
432
490
  readonly loadingText: import("@angular/core").InputSignal<string | null>;
491
+ /**
492
+ * Search mode: text shown in place of the "no results" row when the async
493
+ * loader fails. Falls back to `select.loadError`.
494
+ */
495
+ readonly loadErrorText: import("@angular/core").InputSignal<string | null>;
496
+ /**
497
+ * Search mode: let a failed load be tried again, for the same query, while the
498
+ * panel has nothing else to offer. The error row draws a Try again button, and
499
+ * Enter in the field reaches it, except under `freeText`, where Enter still
500
+ * commits the typed text. Without it the row only reports the failure; the next keystroke
501
+ * tries again either way.
502
+ *
503
+ * @default false
504
+ */
505
+ readonly retryable: import("@angular/core").InputSignalWithTransform<boolean, any>;
506
+ /** Search mode: label of the retry action on the error row. Falls back to `select.retry`. */
507
+ readonly retryText: import("@angular/core").InputSignal<string | null>;
433
508
  protected readonly resolvedNoResults: import("@angular/core").Signal<string>;
434
509
  protected readonly resolvedLoading: import("@angular/core").Signal<string>;
510
+ protected readonly resolvedLoadError: import("@angular/core").Signal<string>;
511
+ protected readonly resolvedRetry: import("@angular/core").Signal<string>;
435
512
  /**
436
513
  * Debounced search query, gated to searchable selects. Emits on every settled
437
514
  * change — including the empty string when the field is cleared — so a
@@ -468,6 +545,19 @@ export declare class WrSelect implements FormValueControl<unknown>, WrSelectCont
468
545
  private readonly loaderLoading;
469
546
  /** Either flag shows the panel's progress row. @internal */
470
547
  protected readonly isLoading: import("@angular/core").Signal<boolean>;
548
+ /** The query whose load failed, until a load for another query starts or one succeeds. */
549
+ private readonly failedQuery;
550
+ /** What the failed load threw or rejected with. */
551
+ private readonly loadErrorValue;
552
+ /** A retry is in flight. The error row stays up for it, with a loader. */
553
+ protected readonly retrying: import("@angular/core").WritableSignal<boolean>;
554
+ /**
555
+ * The load for the query on screen failed. Keyed by the query, so a keystroke
556
+ * takes the error down at once, rather than when its debounced load starts.
557
+ */
558
+ protected readonly loadFailed: import("@angular/core").Signal<boolean>;
559
+ /** Asks the loader pipeline to run the current query again. */
560
+ private readonly retryRequests;
471
561
  /**
472
562
  * Tag mode: keys / characters that commit the current draft into a chip.
473
563
  * `'Enter'` is the key name; everything else is a literal character watched
@@ -748,6 +838,28 @@ export declare class WrSelect implements FormValueControl<unknown>, WrSelectCont
748
838
  protected readonly meetsMinChars: import("@angular/core").Signal<boolean>;
749
839
  /** Search mode: show "no results" when the panel has nothing to offer. */
750
840
  protected readonly hasNoResults: import("@angular/core").Signal<boolean>;
841
+ /** Search mode: the error row, in place of "no results", after a failed load and through its retry. */
842
+ protected readonly showLoadError: import("@angular/core").Signal<boolean>;
843
+ /** A `<ng-template wrSelectLoadError>` declared as a direct child, or `undefined`. */
844
+ protected readonly loadErrorTpl: import("@angular/core").Signal<WrSelectLoadError<any> | undefined>;
845
+ /** What `wrSelectLoadError` is handed. */
846
+ protected readonly loadErrorContext: import("@angular/core").Signal<{
847
+ $implicit: unknown;
848
+ query: string;
849
+ canRetry: boolean;
850
+ retry: () => void;
851
+ retrying: boolean;
852
+ }>;
853
+ /** One function for the context, gated the way the default button is. */
854
+ private readonly retryFn;
855
+ /**
856
+ * Search mode: the error row offers a retry. Only while nothing else is on
857
+ * offer, since the arrows walk the options and never reach this row; with
858
+ * options beside it, a retry by pointer alone would have no keyboard twin.
859
+ */
860
+ protected readonly retryOffered: import("@angular/core").Signal<boolean>;
861
+ /** Id of the error row, which `aria-activedescendant` names while it offers a retry. */
862
+ protected readonly retryRowId: string;
751
863
  /** Search mode: is this option hidden by the current query? @internal */
752
864
  private isOptionHidden;
753
865
  protected readonly panelTpl: import("@angular/core").Signal<TemplateRef<any>>;
@@ -844,6 +956,10 @@ export declare class WrSelect implements FormValueControl<unknown>, WrSelectCont
844
956
  private overlayRef;
845
957
  constructor();
846
958
  isSelected(value: unknown): boolean;
959
+ /** Runs the loader again for the query that failed, unless a retry is already in flight. @internal */
960
+ private retryLoad;
961
+ /** The retry button runs the load only while it is on offer. @internal */
962
+ protected onLoadErrorClick(): void;
847
963
  selectOption(value: unknown): void;
848
964
  /**
849
965
  * Adds a `<wr-option>` to the registry and returns its unregister function.
@@ -1021,6 +1137,21 @@ export declare class WrSelect implements FormValueControl<unknown>, WrSelectCont
1021
1137
  "required": false;
1022
1138
  "isSignal": true;
1023
1139
  };
1140
+ "loadErrorText": {
1141
+ "alias": "loadErrorText";
1142
+ "required": false;
1143
+ "isSignal": true;
1144
+ };
1145
+ "retryable": {
1146
+ "alias": "retryable";
1147
+ "required": false;
1148
+ "isSignal": true;
1149
+ };
1150
+ "retryText": {
1151
+ "alias": "retryText";
1152
+ "required": false;
1153
+ "isSignal": true;
1154
+ };
1024
1155
  "loading": {
1025
1156
  "alias": "loading";
1026
1157
  "required": false;
@@ -1071,7 +1202,7 @@ export declare class WrSelect implements FormValueControl<unknown>, WrSelectCont
1071
1202
  "searchChange": "searchChange";
1072
1203
  "value": "valueChange";
1073
1204
  "touch": "touch";
1074
- }, ["defaultLeading", "projectedOptions"], ["*"], true, never>;
1205
+ }, ["defaultLeading", "projectedOptions", "loadErrorTpl"], ["*"], true, never>;
1075
1206
  }
1076
1207
  /**
1077
1208
  * Single option inside a `<wr-select>`.
@@ -1323,4 +1454,4 @@ export declare class WrOptionLeading<T = SafeAny> {
1323
1454
  * @internal
1324
1455
  */
1325
1456
  export declare const WR_SELECT: InjectionToken<WrSelectContext>;
1326
- export type { WrOptionLeadingContext, WrOptionLeadingPlacement, WrSelectContext, WrSelectMode, WrSelectSearchLoader, WrSelectSize, WrSelectTagValidator };
1457
+ export type { WrOptionLeadingContext, WrOptionLeadingPlacement, WrSelectContext, WrSelectLoadErrorContext, WrSelectMode, WrSelectSearchLoader, WrSelectSize, WrSelectTagValidator };
@@ -1,6 +1,6 @@
1
1
  import * as i0 from "@angular/core";
2
- import { WrIconName } from "ngwr/icon";
3
2
  import { IsActiveMatchOptions } from "@angular/router";
3
+ import { WrIconName } from "ngwr/icon";
4
4
  /**
5
5
  * What `[routerLinkActiveOptions]` accepts: the short form, or any subset of the
6
6
  * router's own match options (`paths`, `queryParams`, `matrixParams`, `fragment`).
@@ -15,7 +15,7 @@ import { InjectionToken } from "@angular/core";
15
15
  * Distinct from `Version` exported by `@angular/core`, which reports the
16
16
  * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.
17
17
  */
18
- export declare const NGWR_VERSION = "15.2.0";
18
+ export declare const NGWR_VERSION = "15.3.0";
19
19
  /**
20
20
  * Injection token holding the ngwr library version string.
21
21
  *