Skip to content

docs(material/stepper): add live example of responsive stepper #22401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 9, 2021
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
2 changes: 2 additions & 0 deletions src/components-examples/material/stepper/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ ng_module(
]),
module_name = "@angular/components-examples/material/stepper",
deps = [
"//src/cdk/layout",
"//src/cdk/stepper",
"//src/cdk/testing",
"//src/cdk/testing/testbed",
Expand All @@ -22,6 +23,7 @@ ng_module(
"//src/material/input",
"//src/material/stepper",
"//src/material/stepper/testing",
"@npm//@angular/common",
"@npm//@angular/forms",
"@npm//@angular/platform-browser",
"@npm//@angular/platform-browser-dynamic",
Expand Down
5 changes: 5 additions & 0 deletions src/components-examples/material/stepper/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {NgModule} from '@angular/core';
import {ReactiveFormsModule} from '@angular/forms';
import {CommonModule} from '@angular/common';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input';
Expand All @@ -15,6 +16,7 @@ import {StepperStatesExample} from './stepper-states/stepper-states-example';
import {StepperVerticalExample} from './stepper-vertical/stepper-vertical-example';
import {StepperHarnessExample} from './stepper-harness/stepper-harness-example';
import {StepperLazyContentExample} from './stepper-lazy-content/stepper-lazy-content-example';
import {StepperResponsiveExample} from './stepper-responsive/stepper-responsive-example';

export {
StepperEditableExample,
Expand All @@ -26,6 +28,7 @@ export {
StepperStatesExample,
StepperVerticalExample,
StepperLazyContentExample,
StepperResponsiveExample,
};

const EXAMPLES = [
Expand All @@ -38,6 +41,7 @@ const EXAMPLES = [
StepperStatesExample,
StepperVerticalExample,
StepperLazyContentExample,
StepperResponsiveExample,
];

@NgModule({
Expand All @@ -47,6 +51,7 @@ const EXAMPLES = [
MatInputModule,
MatStepperModule,
ReactiveFormsModule,
CommonModule,
],
declarations: EXAMPLES,
exports: EXAMPLES,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.example-stepper {
margin-top: 8px;
}

.mat-form-field {
margin-top: 16px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<ng-container [ngSwitch]="stepperOrientation | async">
<div *ngSwitchCase="'horizontal'">Make your screen smaller to see a vertical stepper</div>
<div *ngSwitchCase="'vertical'">Make your screen larger to see a horizontal stepper</div>
</ng-container>

<mat-stepper
class="example-stepper"
[orientation]="(stepperOrientation | async)!">
<mat-step [stepControl]="firstFormGroup" label="Fill out your name">
<form [formGroup]="firstFormGroup">
<mat-form-field>
<mat-label>Name</mat-label>
<input matInput placeholder="Last name, First name" formControlName="firstCtrl" required>
</mat-form-field>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="secondFormGroup" label="Fill out your address">
<form [formGroup]="secondFormGroup">
<mat-form-field>
<mat-label>Address</mat-label>
<input matInput formControlName="secondCtrl" placeholder="Ex. 1 Main St, New York, NY"
required>
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="thirdFormGroup" label="Fill out your phone number">
<form [formGroup]="thirdFormGroup">
<mat-form-field>
<mat-label>Phone number</mat-label>
<input matInput formControlName="thirdCtrl" placeholder="Ex. 12345678" required>
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step>
<ng-template matStepLabel>Done</ng-template>
<p>You are now done.</p>
<div>
<button mat-button matStepperPrevious>Back</button>
</div>
</mat-step>
</mat-stepper>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {Component} from '@angular/core';
import {FormBuilder, Validators} from '@angular/forms';
import {BreakpointObserver} from '@angular/cdk/layout';
import {StepperOrientation} from '@angular/material/stepper';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';

/**
* @title Stepper responsive
*/
@Component({
selector: 'stepper-responsive-example',
templateUrl: 'stepper-responsive-example.html',
styleUrls: ['stepper-responsive-example.css'],
})
export class StepperResponsiveExample {
firstFormGroup = this._formBuilder.group({
firstCtrl: ['', Validators.required]
});
secondFormGroup = this._formBuilder.group({
secondCtrl: ['', Validators.required]
});
thirdFormGroup = this._formBuilder.group({
thirdCtrl: ['', Validators.required]
});
stepperOrientation: Observable<StepperOrientation>;

constructor(private _formBuilder: FormBuilder, breakpointObserver: BreakpointObserver) {
this.stepperOrientation = breakpointObserver.observe('(min-width: 800px)')
.pipe(map(({matches}) => matches ? 'horizontal' : 'vertical'));
}
}
7 changes: 7 additions & 0 deletions src/material/stepper/stepper.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ an `ng-template` with the `matStepContent` attribute.

<!-- example(stepper-lazy-content) -->

### Responsive stepper
If your app supports a wide variety of screens and a stepper's layout doesn't fit a particular
screen size, you can control its `orientation` dynamically to change the layout based on the
viewport.

<!-- example(stepper-responsive) -->

### Keyboard interaction
- <kbd>LEFT_ARROW</kbd>: Focuses the previous step header
- <kbd>RIGHT_ARROW</kbd>: Focuses the next step header
Expand Down