[material-ui][Stepper] Automate/extend its functionality to match same patterns used by Tabs
@DiegoAndai is already working on this.
Since Dec 27, 2023.
- Dominant language
- JavaScript
- Stars
- 99.1k
- Forks
- 32.5k
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 106
Description
Duplicates
- I have searched the existing issues
Latest version
- I have tested the latest version
Summary 💡
With the behavior MUI Tabs component, there's a clear goal: automate the process of indicating the active tab, and keeping the active tab synchronized with the content that is displayed under that tab. With the Stepper, we have a similar but only slightly more complicated goal: automate the process of indicating the active step, already-completed steps, and pending steps. All while, ideally, programmably displaying the content associated with that step.
Stepper has some additional functionality and options that Tabs does not, but in the same way that Tabs provides an API which can be used either standalone or integrated with Routing libraries, we can engineer the Stepper to make the additional functionality both flexible and programmable, by relying on simple props which embody the state of the component, and which can be driven either internally or by overriding the props.
Similarly, the stepper can use optional StepPanel components which are synchronized to the state of the step indicators as TabPanel components are. We do not have those components today, but their behavior should match almost entirely the behavior of a TabPanel, with the minor complication that where TabPanel has only active and inactive states, StepPanel needs three states: active, completed, and pending, to embody steps that come before or after the current step.
The best way to do this, seemingly, is to utilize the code and patterns from the Tabs component, so that MUI provides familiar, predictable UX/DX across the portfolio of components. Thus, the behavior should be based on the "value" prop: whereby the value prop on Stepper defines the state of the group, of which step is 'active'. However, instead of allowing the matching value props on Step components to be defined manually as they are on Tabs, we would exclusively infer it from the position in the Stepper's children array, as a Stepper is inherently a sequential interface, driven by a numeric value.
Then, the Stepper would be augmented by several additional properties:
activeVariantsimply defines which of the MUI global variants we apply to the currently activeStep(the Step which correlates to the 'value' of the Stepper)completedVariantthen defines how we treat those Steps which have already passed (which have a Stepvalueless-than the current Steppervalue)pendingVariantwould define how we treat those steps not-yet-reached (which have a Stepvaluegreater-than the current Steppervalue)
Providing the variants explicitly could be optional, as we could state that the activeVariant defaults to solid, completedVariant defaults to soft, and pendingVariant defaults to outlined; all of which provides a pretty conventional set of "sane defaults", while allowing customization. Beyond that, users could also take advantage of other standard MUI styling patterns to override those variants if they choose.
Would this be a constructive approach? Would we be open to a PR implementing this?
Examples 🌈
- The Tabs API, which emphasizes the use of
value, and how styling is driven by theMui-selectedclass - The Global Variants, which we would use as the default styling of the
active,pending, andcompletedsteps
Motivation 🔦
Providing basic automation/wiring patterns both saves effort for every single user of the component, while also helping people achieve stronger and more sustainable patterns of use. Specifically, the correlation between indicator styling and the state of the active step is a universal need we don't currently support. Also, it provides a more consistent experience across the MUI portfolio, in terms of the level of automation provided by components, specifically comparing Stepper to Tabs. Finally, in detail, by providing this kind of automation in a supported way, we can help avoid all the pitfalls people will encounter when trying to add this automation themselves. For example, if attempting to write a wrapper component for Step, one will wind up with an additional divider line after the last indicator, because it breaks the insertion of the data- attributes which define the last-child... we want to help people avoid that kind of thing by supporting the common need in a well-defined way.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.