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 1 commit
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
Loading