|
| 1 | +# Nimble Stepper |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +The `nimble-stepper`, `nimble-step`, and `nimble-anchor-step` elements. |
| 6 | + |
| 7 | +### Background |
| 8 | + |
| 9 | +<!-- |
| 10 | +- *Relevant historical or background information* |
| 11 | +- *Link to relevant work items, related existing issues, etc.* |
| 12 | +--> |
| 13 | + |
| 14 | +- Nimble issue: [#624](https://github.com/ni/nimble/issues/624) |
| 15 | +- Interaction Design: None |
| 16 | +- Visual Design: |
| 17 | + - [Nimble Components Stepper Figma](https://www.figma.com/design/PO9mFOu5BCl8aJvFchEeuN/Nimble_Components?node-id=11742-71097&p=f&t=U3UnPlU4awyN4ybh-0) |
| 18 | + - [Config App Figma](https://www.figma.com/design/eG9PhYykbokYf1OBd8KLkn/Valinor?node-id=0-1&p=f&t=oRGYidVydXMcgj3I-0) |
| 19 | + |
| 20 | +### Containing Library |
| 21 | + |
| 22 | +<!-- *State whether this component be part of Nimble or Spright and provide justification or considerations leading to that decision.* --> |
| 23 | + |
| 24 | +Nimble: Stepper is a generic component not designed for a specific application / domain. |
| 25 | + |
| 26 | +### Non-goals |
| 27 | + |
| 28 | +<!-- *A list of use cases, features, or functionality which are **not** goals for the component.* --> |
| 29 | + |
| 30 | +- Handling long lists of steps (10+) |
| 31 | +- Non-linear step progressions such as following steps in a branching flow chart or graph are not in the scope of the current HLD / designs. |
| 32 | + |
| 33 | +### Features |
| 34 | + |
| 35 | +- Similar to a collection of card buttons / breadcrumb conceptually but with more visual states. |
| 36 | + |
| 37 | +### Risks and Challenges |
| 38 | + |
| 39 | +<!-- *Notable risks or challenges associated with implementing the component. Would we need to make any breaking changes in order to achieve this component's goals?* --> |
| 40 | + |
| 41 | +No known new unique risks or challenges |
| 42 | + |
| 43 | +### Prior Art / Examples |
| 44 | + |
| 45 | +- Relevant design systems: |
| 46 | + - [Carbon progress indicator](https://carbondesignsystem.com/components/progress-indicator/usage/) |
| 47 | + - [Angular Material stepper](https://material.angular.dev/components/stepper/overview) |
| 48 | + - [WAI Patterns step-by-step indicator](https://www.w3.org/WAI/tutorials/forms/multi-page/#using-step-by-step-indicator) |
| 49 | + - [USDS step indicator](https://designsystem.digital.gov/components/step-indicator/) |
| 50 | + |
| 51 | +## Design |
| 52 | + |
| 53 | +<!-- *Describe the design of the component, thinking through several perspectives:* |
| 54 | +
|
| 55 | +- *A customer using the component on a web page.* |
| 56 | +- *A developer building an app with the component and interacting through HTML/CSS/JavaScript.* |
| 57 | +- *A designer customizing the component.* |
| 58 | +
|
| 59 | +*Include code snippets showing basic component use and any interesting configurations.* |
| 60 | +
|
| 61 | +*For each section below, consider adding an "Alternatives" sub-section to describe any design alternatives and discuss why they were rejected.* --> |
| 62 | + |
| 63 | +The `nimble-stepper` acts a a progress indicator for a wizard / step-by-step workflow. It behaves conceptually as either a collection of card buttons (i.e. collection of `nimble-step`) or as breadcrumbs (i.e. collection of `nimble-anchor-step`). Each item has a standard `severity` state associated with it and the ability to express that a state is the "current" `selected` step. |
| 64 | + |
| 65 | +The `nimble-stepper` is just for layout, placing steps either horizontal or vertical orientation and communicating internal state to child steps as needed (ideally just via style but implementation TBD). |
| 66 | + |
| 67 | +The `nimble-step` and `nimble-anchor-step` are elements representing individual steps with `nimble-step` behaving as a card button (i.e. a button with a concept of a `selected` visual appearance that does not change behavior) and a `nimble-anchor-step` looking visually identical but with link behaviors. |
| 68 | + |
| 69 | +The `step` elements will primarily render a provided nimble icon (and new nimble icons for the visuals of digits 0 - 9 will be added). When a non-default severity is provided the provided icon will be replaced with an icon representing the severity. |
| 70 | + |
| 71 | +### API |
| 72 | + |
| 73 | +<!-- *The key elements of the component's public API surface:* |
| 74 | +
|
| 75 | +- *Component Name* |
| 76 | +- *Props/Attrs: to match native element APIs, prefer primitive types rather than complex configuration objects and expose fields as both properties on the TypeScript class and attributes on the HTML element* |
| 77 | +- *Methods* |
| 78 | +- *Events* |
| 79 | +- *CSS Classes and CSS Custom Properties that affect the component* |
| 80 | +- *How native CSS Properties (height, width, etc.) affect the component* |
| 81 | +
|
| 82 | +*Consider high and low-level APIs. Attempt to design a powerful and extensible low-level API with a high-level API for developer/designer ergonomics and simplicity.* --> |
| 83 | + |
| 84 | +- `nimble-stepper` |
| 85 | + - Attributes |
| 86 | + - orientation: vertical / horizontal (aligned with radio group and wafer) |
| 87 | + <!-- |
| 88 | + - Properties (not attribute reflected) |
| 89 | + - Methods |
| 90 | + - Events |
| 91 | + - CSS custom properties |
| 92 | + --> |
| 93 | + - CSS native properties |
| 94 | + - Will respond to width / height sizing (on the axis corresponding to orientation) and show overflow scroll buttons following the pattern of breadcrumb |
| 95 | + - Vertical use of this pattern is new and not captured in interaction or visual design. If expensive may fallback to other requirements (control overflow hidden and app must sze correctly, etc). |
| 96 | + - Slots |
| 97 | + - default: unused |
| 98 | + - step: supports `nimble-step` and `nimble-anchor-step` children (aligned with tabs use of a tab slot) |
| 99 | + <!-- |
| 100 | + - Parts |
| 101 | + - Localizable labels |
| 102 | + --> |
| 103 | + |
| 104 | +- `nimble-step` |
| 105 | + - Attributes |
| 106 | + - disabled: boolean (standard, i.e. visually disabled and interactions prevented) |
| 107 | + - readonly: boolean (standard, i.e. visually not disabled, interactions other than tab focus prevented) |
| 108 | + - selected: boolean (visual change only, no behavior) (aligned with card button) |
| 109 | + - severity: default / error / warning / success (similar to icon and banner but different subset) |
| 110 | + - severity-text: string (always shown but styled based on severity) |
| 111 | + <!-- |
| 112 | + - Properties (not attribute reflected) |
| 113 | + - Methods |
| 114 | + --> |
| 115 | + - Events |
| 116 | + - click (aligned to button, not emitted on disable) |
| 117 | + <!-- |
| 118 | + - CSS custom properties |
| 119 | + - CSS native properties |
| 120 | + --> |
| 121 | + - Slots |
| 122 | + - default: supports nimble icons, will render inside the circle and have color controlled via iconColor token |
| 123 | + - title: Title content (aligned with dialog) |
| 124 | + - subtitle: Subtitle content (aligned with dialog) |
| 125 | + <!-- |
| 126 | + - Parts |
| 127 | + - Localizable labels |
| 128 | + --> |
| 129 | + |
| 130 | +- `nimble-anchor-step` |
| 131 | + - Attributes |
| 132 | + - All `nimble-step` attributes |
| 133 | + - `<a>` attributes (href, target, etc) |
| 134 | + - href: null / undefined should behave like disabled (seems inconsistent across controls) |
| 135 | + <!-- |
| 136 | + - Properties (not attribute reflected) |
| 137 | + - Methods |
| 138 | + --> |
| 139 | + - Events |
| 140 | + - click (aligned to anchor-button, not emitted on disable) |
| 141 | + <!-- |
| 142 | + - CSS custom properties |
| 143 | + - CSS native properties |
| 144 | + --> |
| 145 | + - Slots |
| 146 | + - All `nimble-step` slots |
| 147 | + <!-- |
| 148 | + - Parts |
| 149 | + - Localizable labels |
| 150 | + --> |
| 151 | + |
| 152 | +### Anatomy |
| 153 | +<!-- |
| 154 | +*Outline the component structure with a diagram of its visual tree (shadow DOM). Enumerate key areas of visual customization, such as:* |
| 155 | +
|
| 156 | +- *Slot Names* |
| 157 | +- *Host Classes* |
| 158 | +- *Slotted Content/Slotted Classes* |
| 159 | +- *CSS Parts* --> |
| 160 | + |
| 161 | +Slots, parts, etc. merged above in API section. |
| 162 | + |
| 163 | +### Native form integration |
| 164 | + |
| 165 | +<!-- *Describe the plan for custom element form integration or why it's not necessary.* |
| 166 | +
|
| 167 | +*Components that are intended to replace a native form element (input, textarea, select) should generally behave like their native counterpart. See ["More capable form controls" on web.dev](https://web.dev/articles/more-capable-form-controls) for an overview of requirements. Leverage patterns from [FAST Form Associated Custom Elements](https://github.com/microsoft/fast/blob/master/packages/web-components/fast-foundation/src/form-associated/form-associated-custom-element.spec.md).* --> |
| 168 | + |
| 169 | +- Anchor related components will use native `<a>` tag and forward attributes. |
| 170 | +- control has no intrinsic "value" state, so not a form control |
| 171 | +- control used for navigation, does not seem like a good candidate for form submit button behavior |
| 172 | + |
| 173 | +### Angular integration |
| 174 | + |
| 175 | +<!-- *Describe the plan for Angular support, including directives for attribute binding and ControlValueAccessor for form integration. Depending on the contributor's needs, implementing Angular integration may be deferred but the initial spec should still document what work will be needed.* --> |
| 176 | + |
| 177 | +- Angular `routerLink` integration for `nimble-anchor-step`. |
| 178 | +- No Angular Form integration. |
| 179 | + |
| 180 | +### Blazor integration |
| 181 | + |
| 182 | +<!-- *Describe the plan for Blazor support, including form integration. See the [nimble-blazor CONTRIBUTING.md](/packages/blazor-workspace/NimbleBlazor/CONTRIBUTING.md) for details. Depending on the contributor's needs, implementing Blazor integration may be deferred but the initial spec should still document what work will be needed.* --> |
| 183 | + |
| 184 | +- To align with Blazor conventions we could implement the same behavior as Blazor [`NavLink`](https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/navigation?view=aspnetcore-10.0#navlink-component) ([component src](https://github.com/dotnet/aspnetcore/blob/main/src/Components/Web/src/Routing/NavLink.cs)) (we have not done that for other anchor controls). Not sure how our current Blazor components behave with the router as they don't have any specific integration. |
| 185 | +- Could be a good candidate for Blazor `EditForm` integration to visualize form error state as [`ValidationSummary`](https://learn.microsoft.com/en-us/aspnet/core/blazor/forms/validation?view=aspnetcore-10.0#validation-summary-and-validation-message-components) components. |
| 186 | +- Current scope does not include specific considerations for Blazor Router / `NavLink` or `EditForm` / `ValidationSummary` support. |
| 187 | + |
| 188 | +### Visual Appearance |
| 189 | + |
| 190 | +<!-- *Work with Visual Design to create Figma files and other design assets. Be sure to account for the various component states, including hover, active, etc. as well as validity, and appearance variants.* --> |
| 191 | + |
| 192 | +See figma linked in background section. |
| 193 | + |
| 194 | +### Interactions |
| 195 | + |
| 196 | +<!-- *Work with Interaction Design to create Figma files and other design assets. Be sure to account for the various interactions from mouse, keyboard, and touch * --> |
| 197 | + |
| 198 | +Step button / link interaction area is the step control size boundaries which includes the icon, title, subtitle, and the line visual. The control size / interaction area does not include the severity text (similar to error text in other controls). |
| 199 | + |
| 200 | +See the blue areas in the following image as an example: |
| 201 | + |
| 202 | + |
| 203 | + |
| 204 | +## Implementation |
| 205 | + |
| 206 | +<!-- *Important aspects of the planned implementation with careful consideration of web standards and integration.* |
| 207 | +
|
| 208 | +*Highlight any alternative implementations you considered in each section.* |
| 209 | +
|
| 210 | +*If you think a section doesn't apply or don't know what to write, please DO NOT delete it. Either mark it "N/A" or leave it blank and the Nimble team can help you fill it in.* --> |
| 211 | + |
| 212 | +No particularly interesting implementation concerns. Follows existing patterns around buttons and anchors. |
| 213 | + |
| 214 | +### States |
| 215 | + |
| 216 | +<!-- *Key component states, valid state transitions, and how interactions trigger a state transition.* --> |
| 217 | + |
| 218 | +Some specific usage notes: |
| 219 | +- Only one step should be marked selected at a time |
| 220 | +- Disabled steps represent a step that doesn't apply for the current workflow (previous step configuration disabled a future step which is now skipped) |
| 221 | +- Readonly steps are steps that don't have associated views for them (it's a step that just indicates something like disk formatted or software installed) |
| 222 | + |
| 223 | +### Accessibility |
| 224 | + |
| 225 | +<!-- *Consider the accessibility of the component, including:* |
| 226 | +
|
| 227 | +- *Keyboard Navigation and Focus* |
| 228 | +- *Form Input and Autofill* |
| 229 | +- *Use with Assistive Technology. For example:* |
| 230 | + - *All components should define a role and support labels / being labelled so that assistive technology can identify them* |
| 231 | + - *The implications shadow dom might have on how roles and attributes are presented in the accessibility tree* |
| 232 | + - *Components which delegate focus require all global ARIA attributes to be enumerated* |
| 233 | + - *Components should either follow an existing [ARIA Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/) or provide thorough research indicating why a new pattern is appropriate. Research should include sources like [Open UI Community Group](https://github.com/openui/open-ui) and other popular design systems.* |
| 234 | +- *Behavior with browser configurations like "Prefers reduced motion"* |
| 235 | +- *Support for standard link behaviors if the component is an anchor or contains an anchor. These behaviors are enumerated in the [anchor-patterns story](https://nimble.ni.dev/storybook/index.html?path=/docs/tests-anchor-patterns--docs). The story should be updated to include the new component.* --> |
| 236 | + |
| 237 | +Will follow the [ARIA WAI Forms: step-by-step indicator pattern](https://www.w3.org/WAI/tutorials/forms/multi-page/#using-step-by-step-indicator) with key elements of: |
| 238 | +- Items are in an ordered list |
| 239 | +- Visibly hidden text is used convey step state |
| 240 | + |
| 241 | +Otherwise standard keyboard accessibility and aria for buttons / links. |
| 242 | + |
| 243 | +### Mobile |
| 244 | + |
| 245 | +<!-- *Consider how the component will behave on mobile devices, including:* |
| 246 | +
|
| 247 | +- *Overflow behavior when screen space is constrained* |
| 248 | +- *Interactions that are affected by touch rather than a pointer device (e.g. hover)* |
| 249 | +- *Integration with common mobile experiences like native pickers, on-screen keyboards, and dictation* --> |
| 250 | + |
| 251 | +No additional support beyond discussion in API section on CSS sizing. |
| 252 | + |
| 253 | +### Globalization |
| 254 | + |
| 255 | +<!-- *Consider whether the component has any special globalization needs such as:* |
| 256 | +
|
| 257 | +- *Special RTL handling* |
| 258 | +- *Swapping of internal icons/visuals* |
| 259 | +- *Localization* --> |
| 260 | + |
| 261 | +Label providers for visibly hidden step states: |
| 262 | +- Reuse `popupIconError`, `popupIconWarning` |
| 263 | +- Add (for consistency but maybe unexpected naming): `popupIconComplete`, `popupIconCurrent` |
| 264 | + |
| 265 | +### Security |
| 266 | + |
| 267 | +<!-- *Are there any security implications surrounding the component?* --> |
| 268 | + |
| 269 | +No unique concerns. |
| 270 | + |
| 271 | +### Performance |
| 272 | + |
| 273 | +<!-- *Are there any performance pitfalls or challenges with implementing the component?* --> |
| 274 | + |
| 275 | +No unique concerns. |
| 276 | + |
| 277 | +### Dependencies |
| 278 | + |
| 279 | +<!-- *Will implementing the component require taking on any dependencies?* |
| 280 | +
|
| 281 | +- *3rd party libraries* |
| 282 | +- *Upcoming standards we need to polyfill* |
| 283 | +- *Dependencies on other fast components or utilities* |
| 284 | +
|
| 285 | +*Do any of these dependencies bring along an associated timeline?* --> |
| 286 | + |
| 287 | +N/A |
| 288 | + |
| 289 | +### Test Plan |
| 290 | + |
| 291 | +<!-- *What is the plan for testing the component, if different from the normal path? Note that the normal plan includes unit tests for basic state/behavior as well as end-to-end tests to validate the specific user stories described above.* --> |
| 292 | + |
| 293 | +No unique concerns. |
| 294 | + |
| 295 | +### Tooling |
| 296 | + |
| 297 | +<!-- *Are there any special considerations for tooling? Will tooling changes need to be made? Is there a special way to light up this component in our tooling that would be compelling for developers/designers?* --> |
| 298 | + |
| 299 | +N/A |
| 300 | + |
| 301 | +### Documentation |
| 302 | + |
| 303 | +<!-- *What additions or changes are needed for user documentation and demos? Are there any architectural/engineering docs we should create as well, perhaps due to some interesting technical challenge or design decisions related to this component?* --> |
| 304 | + |
| 305 | +No unique concerns. Use common link docs. |
| 306 | + |
| 307 | +## Open Issues |
| 308 | + |
| 309 | +<!-- *Highlight any open questions for discussion during the spec PR. Before the spec is approved these should typically be resolved with the answers being incorporated in the spec document.* --> |
| 310 | + |
| 311 | +None. |
0 commit comments