1

Angular has a "stepper" implementation, called CdkStepper, that's very powerful. Basically a CdkStepper has CdkStep DOM children that implement steps, and is clever about advancing between steps with "next" and "previous" events. I need to write a multilevel stepper, like this:

<my-stepper>
    <my-step>Hi there</my-step>
    <my-stepper>
        <my-step>How's it going?</my-step>
        <my-step>Good?</my-step>
    </my-stepper>
</my-stepper>

where my-stepper extends CdkStepper and my-step extends CdkStep. (There's lots missing there, but that captures the essentials.) The thing that's stopping me is that CdkStepper does this:

@ContentChildren(CdkStep, {descendants: true}) _steps: QueryList<CdkStep>;

instead of this:

@ContentChildren(CdkStep) _steps: QueryList<CdkStep>;

That means that the top level stepper grabs all of the steps in the whole DOM tree that descends from it. So in this instance, it acts just as though I'd said:

<my-stepper>
    <my-step>Hi there</my-step>
    <my-stepper>
        <my-step>How's it going?</my-step>
        <my-step>Good?</my-step>
    </my-stepper>
    <my-step>How's it going?</my-step>
    <my-step>Good?</my-step>
</my-stepper>

which is less than ideal. Solutions that I've looked at include:

  • I could write something ad hoc that replicates most of what CdkStepper does. (Terrible idea.)
  • I could copy the whole of the implementation and just change that one thing. (Almost as terrible.)
  • I could find a way to override just the problematic portions of CdkStepper.

One thing that won't work; you can't have an instance variable in a decorator argument (so I couldn't do something like:

@Input() descendants = false;
@ContentChildren(CdkStep, {descendants: this.descendants}) _steps: QueryList<CdkStep>;

because the decorator applies to the class, not the instance and therefore this is meaningless in this context.

So what should I do here? Is there a way to use extends to just override the minimum and get the behavior I want? Something else? What's a best-practice way to approach a situation like this?

Scott Deerwester
  • 3,503
  • 4
  • 33
  • 56

1 Answers1

0

I think you can wrap the nested stepper in a component, like this.

<my-stepper>
    <my-step>Hi there</my-step>
    <my-stepper-wrapper>
    </my-stepper-wrapper>
    <my-step>How's it going?</my-step>
    <my-step>Good?</my-step>
</my-stepper>

And in MyStepperWrapper

<my-stepper>
    <my-step>How's it going?</my-step>
    <my-step>Good?</my-step>
</my-stepper>
Erik Z
  • 4,660
  • 6
  • 47
  • 74