Skip to content

Unable to use MatStepper with transclusion #8014

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

Closed
rpd10 opened this issue Oct 25, 2017 · 10 comments
Closed

Unable to use MatStepper with transclusion #8014

rpd10 opened this issue Oct 25, 2017 · 10 comments
Labels
feature This issue represents a new feature or feature request rather than a bug or bug fix needs: discussion Further discussion with the team is needed before proceeding P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@rpd10
Copy link

rpd10 commented Oct 25, 2017

Bug, feature request, or proposal:

Bug

What is the expected behavior?

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.

What is the current behavior?

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.

What are the steps to reproduce?

https://stackblitz.com/edit/angular-dfvcxd

What is the use-case or motivation for changing an existing behavior?

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.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Material beta 12

Is there anything else we should know?

@julianobrasil
Copy link
Contributor

julianobrasil commented Oct 25, 2017

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.

[EDIT]: It won't work for the reason described above: https://github.com/angular/material2/blob/master/src/lib/stepper/stepper-horizontal.html

@rpd10
Copy link
Author

rpd10 commented Oct 25, 2017

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.

@willshowell
Copy link
Contributor

@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 #6625 about a related, but slightly different problem)

https://github.com/angular/material2/blob/0ea43700efb105aa02ad3b1d3f800bf4a9925883/src/lib/stepper/stepper.ts#L69-L75

You may also be able to create your own implementation of MatStepper that adds the correct classes and animations,

https://github.com/angular/material2/blob/0ea43700efb105aa02ad3b1d3f800bf4a9925883/src/lib/stepper/stepper.ts#L103-L127

@jelbourn jelbourn added discussion feature This issue represents a new feature or feature request rather than a bug or bug fix labels Oct 27, 2017
@tbnovaes
Copy link

tbnovaes commented Dec 3, 2018

any updates on this one?

@cmsImagine
Copy link

cmsImagine commented May 17, 2019

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.

@geyuqiu
Copy link

geyuqiu commented Aug 19, 2019

@cmsImagine could you please tell us more about your solution (in code)?

@FTello31
Copy link

FTello31 commented Nov 7, 2019

any updates on this one? x2

@chriszrc
Copy link

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>

@mmalerba mmalerba added needs: discussion Further discussion with the team is needed before proceeding and removed discussion labels Mar 3, 2020
@mmalerba mmalerba added the needs triage This issue needs to be triaged by the team label May 20, 2020
@jelbourn jelbourn added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent and removed needs triage This issue needs to be triaged by the team labels May 25, 2020
@mmalerba
Copy link
Contributor

This is a limitation of Angular's content projection. angular/angular#37319 has been filed to hopefully improve some of the short-comings

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jun 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature This issue represents a new feature or feature request rather than a bug or bug fix needs: discussion Further discussion with the team is needed before proceeding P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
Development

No branches or pull requests

10 participants