mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(stepper): add CdkStepHeader directive and fix CdkStepper error on init (#10614)
* Adds the `CdkStepHeader` directive which is the equivalent of `MatStepHeader` and can be used by consumers when building custom steppers. * Fixes an error that was being thrown on init when using a `cdkStepper` directly. Fixes #10611.
This commit is contained in:
committed by
mmalerba
parent
d2d8a1f675
commit
fbbe463354
@@ -10,3 +10,4 @@ export * from './stepper';
|
||||
export * from './step-label';
|
||||
export * from './stepper-button';
|
||||
export * from './stepper-module';
|
||||
export * from './step-header';
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Directive, ElementRef} from '@angular/core';
|
||||
import {FocusableOption} from '@angular/cdk/a11y';
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkStepHeader]',
|
||||
host: {
|
||||
'role': 'tab',
|
||||
},
|
||||
})
|
||||
export class CdkStepHeader implements FocusableOption {
|
||||
constructor(protected _elementRef: ElementRef<HTMLElement>) {}
|
||||
|
||||
/** Focuses the step header. */
|
||||
focus() {
|
||||
this._elementRef.nativeElement.focus();
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,26 @@ import {CdkStepper, CdkStep} from './stepper';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {CdkStepLabel} from './step-label';
|
||||
import {CdkStepperNext, CdkStepperPrevious} from './stepper-button';
|
||||
import {CdkStepHeader} from './step-header';
|
||||
import {BidiModule} from '@angular/cdk/bidi';
|
||||
|
||||
@NgModule({
|
||||
imports: [BidiModule, CommonModule],
|
||||
exports: [CdkStep, CdkStepper, CdkStepLabel, CdkStepperNext, CdkStepperPrevious],
|
||||
declarations: [CdkStep, CdkStepper, CdkStepLabel, CdkStepperNext, CdkStepperPrevious]
|
||||
exports: [
|
||||
CdkStep,
|
||||
CdkStepper,
|
||||
CdkStepHeader,
|
||||
CdkStepLabel,
|
||||
CdkStepperNext,
|
||||
CdkStepperPrevious,
|
||||
],
|
||||
declarations: [
|
||||
CdkStep,
|
||||
CdkStepper,
|
||||
CdkStepHeader,
|
||||
CdkStepLabel,
|
||||
CdkStepperNext,
|
||||
CdkStepperPrevious,
|
||||
]
|
||||
})
|
||||
export class CdkStepperModule {}
|
||||
|
||||
@@ -38,6 +38,7 @@ import {AbstractControl} from '@angular/forms';
|
||||
import {CdkStepLabel} from './step-label';
|
||||
import {Observable, Subject, of as obaservableOf} from 'rxjs';
|
||||
import {startWith, takeUntil} from 'rxjs/operators';
|
||||
import {CdkStepHeader} from './step-header';
|
||||
|
||||
/** Used to generate unique ID for each stepper component. */
|
||||
let nextId = 0;
|
||||
@@ -242,8 +243,12 @@ export class CdkStepper implements AfterViewInit, OnDestroy {
|
||||
/** The list of step components that the stepper is holding. */
|
||||
@ContentChildren(CdkStep) _steps: QueryList<CdkStep>;
|
||||
|
||||
/** The list of step headers of the steps in the stepper. */
|
||||
_stepHeader: QueryList<FocusableOption>;
|
||||
/**
|
||||
* The list of step headers of the steps in the stepper.
|
||||
* @deprecated Type to be changed to `QueryList<CdkStepHeader>`.
|
||||
* @breaking-change 8.0.0
|
||||
*/
|
||||
@ContentChildren(CdkStepHeader) _stepHeader: QueryList<FocusableOption>;
|
||||
|
||||
/** Whether the validity of previous steps should be checked or not. */
|
||||
@Input()
|
||||
@@ -302,7 +307,10 @@ export class CdkStepper implements AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this._keyManager = new FocusKeyManager(this._stepHeader)
|
||||
// Note that while the step headers are content children by default, any components that
|
||||
// extend this one might have them as view chidren. We initialize the keyboard handling in
|
||||
// AfterViewInit so we're guaranteed for both view and content children to be defined.
|
||||
this._keyManager = new FocusKeyManager<FocusableOption>(this._stepHeader)
|
||||
.withWrap()
|
||||
.withVerticalOrientation(this._orientation === 'vertical');
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ import {Subscription} from 'rxjs';
|
||||
import {MatStepLabel} from './step-label';
|
||||
import {MatStepperIntl} from './stepper-intl';
|
||||
import {MatStepperIconContext} from './stepper-icon';
|
||||
import {StepState} from '@angular/cdk/stepper';
|
||||
import {CdkStepHeader, StepState} from '@angular/cdk/stepper';
|
||||
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
@@ -35,7 +36,7 @@ import {StepState} from '@angular/cdk/stepper';
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MatStepHeader implements OnDestroy {
|
||||
export class MatStepHeader extends CdkStepHeader implements OnDestroy {
|
||||
private _intlSubscription: Subscription;
|
||||
|
||||
/** State of the given step. */
|
||||
@@ -65,15 +66,16 @@ export class MatStepHeader implements OnDestroy {
|
||||
constructor(
|
||||
public _intl: MatStepperIntl,
|
||||
private _focusMonitor: FocusMonitor,
|
||||
private _element: ElementRef<HTMLElement>,
|
||||
_elementRef: ElementRef<HTMLElement>,
|
||||
changeDetectorRef: ChangeDetectorRef) {
|
||||
_focusMonitor.monitor(_element, true);
|
||||
super(_elementRef);
|
||||
_focusMonitor.monitor(_elementRef, true);
|
||||
this._intlSubscription = _intl.changes.subscribe(() => changeDetectorRef.markForCheck());
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._intlSubscription.unsubscribe();
|
||||
this._focusMonitor.stopMonitoring(this._element);
|
||||
this._focusMonitor.stopMonitoring(this._elementRef);
|
||||
}
|
||||
|
||||
/** Returns string label of given step if it is a text label. */
|
||||
@@ -88,7 +90,7 @@ export class MatStepHeader implements OnDestroy {
|
||||
|
||||
/** Returns the host HTML element. */
|
||||
_getHostElement() {
|
||||
return this._element.nativeElement;
|
||||
return this._elementRef.nativeElement;
|
||||
}
|
||||
|
||||
/** Template context variables that are exposed to the `matStepperIcon` instances. */
|
||||
@@ -99,8 +101,4 @@ export class MatStepHeader implements OnDestroy {
|
||||
optional: this.optional
|
||||
};
|
||||
}
|
||||
|
||||
focus() {
|
||||
this._getHostElement().focus();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user