ngwr 9.0.1 → 9.1.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/date-picker/styles/_index.scss +62 -0
- package/drawer/styles/_index.scss +23 -0
- package/fesm2022/ngwr-date-picker.mjs +509 -1
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-dialog.mjs +85 -12
- package/fesm2022/ngwr-dialog.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +340 -6
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +5 -0
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +5 -0
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +1 -1
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +221 -38
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/llms-full.txt +11 -11
- package/llms.txt +12 -6
- package/package.json +21 -5
- package/schematics/use/symbol-map.json +5 -0
- package/types/ngwr-date-picker.d.ts +167 -1
- package/types/ngwr-dialog.d.ts +71 -8
- package/types/ngwr-drawer.d.ts +225 -6
- package/types/ngwr-select.d.ts +115 -9
- package/types/ngwr-version.d.ts +1 -1
package/types/ngwr-drawer.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { TemplateRef } from '@angular/core';
|
|
2
|
+
import { TemplateRef, ComponentRef, InjectionToken } from '@angular/core';
|
|
3
|
+
import { ComponentType } from '@angular/cdk/portal';
|
|
4
|
+
import { ConfigurableFocusTrap } from '@angular/cdk/a11y';
|
|
5
|
+
import { OverlayRef } from '@angular/cdk/overlay';
|
|
6
|
+
import { ReplaySubject } from 'rxjs';
|
|
3
7
|
|
|
4
8
|
/**
|
|
5
9
|
* @license
|
|
@@ -10,6 +14,44 @@ import { TemplateRef } from '@angular/core';
|
|
|
10
14
|
/** Side of the viewport the drawer slides in from. */
|
|
11
15
|
type WrDrawerPosition = 'left' | 'right' | 'top' | 'bottom';
|
|
12
16
|
|
|
17
|
+
/**
|
|
18
|
+
* @license
|
|
19
|
+
*
|
|
20
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
21
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Options accepted by `WrDrawerManager.open()`.
|
|
26
|
+
*
|
|
27
|
+
* Mirrors the `<wr-drawer>` inputs, minus the ones that need the component's
|
|
28
|
+
* own wrapper markup (`showHandle` / swipe-to-dismiss).
|
|
29
|
+
*/
|
|
30
|
+
interface WrDrawerOptions<D = unknown> {
|
|
31
|
+
/** Data payload exposed to the drawer content via `WR_DRAWER_DATA`. */
|
|
32
|
+
readonly data?: D;
|
|
33
|
+
/** Side the drawer slides in from. @default 'right' */
|
|
34
|
+
readonly position?: WrDrawerPosition;
|
|
35
|
+
/** Width when position is left/right. Any CSS length. @default '20rem' */
|
|
36
|
+
readonly width?: string;
|
|
37
|
+
/** Height when position is top/bottom. Any CSS length. @default '16rem' */
|
|
38
|
+
readonly height?: string;
|
|
39
|
+
/** Upper cap on height (top/bottom positions). Any CSS length. @default null (no cap) */
|
|
40
|
+
readonly maxHeight?: string | null;
|
|
41
|
+
/** Round the leading corners — the edge facing the viewport interior. @default false */
|
|
42
|
+
readonly rounded?: boolean;
|
|
43
|
+
/** Pad the trailing edge with `env(safe-area-inset-*)`. @default false */
|
|
44
|
+
readonly safeArea?: boolean;
|
|
45
|
+
/** Show the dimming backdrop. @default true */
|
|
46
|
+
readonly hasBackdrop?: boolean;
|
|
47
|
+
/** When `true`, clicks on the backdrop close the drawer. @default true */
|
|
48
|
+
readonly closeOnBackdropClick?: boolean;
|
|
49
|
+
/** When `true`, the Escape key closes the drawer. @default true */
|
|
50
|
+
readonly closeOnEscape?: boolean;
|
|
51
|
+
/** Extra CSS class(es) added to the panel. */
|
|
52
|
+
readonly panelClass?: string | readonly string[];
|
|
53
|
+
}
|
|
54
|
+
|
|
13
55
|
/**
|
|
14
56
|
* Side panel that slides in from an edge of the viewport. Two-way binds
|
|
15
57
|
* `open` and renders into a CDK overlay so it sits above page content.
|
|
@@ -92,6 +134,170 @@ declare class WrDrawer {
|
|
|
92
134
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrDrawer, "wr-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showHandle": { "alias": "showHandle"; "required": false; "isSignal": true; }; "safeArea": { "alias": "safeArea"; "required": false; "isSignal": true; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; "isSignal": true; }; "closeOnBackdropClick": { "alias": "closeOnBackdropClick"; "required": false; "isSignal": true; }; "closeOnEscape": { "alias": "closeOnEscape"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*"], true, never>;
|
|
93
135
|
}
|
|
94
136
|
|
|
137
|
+
/**
|
|
138
|
+
* @license
|
|
139
|
+
*
|
|
140
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
141
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Handle returned by `WrDrawerManager.open()`.
|
|
146
|
+
*
|
|
147
|
+
* Wraps the underlying `OverlayRef` and tracks the close result. It is also
|
|
148
|
+
* provided inside the drawer's own injector, so the projected content can
|
|
149
|
+
* inject it and close itself — the counterpart to `[wrDrawerClose]` when the
|
|
150
|
+
* close is programmatic (after a save succeeds, say) rather than a click.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* // Caller side.
|
|
155
|
+
* const ref = drawers.open<ChatComponent, boolean>(ChatComponent, { position: 'right' });
|
|
156
|
+
* const result = await ref.awaitClose(); // boolean | undefined
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* // Content side — the drawer closes itself.
|
|
162
|
+
* @Component({...})
|
|
163
|
+
* export class ChatComponent {
|
|
164
|
+
* private readonly ref = inject(WrDrawerRef);
|
|
165
|
+
*
|
|
166
|
+
* send(): void {
|
|
167
|
+
* this.store.send(this.draft());
|
|
168
|
+
* this.ref.close(true);
|
|
169
|
+
* }
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
declare class WrDrawerRef<C, R = unknown> {
|
|
174
|
+
private readonly _overlayRef;
|
|
175
|
+
/**
|
|
176
|
+
* Emits the close result once and completes.
|
|
177
|
+
*
|
|
178
|
+
* A `ReplaySubject`, not a plain `Subject`, so the result survives a late
|
|
179
|
+
* subscriber: content can close itself before `open()` has even returned, and
|
|
180
|
+
* `awaitClose()` may be called long after the dismissal — both would otherwise
|
|
181
|
+
* see only `complete` and resolve `undefined`.
|
|
182
|
+
*/
|
|
183
|
+
readonly closed: ReplaySubject<R | undefined>;
|
|
184
|
+
/** @internal */
|
|
185
|
+
componentRef: ComponentRef<C> | null;
|
|
186
|
+
/** @internal */
|
|
187
|
+
focusTrap: ConfigurableFocusTrap | null;
|
|
188
|
+
/** @internal */
|
|
189
|
+
previouslyFocused: HTMLElement | null;
|
|
190
|
+
constructor(_overlayRef: OverlayRef);
|
|
191
|
+
/** The instantiated drawer component. */
|
|
192
|
+
get componentInstance(): C;
|
|
193
|
+
private isClosed;
|
|
194
|
+
/** Close the drawer, optionally returning a result. */
|
|
195
|
+
close(result?: R): void;
|
|
196
|
+
private teardown;
|
|
197
|
+
/** Resolves with the close result when the drawer is dismissed. */
|
|
198
|
+
awaitClose(): Promise<R | undefined>;
|
|
199
|
+
/** Underlying overlay ref — escape hatch for advanced cases. */
|
|
200
|
+
get overlayRef(): OverlayRef;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Opens drawer components in an isolated NGWR overlay — the programmatic
|
|
205
|
+
* counterpart to `<wr-drawer [(open)]="…">`.
|
|
206
|
+
*
|
|
207
|
+
* Use the component when the drawer is part of a template and its open state
|
|
208
|
+
* is a signal you already own; use this service when the caller doesn't own
|
|
209
|
+
* the markup (opening a chat panel from a toolbar action, from an effect, from
|
|
210
|
+
* a route guard) or when you need the close result.
|
|
211
|
+
*
|
|
212
|
+
* Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`
|
|
213
|
+
* — drawers render into NGWR's own overlay container and never collide
|
|
214
|
+
* with other CDK consumers (Material, NG-ZORRO, etc.).
|
|
215
|
+
*
|
|
216
|
+
* `showHandle` / swipe-to-dismiss is component-only: it needs the drawer's own
|
|
217
|
+
* wrapper markup, which the service path replaces with your component.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```ts
|
|
221
|
+
* const drawers = inject(WrDrawerManager);
|
|
222
|
+
*
|
|
223
|
+
* const ref = drawers.open(ChatComponent, {
|
|
224
|
+
* data: { threadId },
|
|
225
|
+
* position: 'right',
|
|
226
|
+
* width: '28rem',
|
|
227
|
+
* });
|
|
228
|
+
*
|
|
229
|
+
* await ref.awaitClose();
|
|
230
|
+
* ```
|
|
231
|
+
*
|
|
232
|
+
* @see https://ngwr.dev/reference/components/drawer
|
|
233
|
+
*/
|
|
234
|
+
declare class WrDrawerManager {
|
|
235
|
+
private readonly overlay;
|
|
236
|
+
private readonly scrollStrategies;
|
|
237
|
+
private readonly parentInjector;
|
|
238
|
+
private readonly focusTrapFactory;
|
|
239
|
+
private readonly isBrowser;
|
|
240
|
+
open<C, R = unknown, D = unknown>(component: ComponentType<C>, options?: WrDrawerOptions<D>): WrDrawerRef<C, R>;
|
|
241
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrDrawerManager, never>;
|
|
242
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<WrDrawerManager>;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @license
|
|
247
|
+
*
|
|
248
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
249
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
250
|
+
*/
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Token that exposes the `data` payload passed to `WrDrawerManager.open()`.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```ts
|
|
257
|
+
* @Component({...})
|
|
258
|
+
* export class ChatComponent {
|
|
259
|
+
* readonly data = inject<ChatData>(WR_DRAWER_DATA);
|
|
260
|
+
* }
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
declare const WR_DRAWER_DATA: InjectionToken<unknown>;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* @license
|
|
267
|
+
*
|
|
268
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
269
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
270
|
+
*/
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Token exposing the open drawer's `WrDrawerRef` to components and
|
|
274
|
+
* directives rendered inside it (e.g. `[wrDrawerClose]`).
|
|
275
|
+
*
|
|
276
|
+
* **Prefer `inject(WrDrawerRef)`** — the ref is provided under the class token
|
|
277
|
+
* too, and the class path is the documented one. It already covers both cases
|
|
278
|
+
* you might reach for a token for: `inject(WrDrawerRef, { optional: true })`
|
|
279
|
+
* works for content that also renders outside a drawer, and
|
|
280
|
+
* `inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef)` types the generics
|
|
281
|
+
* without a cast.
|
|
282
|
+
*
|
|
283
|
+
* This token is the same object under a second key. It exists for the library's
|
|
284
|
+
* own directives (`[wrDrawerClose]`) and for swapping the provider out — a test
|
|
285
|
+
* stub, say — without touching the class.
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* @Component({...})
|
|
290
|
+
* export class ChatComponent {
|
|
291
|
+
* private readonly ref = inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef);
|
|
292
|
+
*
|
|
293
|
+
* dismiss(): void {
|
|
294
|
+
* this.ref.close(true);
|
|
295
|
+
* }
|
|
296
|
+
* }
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
declare const WR_DRAWER_REF: InjectionToken<WrDrawerRef<unknown, unknown>>;
|
|
300
|
+
|
|
95
301
|
/**
|
|
96
302
|
* Marks an element as the drawer's title row. Applies the `wr-drawer__title`
|
|
97
303
|
* class so the drawer's stylesheet can lay it out alongside content and
|
|
@@ -147,17 +353,30 @@ declare class WrDrawerFooter {
|
|
|
147
353
|
/**
|
|
148
354
|
* Closes the parent drawer on click. Attach to any clickable element.
|
|
149
355
|
*
|
|
356
|
+
* Works for both drawer flavours: inside `<wr-drawer>` it clears the
|
|
357
|
+
* component's `open` model, and inside a `WrDrawerManager.open()` drawer it
|
|
358
|
+
* closes the ref — optionally passing a `[wrDrawerClose]` value as the close
|
|
359
|
+
* result (the component flavour has no result to carry, so the value is
|
|
360
|
+
* ignored there).
|
|
361
|
+
*
|
|
150
362
|
* @example
|
|
151
363
|
* ```html
|
|
152
364
|
* <wr-btn wrDrawerClose>Close</wr-btn>
|
|
365
|
+
* <wr-btn color="primary" [wrDrawerClose]="true">Save</wr-btn>
|
|
153
366
|
* ```
|
|
154
367
|
*/
|
|
155
|
-
declare class WrDrawerClose {
|
|
368
|
+
declare class WrDrawerClose<R = unknown> {
|
|
369
|
+
/**
|
|
370
|
+
* Value to pass to `close()` for service-opened drawers. When unset — or
|
|
371
|
+
* used as a bare attribute — the drawer closes with `undefined`.
|
|
372
|
+
*/
|
|
373
|
+
readonly result: _angular_core.InputSignalWithTransform<R | undefined, "" | R | undefined>;
|
|
156
374
|
private readonly drawer;
|
|
375
|
+
private readonly ref;
|
|
157
376
|
protected close(): void;
|
|
158
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrDrawerClose
|
|
159
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<WrDrawerClose
|
|
377
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrDrawerClose<any>, never>;
|
|
378
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<WrDrawerClose<any>, "[wrDrawerClose]", never, { "result": { "alias": "wrDrawerClose"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
160
379
|
}
|
|
161
380
|
|
|
162
|
-
export { WrDrawer, WrDrawerClose, WrDrawerContent, WrDrawerFooter, WrDrawerTitle };
|
|
163
|
-
export type { WrDrawerPosition };
|
|
381
|
+
export { WR_DRAWER_DATA, WR_DRAWER_REF, WrDrawer, WrDrawerClose, WrDrawerContent, WrDrawerFooter, WrDrawerManager, WrDrawerRef, WrDrawerTitle };
|
|
382
|
+
export type { WrDrawerOptions, WrDrawerPosition };
|
package/types/ngwr-select.d.ts
CHANGED
|
@@ -81,8 +81,18 @@ interface WrSelectContext {
|
|
|
81
81
|
* no filter applied — options treat that as "show me".
|
|
82
82
|
*/
|
|
83
83
|
readonly searchQuery: Signal<string>;
|
|
84
|
-
/** True only when `mode="search"`.
|
|
84
|
+
/** True only when `mode="search"`. */
|
|
85
85
|
readonly isSearch: Signal<boolean>;
|
|
86
|
+
/**
|
|
87
|
+
* True when a filter is active — `mode="search"` or `[searchable]`. Options
|
|
88
|
+
* gate self-hiding on this.
|
|
89
|
+
*/
|
|
90
|
+
readonly isSearchable: Signal<boolean>;
|
|
91
|
+
/**
|
|
92
|
+
* False when the option list is already query-scoped upstream (`[loader]` or
|
|
93
|
+
* `[serverSearch]`), in which case options must NOT self-hide.
|
|
94
|
+
*/
|
|
95
|
+
readonly clientFilter: Signal<boolean>;
|
|
86
96
|
/** Is the given option value currently selected? Handles both single and multi. */
|
|
87
97
|
isSelected(value: unknown): boolean;
|
|
88
98
|
/**
|
|
@@ -120,6 +130,11 @@ interface SelectedChip {
|
|
|
120
130
|
* - `'tag'` — free-text + chips with `[separators]` / `[validate]` /
|
|
121
131
|
* `[allowDuplicates]`. Replaces `<wr-chips-input>`.
|
|
122
132
|
*
|
|
133
|
+
* `[searchable]` is orthogonal to the mode — it adds the type-ahead filter to
|
|
134
|
+
* `single` / `multi` without changing the value shape, which is how you get a
|
|
135
|
+
* searchable multi-select. Server-side search hangs off the `(searchChange)` output
|
|
136
|
+
* plus `[options]` / `[loading]`.
|
|
137
|
+
*
|
|
123
138
|
* A signal-forms native control: it implements `FormValueControl<unknown>`, so
|
|
124
139
|
* `[formField]` binds straight to its `value` model — no
|
|
125
140
|
* `ControlValueAccessor` in between. `[(value)]` works standalone, and classic
|
|
@@ -139,6 +154,16 @@ interface SelectedChip {
|
|
|
139
154
|
* <wr-option value="ts">TypeScript</wr-option>
|
|
140
155
|
* <wr-option value="ng">Angular</wr-option>
|
|
141
156
|
* </wr-select>
|
|
157
|
+
*
|
|
158
|
+
* <!-- Multi + type-ahead, options from a store -->
|
|
159
|
+
* <wr-select
|
|
160
|
+
* mode="multi"
|
|
161
|
+
* searchable
|
|
162
|
+
* [options]="results()"
|
|
163
|
+
* [loading]="pending()"
|
|
164
|
+
* [(value)]="categories"
|
|
165
|
+
* (searchChange)="store.search($event)"
|
|
166
|
+
* />
|
|
142
167
|
* ```
|
|
143
168
|
*
|
|
144
169
|
* The legacy `[multi]="true"` boolean is still accepted but is now an
|
|
@@ -192,15 +217,44 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
192
217
|
protected readonly isTag: _angular_core.Signal<boolean>;
|
|
193
218
|
/** Convenience — `effectiveMode() === 'search'`. Exposed via context for options. */
|
|
194
219
|
readonly isSearch: _angular_core.Signal<boolean>;
|
|
220
|
+
/**
|
|
221
|
+
* Add a type-ahead filter without changing the value shape — the missing
|
|
222
|
+
* multi-with-search combination, since `[mode]` picks exactly one shape:
|
|
223
|
+
*
|
|
224
|
+
* ```html
|
|
225
|
+
* <wr-select mode="multi" searchable [(value)]="categories">…</wr-select>
|
|
226
|
+
* ```
|
|
227
|
+
*
|
|
228
|
+
* On `multi` the trigger keeps its chips and grows an inline text field (the
|
|
229
|
+
* shape `tag` mode already uses); on `single` it is equivalent to
|
|
230
|
+
* `mode="search"`. Every search input (`[options]`, `[loader]`,
|
|
231
|
+
* `[debounceMs]`, `[minChars]`, `[virtualScroll]`, the `(searchChange)` output, …)
|
|
232
|
+
* applies either way. Ignored in `tag` mode, which owns its own input.
|
|
233
|
+
* @default false
|
|
234
|
+
*/
|
|
235
|
+
readonly searchable: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
236
|
+
/**
|
|
237
|
+
* Filtering is active — either `mode="search"` or `[searchable]`. Exposed via
|
|
238
|
+
* context so each `<wr-option>` can self-hide non-matching rows.
|
|
239
|
+
*/
|
|
240
|
+
readonly isSearchable: _angular_core.Signal<boolean>;
|
|
241
|
+
/** The trigger *is* the search input: `mode="search"`, or a searchable single. */
|
|
242
|
+
protected readonly isSearchTrigger: _angular_core.Signal<boolean>;
|
|
243
|
+
/** Chips plus an inline search field — a searchable multi-select. */
|
|
244
|
+
protected readonly hasChipSearch: _angular_core.Signal<boolean>;
|
|
195
245
|
/** WrSelectContext — resolved multi-selection flag for child options. */
|
|
196
246
|
readonly multi: _angular_core.Signal<boolean>;
|
|
197
247
|
/** Both multi and tag render chips on the trigger. */
|
|
198
248
|
protected readonly hasChips: _angular_core.Signal<boolean>;
|
|
199
249
|
/**
|
|
200
|
-
*
|
|
250
|
+
* The live search query. Empty string = no filter. Exposed via context so
|
|
201
251
|
* each `<wr-option>` can self-hide non-matching rows.
|
|
252
|
+
*
|
|
253
|
+
* Two-way bindable, so the query can be owned or reset from outside:
|
|
254
|
+
* `[(searchQuery)]="query"`. For server-side search prefer the debounced
|
|
255
|
+
* {@link searchChange} output — `searchQueryChange` fires on every keystroke.
|
|
202
256
|
*/
|
|
203
|
-
readonly searchQuery: _angular_core.
|
|
257
|
+
readonly searchQuery: _angular_core.ModelSignal<string>;
|
|
204
258
|
/**
|
|
205
259
|
* Search mode: dynamic option array. Each item is rendered as a
|
|
206
260
|
* `<wr-option>` whose label comes from `[displayWith]`. Works
|
|
@@ -216,6 +270,21 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
216
270
|
* Observables, Promises, and plain arrays.
|
|
217
271
|
*/
|
|
218
272
|
readonly loader: _angular_core.InputSignal<WrSelectSearchLoader<unknown> | null>;
|
|
273
|
+
/**
|
|
274
|
+
* The option list is already scoped to the query upstream — skip the built-in
|
|
275
|
+
* client-side label filter. Set it when `[options]` is fed from a server via
|
|
276
|
+
* the {@link searchChange} output; the async `[loader]` path implies it.
|
|
277
|
+
*
|
|
278
|
+
* Without this, a server that ranks or fuzzy-matches (returning rows whose
|
|
279
|
+
* labels don't literally contain the query) would have those rows hidden
|
|
280
|
+
* again on the client. @default false
|
|
281
|
+
*/
|
|
282
|
+
readonly serverSearch: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
283
|
+
/**
|
|
284
|
+
* Whether the built-in label filter runs. Exposed via context so each
|
|
285
|
+
* `<wr-option>` knows whether to self-hide. @internal
|
|
286
|
+
*/
|
|
287
|
+
readonly clientFilter: _angular_core.Signal<boolean>;
|
|
219
288
|
/** Search mode: debounce (ms) applied to the loader. @default 250 */
|
|
220
289
|
readonly debounceMs: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
221
290
|
/** Search mode: minimum query length before the panel opens / loader fires. @default 0 */
|
|
@@ -253,10 +322,42 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
253
322
|
readonly loadingText: _angular_core.InputSignal<string | null>;
|
|
254
323
|
protected readonly resolvedNoResults: _angular_core.Signal<string>;
|
|
255
324
|
protected readonly resolvedLoading: _angular_core.Signal<string>;
|
|
325
|
+
/**
|
|
326
|
+
* Debounced search query, gated to searchable selects. Emits on every settled
|
|
327
|
+
* change — including the empty string when the field is cleared — so a
|
|
328
|
+
* store-backed option list can stay in sync and reset itself. `[debounceMs]`
|
|
329
|
+
* controls the delay; `[minChars]` does NOT gate it, for the same reason the
|
|
330
|
+
* `[loader]` path clears its results below that threshold.
|
|
331
|
+
*
|
|
332
|
+
* This is the hook for server-side search: dispatch on `(searchChange)`, feed
|
|
333
|
+
* the results back through `[options]` (plus `[serverSearch]`), and drive the
|
|
334
|
+
* panel's progress row with `[loading]`. Prefer it over the model's raw
|
|
335
|
+
* `(searchQueryChange)`, which fires on every keystroke.
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```html
|
|
339
|
+
* <wr-select
|
|
340
|
+
* mode="search"
|
|
341
|
+
* serverSearch
|
|
342
|
+
* [options]="results()"
|
|
343
|
+
* [loading]="pending()"
|
|
344
|
+
* (searchChange)="store.search($event)"
|
|
345
|
+
* />
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
readonly searchChange: _angular_core.OutputEmitterRef<string>;
|
|
349
|
+
/**
|
|
350
|
+
* Show the panel's progress row. Independent of `[loader]`, which raises and
|
|
351
|
+
* lowers its own flag — use this when the options come from a store fed by
|
|
352
|
+
* the {@link searchChange} output. @default false
|
|
353
|
+
*/
|
|
354
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
256
355
|
/** Search mode: results returned by the async loader. @internal */
|
|
257
356
|
protected readonly loadedOptions: _angular_core.WritableSignal<readonly unknown[]>;
|
|
258
|
-
/**
|
|
259
|
-
|
|
357
|
+
/** True while the async `[loader]` is in flight. @internal */
|
|
358
|
+
private readonly loaderLoading;
|
|
359
|
+
/** Either flag shows the panel's progress row. @internal */
|
|
360
|
+
protected readonly isLoading: _angular_core.Signal<boolean>;
|
|
260
361
|
/**
|
|
261
362
|
* Tag mode: keys / characters that commit the current draft into a chip.
|
|
262
363
|
* `'Enter'` is the key name; everything else is a literal character watched
|
|
@@ -331,7 +432,7 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
331
432
|
* `dynamicOptions()` narrowed to the current search query. `dynamicOptions()`
|
|
332
433
|
* is intentionally UNFILTERED (projected `<wr-option>` self-hide via CSS), so
|
|
333
434
|
* the virtual path — which renders plain rows that can't self-hide — filters
|
|
334
|
-
* here. Loader results are already query-scoped upstream.
|
|
435
|
+
* here. Loader / `serverSearch` results are already query-scoped upstream.
|
|
335
436
|
*/
|
|
336
437
|
protected readonly filteredDynamicOptions: _angular_core.Signal<readonly unknown[]>;
|
|
337
438
|
/**
|
|
@@ -376,12 +477,17 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
376
477
|
/** Search mode: is this option hidden by the current query? @internal */
|
|
377
478
|
private isOptionHidden;
|
|
378
479
|
protected readonly panelTpl: _angular_core.Signal<TemplateRef<any>>;
|
|
379
|
-
/**
|
|
480
|
+
/** The inline input inside a chip trigger — tag mode or a searchable multi. @internal */
|
|
380
481
|
protected readonly tagInputEl: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
381
482
|
/** Search-mode inline input. Present only when `mode="search"`. @internal */
|
|
382
483
|
protected readonly searchInputEl: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
383
484
|
protected focusTagInput(): void;
|
|
384
485
|
protected focusSearchInput(): void;
|
|
486
|
+
protected onChipsInput(event: Event): void;
|
|
487
|
+
protected onChipsKeydown(event: KeyboardEvent): void;
|
|
488
|
+
protected onChipsFocus(): void;
|
|
489
|
+
protected onChipsPaste(event: ClipboardEvent): void;
|
|
490
|
+
protected onChipsBlur(): void;
|
|
385
491
|
protected onSearchInput(event: Event): void;
|
|
386
492
|
protected onSearchFocus(): void;
|
|
387
493
|
protected onSearchKey(event: KeyboardEvent): void;
|
|
@@ -426,7 +532,7 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
426
532
|
private openOverlay;
|
|
427
533
|
private closeOverlay;
|
|
428
534
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrSelect, never>;
|
|
429
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrSelect, "wr-select", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "loader": { "alias": "loader"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; "minChars": { "alias": "minChars"; "required": false; "isSignal": true; }; "freeText": { "alias": "freeText"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "rowHeight": { "alias": "rowHeight"; "required": false; "isSignal": true; }; "viewportHeight": { "alias": "viewportHeight"; "required": false; "isSignal": true; }; "overscan": { "alias": "overscan"; "required": false; "isSignal": true; }; "noResultsText": { "alias": "noResultsText"; "required": false; "isSignal": true; }; "loadingText": { "alias": "loadingText"; "required": false; "isSignal": true; }; "separators": { "alias": "separators"; "required": false; "isSignal": true; }; "allowDuplicates": { "alias": "allowDuplicates"; "required": false; "isSignal": true; }; "validate": { "alias": "validate"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "maxItems": { "alias": "maxItems"; "required": false; "isSignal": true; }; "maxTagCount": { "alias": "maxTagCount"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, ["projectedOptions"], ["*"], true, never>;
|
|
535
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrSelect, "wr-select", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchQuery": { "alias": "searchQuery"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "loader": { "alias": "loader"; "required": false; "isSignal": true; }; "serverSearch": { "alias": "serverSearch"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; "minChars": { "alias": "minChars"; "required": false; "isSignal": true; }; "freeText": { "alias": "freeText"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "rowHeight": { "alias": "rowHeight"; "required": false; "isSignal": true; }; "viewportHeight": { "alias": "viewportHeight"; "required": false; "isSignal": true; }; "overscan": { "alias": "overscan"; "required": false; "isSignal": true; }; "noResultsText": { "alias": "noResultsText"; "required": false; "isSignal": true; }; "loadingText": { "alias": "loadingText"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "separators": { "alias": "separators"; "required": false; "isSignal": true; }; "allowDuplicates": { "alias": "allowDuplicates"; "required": false; "isSignal": true; }; "validate": { "alias": "validate"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "maxItems": { "alias": "maxItems"; "required": false; "isSignal": true; }; "maxTagCount": { "alias": "maxTagCount"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "searchQuery": "searchQueryChange"; "searchChange": "searchChange"; "value": "valueChange"; "touch": "touch"; }, ["projectedOptions"], ["*"], true, never>;
|
|
430
536
|
}
|
|
431
537
|
|
|
432
538
|
/**
|
|
@@ -458,7 +564,7 @@ declare class WrOption {
|
|
|
458
564
|
/** @internal — true when this option is the keyboard cursor target. */
|
|
459
565
|
protected readonly active: _angular_core.Signal<boolean>;
|
|
460
566
|
/**
|
|
461
|
-
* @internal —
|
|
567
|
+
* @internal — searchable selects only. True when the parent has a query that
|
|
462
568
|
* the option's text content does not match (case-insensitive substring).
|
|
463
569
|
* Hidden options stay in the DOM so registration order survives but
|
|
464
570
|
* collapse via CSS.
|
package/types/ngwr-version.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { InjectionToken } from '@angular/core';
|
|
|
16
16
|
* Distinct from `Version` exported by `@angular/core`, which reports the
|
|
17
17
|
* loaded Angular runtime version (e.g. `'21.2.13'`), not ngwr's.
|
|
18
18
|
*/
|
|
19
|
-
declare const NGWR_VERSION = "9.0
|
|
19
|
+
declare const NGWR_VERSION = "9.1.0";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* @license
|