Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

refactor: switch to signal queries #1271

Merged
merged 3 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions scenes/src/app/scene-viewer/scene-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import {
HostBinding,
Input,
OnInit,
ViewChild,
ViewContainerRef,
ViewEncapsulation
ViewEncapsulation,
viewChild
} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {DomSanitizer, SafeStyle} from '@angular/platform-browser';
Expand Down Expand Up @@ -44,8 +44,7 @@ export class SceneViewer implements OnInit {
/** Component of scene to display */
@Input() component: any;

@ViewChild('scene', {read: ViewContainerRef, static: true})
scene!: ViewContainerRef;
readonly scene = viewChild.required('scene', { read: ViewContainerRef });

constructor(private readonly componentFactoryResolver: ComponentFactoryResolver,
private route: ActivatedRoute,
Expand All @@ -57,7 +56,7 @@ export class SceneViewer implements OnInit {

ngOnInit() {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.component);
this.scene.createComponent(componentFactory);
this.scene().createComponent(componentFactory);
const container = document.querySelector('#scene-content-container') as HTMLElement;
container.style.transform = `scale(${this.scale})`;
container.style.transformOrigin = 'center';
Expand Down
8 changes: 4 additions & 4 deletions scenes/src/app/scenes/autocomplete/autocomplete-scene.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
AfterViewInit,
Component,
ViewChild,
ViewEncapsulation
ViewEncapsulation,
viewChild
} from '@angular/core';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatFormFieldModule} from '@angular/material/form-field';
Expand All @@ -27,10 +27,10 @@ export class AutocompleteScene implements AfterViewInit {
myControl = new FormControl('');
options: string[] = ['hello', 'hello world'];

@ViewChild(MatInput) input!: MatInput;
readonly input = viewChild.required(MatInput);

ngAfterViewInit() {
this.input.focus();
this.input().focus();
}
}

6 changes: 3 additions & 3 deletions scenes/src/app/scenes/menu/menu-scene.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {AfterViewInit, Component, ViewChild, ViewEncapsulation} from '@angular/core';
import {AfterViewInit, Component, ViewEncapsulation, viewChild} from '@angular/core';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {MatMenuModule, MatMenuTrigger} from '@angular/material/menu';
Expand All @@ -12,9 +12,9 @@ import {MatMenuModule, MatMenuTrigger} from '@angular/material/menu';
imports: [MatButtonModule, MatMenuModule, MatIconModule]
})
export class MenuScene implements AfterViewInit {
@ViewChild('menuTrigger') trigger!: MatMenuTrigger;
readonly trigger = viewChild.required<MatMenuTrigger>('menuTrigger');

ngAfterViewInit() {
this.trigger.openMenu();
this.trigger().openMenu();
}
}
10 changes: 5 additions & 5 deletions scenes/src/app/scenes/ripples/ripples-scene.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {AfterViewInit, Component, ViewChild, ViewEncapsulation} from '@angular/core';
import {AfterViewInit, Component, ViewEncapsulation, viewChild} from '@angular/core';
import {MatButtonModule} from '@angular/material/button';
import {MatRipple, MatRippleModule} from '@angular/material/core';

Expand All @@ -11,17 +11,17 @@ import {MatRipple, MatRippleModule} from '@angular/material/core';
imports: [MatRippleModule, MatButtonModule]
})
export class RipplesScene implements AfterViewInit {
@ViewChild('button', {read: MatRipple}) buttonRipple!: MatRipple;
@ViewChild('wrapper', {read: MatRipple}) wrapperRipple!: MatRipple;
readonly buttonRipple = viewChild.required('button', { read: MatRipple });
readonly wrapperRipple = viewChild.required('wrapper', { read: MatRipple });

ngAfterViewInit() {
this.buttonRipple.launch(140, 100, {
this.buttonRipple().launch(140, 100, {
persistent: true,
animation: {enterDuration: 0},
radius: 50,
});

this.wrapperRipple.launch(300, 100, {
this.wrapperRipple().launch(300, 100, {
persistent: true,
animation: {enterDuration: 0},
radius: 150,
Expand Down
6 changes: 3 additions & 3 deletions scenes/src/app/scenes/select/select-scene.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {AfterViewInit, Component, ViewChild, ViewEncapsulation} from '@angular/core';
import {AfterViewInit, Component, ViewEncapsulation, viewChild} from '@angular/core';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatSelect, MatSelectModule} from '@angular/material/select';
import {MatOptionModule} from '@angular/material/core';
Expand All @@ -12,9 +12,9 @@ import {MatOptionModule} from '@angular/material/core';
imports: [MatFormFieldModule, MatSelectModule, MatOptionModule]
})
export class SelectScene implements AfterViewInit {
@ViewChild(MatSelect) select!: MatSelect;
readonly select = viewChild.required(MatSelect);

ngAfterViewInit() {
this.select.open();
this.select().open();
}
}
6 changes: 3 additions & 3 deletions scenes/src/app/scenes/tooltip/tooltip-scene.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component, ViewChild, AfterViewInit, ViewEncapsulation} from '@angular/core';
import {Component, AfterViewInit, ViewEncapsulation, viewChild} from '@angular/core';
import {MatButtonModule} from '@angular/material/button';
import {MatTooltipModule, MatTooltip} from '@angular/material/tooltip';
import {MatIconModule} from '@angular/material/icon';
Expand All @@ -16,9 +16,9 @@ import {MatIconModule} from '@angular/material/icon';
],
})
export class TooltipScene implements AfterViewInit {
@ViewChild(MatTooltip) tooltip!: MatTooltip;
readonly tooltip = viewChild.required(MatTooltip);

ngAfterViewInit() {
this.tooltip.toggle();
this.tooltip().toggle();
}
}
2 changes: 1 addition & 1 deletion src/app/pages/component-sidenav/component-sidenav.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</mat-sidenav>
}
<div class="docs-component-sidenav-content">
<component-page-header (toggleSidenav)="toggleSidenav(sidenav)"></component-page-header>
<component-page-header (toggleSidenav)="toggleSidenav(sidenav())"></component-page-header>
<div class="docs-component-sidenav-inner-content">
<main class="docs-component-sidenav-body-content">
<!-- If on large screen, menu resides to left of content -->
Expand Down
4 changes: 2 additions & 2 deletions src/app/pages/component-sidenav/component-sidenav.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ describe('ComponentSidenav', () => {

// TODO refactor this as none of these expectations are ever verified
waitForAsync(() => {
expect(component.sidenav instanceof MatSidenav).toBeTruthy();
expect(component.sidenav() instanceof MatSidenav).toBeTruthy();
component.isScreenSmall.pipe(take(1)).subscribe(isSmall => expect(isSmall).toBeTruthy());
expect(component.sidenav.opened).toBe(false);
expect(component.sidenav().opened).toBe(false);
});
});

Expand Down
11 changes: 6 additions & 5 deletions src/app/pages/component-sidenav/component-sidenav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import {
NgZone,
OnDestroy,
OnInit,
ViewChild,
ViewEncapsulation,
forwardRef,
input
input,
viewChild
} from '@angular/core';
import {animate, state, style, transition, trigger} from '@angular/animations';
import {CdkAccordionModule} from '@angular/cdk/accordion';
Expand Down Expand Up @@ -82,7 +82,7 @@ const SMALL_WIDTH_BREAKPOINT = 959;
],
})
export class ComponentSidenav implements OnInit, OnDestroy {
@ViewChild(MatSidenav) sidenav!: MatSidenav;
readonly sidenav = viewChild.required(MatSidenav);
params: Observable<Params> | undefined;
isExtraScreenSmall: Observable<boolean>;
isScreenSmall: Observable<boolean>;
Expand All @@ -108,8 +108,9 @@ export class ComponentSidenav implements OnInit, OnDestroy {
this.subscriptions.add(
this._navigationFocusService.navigationEndEvents.pipe(map(() => this.isScreenSmall))
.subscribe((shouldCloseSideNav) => {
if (shouldCloseSideNav && this.sidenav) {
this.sidenav.close();
const sidenav = this.sidenav();
if (shouldCloseSideNav && sidenav) {
sidenav.close();
}
}
));
Expand Down
25 changes: 13 additions & 12 deletions src/app/pages/component-viewer/component-viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import {
NgModule,
OnDestroy,
OnInit,
QueryList,
ViewChild,
ViewChildren,
ViewEncapsulation,
viewChild,
viewChildren
} from '@angular/core';
import {MatTabsModule} from '@angular/material/tabs';
import {ActivatedRoute,
Expand Down Expand Up @@ -95,8 +94,8 @@ export class ComponentViewer implements OnDestroy {
*/
@Directive()
export class ComponentBaseView implements OnInit, OnDestroy {
@ViewChild('toc') tableOfContents!: TableOfContents;
@ViewChildren(DocViewer) viewers!: QueryList<DocViewer>;
readonly tableOfContents = viewChild.required<TableOfContents>('toc');
readonly viewers = viewChildren(DocViewer);

showToc: Observable<boolean>;
private _destroyed = new Subject();
Expand All @@ -116,17 +115,18 @@ export class ComponentBaseView implements OnInit, OnDestroy {

ngOnInit() {
this.componentViewer.componentDocItem.pipe(takeUntil(this._destroyed)).subscribe(() => {
if (this.tableOfContents) {
this.tableOfContents.resetHeaders();
const tableOfContents = this.tableOfContents();
if (tableOfContents) {
tableOfContents.resetHeaders();
}
});

this.showToc.pipe(
skip(1),
takeUntil(this._destroyed)
).subscribe(() => {
if (this.tableOfContents) {
this.viewers.forEach(viewer => {
if (this.tableOfContents()) {
this.viewers().forEach(viewer => {
viewer.contentRendered.emit(viewer._elementRef.nativeElement);
});
}
Expand All @@ -139,9 +139,10 @@ export class ComponentBaseView implements OnInit, OnDestroy {
}

updateTableOfContents(sectionName: string, docViewerContent: HTMLElement, sectionIndex = 0) {
if (this.tableOfContents) {
this.tableOfContents.addHeaders(sectionName, docViewerContent, sectionIndex);
this.tableOfContents.updateScrollPosition();
const tableOfContents = this.tableOfContents();
if (tableOfContents) {
tableOfContents.addHeaders(sectionName, docViewerContent, sectionIndex);
tableOfContents.updateScrollPosition();
}
}
}
Expand Down
25 changes: 12 additions & 13 deletions src/app/shared/carousel/carousel.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import {
AfterContentInit,
Component,
ContentChildren,
Directive,
ElementRef,
HostBinding,
Inject,
Optional,
QueryList,
ViewChild,
ViewEncapsulation,
input
input,
contentChildren,
viewChild
} from '@angular/core';
import {FocusableOption, FocusKeyManager} from '@angular/cdk/a11y';
import {LEFT_ARROW, RIGHT_ARROW, TAB} from '@angular/cdk/keycodes';
Expand Down Expand Up @@ -43,8 +42,8 @@ export class CarouselItem implements FocusableOption {
})
export class Carousel implements AfterContentInit {
readonly ariaLabel = input<string|undefined>(undefined, { alias: 'aria-label' });
@ContentChildren(CarouselItem) items!: QueryList<CarouselItem>;
@ViewChild('list') list!: ElementRef<HTMLElement>;
readonly items = contentChildren(CarouselItem);
readonly list = viewChild.required<ElementRef<HTMLElement>>('list');
@HostBinding('class.animations-disabled') readonly animationsDisabled: boolean;
position = 0;
showPrevArrow = false;
Expand Down Expand Up @@ -79,12 +78,12 @@ export class Carousel implements AfterContentInit {
}

ngAfterContentInit(): void {
this._keyManager = new FocusKeyManager<CarouselItem>(this.items);
this._keyManager = new FocusKeyManager<CarouselItem>(this.items());
}

/** Goes to the next set of items */
next() {
for (let i = this.index; i < this.items.length; i++) {
for (let i = this.index; i < this.items().length; i++) {
if (this._isOutOfView(i)) {
this.index = i;
this._scrollToActiveItem();
Expand All @@ -106,7 +105,7 @@ export class Carousel implements AfterContentInit {

/** Updates the `tabindex` of each of the items based on their active state. */
private _updateItemTabIndices() {
this.items.forEach((item: CarouselItem) => {
this.items().forEach((item: CarouselItem) => {
if (this._keyManager != null) {
item.tabindex = item === this._keyManager.activeItem ? '0' : '-1';
}
Expand All @@ -119,7 +118,7 @@ export class Carousel implements AfterContentInit {
return;
}

const itemsArray = this.items.toArray();
const itemsArray = this.items();
let targetItemIndex = this.index;

// Only shift the carousel by one if we're going forwards. This
Expand All @@ -129,7 +128,7 @@ export class Carousel implements AfterContentInit {
}

this.position = itemsArray[targetItemIndex].element.nativeElement.offsetLeft;
this.list.nativeElement.style.transform = `translateX(-${this.position}px)`;
this.list().nativeElement.style.transform = `translateX(-${this.position}px)`;
this.showPrevArrow = this.index > 0;
this.showNextArrow = false;

Expand All @@ -143,15 +142,15 @@ export class Carousel implements AfterContentInit {

/** Checks whether an item at a specific index is outside of the viewport. */
private _isOutOfView(index: number, side?: 'start' | 'end') {
const {offsetWidth, offsetLeft} = this.items.toArray()[index].element.nativeElement;
const {offsetWidth, offsetLeft} = this.items()[index].element.nativeElement;

if ((!side || side === 'start') && offsetLeft - this.position < 0) {
return true;
}

return (
(!side || side === 'end') &&
offsetWidth + offsetLeft - this.position > this.list.nativeElement.clientWidth
offsetWidth + offsetLeft - this.position > this.list().nativeElement.clientWidth
);
}
}
6 changes: 3 additions & 3 deletions src/app/shared/example-viewer/code-snippet.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
ChangeDetectionStrategy,
Component,
ViewChild,
forwardRef,
input
input,
viewChild
} from '@angular/core';
import {DocViewer} from '../doc-viewer/doc-viewer';

Expand All @@ -17,5 +17,5 @@ import {DocViewer} from '../doc-viewer/doc-viewer';
})
export class CodeSnippet {
readonly source = input<string>();
@ViewChild('viewer') viewer!: DocViewer;
readonly viewer = viewChild.required<DocViewer>('viewer');
}
4 changes: 2 additions & 2 deletions src/app/shared/example-viewer/example-viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@if (view === 'snippet') {
<div class="docs-example-viewer-source-compact">
<div class="button-bar">
<button mat-icon-button type="button" (click)="copySource(snippet)"
<button mat-icon-button type="button" (click)="copySource(snippet())"
class="docs-example-source-copy docs-example-button" matTooltip="Copy snippet"
title="Copy example source" aria-label="Copy example source to clipboard">
<mat-icon>content_copy</mat-icon>
Expand Down Expand Up @@ -65,7 +65,7 @@
@for (tabName of _getExampleTabNames(); track tabName) {
<mat-tab [label]="tabName">
<div class="button-bar">
<button mat-icon-button type="button" (click)="copySource(snippet, selectedTab)"
<button mat-icon-button type="button" (click)="copySource(snippet(), selectedTab)"
class="docs-example-source-copy docs-example-button" matTooltip="Copy example source"
title="Copy example source" aria-label="Copy example source to clipboard">
<mat-icon>content_copy</mat-icon>
Expand Down
Loading