From 933c2b416be831ee2723bf961ed7dda3ca35cd72 Mon Sep 17 00:00:00 2001 From: rajsite Date: Wed, 14 Jan 2026 14:51:55 -0600 Subject: [PATCH 1/8] wip --- .../src/stepper/specs/README.md | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 packages/nimble-components/src/stepper/specs/README.md diff --git a/packages/nimble-components/src/stepper/specs/README.md b/packages/nimble-components/src/stepper/specs/README.md new file mode 100644 index 0000000000..176b9d8cac --- /dev/null +++ b/packages/nimble-components/src/stepper/specs/README.md @@ -0,0 +1,168 @@ +# Nimble Stepper + +## Overview + +The `nimble-stepper-group` and + +### Background + + +- *Relevant historical or background information* +- *Link to Interaction Design spec* +- *Link to Visual Design spec* +- *Link to relevant work items, related existing issues, etc.* + +### Containing Library + +*State whether this component be part of Nimble or Spright and provide justification or considerations leading to that decision.* + +### Non-goals + +*A list of use cases, features, or functionality which are **not** goals for the component.* + +### Features + +*A list of the key features unique to this component.* + +### Risks and Challenges + +*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?* + +### Prior Art/Examples + +- Carbon design system progress: https://carbondesignsystem.com/components/progress-indicator/usage/ + +*Screenshots and/or links to existing, canonical, or exemplary implementations of the component.* + +--- + +## Design + +*Describe the design of the component, thinking through several perspectives:* + +- *A customer using the component on a web page.* +- *A developer building an app with the component and interacting through HTML/CSS/JavaScript.* +- *A designer customizing the component.* + +*Include code snippets showing basic component use and any interesting configurations.* + +*For each section below, consider adding an "Alternatives" sub-section to describe any design alternatives and discuss why they were rejected.* + +### API + +*The key elements of the component's public API surface:* + +- *Component Name* +- *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* +- *Methods* +- *Events* +- *CSS Classes and CSS Custom Properties that affect the component* +- *How native CSS Properties (height, width, etc.) affect the component* + +*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.* + +### Anatomy + +*Outline the component structure with a diagram of its visual tree (shadow DOM). Enumerate key areas of visual customization, such as:* + +- *Slot Names* +- *Host Classes* +- *Slotted Content/Slotted Classes* +- *CSS Parts* + +### Native form integration + +*Describe the plan for custom element form integration or why it's not necessary.* + +*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).* + +### Angular integration + +*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.* + +### Blazor integration + +*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.* + +### Visual Appearance + +*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.* + +--- + +## Implementation + +*Important aspects of the planned implementation with careful consideration of web standards and integration.* + +*Highlight any alternative implementations you considered in each section.* + +*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.* + +### States + +*Key component states, valid state transitions, and how interactions trigger a state transition.* + +### Accessibility + +*Consider the accessibility of the component, including:* + +- *Keyboard Navigation and Focus* +- *Form Input and Autofill* +- *Use with Assistive Technology. For example:* + - *All components should define a role and support labels / being labelled so that assistive technology can identify them* + - *The implications shadow dom might have on how roles and attributes are presented in the accessibility tree* + - *Components which delegate focus require all global ARIA attributes to be enumerated* + - *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.* +- *Behavior with browser configurations like "Prefers reduced motion"* +- *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.* + +### Mobile + +*Consider how the component will behave on mobile devices, including:* + +- *Overflow behavior when screen space is constrained* +- *Interactions that are affected by touch rather than a pointer device (e.g. hover)* +- *Integration with common mobile experiences like native pickers, on-screen keyboards, and dictation* + +### Globalization + +*Consider whether the component has any special globalization needs such as:* + +- *Special RTL handling* +- *Swapping of internal icons/visuals* +- *Localization* + +### Security + +*Are there any security implications surrounding the component?* + +### Performance + +*Are there any performance pitfalls or challenges with implementing the component?* + +### Dependencies + +*Will implementing the component require taking on any dependencies?* + +- *3rd party libraries* +- *Upcoming standards we need to polyfill* +- *Dependencies on other fast components or utilities* + +*Do any of these dependencies bring along an associated timeline?* + +### Test Plan + +*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.* + +### Tooling + +*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?* + +### Documentation + +*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?* + +--- +## Open Issues + +*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.* \ No newline at end of file From ed63e9aaf2dffa3d2a3949724d31c0571eb68a66 Mon Sep 17 00:00:00 2001 From: rajsite <1588923+rajsite@users.noreply.github.com> Date: Thu, 15 Jan 2026 13:59:12 -0600 Subject: [PATCH 2/8] Update README.md --- packages/nimble-components/src/stepper/specs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nimble-components/src/stepper/specs/README.md b/packages/nimble-components/src/stepper/specs/README.md index 176b9d8cac..ee8dac37f8 100644 --- a/packages/nimble-components/src/stepper/specs/README.md +++ b/packages/nimble-components/src/stepper/specs/README.md @@ -30,7 +30,7 @@ The `nimble-stepper-group` and ### Prior Art/Examples -- Carbon design system progress: https://carbondesignsystem.com/components/progress-indicator/usage/ +- Carbon design system progress: *Screenshots and/or links to existing, canonical, or exemplary implementations of the component.* From 9e24651d601fa702cd7f237d31547c7f9a5a07db Mon Sep 17 00:00:00 2001 From: rajsite <1588923+rajsite@users.noreply.github.com> Date: Wed, 21 Jan 2026 17:47:07 -0600 Subject: [PATCH 3/8] wip --- .../src/stepper/specs/README.md | 75 +++++++++++++------ 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/packages/nimble-components/src/stepper/specs/README.md b/packages/nimble-components/src/stepper/specs/README.md index ee8dac37f8..a6299d6541 100644 --- a/packages/nimble-components/src/stepper/specs/README.md +++ b/packages/nimble-components/src/stepper/specs/README.md @@ -2,43 +2,54 @@ ## Overview -The `nimble-stepper-group` and +The `nimble-stepper`, `nimble-step`, and `nimble-anchor-step` elements. ### Background - + + +- Interaction Design: None +- Visual Design: + - [Nimble Components Stepper Figma](https://www.figma.com/design/PO9mFOu5BCl8aJvFchEeuN/Nimble_Components?node-id=11742-71097&p=f&t=U3UnPlU4awyN4ybh-0) + - [Config App Figma](https://www.figma.com/design/eG9PhYykbokYf1OBd8KLkn/Valinor?node-id=0-1&p=f&t=oRGYidVydXMcgj3I-0) ### Containing Library -*State whether this component be part of Nimble or Spright and provide justification or considerations leading to that decision.* + + +Nimble, general component ### Non-goals -*A list of use cases, features, or functionality which are **not** goals for the component.* - + + +- Very long lists of steps +- Non-linear steps + ### Features -*A list of the key features unique to this component.* +- Similar to a breadcrumb but with more visual states ### Risks and Challenges -*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?* + -### Prior Art/Examples +No known new risks or challenges -- Carbon design system progress: +### Prior Art / Examples -*Screenshots and/or links to existing, canonical, or exemplary implementations of the component.* - ---- +- Relevant design systems: + - [Carbon progress indicator](https://carbondesignsystem.com/components/progress-indicator/usage/) + - [Angular Material stepper](https://material.angular.dev/components/stepper/overview) + - [WAI Patterns step-by-step indicator](https://www.w3.org/WAI/tutorials/forms/multi-page/#using-step-by-step-indicator) + - [USDS step indicator](https://designsystem.digital.gov/components/step-indicator/) ## Design -*Describe the design of the component, thinking through several perspectives:* + + +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 a breadcrumb (i.e. collection of `nimble-anchor-step`). Each item has a severity state associated with it (potentially with extra detail messages to show) and the ability to show what state is the "current" selected step that the user is on. + +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) + ### API -*The key elements of the component's public API surface:* + + +- `nimble-stepper` +- *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* +- *Methods* +- *Events* +- *CSS Classes and CSS Custom Properties that affect the component* +- *How native CSS Properties (height, width, etc.) affect the component* ### Anatomy @@ -72,13 +95,17 @@ The `nimble-stepper-group` and ### Native form integration -*Describe the plan for custom element form integration or why it's not necessary.* + -*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).* +N/A ### Angular integration -*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.* + + +Angular `routerLink` integration for `nimble-anchor-step` ### Blazor integration @@ -118,11 +145,13 @@ The `nimble-stepper-group` and ### Mobile -*Consider how the component will behave on mobile devices, including:* + + +Overflow of `nimble-step-group` ### Globalization From b4e56178256acdac9f888e445fd86fa3d949c9a8 Mon Sep 17 00:00:00 2001 From: rajsite <1588923+rajsite@users.noreply.github.com> Date: Thu, 22 Jan 2026 16:53:48 -0600 Subject: [PATCH 4/8] WIP --- .../src/stepper/specs/README.md | 72 +++++++++++++++---- 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/packages/nimble-components/src/stepper/specs/README.md b/packages/nimble-components/src/stepper/specs/README.md index a6299d6541..e779f9ab9b 100644 --- a/packages/nimble-components/src/stepper/specs/README.md +++ b/packages/nimble-components/src/stepper/specs/README.md @@ -20,24 +20,24 @@ The `nimble-stepper`, `nimble-step`, and `nimble-anchor-step` elements. -Nimble, general component +Nimble: Stepper is a generic component not designed for a specific application / domain. ### Non-goals -- Very long lists of steps -- Non-linear steps +- Handling long lists of steps (10s+) +- Non-linear step progressions ### Features -- Similar to a breadcrumb but with more visual states +- Similar to a breadcrumb conceptually but with more visual states and not only link based. ### Risks and Challenges -No known new risks or challenges +No known new unique risks or challenges ### Prior Art / Examples @@ -59,10 +59,13 @@ No known new risks or challenges *For each section below, consider adding an "Alternatives" sub-section to describe any design alternatives and discuss why they were rejected.* --> -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 a breadcrumb (i.e. collection of `nimble-anchor-step`). Each item has a severity state associated with it (potentially with extra detail messages to show) and the ability to show what state is the "current" selected step that the user is on. +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 a breadcrumb (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. -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) +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). +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. + +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. ### API @@ -78,20 +81,61 @@ The `nimble-stepper` is just for layout, placing steps either horizontal or vert *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.* --> - `nimble-stepper` -- *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* -- *Methods* -- *Events* -- *CSS Classes and CSS Custom Properties that affect the component* -- *How native CSS Properties (height, width, etc.) affect the component* + - Attributes + - orientation: vertical / horizontal (aligned with radio group and wafer) + + - CSS native properties + - Will respond to width / height sizing (on the axis corresponding to orientation) and show overflow scroll buttons following the pattern of breadcrumb + - Slots + - default: supports `nimble-step` and `nimble-anchor-step` children + + +- `nimble-step` + - Attributes + - disabled: boolean (standard, i.e. visually disabled and interactions prevented) + - `disabled[appearance-readonly]`: (standard, i.e. visually not disabled, interactions prevented) + - readonly: boolean (standard, i.e. visually not disabled, interactions other than tab focus prevented) + - selected: boolean (visual change only, no behavior) (aligned with card button) + - severity: default / error / warning / success / information (aligned with icon) + - severity-text: string (if provided, only renders during warning, error, and information severity) + + - Slots + - default: supports nimble icons, will render inside the circle and have color controlled via css + - title: Title content (aligned with dialog) + - subtitle: Subtitle content (aligned with dialog) + + +- `nimble-anchor-step` + - Attributes + - Properties (not attribute reflected) + - Methods + - Events + - CSS custom properties + - CSS native properties + - Slots + - Parts + - Localizable labels ### Anatomy - + + +Merged above in API. ### Native form integration From 8205df414f1f7acebdbb199b7b10955320d5ba68 Mon Sep 17 00:00:00 2001 From: rajsite <1588923+rajsite@users.noreply.github.com> Date: Fri, 23 Jan 2026 19:07:42 -0600 Subject: [PATCH 5/8] WIP --- .../src/stepper/specs/README.md | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/packages/nimble-components/src/stepper/specs/README.md b/packages/nimble-components/src/stepper/specs/README.md index e779f9ab9b..cfe3b96303 100644 --- a/packages/nimble-components/src/stepper/specs/README.md +++ b/packages/nimble-components/src/stepper/specs/README.md @@ -26,7 +26,7 @@ Nimble: Stepper is a generic component not designed for a specific application / -- Handling long lists of steps (10s+) +- Handling long lists of steps (10+) - Non-linear step progressions ### Features @@ -103,13 +103,13 @@ The `step` elements will primarily render a provided nimble icon (and new nimble - severity: default / error / warning / success / information (aligned with icon) - severity-text: string (if provided, only renders during warning, error, and information severity) - Events - - CSS custom properties - - CSS native properties - --> + - click (aligned to button, not emitted on disable) + - Slots - - default: supports nimble icons, will render inside the circle and have color controlled via css + - default: supports nimble icons, will render inside the circle and have color controlled via iconColor token - title: Title content (aligned with dialog) - subtitle: Subtitle content (aligned with dialog) - Events - - CSS custom properties - - CSS native properties + - click (aligned to anchor-button, not emitted on disable) + - Slots - - Parts - - Localizable labels + - All `nimble-step` slots + ### Anatomy -Merged above in API. +Slots, parts, etc. merged above in API section. ### Native form integration @@ -143,7 +149,7 @@ Merged above in API. *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).* --> -N/A +N/A, control has no intrinsic "value" state. ### Angular integration @@ -153,11 +159,15 @@ Angular `routerLink` integration for `nimble-anchor-step` ### Blazor integration -*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.* + + +Open Question: We have not historically taken Blazor Router support into account. To align with Blazor conventions we'd want to 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)). Not sure how our current Blazor components behave with the router. ### Visual Appearance -*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.* + + +See figma linked in background. --- From a2ff31d0f226b31182bef7332ac6db7581b0c6e8 Mon Sep 17 00:00:00 2001 From: rajsite <1588923+rajsite@users.noreply.github.com> Date: Mon, 26 Jan 2026 15:13:23 -0600 Subject: [PATCH 6/8] WIP --- .../src/stepper/specs/README.md | 76 +++++++++++++------ 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/packages/nimble-components/src/stepper/specs/README.md b/packages/nimble-components/src/stepper/specs/README.md index cfe3b96303..46274a8fbd 100644 --- a/packages/nimble-components/src/stepper/specs/README.md +++ b/packages/nimble-components/src/stepper/specs/README.md @@ -59,7 +59,7 @@ No known new unique risks or challenges *For each section below, consider adding an "Alternatives" sub-section to describe any design alternatives and discuss why they were rejected.* --> -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 a breadcrumb (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. +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. 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). @@ -149,43 +149,52 @@ Slots, parts, etc. merged above in API section. *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).* --> -N/A, control has no intrinsic "value" state. +- Anchor related components will use native `` tag and forward attributes. +- control has no intrinsic "value" state, so not a form control +- control used for navigation, does not seem like a good candidate for form submit button behavior ### Angular integration -Angular `routerLink` integration for `nimble-anchor-step` +- Angular `routerLink` integration for `nimble-anchor-step`. +- No Angular Form integration. ### Blazor integration -Open Question: We have not historically taken Blazor Router support into account. To align with Blazor conventions we'd want to 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)). Not sure how our current Blazor components behave with the router. +- 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. +- 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. +- Current scope does not include specific considerations for Blazor Router / `NavLink` or `EditForm` / `ValidationSummary` support. ### Visual Appearance -See figma linked in background. +See figma linked in background section. --- ## Implementation -*Important aspects of the planned implementation with careful consideration of web standards and integration.* + + +No particularly interesting implementation concerns. Follows existing patterns around buttons and anchors. ### States -*Key component states, valid state transitions, and how interactions trigger a state transition.* + + +Nothing unique beyond what's captured in the API section. ### Accessibility -*Consider the accessibility of the component, including:* + + +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: +- Items are in an ordered list +- Visibly hidden text is used convey step state + +Otherwise standard keyboard accessibility and aria for buttons / links. ### Mobile @@ -205,47 +220,64 @@ See figma linked in background. - *Interactions that are affected by touch rather than a pointer device (e.g. hover)* - *Integration with common mobile experiences like native pickers, on-screen keyboards, and dictation* --> -Overflow of `nimble-step-group` +No additional support beyond discussion in API section on CSS sizing. ### Globalization -*Consider whether the component has any special globalization needs such as:* + + +Label providers for visibly hidden step states: +- Reuse `popupIconError`, `popupIconInformation`, `popupIconWarning` +- Add (for consistency but maybe unexpected naming): `popupIconComplete`, `popupIconCurrent` ### Security -*Are there any security implications surrounding the component?* + + +No unique concerns. ### Performance -*Are there any performance pitfalls or challenges with implementing the component?* + + +No unique concerns. ### Dependencies -*Will implementing the component require taking on any dependencies?* + + +N/A ### Test Plan -*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.* + + +No unique concerns. ### Tooling -*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?* + + +N/A ### Documentation -*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?* + + +No unique concerns. Use common link docs. ---- ## Open Issues -*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.* \ No newline at end of file + + +Visual design does not currently represent full matrix of states: `severity` x `selected` x `interaction` (hover, mouse down, tab focus). From f0734013fe66a986f8295da67dda563c4f3471b5 Mon Sep 17 00:00:00 2001 From: rajsite <1588923+rajsite@users.noreply.github.com> Date: Mon, 26 Jan 2026 15:18:33 -0600 Subject: [PATCH 7/8] tweaks --- packages/nimble-components/src/stepper/specs/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nimble-components/src/stepper/specs/README.md b/packages/nimble-components/src/stepper/specs/README.md index 46274a8fbd..21f3904311 100644 --- a/packages/nimble-components/src/stepper/specs/README.md +++ b/packages/nimble-components/src/stepper/specs/README.md @@ -31,7 +31,7 @@ Nimble: Stepper is a generic component not designed for a specific application / ### Features -- Similar to a breadcrumb conceptually but with more visual states and not only link based. +- Similar to a collection of card buttons / breadcrumb conceptually but with more visual states. ### Risks and Challenges @@ -119,7 +119,6 @@ The `step` elements will primarily render a provided nimble icon (and new nimble - Attributes - All `nimble-step` attributes - `` attributes (href, target, etc) - - Open question (for all anchors): Visual design of open in new window icon? Expected to slot in title? - href: null / undefined should behave like disabled (seems inconsistent across controls) From eb732db4789323f510a4bd433cacf02465444424 Mon Sep 17 00:00:00 2001 From: rajsite <1588923+rajsite@users.noreply.github.com> Date: Wed, 28 Jan 2026 11:49:04 -0600 Subject: [PATCH 8/8] feedback --- .../src/stepper/specs/README.md | 19 ++++++++++++++---- .../specs/stepper-interaction-bounds.png | Bin 0 -> 38278 bytes .../templates/component-interaction-design.md | 2 +- specs/templates/custom-component.md | 9 ++++----- specs/templates/fast-based-component.md | 7 +------ 5 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 packages/nimble-components/src/stepper/specs/stepper-interaction-bounds.png diff --git a/packages/nimble-components/src/stepper/specs/README.md b/packages/nimble-components/src/stepper/specs/README.md index 21f3904311..4982306e92 100644 --- a/packages/nimble-components/src/stepper/specs/README.md +++ b/packages/nimble-components/src/stepper/specs/README.md @@ -11,6 +11,7 @@ The `nimble-stepper`, `nimble-step`, and `nimble-anchor-step` elements. - *Link to relevant work items, related existing issues, etc.* --> +- Nimble issue: [#624](https://github.com/ni/nimble/issues/624) - Interaction Design: None - Visual Design: - [Nimble Components Stepper Figma](https://www.figma.com/design/PO9mFOu5BCl8aJvFchEeuN/Nimble_Components?node-id=11742-71097&p=f&t=U3UnPlU4awyN4ybh-0) @@ -27,7 +28,7 @@ Nimble: Stepper is a generic component not designed for a specific application / - Handling long lists of steps (10+) -- Non-linear step progressions +- 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. ### Features @@ -97,7 +98,6 @@ The `step` elements will primarily render a provided nimble icon (and new nimble - `nimble-step` - Attributes - disabled: boolean (standard, i.e. visually disabled and interactions prevented) - - `disabled[appearance-readonly]`: (standard, i.e. visually not disabled, interactions prevented) - readonly: boolean (standard, i.e. visually not disabled, interactions other than tab focus prevented) - selected: boolean (visual change only, no behavior) (aligned with card button) - severity: default / error / warning / success / information (aligned with icon) @@ -173,7 +173,15 @@ Slots, parts, etc. merged above in API section. See figma linked in background section. ---- +### Interactions + + + +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). + +See the blue areas in the following image as an example: + +![step interaction bounds](./stepper-interaction-bounds.png) ## Implementation @@ -189,7 +197,10 @@ No particularly interesting implementation concerns. Follows existing patterns a -Nothing unique beyond what's captured in the API section. +Some specific usage notes: +- Only one step should be marked selected at a time +- Disabled steps represent a step that doesn't apply for the current workflow (previous step configuration disabled a future step which is now skipped) +- 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) ### Accessibility diff --git a/packages/nimble-components/src/stepper/specs/stepper-interaction-bounds.png b/packages/nimble-components/src/stepper/specs/stepper-interaction-bounds.png new file mode 100644 index 0000000000000000000000000000000000000000..e69ee4cd547110c8af28424588eeb23b15a1a6be GIT binary patch literal 38278 zcmeFZdpwhG{P?ef6iMY&6!q?)2qm*}ER<5n`Al-2HpiLsI^iujq>wqEhB-{mHmoQr zInE3-bBJN)%-C#x^X~Kg{{H}m*D5& z;SqfJK-Ywa=OCGfXJ69cL)=e@F7?UWKl}Vm^t5>@y3fpU-yC$mYjBr`=W~L`|kAhi!UC&`S+&s)CCCo#HaVV>_^|eT0VZWePQObaoD@W69>|a&)q#AWBjiF z;h_(ew|!&w3o7K?fmJUVg&Ps(Dq2Rz6nn#$sB~ILsi8c>#2)HRU}X8r(t^HlpKI?Z zcpN)>`tRwTx5qL2{+?b9{H0SbZ(C<&Z2Vr{vE?6G&y1=nrTP}*{0dkCLVf$s=-X{E z1v`=C{eRn+K)LPBOW)d$*EzLC6&LufuC0N`nt~w>4GlvYmefI8nW2wYVc2aEPNr

hHGw6GF0TS4`|jS5mfoWzv4SsK)04;?$> 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 J