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?