ngwr 14.6.0 → 14.7.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/alert/styles/_index.scss +14 -3
- package/avatar/styles/_index.scss +44 -0
- package/cascader/styles/_rules.scss +0 -4
- package/collapse/styles/_index.scss +0 -1
- package/fesm2022/ngwr-avatar.mjs +19 -2
- package/fesm2022/ngwr-avatar.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +2 -2
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper.mjs +149 -62
- package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +2 -2
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +73 -22
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/input/styles/_index.scss +8 -2
- package/lightbox/styles/_rules.scss +7 -1
- package/package.json +1 -1
- package/select/styles/_index.scss +16 -4
- package/table/styles/_index.scss +55 -0
- package/toast/styles/_index.scss +9 -3
- package/tree/styles/_index.scss +0 -3
- package/types/ngwr-avatar.d.ts +15 -1
- package/types/ngwr-image-cropper.d.ts +48 -0
- package/types/ngwr-select.d.ts +63 -6
- package/types/ngwr-version.d.ts +1 -1
|
@@ -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. `'22.0.0'`), not ngwr's.
|
|
18
18
|
*/
|
|
19
|
-
const NGWR_VERSION = '14.
|
|
19
|
+
const NGWR_VERSION = '14.7.0';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* @license
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-version.mjs","sources":["../../../projects/lib/version/version.ts","../../../projects/lib/version/version.token.ts","../../../projects/lib/version/ngwr-version.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * The ngwr library version string, kept in sync with\n * `projects/lib/package.json` by `scripts/release-prepare.ts`.\n *\n * Prefer this over reading `package.json` at runtime — that requires a JSON\n * import or `require`, neither of which tree-shakes well in Angular builds.\n *\n * Distinct from `Version` exported by `@angular/core`, which reports the\n * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.\n */\nexport const NGWR_VERSION = '14.
|
|
1
|
+
{"version":3,"file":"ngwr-version.mjs","sources":["../../../projects/lib/version/version.ts","../../../projects/lib/version/version.token.ts","../../../projects/lib/version/ngwr-version.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * The ngwr library version string, kept in sync with\n * `projects/lib/package.json` by `scripts/release-prepare.ts`.\n *\n * Prefer this over reading `package.json` at runtime — that requires a JSON\n * import or `require`, neither of which tree-shakes well in Angular builds.\n *\n * Distinct from `Version` exported by `@angular/core`, which reports the\n * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.\n */\nexport const NGWR_VERSION = '14.7.0';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport { NGWR_VERSION } from './version';\n\n/**\n * Injection token holding the ngwr library version string.\n *\n * Default factory returns {@link NGWR_VERSION}. Override it in tests or in\n * apps that want to surface a custom build identifier.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class FooterComponent {\n * readonly version = inject(NGWR_VERSION_TOKEN);\n * }\n * ```\n */\nexport const NGWR_VERSION_TOKEN = new InjectionToken<string>('NGWR_VERSION_TOKEN', {\n providedIn: 'root',\n factory: () => NGWR_VERSION,\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAEH;;;;;;;;;AASG;AACI,MAAM,YAAY,GAAG;;ACjB5B;;;;;AAKG;AAMH;;;;;;;;;;;;;AAaG;MACU,kBAAkB,GAAG,IAAI,cAAc,CAAS,oBAAoB,EAAE;AACjF,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,YAAY;AAC5B,CAAA;;AC5BD;;AAEG;;;;"}
|
package/input/styles/_index.scss
CHANGED
|
@@ -199,8 +199,14 @@
|
|
|
199
199
|
color: var(--wr-input-group-affix);
|
|
200
200
|
cursor: pointer;
|
|
201
201
|
transition: color var(--wr-transition-base);
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
// The eye is a bare `.wr-icon__svg`, which is `1em`, and a `<button>` does
|
|
203
|
+
// not inherit its font-size — so it drew the browser's control font (about
|
|
204
|
+
// 13.33px) with no reset and the surrounding text's size under `ngwr/reset`.
|
|
205
|
+
// Inheriting the size makes `1em` the text around the field in every app.
|
|
206
|
+
// The size only, not the `font` shorthand, which would also hand the button
|
|
207
|
+
// the group's line-height. `--wr-icon-size` only drives `<wr-icon>` hosts, so
|
|
208
|
+
// the declaration that used to sit here drove nothing.
|
|
209
|
+
font-size: inherit;
|
|
204
210
|
|
|
205
211
|
&:hover:not(:disabled) {
|
|
206
212
|
color: var(--wr-color-primary);
|
|
@@ -132,7 +132,13 @@
|
|
|
132
132
|
touch-action: none;
|
|
133
133
|
|
|
134
134
|
&__close {
|
|
135
|
-
|
|
135
|
+
// A bare `.wr-icon__svg` in a `<button>`: `1em`, and a button inherits no
|
|
136
|
+
// font-size — so the ✕ came out at the browser's control font, about
|
|
137
|
+
// 13.33px, inside a 36px circle, and at the surrounding text's size under
|
|
138
|
+
// `ngwr/reset`. Inheriting the size gives the same glyph either way. The
|
|
139
|
+
// size only, not the `font` shorthand. `--wr-icon-size` was never going to
|
|
140
|
+
// do it: only a `<wr-icon>` host reads that hook.
|
|
141
|
+
font-size: inherit;
|
|
136
142
|
position: absolute;
|
|
137
143
|
top: 1rem;
|
|
138
144
|
inset-inline-end: 1rem;
|
package/package.json
CHANGED
|
@@ -129,7 +129,6 @@
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
&__chevron {
|
|
132
|
-
--wr-icon-size: 1rem;
|
|
133
132
|
flex: 0 0 auto;
|
|
134
133
|
color: var(--wr-color-on-surface-muted);
|
|
135
134
|
transition: transform var(--wr-transition-base);
|
|
@@ -179,6 +178,22 @@
|
|
|
179
178
|
}
|
|
180
179
|
}
|
|
181
180
|
|
|
181
|
+
// A leading visual inside a search trigger. The FIELD owns the leading
|
|
182
|
+
// padding here (see `--search` above), so the inset has to move with the
|
|
183
|
+
// visual — otherwise the avatar sits on the border. Only the trigger's own
|
|
184
|
+
// 0.5rem `gap` is then left between the two, which is the spacing the button
|
|
185
|
+
// trigger already has between `__value-leading` and `__value`.
|
|
186
|
+
&__trigger--search &__value-leading {
|
|
187
|
+
padding-inline-start: calc(var(--wr-select-padding-x) * var(--wr-density-x, 1));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// …and the field drops the inset it just handed over. Keyed on the sibling
|
|
191
|
+
// rather than on a modifier class so the two can never be set apart: the
|
|
192
|
+
// padding moves exactly when the element it moved to exists.
|
|
193
|
+
&__value-leading + &__search-input {
|
|
194
|
+
padding-inline-start: 0;
|
|
195
|
+
}
|
|
196
|
+
|
|
182
197
|
&__search-input {
|
|
183
198
|
flex: 1 1 auto;
|
|
184
199
|
min-width: 0;
|
|
@@ -294,7 +309,6 @@
|
|
|
294
309
|
}
|
|
295
310
|
|
|
296
311
|
&__chip-remove {
|
|
297
|
-
--wr-icon-size: 0.875rem;
|
|
298
312
|
display: inline-flex;
|
|
299
313
|
align-items: center;
|
|
300
314
|
justify-content: center;
|
|
@@ -320,7 +334,6 @@
|
|
|
320
334
|
}
|
|
321
335
|
|
|
322
336
|
&__clear {
|
|
323
|
-
--wr-icon-size: 0.875rem;
|
|
324
337
|
// Never shrink: the chips box is allowed to grow into the whole row, so the
|
|
325
338
|
// × has to hold its own size against it.
|
|
326
339
|
flex: 0 0 auto;
|
|
@@ -568,7 +581,6 @@
|
|
|
568
581
|
|
|
569
582
|
.wr-select__chip-remove,
|
|
570
583
|
.wr-select__clear {
|
|
571
|
-
--wr-icon-size: 1.125rem;
|
|
572
584
|
width: 2rem;
|
|
573
585
|
height: 2rem;
|
|
574
586
|
}
|
package/table/styles/_index.scss
CHANGED
|
@@ -376,6 +376,28 @@
|
|
|
376
376
|
display: inline-flex;
|
|
377
377
|
align-items: center;
|
|
378
378
|
gap: 0.375rem;
|
|
379
|
+
|
|
380
|
+
// The spacing of the header's controls, and it moves for a COARSE pointer
|
|
381
|
+
// only. A column that is both `sortable` and `filterable` puts two 12px
|
|
382
|
+
// controls in this row 0.375rem apart, so their centres are 18px apart —
|
|
383
|
+
// while the touch halo each one grows below is 24px wide and centred on its
|
|
384
|
+
// control. Two 24px boxes with centres 18px apart OVERLAP by 6px, and the
|
|
385
|
+
// later one in the DOM (the filter) wins the hit test, so the sort button
|
|
386
|
+
// would hand over a strip of the slack it just gained. 0.75rem puts the
|
|
387
|
+
// centres 24px apart, which is the closest the two halos can come: at rest
|
|
388
|
+
// they abut exactly, and a filter showing a count pill is 32px wide, which
|
|
389
|
+
// only separates them further. A fine pointer keeps the 0.375rem this row
|
|
390
|
+
// has always drawn.
|
|
391
|
+
//
|
|
392
|
+
// This gap is also the whole of what a COARSE-pointer `target-size` run
|
|
393
|
+
// measures. axe never sees the halo — an `::after` enters no rect, so it
|
|
394
|
+
// reads 12x12 either way — but 24px between centres satisfies WCAG 2.5.8's
|
|
395
|
+
// spacing exception exactly, and the pair passes. Narrow this and a coarse
|
|
396
|
+
// run reports both nodes again; `table-header-target.spec.ts` pins the
|
|
397
|
+
// value here so a PR catches it without a browser.
|
|
398
|
+
@media (pointer: coarse) {
|
|
399
|
+
gap: 0.75rem;
|
|
400
|
+
}
|
|
379
401
|
}
|
|
380
402
|
|
|
381
403
|
&__title {
|
|
@@ -398,6 +420,24 @@
|
|
|
398
420
|
// reads it, and the rule here used to set it for nothing.
|
|
399
421
|
font-size: inherit;
|
|
400
422
|
line-height: 0;
|
|
423
|
+
// The pointer target, widened for a COARSE pointer and for nothing else.
|
|
424
|
+
// WCAG 2.5.8 asks 24x24 of every control, a mouse included, and this glyph
|
|
425
|
+
// is 12x12: a lone one passes on the criterion's spacing exception, and a
|
|
426
|
+
// column carrying both this button and a filter trigger 6px away does not.
|
|
427
|
+
// A real 24px box on every pointer is what satisfies the criterion outright,
|
|
428
|
+
// and it was written, measured and REFUSED — it moves the caret and the
|
|
429
|
+
// funnel apart on a mouse, and the maintainer chose to keep the geometry
|
|
430
|
+
// 14.6.0 draws. So the coarse half ships, the fine-pointer failure is a
|
|
431
|
+
// decided trade recorded in AGENTS.md and in `scripts/contrast-baseline.json`,
|
|
432
|
+
// and the table's docs page says so to the reader. Do not re-report it.
|
|
433
|
+
//
|
|
434
|
+
// 24px rather than the mixin's 44px default, which is a real constraint and
|
|
435
|
+
// not a preference: the halo is centred on the control, so 44 reaches 22px
|
|
436
|
+
// either side and swallows the filter trigger beside it — the mixin's own
|
|
437
|
+
// docblock warns off tightly-packed rows for exactly this. 24 is the
|
|
438
|
+
// criterion's number, and `__th-inner` opens its gap under the same media
|
|
439
|
+
// query so the two halos cannot overlap.
|
|
440
|
+
@include theme.touch-target($size: 24px);
|
|
401
441
|
}
|
|
402
442
|
|
|
403
443
|
&__tr {
|
|
@@ -810,6 +850,13 @@
|
|
|
810
850
|
// count pill beside the funnel — 10px type with no line-height of its own —
|
|
811
851
|
// grows from 12px to 20px tall under it.
|
|
812
852
|
font-size: inherit;
|
|
853
|
+
// The same coarse-pointer target as the sort button beside it, where the
|
|
854
|
+
// whole reasoning — why 24 and not 44, and why a fine pointer keeps the
|
|
855
|
+
// 12px glyph — is written out. It goes on the TRIGGER and never on the
|
|
856
|
+
// `<wr-table-filter>` host: the halo belongs to the element that owns the
|
|
857
|
+
// click, and a tap landing on the host's own pseudo-element would target
|
|
858
|
+
// the host and open nothing.
|
|
859
|
+
@include theme.touch-target($size: 24px);
|
|
813
860
|
}
|
|
814
861
|
|
|
815
862
|
&__count {
|
|
@@ -822,6 +869,14 @@
|
|
|
822
869
|
background: var(--wr-color-primary);
|
|
823
870
|
color: var(--wr-color-primary-contrast);
|
|
824
871
|
font-size: 0.625rem; // 10px — intentional micro-count badge, below --wr-text-xs
|
|
872
|
+
// The pill has no padding on the block axis, so its height IS its line box,
|
|
873
|
+
// and leaving that at `normal` handed the box to whatever the page
|
|
874
|
+
// inherited: 12px in an app with no reset, 20px under `ngwr/reset`, whose
|
|
875
|
+
// `font: inherit` on a `<button>` brings the header's 1.25rem down with the
|
|
876
|
+
// font-size. A ratio of its own makes it 12px in both — and a ratio rather
|
|
877
|
+
// than a length, so a consumer who enlarges the numeral gets a pill that
|
|
878
|
+
// grows with it.
|
|
879
|
+
line-height: 1.2;
|
|
825
880
|
font-weight: 600;
|
|
826
881
|
}
|
|
827
882
|
|
package/toast/styles/_index.scss
CHANGED
|
@@ -205,8 +205,15 @@ $toast-colors: (
|
|
|
205
205
|
transition:
|
|
206
206
|
color var(--wr-transition-base),
|
|
207
207
|
background var(--wr-transition-base);
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
// The glyph is a bare `.wr-icon__svg` — `1em` — and a `<button>` does not
|
|
209
|
+
// inherit its font-size, so it drew the browser's control font (about
|
|
210
|
+
// 13.33px) with no reset and the surrounding text's size under `ngwr/reset`.
|
|
211
|
+
// Inheriting the size makes `1em` the toast's own text in every app; only a
|
|
212
|
+
// `<wr-icon>` host reads `--wr-icon-size`, so the hook never applied here.
|
|
213
|
+
// The SIZE only, never the `font` shorthand: that would also bring the
|
|
214
|
+
// surrounding line-height, which is what stretched the table's filter count
|
|
215
|
+
// pill from 12px to 20px when it was tried there.
|
|
216
|
+
font-size: inherit;
|
|
210
217
|
|
|
211
218
|
&:hover {
|
|
212
219
|
color: var(--wr-color-on-surface);
|
|
@@ -323,7 +330,6 @@ $toast-colors: (
|
|
|
323
330
|
width: 2rem;
|
|
324
331
|
height: 2rem;
|
|
325
332
|
padding: 0;
|
|
326
|
-
--wr-icon-size: 1.125rem;
|
|
327
333
|
}
|
|
328
334
|
|
|
329
335
|
.wr-toast-host__close-all {
|
package/tree/styles/_index.scss
CHANGED
|
@@ -249,7 +249,6 @@
|
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
&__chevron {
|
|
252
|
-
--wr-icon-size: 1rem;
|
|
253
252
|
flex: 0 0 auto;
|
|
254
253
|
color: var(--wr-color-on-surface-muted);
|
|
255
254
|
transition: transform var(--wr-transition-base);
|
|
@@ -260,7 +259,6 @@
|
|
|
260
259
|
}
|
|
261
260
|
|
|
262
261
|
&__clear {
|
|
263
|
-
--wr-icon-size: 0.875rem;
|
|
264
262
|
display: inline-flex;
|
|
265
263
|
align-items: center;
|
|
266
264
|
justify-content: center;
|
|
@@ -329,7 +327,6 @@
|
|
|
329
327
|
}
|
|
330
328
|
|
|
331
329
|
&__chip-remove {
|
|
332
|
-
--wr-icon-size: 0.875rem;
|
|
333
330
|
display: inline-flex;
|
|
334
331
|
align-items: center;
|
|
335
332
|
justify-content: center;
|
package/types/ngwr-avatar.d.ts
CHANGED
|
@@ -47,6 +47,19 @@ type WrAvatarSize = number | `${number}` | `${number}px` | `${number}rem`;
|
|
|
47
47
|
* spinner is drawn over it; with nothing projected, the spinner marks the
|
|
48
48
|
* loading state instead. See `alt` for what a screen reader hears.
|
|
49
49
|
*
|
|
50
|
+
* Projected initials take the text size around the avatar, capped at
|
|
51
|
+
* `--wr-avatar-initials-scale` (`0.375`) of the box, so they shrink only where
|
|
52
|
+
* they would not fit: a 16px avatar in a 14px chip draws 6px letters, while a
|
|
53
|
+
* `6rem` one keeps the surrounding size up to 36px and is capped only past it.
|
|
54
|
+
* Anything projected that is sized in `em` follows the cap too — a `<wr-icon>`
|
|
55
|
+
* at its default `1.2em` included — so pin a `px` or `rem` size on the projected
|
|
56
|
+
* element, or override the hook, to keep it. A `font-size` rule on the avatar
|
|
57
|
+
* itself still wins, unless it sits in a cascade layer (Tailwind v4's utilities
|
|
58
|
+
* do), which ngwr's unlayered stylesheet beats whatever the selector.
|
|
59
|
+
*
|
|
60
|
+
* The initials are inert: `pointer-events: none` hands a click on them to whatever
|
|
61
|
+
* holds the avatar, and `user-select: none` keeps them out of a text selection.
|
|
62
|
+
*
|
|
50
63
|
* @example
|
|
51
64
|
* ```html
|
|
52
65
|
* <wr-avatar url="/me.png" alt="Roman" size="3rem" shape="circle" />
|
|
@@ -84,7 +97,8 @@ declare class WrAvatar {
|
|
|
84
97
|
*/
|
|
85
98
|
readonly shape: _angular_core.InputSignal<WrAvatarShape>;
|
|
86
99
|
/**
|
|
87
|
-
* Box size. See {@link WrAvatarSize} for accepted values.
|
|
100
|
+
* Box size. See {@link WrAvatarSize} for accepted values. The resolved value is
|
|
101
|
+
* published on the host as `--wr-avatar-size`.
|
|
88
102
|
*
|
|
89
103
|
* @default '6rem'
|
|
90
104
|
*/
|
|
@@ -157,6 +157,12 @@ declare class WrImageCropper {
|
|
|
157
157
|
private active;
|
|
158
158
|
private startPointer;
|
|
159
159
|
private startRect;
|
|
160
|
+
/** The element the live drag set pointer capture on, so the end releases that one. */
|
|
161
|
+
private captureTarget;
|
|
162
|
+
/** The pointer the live drag belongs to. Every other pointer's events are ignored. */
|
|
163
|
+
private pointerId;
|
|
164
|
+
/** How far past each side of the crop the live resize was pressed — see `onPointerMove`. */
|
|
165
|
+
private overhang;
|
|
160
166
|
private readonly destroyRef;
|
|
161
167
|
private readonly statusState;
|
|
162
168
|
/**
|
|
@@ -217,8 +223,50 @@ declare class WrImageCropper {
|
|
|
217
223
|
private initialCrop;
|
|
218
224
|
protected readonly handles: readonly WrCropHandle[];
|
|
219
225
|
protected onPointerDown(handle: WrCropHandle, event: PointerEvent): void;
|
|
226
|
+
/**
|
|
227
|
+
* A resize ENDS when the pointer leaves the image, exactly as `pointerup` would end it:
|
|
228
|
+
* the move that carried it out is applied — clamped to the image like any other — and
|
|
229
|
+
* then the drag is over. Nothing after that resumes it or changes the crop, pointer
|
|
230
|
+
* back over the image or not, until a new `pointerdown`. A move drag is not affected:
|
|
231
|
+
* its size is fixed, so it simply rests against the edge.
|
|
232
|
+
*
|
|
233
|
+
* The move that leaves is applied rather than dropped because pointer moves are
|
|
234
|
+
* SAMPLES. Dropped, a quick drag toward a corner would stop wherever its last sample
|
|
235
|
+
* inside happened to fall — a single move from a handle to past the image would change
|
|
236
|
+
* nothing at all — and even a slow one would stop a fraction of a pixel short of the
|
|
237
|
+
* edge. A drag that leaves across one edge still ends there: heading for a corner at a
|
|
238
|
+
* slant that crosses the bottom first, the crop's right edge stays where it was then.
|
|
239
|
+
*
|
|
240
|
+
* "The image" is the `<img>`'s own box — the bounds `applyMove` / `applyResize` clamp
|
|
241
|
+
* the crop to — with its edges counting as inside, since the crop may reach them. The
|
|
242
|
+
* box is re-measured on every move and compared with `clientX` / `clientY`: both are
|
|
243
|
+
* viewport coordinates, so a scroll mid-drag cannot put them out of step. The moves
|
|
244
|
+
* outside reach this handler at all only because the drag holds pointer capture.
|
|
245
|
+
*
|
|
246
|
+
* One allowance, fixed at `pointerdown`: the box is widened on each side by however far
|
|
247
|
+
* past that side of the CROP the press landed — at most as far as the pressed handle
|
|
248
|
+
* reaches past it. Half of an edge handle, and three quarters of a corner handle, lies
|
|
249
|
+
* outside the crop, so a press there already has the pointer ahead of the edge it drags.
|
|
250
|
+
* Measured without the allowance, that pointer would leave the image while the crop was
|
|
251
|
+
* still short of the image's edge by the same distance, with nothing able to close the
|
|
252
|
+
* gap; and a handle resting on the image's edge, pressed on its outer part, would begin
|
|
253
|
+
* its drag already outside. A press on a handle's inner part widens nothing.
|
|
254
|
+
*/
|
|
220
255
|
protected onPointerMove(event: PointerEvent): void;
|
|
256
|
+
/**
|
|
257
|
+
* Ends the drag — for `pointerup`, `pointercancel`, a capture lost to something else,
|
|
258
|
+
* and a resize whose pointer left the image. Once per drag: the capture released here
|
|
259
|
+
* fires `lostpointercapture` afterwards, and by then there is nothing left to end.
|
|
260
|
+
*
|
|
261
|
+
* Only for the pointer that started it. A second finger is refused a drag of its own at
|
|
262
|
+
* `pointerdown`, but its moves and its lifting reach these handlers all the same, and
|
|
263
|
+
* would otherwise drive or end the first finger's drag.
|
|
264
|
+
*/
|
|
221
265
|
protected onPointerUp(event: PointerEvent): void;
|
|
266
|
+
/** How far past each side of the crop window the pointer is, in CSS pixels. */
|
|
267
|
+
private pastCrop;
|
|
268
|
+
/** Whether the pointer is on the image, edges and the press's `overhang` included. */
|
|
269
|
+
private withinImage;
|
|
222
270
|
/** Whether a key has moved the crop since the last `keyup`. */
|
|
223
271
|
private keyboardDirty;
|
|
224
272
|
/**
|
package/types/ngwr-select.d.ts
CHANGED
|
@@ -44,7 +44,11 @@ type WrSelectSize = 'sm' | 'md' | 'lg';
|
|
|
44
44
|
*
|
|
45
45
|
* - `'option'` — the row in the open panel.
|
|
46
46
|
* - `'chip'` — a selected chip on a `mode="multi"` trigger.
|
|
47
|
-
* - `'value'` — the selected value on a single-mode
|
|
47
|
+
* - `'value'` — the selected value on a single-mode trigger: beside the label on
|
|
48
|
+
* a button trigger, and before the input on a search-shaped one while that
|
|
49
|
+
* input is showing the label. One placement rather than two, because it is one
|
|
50
|
+
* surface — the same size is right on both, and splitting it would ask every
|
|
51
|
+
* consumer to name a case they do not have.
|
|
48
52
|
*/
|
|
49
53
|
type WrOptionLeadingPlacement = 'option' | 'chip' | 'value';
|
|
50
54
|
/** Template context of `<ng-template wrOptionLeading>`. */
|
|
@@ -572,10 +576,38 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
572
576
|
private leadingFor;
|
|
573
577
|
/**
|
|
574
578
|
* The leading visual beside the selected value on a single-mode BUTTON trigger
|
|
575
|
-
* — one instance, for the one selected value.
|
|
576
|
-
*
|
|
579
|
+
* — one instance, for the one selected value. A search-shaped trigger draws the
|
|
580
|
+
* same visual through {@link searchLeading}, on a narrower condition.
|
|
577
581
|
*/
|
|
578
582
|
protected readonly selectedLeading: _angular_core.Signal<TemplateRef<WrOptionLeadingContext<unknown>> | null>;
|
|
583
|
+
/**
|
|
584
|
+
* The same visual on a SEARCH-shaped trigger (`mode="search"`, a searchable
|
|
585
|
+
* single), drawn before the input — the surface an assignee picker actually
|
|
586
|
+
* uses, and the one that lost its avatar the moment the trigger became a field.
|
|
587
|
+
*
|
|
588
|
+
* The condition is {@link searchShowsValue} rather than `hasSelection()`, and
|
|
589
|
+
* the two part company on every open panel: focusing the field replaces the
|
|
590
|
+
* label with the live query, which starts empty, so what is on screen is the
|
|
591
|
+
* placeholder. An avatar left standing there names a value the field no longer
|
|
592
|
+
* shows, and then sits in front of whatever the user types next — the visual
|
|
593
|
+
* would be answering a different question from the text beside it. It comes
|
|
594
|
+
* back with the label, which is one signal flipping rather than two things
|
|
595
|
+
* kept in step: committing a choice clears the query and closes the panel.
|
|
596
|
+
*
|
|
597
|
+
* Nothing is instantiated for a search select with no selection, panel open or
|
|
598
|
+
* shut — `selectedLabel()` is `null` there, and this returns `null` with it.
|
|
599
|
+
*
|
|
600
|
+
* The COST of that rule, stated because it is a consumer's to weigh: stepping
|
|
601
|
+
* aside is a destroy, so opening the picker and dismissing it unchanged
|
|
602
|
+
* re-creates the visual — a template built on an `<img>` re-mounts once per
|
|
603
|
+
* round trip, and re-requests unless the cache answers. Kept rather than
|
|
604
|
+
* traded for a hidden-but-alive node: the panel's own rows already create and
|
|
605
|
+
* destroy one apiece on the same gesture, so holding this one back buys a
|
|
606
|
+
* fraction of that, and a node retained while it must not be seen is a second
|
|
607
|
+
* piece of state to keep in step with the field. Pinned in `option.spec.ts`
|
|
608
|
+
* ("re-creates it after a round trip"), so a future change here has to say so.
|
|
609
|
+
*/
|
|
610
|
+
protected readonly searchLeading: _angular_core.Signal<TemplateRef<WrOptionLeadingContext<unknown>> | null>;
|
|
579
611
|
/**
|
|
580
612
|
* Trigger label for single mode. Multi reads `selectedChips` instead.
|
|
581
613
|
*
|
|
@@ -748,6 +780,26 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
748
780
|
protected onSearchFocus(): void;
|
|
749
781
|
protected onSearchBlur(): void;
|
|
750
782
|
protected onSearchKey(event: KeyboardEvent): void;
|
|
783
|
+
/**
|
|
784
|
+
* Whether the search field is showing the SELECTED VALUE rather than a query.
|
|
785
|
+
* `searchDisplay` takes its text off this, and `searchLeading` the visual that
|
|
786
|
+
* goes before it, so the two can never disagree about which of the two things
|
|
787
|
+
* the field is holding.
|
|
788
|
+
*
|
|
789
|
+
* FOCUS as well as open, and that second term is the whole `[minChars]` story.
|
|
790
|
+
* Backspacing under the threshold closes the panel, and falling back to the
|
|
791
|
+
* selected label the moment `open()` goes false rewrote the field out from
|
|
792
|
+
* under someone who was still typing — "sma" -> "sm" showed an empty box.
|
|
793
|
+
*
|
|
794
|
+
* A NON-EMPTY query, though: picking an option clears it and leaves focus in
|
|
795
|
+
* the field, and there the label is what belongs on screen.
|
|
796
|
+
*
|
|
797
|
+
* Only the search-shaped trigger reads it. A searchable MULTI binds its input
|
|
798
|
+
* to `searchQuery()` directly and shows its selection as chips, which carry
|
|
799
|
+
* their own leading visuals whatever the field holds.
|
|
800
|
+
* @internal
|
|
801
|
+
*/
|
|
802
|
+
protected readonly searchShowsValue: _angular_core.Signal<boolean>;
|
|
751
803
|
/**
|
|
752
804
|
* Display text for the search input. Shows the selected option's
|
|
753
805
|
* label when collapsed, or the live query while typing / panel open.
|
|
@@ -997,9 +1049,14 @@ declare class WrOptionGroup {
|
|
|
997
1049
|
* - in an option row, while the panel is OPEN — destroyed again when it closes,
|
|
998
1050
|
* and under `virtualScroll` only for the rows in the rendered window;
|
|
999
1051
|
* - in a selected chip on a `mode="multi"` trigger, one per visible chip;
|
|
1000
|
-
* - beside the selected value on a single-mode BUTTON trigger — one copy
|
|
1001
|
-
*
|
|
1002
|
-
*
|
|
1052
|
+
* - beside the selected value on a single-mode BUTTON trigger — one copy;
|
|
1053
|
+
* - before the input on a SEARCH-shaped trigger (`mode="search"`, a searchable
|
|
1054
|
+
* single), while that input is showing the selected label. It goes beside the
|
|
1055
|
+
* field rather than into it — an `<input>` holds a string — and it steps aside
|
|
1056
|
+
* while a query is on screen, panel open or half-typed, because the value it
|
|
1057
|
+
* names is not what the field is showing then. Picking an option brings it
|
|
1058
|
+
* back with the label. Stepping aside is a DESTROY, like a closing panel's
|
|
1059
|
+
* rows, so an `<img>`-backed visual re-mounts once per open-and-dismiss.
|
|
1003
1060
|
*
|
|
1004
1061
|
* Every copy sits in an `aria-hidden` wrapper and is skipped when the option's
|
|
1005
1062
|
* text is read, so the trigger label, the chip, the search filter and the
|
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. `'22.0.0'`), not ngwr's.
|
|
18
18
|
*/
|
|
19
|
-
declare const NGWR_VERSION = "14.
|
|
19
|
+
declare const NGWR_VERSION = "14.7.0";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* @license
|