@flywheel-io/vision 21.1.2 → 21.1.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.
|
@@ -3177,10 +3177,26 @@ class FwDialogComponent {
|
|
|
3177
3177
|
return classes;
|
|
3178
3178
|
}
|
|
3179
3179
|
ngOnInit() {
|
|
3180
|
-
|
|
3180
|
+
// `<fw-dialog>` is usable outside an overlay, so there may be no dialogRef at all.
|
|
3181
|
+
const container = this.dialogRef?.containerInstance;
|
|
3182
|
+
if (container) {
|
|
3183
|
+
// Deferred by one microtask on purpose: `_addAriaLabelledBy` mutates the container's
|
|
3184
|
+
// `_ariaLabelledByQueue`, which `CdkDialogContainer` exposes as a host binding. A component's
|
|
3185
|
+
// host bindings are evaluated in its parent view *before* Angular descends into child
|
|
3186
|
+
// components, so mutating the queue synchronously here changes a value the container already
|
|
3187
|
+
// read in the same change-detection pass, which throws NG0100 in dev builds. Same approach as
|
|
3188
|
+
// Angular Material's `MatDialogLayoutSection`.
|
|
3189
|
+
Promise.resolve().then(() => container._addAriaLabelledBy(this.headerId));
|
|
3190
|
+
}
|
|
3181
3191
|
}
|
|
3182
3192
|
ngOnDestroy() {
|
|
3183
|
-
this.dialogRef?.containerInstance
|
|
3193
|
+
const container = this.dialogRef?.containerInstance;
|
|
3194
|
+
if (container) {
|
|
3195
|
+
// Deferred to stay ordered behind the deferred add in `ngOnInit` — otherwise a dialog created
|
|
3196
|
+
// and destroyed within the same task would remove the id before it was ever added and leave
|
|
3197
|
+
// it orphaned in the queue.
|
|
3198
|
+
Promise.resolve().then(() => container._removeAriaLabelledBy(this.headerId));
|
|
3199
|
+
}
|
|
3184
3200
|
}
|
|
3185
3201
|
handleCloseButton() {
|
|
3186
3202
|
this.closeWithAnimation();
|
|
@@ -4324,6 +4340,16 @@ class FwMenuItemComponent {
|
|
|
4324
4340
|
this.focused = model(false, ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
|
|
4325
4341
|
this.selected = model(false, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
4326
4342
|
this.subscriptions = [];
|
|
4343
|
+
this.isDestroyed = false;
|
|
4344
|
+
}
|
|
4345
|
+
/**
|
|
4346
|
+
* Whether this item's view has been torn down. Owners that iterate their items (`fw-menu`) have to
|
|
4347
|
+
* check this before writing to the item's `model()`s: neither `QueryList` nor a signal query is
|
|
4348
|
+
* emptied by view destruction, so an item can still be reachable from a query after the menu it
|
|
4349
|
+
* lives in was destroyed - writing to it then logs NG0953.
|
|
4350
|
+
*/
|
|
4351
|
+
get destroyed() {
|
|
4352
|
+
return this.isDestroyed;
|
|
4327
4353
|
}
|
|
4328
4354
|
scrollIntoView(options = { behavior: 'smooth', block: 'nearest' }) {
|
|
4329
4355
|
// eslint-disable-next-line @rx-angular/prefer-no-layout-sensitive-apis
|
|
@@ -4341,6 +4367,7 @@ class FwMenuItemComponent {
|
|
|
4341
4367
|
this.updateLayout();
|
|
4342
4368
|
}
|
|
4343
4369
|
ngOnDestroy() {
|
|
4370
|
+
this.isDestroyed = true;
|
|
4344
4371
|
for (const subscription of this.subscriptions) {
|
|
4345
4372
|
subscription.unsubscribe();
|
|
4346
4373
|
}
|
|
@@ -4487,9 +4514,15 @@ class FwMenuComponent {
|
|
|
4487
4514
|
}
|
|
4488
4515
|
writeValue(value) {
|
|
4489
4516
|
this.value.set(value);
|
|
4517
|
+
// Lay the items out BEFORE calling out to any listener. `change` is wired to `fw-select`'s
|
|
4518
|
+
// `handleClick`, which closes the options panel and so synchronously destroys every
|
|
4519
|
+
// `fw-menu-item` rendered in it. View teardown does not empty a `QueryList`, so laying out
|
|
4520
|
+
// afterwards writes to `model()`s on already-destroyed nodes, which logs NG0953 once per item
|
|
4521
|
+
// whose `selected` flag changed. Everything `updateLayout()` reads derives from `this.value()`,
|
|
4522
|
+
// set on the line above, so the resulting layout is identical either way.
|
|
4523
|
+
this.updateLayout();
|
|
4490
4524
|
this.onChange(value);
|
|
4491
4525
|
this.change.emit(value);
|
|
4492
|
-
this.updateLayout();
|
|
4493
4526
|
}
|
|
4494
4527
|
registerOnChange(fn) {
|
|
4495
4528
|
this.onChange = fn;
|
|
@@ -4528,6 +4561,12 @@ class FwMenuComponent {
|
|
|
4528
4561
|
if (this.menuItems) {
|
|
4529
4562
|
const itemRole = this.computeItemRole();
|
|
4530
4563
|
this.menuItems.forEach((item) => {
|
|
4564
|
+
// A destroyed item is still reachable through the QueryList; writing to its models would
|
|
4565
|
+
// emit on a dead OutputRef (NG0953). Belt and braces for any other listener that tears the
|
|
4566
|
+
// menu down from underneath a layout pass.
|
|
4567
|
+
if (item.destroyed) {
|
|
4568
|
+
return;
|
|
4569
|
+
}
|
|
4531
4570
|
item.itemRole.set(itemRole);
|
|
4532
4571
|
const size = this.size();
|
|
4533
4572
|
if (size !== undefined) {
|
|
@@ -6361,7 +6400,9 @@ class FwSelectMenuComponent {
|
|
|
6361
6400
|
return displayFn(selectedMenuItem);
|
|
6362
6401
|
}
|
|
6363
6402
|
const selectedOption = options.find((opt) => opt[this.valueProperty()]?.toString() === currentValue);
|
|
6364
|
-
|
|
6403
|
+
// `||` would swallow a legitimate `0` title and leave the input showing its placeholder, and it
|
|
6404
|
+
// would also let a non-string title through into this `linkedSignal<string>` untouched
|
|
6405
|
+
return String(selectedOption?.[this.titleProperty()] ?? '');
|
|
6365
6406
|
}, ...(ngDevMode ? [{ debugName: "selectTitle" }] : /* istanbul ignore next */ []));
|
|
6366
6407
|
// Watch for menu items changes and re-subscribe
|
|
6367
6408
|
this.menuItemsWatcher = effect(() => {
|
|
@@ -8526,8 +8567,12 @@ class FwStepperComponent {
|
|
|
8526
8567
|
return;
|
|
8527
8568
|
}
|
|
8528
8569
|
this.activeStep.set(step);
|
|
8529
|
-
|
|
8570
|
+
// Same ordering rule as FwMenuComponent.writeValue: lay the steps out before calling out to a
|
|
8571
|
+
// listener, so a handler that removes the stepper cannot leave `updateSteps()` writing to
|
|
8572
|
+
// `model()`s on destroyed `fw-step`s (NG0953). `updateSteps()` only reads `activeStep()`, set
|
|
8573
|
+
// on the line above, so the layout is unchanged.
|
|
8530
8574
|
this.updateSteps();
|
|
8575
|
+
this.stepChange.emit(parseInt(step?.toString())); // weirdly passing out step directly fails the eqeqeq
|
|
8531
8576
|
}
|
|
8532
8577
|
updateSteps() {
|
|
8533
8578
|
if (this.steps && this.steps.length > 0) {
|