Bug
Since there is not currently a responsive stepper, I am attempting to write a component that will switch between a horizontal and vertical stepper depending on the size of the viewport. My idea was that the responsive-stepper would not define any steps inside it. It would use *ngIf to determine which stepper to render, and then use <ng-content> transclusion to allow other components to include the actual steps.
When I attempt to use <mat-step> outside of a stepper, I get an error No provider for MatStepper. I have set up a stackblitz reproduction of the bug, the error is visible in the console.
https://stackblitz.com/edit/angular-dfvcxd
I'm working in an enterprise and I'd like to be able to define a responsive stepper component once, and let others reuse it in a generic fashion. I'm open to other strategies to achieve this.
Material beta 12
I have never test it, but you could try, instead of <mat-step>, use a div as a container with the attribute ngProjectAs="mat-step". It will work if mat-stepper expects mat-step to be a select attribute value of an ng-content. I doubt, but take a look at the source code and give it a shot if you think It makes sense.
Thanks for the suggestion, I did give it a shot but that didn't work either (as I saw you just commented).
I started down the path of just having 2 steppers inside my component, using ngIf to hide them, and then to avoid duplicating logic, pulling out the content of the mat-steps into separate components - something like this:
<mat-card>
<mat-card-content>
<mat-horizontal-stepper linear="true" *ngIf="facade.largeScreen">
<mat-step label="Verify Account" [stepControl]="verify.group">
<dash-password-verify #verify></dash-password-verify>
</mat-step>
<mat-step label="New Password">
<dash-password-choose></dash-password-choose>
</mat-step>
<mat-step label="Secondary Email">
<dash-password-email></dash-password-email>
</mat-step>
</mat-horizontal-stepper>
<mat-vertical-stepper linear="true" *ngIf="!facade.largeScreen">
<mat-step label="Verify Account" [stepControl]="verify.group">
<dash-password-verify></dash-password-verify>
</mat-step>
<mat-step label="New Password">
<dash-password-choose></dash-password-choose>
</mat-step>
<mat-step label="Secondary Email">
<dash-password-email></dash-password-email>
</mat-step>
</mat-vertical-stepper>
</mat-card-content>
</mat-card>
However, I think that will have its own set of issues. When one component is destroyed, I think I'm going to end up losing the user's form state, unless I put in code to manage it separately. The same problems would apply if I were to use fxShow/fxHide from @angular/flex-layout, since there would be two instances of the controls.
It sounds like the only way forward at this time is to have the form/forms contained within a single component, and duplicate the markup for both steppers, which is less than ideal.
@rpd10 I think this _may_ be possible if MatStepper would use descendants: true on it's ContentChildren query, (there's a lot more discussion on https://github.com/angular/material2/issues/6625 about a related, but slightly different problem)
You may also be able to create your own implementation of MatStepper that adds the correct classes and animations,
any updates on this one?
I got around this for now by having an <ng-container>, the <mat-step> then another <ng-container>with an *ngTemplateOutlet pointed at the template which in turn has <ng-content> in it. I feel like there has to be a better way but I haven't found it yet.
@cmsImagine could you please tell us more about your solution (in code)?
any updates on this one? x2
I didn't find a way to transclude the full template, but if you're looking to just transclude everything but the title and the previous/next buttons, then this worked:
<ng-template #matStep1 let-fileInput="fileInput">
<p>
My form
</p>
<mat-form-field>
<input matInput placeholder="Upload" [formControl]="fileInput" required autocomplete="off">
<mat-error *ngIf="fileInput.hasError('required')">
File is <strong>required</strong>
</mat-error>
</mat-form-field>
</ng-template>
<mat-horizontal-stepper #horizontalStepper fxFlex>
<mat-step [stepControl]="fileInput">
<ng-template matStepLabel>{{STEP_NAMES.step1}}</ng-template>
<ng-container *ngTemplateOutlet="matStep1;context:{fileInput: fileInput}">
</ng-container>
<button mat-button class="button-back" type="button">Back</button>
<button mat-flat-button color="accent" matStepperNext type="button" (click)="markAsTouched(fileInput)">Next</button>
</mat-step>
</mat-horizontal-stepper>
This is a limitation of Angular's content projection. https://github.com/angular/angular/issues/37319 has been filed to hopefully improve some of the short-comings
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
any updates on this one?