parent
b1ba2d6f4e
commit
8c1a041411
|
@ -6,8 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ErrorHandler} from '@angular/core';
|
import {Component, ErrorHandler, Injectable, NgModule} from '@angular/core';
|
||||||
import {Component, Injectable, NgModule} from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'benchmark-area',
|
selector: 'benchmark-area',
|
||||||
|
@ -27,9 +26,7 @@ import {Component, Injectable, NgModule} from '@angular/core';
|
||||||
export class BenchmarkArea {
|
export class BenchmarkArea {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface ExtendedWindow extends Window {
|
declare interface ExtendedWindow extends Window { benchmarkErrors?: string[]; }
|
||||||
benchmarkErrors?: string[];
|
|
||||||
}
|
|
||||||
const extendedWindow = window as ExtendedWindow;
|
const extendedWindow = window as ExtendedWindow;
|
||||||
|
|
||||||
@Injectable({providedIn: 'root'})
|
@Injectable({providedIn: 'root'})
|
||||||
|
|
|
@ -44,12 +44,12 @@ export interface MlbTeam {
|
||||||
})
|
})
|
||||||
export class BenchmarkableExpandingRow {
|
export class BenchmarkableExpandingRow {
|
||||||
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
||||||
showExpandingRow!: boolean;
|
showExpandingRow !: boolean;
|
||||||
|
|
||||||
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
||||||
teams!: MlbTeam[];
|
teams !: MlbTeam[];
|
||||||
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
||||||
private fakeTeams!: MlbTeam[];
|
private fakeTeams !: MlbTeam[];
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
this.teams = this.fakeTeams;
|
this.teams = this.fakeTeams;
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
import {CommonModule} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {ExpandingRowModule} from './expanding_row_module';
|
|
||||||
|
|
||||||
import {BenchmarkableExpandingRow} from './benchmarkable_expanding_row';
|
import {BenchmarkableExpandingRow} from './benchmarkable_expanding_row';
|
||||||
|
import {ExpandingRowModule} from './expanding_row_module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [BenchmarkableExpandingRow],
|
declarations: [BenchmarkableExpandingRow],
|
||||||
|
@ -22,4 +22,3 @@ import {BenchmarkableExpandingRow} from './benchmarkable_expanding_row';
|
||||||
})
|
})
|
||||||
export class BenchmarkableExpandingRowModule {
|
export class BenchmarkableExpandingRowModule {
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,10 @@
|
||||||
|
|
||||||
import {AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Inject, InjectionToken, Input, Output, QueryList, ViewChild} from '@angular/core';
|
import {AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Inject, InjectionToken, Input, Output, QueryList, ViewChild} from '@angular/core';
|
||||||
|
|
||||||
|
import {expanding_row_css} from './expanding_row_css';
|
||||||
import {ExpandingRowSummary} from './expanding_row_summary';
|
import {ExpandingRowSummary} from './expanding_row_summary';
|
||||||
import {ExpandingRowToggleEvent} from './expanding_row_toggle_event';
|
import {ExpandingRowToggleEvent} from './expanding_row_toggle_event';
|
||||||
import { expanding_row_css } from './expanding_row_css';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection token to break cylic dependency between ExpandingRow and
|
* Injection token to break cylic dependency between ExpandingRow and
|
||||||
|
@ -111,7 +112,7 @@ export class ExpandingRow {
|
||||||
* The identifier for this node provided by the user code. We need this
|
* The identifier for this node provided by the user code. We need this
|
||||||
* while we are emitting onToggle event.
|
* while we are emitting onToggle event.
|
||||||
*/
|
*/
|
||||||
@Input() rowId!: string;
|
@Input() rowId !: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ElementRef to the main element in this component. We need a reference
|
* An ElementRef to the main element in this component. We need a reference
|
||||||
|
@ -119,7 +120,7 @@ export class ExpandingRow {
|
||||||
* is used in [cfcExpandingRowHost] directive for scroll adjustments.
|
* is used in [cfcExpandingRowHost] directive for scroll adjustments.
|
||||||
*/
|
*/
|
||||||
@ViewChild('expandingRowMainElement', {static: true})
|
@ViewChild('expandingRowMainElement', {static: true})
|
||||||
expandingRowMainElement!: ElementRef;
|
expandingRowMainElement !: ElementRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This @Output event emitter will be triggered when the user expands or
|
* This @Output event emitter will be triggered when the user expands or
|
||||||
|
@ -144,9 +145,7 @@ export class ExpandingRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** TS getter for isExpanded property. */
|
/** TS getter for isExpanded property. */
|
||||||
get isExpanded(): boolean {
|
get isExpanded(): boolean { return this.isExpandedInternal; }
|
||||||
return this.isExpandedInternal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Triggered when isExpanded property changes. */
|
/** Triggered when isExpanded property changes. */
|
||||||
isExpandedChange = new EventEmitter<void>();
|
isExpandedChange = new EventEmitter<void>();
|
||||||
|
@ -165,9 +164,7 @@ export class ExpandingRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** TS getter for isFocused property. */
|
/** TS getter for isFocused property. */
|
||||||
get isFocused(): boolean {
|
get isFocused(): boolean { return this.isFocusedInternal; }
|
||||||
return this.isFocusedInternal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The index of the row in the context of the entire collection. */
|
/** The index of the row in the context of the entire collection. */
|
||||||
set index(value: number) {
|
set index(value: number) {
|
||||||
|
@ -181,9 +178,7 @@ export class ExpandingRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** TS getter for index property. */
|
/** TS getter for index property. */
|
||||||
get index(): number {
|
get index(): number { return this.indexInternal; }
|
||||||
return this.indexInternal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We should probably rename this to summaryContentChild. Because technically
|
* We should probably rename this to summaryContentChild. Because technically
|
||||||
|
@ -193,7 +188,7 @@ export class ExpandingRow {
|
||||||
* component is not in the same file as ExpandingRow.
|
* component is not in the same file as ExpandingRow.
|
||||||
*/
|
*/
|
||||||
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
||||||
summaryViewChild!: ExpandingRowSummary;
|
summaryViewChild !: ExpandingRowSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We compute the collapsed height (which is just height of
|
* We compute the collapsed height (which is just height of
|
||||||
|
@ -210,7 +205,7 @@ export class ExpandingRow {
|
||||||
|
|
||||||
/** Internal storage for index public property. */
|
/** Internal storage for index public property. */
|
||||||
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
||||||
private indexInternal!: number;
|
private indexInternal !: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This holds a reference to [cfcExpandingRowHost] directive. We need
|
* This holds a reference to [cfcExpandingRowHost] directive. We need
|
||||||
|
@ -219,8 +214,7 @@ export class ExpandingRow {
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
public elementRef: ElementRef,
|
public elementRef: ElementRef,
|
||||||
@Inject(EXPANDING_ROW_HOST_INJECTION_TOKEN) public expandingRowHost:
|
@Inject(EXPANDING_ROW_HOST_INJECTION_TOKEN) public expandingRowHost: ExpandingRowHostBase,
|
||||||
ExpandingRowHostBase,
|
|
||||||
private readonly changeDetectorRef: ChangeDetectorRef) {}
|
private readonly changeDetectorRef: ChangeDetectorRef) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -229,9 +223,8 @@ export class ExpandingRow {
|
||||||
* is handled in [cfcExpandingRowHost] directive.
|
* is handled in [cfcExpandingRowHost] directive.
|
||||||
*/
|
*/
|
||||||
handleSummaryClick(): void {
|
handleSummaryClick(): void {
|
||||||
this.collapsedHeight = this.elementRef.nativeElement
|
this.collapsedHeight =
|
||||||
.querySelector('.cfc-expanding-row-summary')
|
this.elementRef.nativeElement.querySelector('.cfc-expanding-row-summary').offsetHeight;
|
||||||
.offsetHeight;
|
|
||||||
this.expandingRowHost.handleRowSummaryClick(this);
|
this.expandingRowHost.handleRowSummaryClick(this);
|
||||||
this.expand();
|
this.expand();
|
||||||
}
|
}
|
||||||
|
@ -240,9 +233,7 @@ export class ExpandingRow {
|
||||||
* When user tabs into child cfc-expanding-row-summary component. This method
|
* When user tabs into child cfc-expanding-row-summary component. This method
|
||||||
* will make sure we focuse on this row, and blur on previously focused row.
|
* will make sure we focuse on this row, and blur on previously focused row.
|
||||||
*/
|
*/
|
||||||
handleSummaryFocus(): void {
|
handleSummaryFocus(): void { this.focus(); }
|
||||||
this.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cfc-expanding-row-details-caption component will call this function to
|
* cfc-expanding-row-details-caption component will call this function to
|
||||||
|
@ -253,8 +244,7 @@ export class ExpandingRow {
|
||||||
* not trigger the row collapse.
|
* not trigger the row collapse.
|
||||||
*/
|
*/
|
||||||
handleCaptionClick(event: MouseEvent): void {
|
handleCaptionClick(event: MouseEvent): void {
|
||||||
if (this.expandingRowHost.isBlacklisted(
|
if (this.expandingRowHost.isBlacklisted(event.target as {} as HTMLElement)) {
|
||||||
event.target as {} as HTMLElement)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.expandingRowHost.handleRowCaptionClick(this);
|
this.expandingRowHost.handleRowCaptionClick(this);
|
||||||
|
@ -266,9 +256,7 @@ export class ExpandingRow {
|
||||||
* Gets the height of this component. This height is used in parent
|
* Gets the height of this component. This height is used in parent
|
||||||
* [cfcExpandingRowHost] directive to compute scroll adjustment.
|
* [cfcExpandingRowHost] directive to compute scroll adjustment.
|
||||||
*/
|
*/
|
||||||
getHeight(): number {
|
getHeight(): number { return this.expandingRowMainElement.nativeElement.offsetHeight; }
|
||||||
return this.expandingRowMainElement.nativeElement.offsetHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expands this row. This will notify the host so that it can collapse
|
* Expands this row. This will notify the host so that it can collapse
|
||||||
|
@ -280,9 +268,7 @@ export class ExpandingRow {
|
||||||
this.expandingRowHost.handleRowExpand(this);
|
this.expandingRowHost.handleRowExpand(this);
|
||||||
|
|
||||||
// setTimeout here makes sure we scroll this row into view after animation.
|
// setTimeout here makes sure we scroll this row into view after animation.
|
||||||
setTimeout(() => {
|
setTimeout(() => { this.expandingRowMainElement.nativeElement.focus(); });
|
||||||
this.expandingRowMainElement.nativeElement.focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.onToggle.emit({rowId: this.rowId, isExpand: true});
|
this.onToggle.emit({rowId: this.rowId, isExpand: true});
|
||||||
}
|
}
|
||||||
|
@ -319,9 +305,7 @@ export class ExpandingRow {
|
||||||
|
|
||||||
// Summary child is not present currently. We need to NG2 to update the
|
// Summary child is not present currently. We need to NG2 to update the
|
||||||
// template.
|
// template.
|
||||||
setTimeout(() => {
|
setTimeout(() => { this.summaryViewChild.focus(); });
|
||||||
this.summaryViewChild.focus();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,4 +16,5 @@ import {Directive} from '@angular/core';
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[cfcExpandingRowBlacklist]',
|
selector: '[cfcExpandingRowBlacklist]',
|
||||||
})
|
})
|
||||||
export class ExpandingRowBlacklist {}
|
export class ExpandingRowBlacklist {
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {Subject} from 'rxjs';
|
||||||
import {takeUntil} from 'rxjs/operators';
|
import {takeUntil} from 'rxjs/operators';
|
||||||
|
|
||||||
import {ExpandingRow} from './expanding_row';
|
import {ExpandingRow} from './expanding_row';
|
||||||
import { expanding_row_css } from './expanding_row_css';
|
import {expanding_row_css} from './expanding_row_css';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component should be within cfc-expanding-row component. The caption
|
* This component should be within cfc-expanding-row component. The caption
|
||||||
|
@ -42,17 +42,12 @@ export class ExpandingRowDetailsCaption implements OnDestroy {
|
||||||
* this component when the row is collapsed. We also need to relay clicks
|
* this component when the row is collapsed. We also need to relay clicks
|
||||||
* to the parent component.
|
* to the parent component.
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(@Host() public expandingRow: ExpandingRow, changeDetectorRef: ChangeDetectorRef) {
|
||||||
@Host() public expandingRow: ExpandingRow,
|
this.expandingRow.isExpandedChange.pipe(takeUntil(this.onDestroy)).subscribe(() => {
|
||||||
changeDetectorRef: ChangeDetectorRef) {
|
|
||||||
this.expandingRow.isExpandedChange.pipe(takeUntil(this.onDestroy))
|
|
||||||
.subscribe(() => {
|
|
||||||
changeDetectorRef.markForCheck();
|
changeDetectorRef.markForCheck();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** When component is destroyed, unlisten to isExpanded. */
|
/** When component is destroyed, unlisten to isExpanded. */
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void { this.onDestroy.next(); }
|
||||||
this.onDestroy.next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Host, OnDestroy}
|
||||||
import {Subscription} from 'rxjs';
|
import {Subscription} from 'rxjs';
|
||||||
|
|
||||||
import {ExpandingRow} from './expanding_row';
|
import {ExpandingRow} from './expanding_row';
|
||||||
import { expanding_row_css } from './expanding_row_css';
|
import {expanding_row_css} from './expanding_row_css';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component should be within cfc-expanding-row component. Note that the
|
* This component should be within cfc-expanding-row component. Note that the
|
||||||
|
@ -34,17 +34,11 @@ export class ExpandingRowDetailsContent implements OnDestroy {
|
||||||
* We need a reference to parent cfc-expanding-row component to make sure we
|
* We need a reference to parent cfc-expanding-row component to make sure we
|
||||||
* hide this component if the row is collapsed.
|
* hide this component if the row is collapsed.
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(@Host() public expandingRow: ExpandingRow, changeDetectorRef: ChangeDetectorRef) {
|
||||||
@Host() public expandingRow: ExpandingRow,
|
|
||||||
changeDetectorRef: ChangeDetectorRef) {
|
|
||||||
this.isExpandedChangeSubscription =
|
this.isExpandedChangeSubscription =
|
||||||
this.expandingRow.isExpandedChange.subscribe(() => {
|
this.expandingRow.isExpandedChange.subscribe(() => { changeDetectorRef.markForCheck(); });
|
||||||
changeDetectorRef.markForCheck();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Unsubscribe from changes in parent isExpanded property. */
|
/** Unsubscribe from changes in parent isExpanded property. */
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void { this.isExpandedChangeSubscription.unsubscribe(); }
|
||||||
this.isExpandedChangeSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AfterContentInit, AfterViewInit, ChangeDetectionStrategy, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, HostListener, Input, OnDestroy, Output, QueryList, ViewChild} from '@angular/core';
|
import {AfterContentInit, AfterViewInit, ChangeDetectionStrategy, Component, ContentChildren, ElementRef, EventEmitter, HostListener, Input, OnDestroy, Output, QueryList, ViewChild, forwardRef} from '@angular/core';
|
||||||
import {Subscription} from 'rxjs';
|
import {Subscription} from 'rxjs';
|
||||||
|
|
||||||
import {EXPANDING_ROW_HOST_INJECTION_TOKEN, ExpandingRow, ExpandingRowHostBase} from './expanding_row';
|
import {EXPANDING_ROW_HOST_INJECTION_TOKEN, ExpandingRow, ExpandingRowHostBase} from './expanding_row';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We use this class in <cfc-expanding-row/> template to identify the row.
|
* We use this class in <cfc-expanding-row/> template to identify the row.
|
||||||
* The [cfcExpandingRowHost] directive also uses this class to check if a given
|
* The [cfcExpandingRowHost] directive also uses this class to check if a given
|
||||||
|
@ -25,7 +26,7 @@ export const EXPANDING_ROW_KEYPRESS_THORTTLE_MS = 50;
|
||||||
* This type union is created to make arguments of handleUpOrDownPress*
|
* This type union is created to make arguments of handleUpOrDownPress*
|
||||||
* methods in ExpandingRowHost class more readable.
|
* methods in ExpandingRowHost class more readable.
|
||||||
*/
|
*/
|
||||||
type UpOrDown = 'up'|'down';
|
type UpOrDown = 'up' | 'down';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the wrapper directive for the cfc-expanding-row components. Note that
|
* This is the wrapper directive for the cfc-expanding-row components. Note that
|
||||||
|
@ -45,12 +46,10 @@ type UpOrDown = 'up'|'down';
|
||||||
tabindex="0">
|
tabindex="0">
|
||||||
</div>`,
|
</div>`,
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
providers: [
|
providers: [{provide: EXPANDING_ROW_HOST_INJECTION_TOKEN, useExisting: ExpandingRowHost}],
|
||||||
{provide: EXPANDING_ROW_HOST_INJECTION_TOKEN, useExisting: ExpandingRowHost}
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
export class ExpandingRowHost implements AfterViewInit,
|
||||||
ExpandingRowHostBase {
|
OnDestroy, ExpandingRowHostBase {
|
||||||
/**
|
/**
|
||||||
* An HTML selector (e.g. "body") for the scroll element. We need this to
|
* An HTML selector (e.g. "body") for the scroll element. We need this to
|
||||||
* make some scroll adjustments.
|
* make some scroll adjustments.
|
||||||
|
@ -72,11 +71,11 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
@Output() onPrepend = new EventEmitter<void>();
|
@Output() onPrepend = new EventEmitter<void>();
|
||||||
|
|
||||||
/** A reference to the last focusable element in list of expanding rows. */
|
/** A reference to the last focusable element in list of expanding rows. */
|
||||||
@ViewChild('lastFocusable', {static: true}) lastFocusableElement!: ElementRef;
|
@ViewChild('lastFocusable', {static: true}) lastFocusableElement !: ElementRef;
|
||||||
|
|
||||||
/** A reference to the first focusable element in list of expanding rows. */
|
/** A reference to the first focusable element in list of expanding rows. */
|
||||||
@ViewChild('firstFocusable', {static: true})
|
@ViewChild('firstFocusable', {static: true})
|
||||||
firstFocusableElement!: ElementRef;
|
firstFocusableElement !: ElementRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to all child cfc-expanding-row elements. We will need for
|
* A reference to all child cfc-expanding-row elements. We will need for
|
||||||
|
@ -84,7 +83,7 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
* which row is previous row when user presses "left arrow" on a focused row.
|
* which row is previous row when user presses "left arrow" on a focused row.
|
||||||
*/
|
*/
|
||||||
@ContentChildren(forwardRef(() => ExpandingRow), {descendants: true})
|
@ContentChildren(forwardRef(() => ExpandingRow), {descendants: true})
|
||||||
contentRows!: QueryList<ExpandingRow>;
|
contentRows !: QueryList<ExpandingRow>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps track of the last row that had focus before focus left the list
|
* Keeps track of the last row that had focus before focus left the list
|
||||||
|
@ -113,8 +112,7 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
* function around. This enables us to detach the click listener when
|
* function around. This enables us to detach the click listener when
|
||||||
* component is destroyed.
|
* component is destroyed.
|
||||||
*/
|
*/
|
||||||
private handleRootMouseUpBound: EventListenerObject =
|
private handleRootMouseUpBound: EventListenerObject = this.handleRootMouseUp.bind(this);
|
||||||
this.handleRootMouseUp.bind(this);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 16px is the margin animation we have on cfc-expanding-row component.
|
* 16px is the margin animation we have on cfc-expanding-row component.
|
||||||
|
@ -124,7 +122,7 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
|
|
||||||
/** Subscription to changes in the expanding rows. */
|
/** Subscription to changes in the expanding rows. */
|
||||||
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
|
||||||
private rowChangeSubscription!: Subscription;
|
private rowChangeSubscription !: Subscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When component initializes we need to attach click listener to the root
|
* When component initializes we need to attach click listener to the root
|
||||||
|
@ -140,9 +138,8 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
|
|
||||||
clickRootElement.addEventListener('mouseup', this.handleRootMouseUpBound);
|
clickRootElement.addEventListener('mouseup', this.handleRootMouseUpBound);
|
||||||
|
|
||||||
this.rowChangeSubscription = this.contentRows.changes.subscribe(() => {
|
this.rowChangeSubscription =
|
||||||
this.recalcRowIndexes();
|
this.contentRows.changes.subscribe(() => { this.recalcRowIndexes(); });
|
||||||
});
|
|
||||||
this.recalcRowIndexes();
|
this.recalcRowIndexes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,8 +154,7 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clickRootElement.removeEventListener(
|
clickRootElement.removeEventListener('mouseup', this.handleRootMouseUpBound);
|
||||||
'mouseup', this.handleRootMouseUpBound);
|
|
||||||
|
|
||||||
if (this.rowChangeSubscription) {
|
if (this.rowChangeSubscription) {
|
||||||
this.rowChangeSubscription.unsubscribe();
|
this.rowChangeSubscription.unsubscribe();
|
||||||
|
@ -191,11 +187,9 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
*/
|
*/
|
||||||
handleRowSummaryClick(row: ExpandingRow): void {
|
handleRowSummaryClick(row: ExpandingRow): void {
|
||||||
const hadPreviousSelection: boolean = !!this.expandedRow;
|
const hadPreviousSelection: boolean = !!this.expandedRow;
|
||||||
const previousSelectedRowIndex: number =
|
const previousSelectedRowIndex: number = this.getRowIndex(this.expandedRow as ExpandingRow);
|
||||||
this.getRowIndex(this.expandedRow as ExpandingRow);
|
|
||||||
const newSelectedRowIndex: number = this.getRowIndex(row);
|
const newSelectedRowIndex: number = this.getRowIndex(row);
|
||||||
const previousCollapsedHeight: number =
|
const previousCollapsedHeight: number = this.getSelectedRowCollapsedHeight();
|
||||||
this.getSelectedRowCollapsedHeight();
|
|
||||||
const previousExpansionHeight = this.getSelectedRowExpandedHeight();
|
const previousExpansionHeight = this.getSelectedRowExpandedHeight();
|
||||||
|
|
||||||
if (this.expandedRow) {
|
if (this.expandedRow) {
|
||||||
|
@ -212,11 +206,9 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
scrollAdjustment = previousExpansionHeight - previousCollapsedHeight;
|
scrollAdjustment = previousExpansionHeight - previousCollapsedHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newSelectionIsInfrontOfPrevious: boolean =
|
const newSelectionIsInfrontOfPrevious: boolean = newSelectedRowIndex > previousSelectedRowIndex;
|
||||||
newSelectedRowIndex > previousSelectedRowIndex;
|
|
||||||
const multiplier = newSelectionIsInfrontOfPrevious ? -1 : 0;
|
const multiplier = newSelectionIsInfrontOfPrevious ? -1 : 0;
|
||||||
scrollAdjustment =
|
scrollAdjustment = scrollAdjustment * multiplier + ExpandingRowHost.rowMargin;
|
||||||
scrollAdjustment * multiplier + ExpandingRowHost.rowMargin;
|
|
||||||
|
|
||||||
scrollElement.scrollTop += scrollAdjustment;
|
scrollElement.scrollTop += scrollAdjustment;
|
||||||
}
|
}
|
||||||
|
@ -264,17 +256,13 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
* Function that is called by expanding row summary to focus on the last
|
* Function that is called by expanding row summary to focus on the last
|
||||||
* focusable element before the list of expanding rows.
|
* focusable element before the list of expanding rows.
|
||||||
*/
|
*/
|
||||||
focusOnPreviousFocusableElement(): void {
|
focusOnPreviousFocusableElement(): void { this.lastFocusedRow = this.focusedRow; }
|
||||||
this.lastFocusedRow = this.focusedRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function that is called by expanding row summary to focus on the next
|
* Function that is called by expanding row summary to focus on the next
|
||||||
* focusable element after the list of expanding rows.
|
* focusable element after the list of expanding rows.
|
||||||
*/
|
*/
|
||||||
focusOnNextFocusableElement(): void {
|
focusOnNextFocusableElement(): void { this.lastFocusedRow = this.focusedRow; }
|
||||||
this.lastFocusedRow = this.focusedRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles keydown event on the host. We are just concerned with up,
|
* Handles keydown event on the host. We are just concerned with up,
|
||||||
|
@ -287,8 +275,7 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
* - Enter: Expands the focused row.
|
* - Enter: Expands the focused row.
|
||||||
*/
|
*/
|
||||||
@HostListener('keydown', ['$event'])
|
@HostListener('keydown', ['$event'])
|
||||||
handleKeyDown(event: KeyboardEvent) {
|
handleKeyDown(event: KeyboardEvent) {}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively returns true if target HTMLElement is within a
|
* Recursively returns true if target HTMLElement is within a
|
||||||
|
@ -431,8 +418,7 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
|
|
||||||
/** Returns the HTMLElement that is the currently focused row summary. */
|
/** Returns the HTMLElement that is the currently focused row summary. */
|
||||||
private focusedRowSummary(): HTMLElement|undefined {
|
private focusedRowSummary(): HTMLElement|undefined {
|
||||||
return this.focusedRow ?
|
return this.focusedRow ? this.focusedRow.summaryViewChild.mainElementRef.nativeElement :
|
||||||
this.focusedRow.summaryViewChild.mainElementRef.nativeElement :
|
|
||||||
undefined;
|
undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,30 +437,26 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
* the computed (the one above or below) row. If host has an expanded row,
|
* the computed (the one above or below) row. If host has an expanded row,
|
||||||
* this function will expand the computed row.
|
* this function will expand the computed row.
|
||||||
*/
|
*/
|
||||||
private handleUpOrDownPressOnce(upOrDown: UpOrDown, event: KeyboardEvent):
|
private handleUpOrDownPressOnce(upOrDown: UpOrDown, event: KeyboardEvent): void {
|
||||||
void {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
// If row is expanded but focus is inside the expanded element, arrow
|
// If row is expanded but focus is inside the expanded element, arrow
|
||||||
// key presses should not do anything.
|
// key presses should not do anything.
|
||||||
if (this.expandedRow &&
|
if (this.expandedRow &&
|
||||||
document.activeElement !==
|
document.activeElement !== this.expandedRow.expandingRowMainElement.nativeElement) {
|
||||||
this.expandedRow.expandingRowMainElement.nativeElement) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If focus is inside a collapsed row header, arrow key presses should not
|
// If focus is inside a collapsed row header, arrow key presses should not
|
||||||
// do anything.
|
// do anything.
|
||||||
if (this.focusedRow &&
|
if (this.focusedRow && document.activeElement !== this.focusedRowSummary()) {
|
||||||
document.activeElement !== this.focusedRowSummary()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// We only want screen reader to read the message the first time we enter
|
// We only want screen reader to read the message the first time we enter
|
||||||
// the list of expanding rows, so we must reset the variable here
|
// the list of expanding rows, so we must reset the variable here
|
||||||
this.lastFocusedRow = undefined;
|
this.lastFocusedRow = undefined;
|
||||||
|
|
||||||
const rowToLookFor: ExpandingRow|undefined =
|
const rowToLookFor: ExpandingRow|undefined = this.expandedRow || this.focusedRow;
|
||||||
this.expandedRow || this.focusedRow;
|
|
||||||
if (!rowToLookFor) {
|
if (!rowToLookFor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -509,11 +491,7 @@ export class ExpandingRowHost implements AfterViewInit, OnDestroy,
|
||||||
// Updates all of the rows with their new index.
|
// Updates all of the rows with their new index.
|
||||||
private recalcRowIndexes() {
|
private recalcRowIndexes() {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
setTimeout(() => {
|
setTimeout(
|
||||||
this.contentRows.forEach((row: ExpandingRow) => {
|
() => { this.contentRows.forEach((row: ExpandingRow) => { row.index = index++; }); });
|
||||||
row.index = index++;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Host,
|
||||||
import {Subscription} from 'rxjs';
|
import {Subscription} from 'rxjs';
|
||||||
|
|
||||||
import {ExpandingRow} from './expanding_row';
|
import {ExpandingRow} from './expanding_row';
|
||||||
import { expanding_row_css } from './expanding_row_css';
|
import {expanding_row_css} from './expanding_row_css';
|
||||||
|
|
||||||
const KEY_CODE_TAB = 9;
|
const KEY_CODE_TAB = 9;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ export class ExpandingRowSummary implements OnDestroy {
|
||||||
* reference for focus and blur methods below.
|
* reference for focus and blur methods below.
|
||||||
*/
|
*/
|
||||||
@ViewChild('expandingRowSummaryMainElement', {static: false})
|
@ViewChild('expandingRowSummaryMainElement', {static: false})
|
||||||
mainElementRef!: ElementRef;
|
mainElementRef !: ElementRef;
|
||||||
|
|
||||||
/** Subscription for changes in parent isExpanded property. */
|
/** Subscription for changes in parent isExpanded property. */
|
||||||
private isExpandedSubscription: Subscription;
|
private isExpandedSubscription: Subscription;
|
||||||
|
@ -63,18 +63,13 @@ export class ExpandingRowSummary implements OnDestroy {
|
||||||
* will act as a header for expanded rows. We also need to relay tab-in and
|
* will act as a header for expanded rows. We also need to relay tab-in and
|
||||||
* click events to the parent.
|
* click events to the parent.
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(@Host() public expandingRow: ExpandingRow, changeDetectorRef: ChangeDetectorRef) {
|
||||||
@Host() public expandingRow: ExpandingRow,
|
|
||||||
changeDetectorRef: ChangeDetectorRef) {
|
|
||||||
this.expandingRow.summaryViewChild = this;
|
this.expandingRow.summaryViewChild = this;
|
||||||
this.isExpandedSubscription =
|
this.isExpandedSubscription =
|
||||||
this.expandingRow.isExpandedChange.subscribe(() => {
|
this.expandingRow.isExpandedChange.subscribe(() => { changeDetectorRef.markForCheck(); });
|
||||||
changeDetectorRef.markForCheck();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.indexSubscription = this.expandingRow.indexChange.subscribe(() => {
|
this.indexSubscription =
|
||||||
changeDetectorRef.markForCheck();
|
this.expandingRow.indexChange.subscribe(() => { changeDetectorRef.markForCheck(); });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,8 +94,8 @@ export class ExpandingRowSummary implements OnDestroy {
|
||||||
//
|
//
|
||||||
// TODO(b/62385992) Use the KeyboardFocusService to detect focus cause
|
// TODO(b/62385992) Use the KeyboardFocusService to detect focus cause
|
||||||
// instead of creating multiple monitors on a page.
|
// instead of creating multiple monitors on a page.
|
||||||
if (this.expandingRow.expandingRowMainElement.nativeElement.classList
|
if (this.expandingRow.expandingRowMainElement.nativeElement.classList.contains(
|
||||||
.contains('cdk-mouse-focused')) {
|
'cdk-mouse-focused')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,13 +139,11 @@ export class ExpandingRowSummary implements OnDestroy {
|
||||||
// before expanding row list. Otherwise, if shift+tab is pressed on first
|
// before expanding row list. Otherwise, if shift+tab is pressed on first
|
||||||
// focusable child inside expanding row summary, it should focus on main
|
// focusable child inside expanding row summary, it should focus on main
|
||||||
// expanding row summary element.
|
// expanding row summary element.
|
||||||
if (event.shiftKey &&
|
if (event.shiftKey && document.activeElement === this.mainElementRef.nativeElement) {
|
||||||
document.activeElement === this.mainElementRef.nativeElement) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.expandingRow.expandingRowHost.focusOnPreviousFocusableElement();
|
this.expandingRow.expandingRowHost.focusOnPreviousFocusableElement();
|
||||||
return;
|
return;
|
||||||
} else if (
|
} else if (event.shiftKey && document.activeElement === focusableChildren[0]) {
|
||||||
event.shiftKey && document.activeElement === focusableChildren[0]) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.expandingRow.focus();
|
this.expandingRow.focus();
|
||||||
}
|
}
|
||||||
|
@ -159,8 +152,7 @@ export class ExpandingRowSummary implements OnDestroy {
|
||||||
// summary, focus should be set to the next focusable element after the list
|
// summary, focus should be set to the next focusable element after the list
|
||||||
// of expanding rows.
|
// of expanding rows.
|
||||||
if (!event.shiftKey &&
|
if (!event.shiftKey &&
|
||||||
document.activeElement ===
|
document.activeElement === focusableChildren[focusableChildren.length - 1]) {
|
||||||
focusableChildren[focusableChildren.length - 1]) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.expandingRow.expandingRowHost.focusOnNextFocusableElement();
|
this.expandingRow.expandingRowHost.focusOnNextFocusableElement();
|
||||||
}
|
}
|
||||||
|
@ -188,8 +180,7 @@ export class ExpandingRowSummary implements OnDestroy {
|
||||||
// If the current expanding row summary was the last focused one before
|
// If the current expanding row summary was the last focused one before
|
||||||
// focus exited the list, then return true to trigger the screen reader
|
// focus exited the list, then return true to trigger the screen reader
|
||||||
if (this.mainElementRef.nativeElement ===
|
if (this.mainElementRef.nativeElement ===
|
||||||
expandingRowHost.lastFocusedRow.summaryViewChild.mainElementRef
|
expandingRowHost.lastFocusedRow.summaryViewChild.mainElementRef.nativeElement) {
|
||||||
.nativeElement) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -197,8 +188,7 @@ export class ExpandingRowSummary implements OnDestroy {
|
||||||
|
|
||||||
/** Puts the DOM focus on the main element. */
|
/** Puts the DOM focus on the main element. */
|
||||||
focus(): void {
|
focus(): void {
|
||||||
if (this.mainElementRef &&
|
if (this.mainElementRef && document.activeElement !== this.mainElementRef.nativeElement) {
|
||||||
document.activeElement !== this.mainElementRef.nativeElement) {
|
|
||||||
this.mainElementRef.nativeElement.focus();
|
this.mainElementRef.nativeElement.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +203,5 @@ export class ExpandingRowSummary implements OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns array of focusable elements within this component. */
|
/** Returns array of focusable elements within this component. */
|
||||||
private getFocusableChildren(): HTMLElement[] {
|
private getFocusableChildren(): HTMLElement[] { return []; }
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue