Date: Sat, 6 Dec 2025 21:12:39 -0600
Subject: [PATCH 5/7] Switch to spaces hard break
---
packages/eslint-config-nimble/lint.js | 5 ++++-
.../src/accordion/specs/IxD.md | 6 ++---
.../src/breadcrumb/specs/README.md | 22 +++++++++----------
.../src/spinner/specs/README.md | 18 +++++++--------
.../specs/cell-state-when-scrolling-hld.md | 20 ++++++++---------
.../src/table/specs/table-column-sort-hld.md | 6 ++---
.../specs/table-keyboard-navigation-hld.md | 4 ++--
.../src/wafer-map/specs/README.md | 8 +++----
8 files changed, 46 insertions(+), 43 deletions(-)
diff --git a/packages/eslint-config-nimble/lint.js b/packages/eslint-config-nimble/lint.js
index 80a99a9d0b..36b4ea9d5b 100644
--- a/packages/eslint-config-nimble/lint.js
+++ b/packages/eslint-config-nimble/lint.js
@@ -34,7 +34,10 @@ export const lintNimbleConfig = defineConfig([
{
basePath: resolve(import.meta.dirname, '../../'),
}
- ]
+ ],
+ 'markdown-preferences/hard-linebreak-style': ['error', {
+ style: 'spaces'
+ }]
},
}
]);
diff --git a/packages/nimble-components/src/accordion/specs/IxD.md b/packages/nimble-components/src/accordion/specs/IxD.md
index 739a3d073e..c7588c4edc 100644
--- a/packages/nimble-components/src/accordion/specs/IxD.md
+++ b/packages/nimble-components/src/accordion/specs/IxD.md
@@ -39,10 +39,10 @@ When not to use:
It is best practice to use one accordion with multiple sections over multiple accordions with one section.
-Do this:\
+Do this:

-Avoid this:\
+Avoid this:

#### Header Button
@@ -89,7 +89,7 @@ The client-user should be able to specify whether only one content panel can be
> NOTE:
-The client-user may need/want to have additional icon buttons, badge counts, or status indicators in the header. For example, an expand button:\
+The client-user may need/want to have additional icon buttons, badge counts, or status indicators in the header. For example, an expand button:

### Behavior
diff --git a/packages/nimble-components/src/breadcrumb/specs/README.md b/packages/nimble-components/src/breadcrumb/specs/README.md
index 2da4fc81f8..13ad4378c6 100644
--- a/packages/nimble-components/src/breadcrumb/specs/README.md
+++ b/packages/nimble-components/src/breadcrumb/specs/README.md
@@ -10,14 +10,14 @@ A breadcrumb component is used as a navigational aid, allowing users to maintain
### Use in SystemLink
-[F1792531: [Design System] Components for sl-breadcrumb-bar](https://dev.azure.com/ni/DevCentral/_workitems/edit/1792531)\
-Current SystemLink breadcrumb:\
-
\
-Future planned SystemLink breadcrumb ([see discussion here](https://teams.microsoft.com/l/message/19:8e5f3e80de8146d5aaecdc2112e89191@thread.skype/1642192016552?tenantId=87ba1f9a-44cd-43a6-b008-6fdb45a5204e&groupId=41626d4a-3f1f-49e2-abdc-f590be4a329d&parentMessageId=1642192016552&teamName=ASW%20SystemLink&channelName=UX&createdTime=1642192016552)):\
-The future/planned behavior of the SystemLink breadcrumb (where it's moved into the header, and won't include tab names) doesn't add any new requirements to this control.\
+[F1792531: [Design System] Components for sl-breadcrumb-bar](https://dev.azure.com/ni/DevCentral/_workitems/edit/1792531)
+Current SystemLink breadcrumb:
+
+Future planned SystemLink breadcrumb ([see discussion here](https://teams.microsoft.com/l/message/19:8e5f3e80de8146d5aaecdc2112e89191@thread.skype/1642192016552?tenantId=87ba1f9a-44cd-43a6-b008-6fdb45a5204e&groupId=41626d4a-3f1f-49e2-abdc-f590be4a329d&parentMessageId=1642192016552&teamName=ASW%20SystemLink&channelName=UX&createdTime=1642192016552)):
+The future/planned behavior of the SystemLink breadcrumb (where it's moved into the header, and won't include tab names) doesn't add any new requirements to this control.
-After uptaking the Nimble breadcrumb, SystemLink's breadcrumb will no longer include the `>` separator as part of the clickable link, which is a change from the current breadcrumb's behavior:\
+After uptaking the Nimble breadcrumb, SystemLink's breadcrumb will no longer include the `>` separator as part of the clickable link, which is a change from the current breadcrumb's behavior:
## Design
@@ -81,10 +81,10 @@ Component Name: `nimble-breadcrumb-item` (extends fast-foundation BreadcrumbItem
### Angular integration
-**NimbleBreadcrumbDirective**: Directive for selector `nimble-breadcrumb`.\
+**NimbleBreadcrumbDirective**: Directive for selector `nimble-breadcrumb`.
No attribute/property bindings.
-**NimbleBreadcrumbItemDirective**: Directive for selector `nimble-breadcrumb-item`.\
+**NimbleBreadcrumbItemDirective**: Directive for selector `nimble-breadcrumb-item`.
Attribute bindings for all `` properties inherited from fast-breadcrumb-item: `download`, `href`, `hreflang`, `ping`, `referrerpolicy`, `rel`, `target`, `type`.
- Nimble Anchor can share this directive once created - we'd probably name it `NimbleAnchorDirective` with selector `nimble-anchor,nimble-breadcrumb-item`.
@@ -103,8 +103,8 @@ When used in an Angular app, frequently the `[routerLink]` directive will be use
```
-As shown above, clients using [routerLink] can also set queryParams dynamically, pass state when the router navigates, etc.\
-[[routerLinkActive]](https://github.com/angular/angular/blob/0a2191f8e7e232087aab0a7a9eb9ee6871580267/packages/router/src/directives/router_link_active.ts) can also be used to add CSS classes on a link that points to the current page/ route.\
+As shown above, clients using [routerLink] can also set queryParams dynamically, pass state when the router navigates, etc.
+[[routerLinkActive]](https://github.com/angular/angular/blob/0a2191f8e7e232087aab0a7a9eb9ee6871580267/packages/router/src/directives/router_link_active.ts) can also be used to add CSS classes on a link that points to the current page/ route.
One use case for the Nimble breadcrumb is the [SystemLink sl-breadcrumb-bar, which already uses [routerLink]](https://ni.visualstudio.com/DevCentral/_git/Skyline?path=/Web/Workspaces/SystemLinkShared/projects/systemlink-lib-angular/src/sl-breadcrumb-bar/sl-breadcrumb-bar.component.html&version=GBmaster&line=4&lineEnd=5&lineStartColumn=1&lineEndColumn=1&lineStyle=plain&_a=contents).
Angular has 2 directives handling [routerLink]:
@@ -113,7 +113,7 @@ Angular has 2 directives handling [routerLink]:
- [RouterLinkWithHref](https://github.com/angular/angular/blob/0a2191f8e7e232087aab0a7a9eb9ee6871580267/packages/router/src/directives/router_link.ts#L257): Selector `a[routerLink],area[routerLink]`: Computes an href for the anchor element it targets; left-click does a router navigation; Ctrl-click and middle-mouse-button click defer to the browser (to open a new tab/window)
We want the behavior of RouterLinkWithHref, so we can subclass it and update the selector to target `nimble-breadcrumb-item`.
-However, if we have clients use the existing `routerLink` attribute to opt into our directive, there'll still be a RouterLink directive active doing the wrong action too. In current Angular versions there's not a good way to disable RouterLink navigation ([see the comment on this Angular commit](https://github.com/angular/angular/commit/ccb09b4558a3864fb5b2fe2214d08f1c1fe2758f)).\
+However, if we have clients use the existing `routerLink` attribute to opt into our directive, there'll still be a RouterLink directive active doing the wrong action too. In current Angular versions there's not a good way to disable RouterLink navigation ([see the comment on this Angular commit](https://github.com/angular/angular/commit/ccb09b4558a3864fb5b2fe2214d08f1c1fe2758f)).
We have a few options:
- **Current Plan**: Make our directive selector something like `nimble-breadcrumb-item[nimbleRouterLink]`, and add an `@Input nimbleRouterLink` to our subclass (which sets `routerLink`). This is a small change for clients which we can document, and other routerLink attributes can still be used as-is:
diff --git a/packages/nimble-components/src/spinner/specs/README.md b/packages/nimble-components/src/spinner/specs/README.md
index befd694d97..cde8daeddd 100644
--- a/packages/nimble-components/src/spinner/specs/README.md
+++ b/packages/nimble-components/src/spinner/specs/README.md
@@ -6,8 +6,8 @@ Spinner component (`nimble-spinner`): Indeterminate progress indicator / loading
### Background
-[Nimble spinner: #346](https://github.com/ni/nimble/issues/346)\
-[Nimble spinner design: #822](https://github.com/ni/nimble/issues/822)\
+[Nimble spinner: #346](https://github.com/ni/nimble/issues/346)
+[Nimble spinner design: #822](https://github.com/ni/nimble/issues/822)
[Visual Design spec - Adobe XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/dece308f-79e7-48ec-ab41-011f3376b49b/)
[Follow-up issue about PowerGreen/custom color variants: #916](https://github.com/ni/nimble/issues/916)
@@ -35,10 +35,10 @@ None
### Prior Art/Examples
-SystemLink Enterprise uses a spinner based on the Material `mat-spinner`:\
+SystemLink Enterprise uses a spinner based on the Material `mat-spinner`:

-A variant of this spinner design is already implemented in the Web Config tool written in Blazor:\
+A variant of this spinner design is already implemented in the Web Config tool written in Blazor:

## Design
@@ -77,17 +77,17 @@ Standard Blazor implementation (`NimbleSpinner` deriving from `ComponentBase`),
[Visual Design spec - Adobe XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/dece308f-79e7-48ec-ab41-011f3376b49b/)
-\
+
**Note:** 'Color UI Alt.' appearance is unsupported for the initial implementation, see the _Potential Future Enhancements_ section.
-When `prefers-reduced-motion` is enabled, a simplified version will be used:\
+When `prefers-reduced-motion` is enabled, a simplified version will be used:

## Implementation
Component implementation will derive from the FAST `FoundationElement`.
-**Alternatives Considered:** We could derive from `fast-progress-ring` (radial progress indicator, which supports an indeterminate progress display), however then our component API would also pick up the `min`/`max`/`value` properties for determinate progress (and `paused` to pause the indicator), which we don't plan on supporting at this time. Additionally, the visual appearance of our spinner will be a little different from a radial progress bar, and we still may end up supporting a standard radial progress bar in the future.\
+**Alternatives Considered:** We could derive from `fast-progress-ring` (radial progress indicator, which supports an indeterminate progress display), however then our component API would also pick up the `min`/`max`/`value` properties for determinate progress (and `paused` to pause the indicator), which we don't plan on supporting at this time. Additionally, the visual appearance of our spinner will be a little different from a radial progress bar, and we still may end up supporting a standard radial progress bar in the future.
For reference, the FAST spec for `progress` / `progress-ring` is [here](https://github.com/microsoft/fast/blob/802443ffb2b19a078f9b48f62e6d1a35e3276fb5/packages/web-components/fast-foundation/src/progress/README.md).
### States
@@ -98,7 +98,7 @@ Only one component state: visible and animating. Pausing not supported; spinner
No keyboard states / form integration.
-ARIA: We plan to use the [`progressbar role`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/progressbar_role) without setting `aria-valuemin` / `aria-valuemax` / `aria-valuenow` (representing indeterminate).\
+ARIA: We plan to use the [`progressbar role`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/progressbar_role) without setting `aria-valuemin` / `aria-valuemax` / `aria-valuenow` (representing indeterminate).
This matches the behavior of an indeterminate FAST progress ring (in which case min/max/value are unset) - see the [FAST template here](https://github.com/microsoft/fast/blob/802443ffb2b19a078f9b48f62e6d1a35e3276fb5/packages/web-components/fast-foundation/src/progress-ring/progress-ring.template.ts#L17).
`prefers-reduced-motion`: A simplified spinner indicator will be shown when this is enabled, see the Visual Appearance section.
@@ -123,7 +123,7 @@ None
### Test Plan
-Standard tests planned.\
+Standard tests planned.
[Chromatic is supposed to handle pausing CSS animations by default](https://www.chromatic.com/docs/animations), however we should verify that by ensuring the snapshots of the spinner show the same state across 2 Chromatic builds.
### Tooling
diff --git a/packages/nimble-components/src/table/specs/cell-state-when-scrolling-hld.md b/packages/nimble-components/src/table/specs/cell-state-when-scrolling-hld.md
index e018d4d66b..2717ba121d 100644
--- a/packages/nimble-components/src/table/specs/cell-state-when-scrolling-hld.md
+++ b/packages/nimble-components/src/table/specs/cell-state-when-scrolling-hld.md
@@ -28,16 +28,16 @@ We will not:
- See the "Alternative Implementations" section for additional information on this decision.
- Try and re-apply any state to the re-bound rows/cells after the scroll. That means that we won't re-focus the previously focused control in a cell / re-open an action menu, after a scroll operation.
-**Prototype:**\
-See [the prototype branch](https://github.com/ni/nimble/compare/%40ni/nimble-components_v18.8.0...table-cell-state-custom-elements-1) and the [prototype table Storybook](https://60e89457a987cf003efc0a5b-ktcaixsgzs.chromatic.com/?path=/story/table--table&args=data:LargeDataSet) to illustrate the concepts discussed in the following sections.\
+**Prototype:**
+See [the prototype branch](https://github.com/ni/nimble/compare/%40ni/nimble-components_v18.8.0...table-cell-state-custom-elements-1) and the [prototype table Storybook](https://60e89457a987cf003efc0a5b-ktcaixsgzs.chromatic.com/?path=/story/table--table&args=data:LargeDataSet) to illustrate the concepts discussed in the following sections.
As we don't yet support editable column types, the prototype Storybook updates the Last Name column to show text which can be focused by clicking on it. After clicking a Last Name cell value, you'll see the text get a green border as its focused styling. Once you scroll the table vertically, the green border goes away, and you'll see a `console.log` indicating that the new cell `focusedRecycleCallback` API was used.
### Blur Focused Controls in Cells
In this case, `document.activeElement` will be the Nimble `Table`, and `table.shadowRoot.activeElement` will be a Nimble `TableRow`. We can recursively look at the active element's `shadowRoot.activeElement`, starting from the TableRow, and stop when we reach a `TableCellView` (the custom element in table cells implemented by column plugin authors) or `null` (see [prototype](https://github.com/ni/nimble/compare/%40ni/nimble-components_v18.8.0...table-cell-state-custom-elements-1#diff-e2bfd4eda0a3c89f54b4e09624e6cfd5a68ea2f14c0e79f717eacce38ec5982bR124)).
-If we found a focused `TableCellView`, then we will call the new API `focusedRecycleCallback()` on it.\
-(Prototype: [TableCellView API](https://github.com/ni/nimble/compare/%40ni/nimble-components_v18.8.0...table-cell-state-custom-elements-1#diff-e307bbd379116ba5f5690332122a16b1fe392878b3899cbe487f98672766dcedR10), [calling focusedRecycleCallback() from virtualizer code](https://github.com/ni/nimble/compare/%40ni/nimble-components_v18.8.0...table-cell-state-custom-elements-1#diff-e2bfd4eda0a3c89f54b4e09624e6cfd5a68ea2f14c0e79f717eacce38ec5982bR130))\
+If we found a focused `TableCellView`, then we will call the new API `focusedRecycleCallback()` on it.
+(Prototype: [TableCellView API](https://github.com/ni/nimble/compare/%40ni/nimble-components_v18.8.0...table-cell-state-custom-elements-1#diff-e307bbd379116ba5f5690332122a16b1fe392878b3899cbe487f98672766dcedR10), [calling focusedRecycleCallback() from virtualizer code](https://github.com/ni/nimble/compare/%40ni/nimble-components_v18.8.0...table-cell-state-custom-elements-1#diff-e2bfd4eda0a3c89f54b4e09624e6cfd5a68ea2f14c0e79f717eacce38ec5982bR130))
Column plugins, in their derived versions of `TableCellView`, should generally override `focusedRecycleCallback()` if they have a focusable control - they can commit changes, and then blur the focusable control.
([Prototype:](https://github.com/ni/nimble/compare/%40ni/nimble-components_v18.8.0...table-cell-state-custom-elements-1#diff-d1db6a67f7353782eeb2c4769380687c9c1e70261dd7fb43960efe293cf04d97) A simplified column implementation that shows focusable text, and blurs it in the `focusedRecycleCallback` method.)
@@ -46,7 +46,7 @@ Column plugins, in their derived versions of `TableCellView`, should generally o
The table will handle this internally (in the `Virtualizer` class, via `handleVirtualizerChange()`), without affecting the TableColumn public API.
We want to close the action menu via the associated `MenuButton`, which allows the rest of the table logic dealing with action menus to get called normally.
-In this case, `table.shadowRoot.activeElement` will be null (since the action menus are slotted in), but `document.activeElement` will be a Nimble `MenuItem`. (We can also doublecheck that `table.contains(document.activeElement)` before proceeding.)\
+In this case, `table.shadowRoot.activeElement` will be null (since the action menus are slotted in), but `document.activeElement` will be a Nimble `MenuItem`. (We can also doublecheck that `table.contains(document.activeElement)` before proceeding.)
We have a few options:
- We can use `table.openActionMenuRecordId` to find the row with an open action menu (via `querySelector` as one option). `tableRow.currentActionMenuColumn` gives us the `TableColumn` with an open menu but no direct way to get to the associated cell (we may need to look at all cells in the row, and find the one with `cell.menuOpen` being `true`).
@@ -60,8 +60,8 @@ Once we have a `TableCell`, we can get the `MenuButton` for the cell, and call `
### Clearing Text Selection
-**Background Info:**\
-The DOM API for text selection is [`window.getSelection()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection), but unfortunately the text selection APIs are incomplete / inconsistent across browsers, once you're using them on DOM elements that use Shadow DOM ([StackOverflow reference](https://stackoverflow.com/a/70523247)). In the future there may be a `getComposedRange()` API added that works better with Shadow DOM, however it's not yet finalized and is not yet in any browsers ([webcomponents#79](https://github.com/WICG/webcomponents/issues/79), [getComposedRange() draft proposal](https://w3c.github.io/selection-api/#dom-selection-getcomposedrange), [feedback thread for proposal](https://github.com/w3c/selection-api/issues/161)).\
+**Background Info:**
+The DOM API for text selection is [`window.getSelection()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection), but unfortunately the text selection APIs are incomplete / inconsistent across browsers, once you're using them on DOM elements that use Shadow DOM ([StackOverflow reference](https://stackoverflow.com/a/70523247)). In the future there may be a `getComposedRange()` API added that works better with Shadow DOM, however it's not yet finalized and is not yet in any browsers ([webcomponents#79](https://github.com/WICG/webcomponents/issues/79), [getComposedRange() draft proposal](https://w3c.github.io/selection-api/#dom-selection-getcomposedrange), [feedback thread for proposal](https://github.com/w3c/selection-api/issues/161)).
Note: The specific problem is detecting whether the active text selection is (wholly or partially) within the table. Clearing the text selection, once we decide we want to, is always straightforward (`window.getSelection()?.removeAllRanges()`, `window.getSelection().removeRange(range)`).
There's several potential approaches to detecting if the table contains selected text, but none of them work in all cases / across all browsers. Given a [`Range` instance](https://developer.mozilla.org/en-US/docs/Web/API/Range) (`window.getSelection().getRangeAt(n)`):
@@ -84,20 +84,20 @@ There's several potential approaches to detecting if the table contains selected
**Possible Implementation Plan: Detecting Table Text Selection**
-To check if the table contains selected text:\
+To check if the table contains selected text:
Get `window.getSelection()`. If null or `rangeCount === 0`, no text is selected. Otherwise, for each `Range`:
- Check if `startContainer`/`endContainer` is the `nimble-table`
- Else, do the `compareBoundaryPoints` check (in a `try/catch`)
- Else, check if `startContainer`/`endContainer` has the `nimble-table` as an ancestor
-If any of those `Range` checks succeed, remove that `Range` from the selection.\
+If any of those `Range` checks succeed, remove that `Range` from the selection.
_Limitations:_
- If text is selected in the table but outside rows (e.g. column header text), it will also be cleared when the user scrolls. (There's not a good way to differentiate the text location that works in each browser.)
- (Safari only) If text selection is partially in the table and partially before/ after it, there isn't any way for us to detect that case. So Safari will still have text incorrectly selected after the scroll in that case.
-_API:_\
+_API:_
This logic will be in the Nimble Virtualizer class, called from `handleVirtualizerChange()` (called when the user scrolls). It will apply to all Nimble tables / all column types, without an opt-out option.
**Conclusion**: Since the code required to detect table selection is problematic (`try/catch`) and complex, doesn't work fully in Safari, and is potentially fragile, we currently don't plan to try and detect table text selection.
diff --git a/packages/nimble-components/src/table/specs/table-column-sort-hld.md b/packages/nimble-components/src/table/specs/table-column-sort-hld.md
index 27df74ae47..f06ac94c58 100644
--- a/packages/nimble-components/src/table/specs/table-column-sort-hld.md
+++ b/packages/nimble-components/src/table/specs/table-column-sort-hld.md
@@ -88,7 +88,7 @@ When a column is sorted interactively, either by clicking on the column header o
### Interactive Sorting UX
-The UX/ interactions for interactive sorting are captured in [#885: UX Design for basic column/row interactions](https://github.com/ni/nimble/issues/885).\
+The UX/ interactions for interactive sorting are captured in [#885: UX Design for basic column/row interactions](https://github.com/ni/nimble/issues/885).
To summarize:
Single-clicking a column header will cycle the column from unsorted, to ascending sort, descending sort, then back to unsorted.
@@ -103,8 +103,8 @@ Shift-clicking a column header will cycle the column from unsorted, to ascending
- If the clicked column is transitioning to being sorted, it will get a `currentSortIndex` of `0` if no other columns were already sorted, or `n` if there were `n` other columns already sorted
If sorting is enabled for a column, sorting menu items also appear in the column header menu:
-\
-If sorting is disabled for a column, and no other enabled items are in the column header menu, the column header menu button will not appear.\
+
+If sorting is disabled for a column, and no other enabled items are in the column header menu, the column header menu button will not appear.
Updating sorting via the menu will always unsort any other columns that were already sorted, even when the current column is being unsorted too.
For columns with `sorting-disabled` set to true:
diff --git a/packages/nimble-components/src/table/specs/table-keyboard-navigation-hld.md b/packages/nimble-components/src/table/specs/table-keyboard-navigation-hld.md
index 107c77091b..59a4aad152 100644
--- a/packages/nimble-components/src/table/specs/table-keyboard-navigation-hld.md
+++ b/packages/nimble-components/src/table/specs/table-keyboard-navigation-hld.md
@@ -27,14 +27,14 @@ Some noteworthy aspects of the treegrid pattern are:
> ARIA: "One reason it is important for all cells to be able to receive or contain keyboard focus is that screen readers will typically be in their application reading mode, rather than their document reading mode, when users are interacting with the grid. While in application mode, a screen reader user hears only focusable elements and content that labels focusable elements. So, screen reader users may unknowingly overlook elements contained in a treegrid that are either not focusable or not used to label a column or row."
2. The `Tab` key moves focus between the focusable elements in a row (not the cells). When focus has reached the end (or beginning of the row), a continued `Tab` (or `Shift-Tab`) will move focus outside of the table.
-3. When a cell has multiple interactive elements, or editable content, the user needs a way to leave navigation mode to interact with the cell (`Enter` and `F2` are suggested), and a way to return to navigation mode (`Esc`, also `Enter` for editable content).\
+3. When a cell has multiple interactive elements, or editable content, the user needs a way to leave navigation mode to interact with the cell (`Enter` and `F2` are suggested), and a way to return to navigation mode (`Esc`, also `Enter` for editable content).
(Note: The `treegrid` and `grid` guidance are identical here.)
If the above guidelines are adhered to, technologies like screen readers should be able to handle navigating through the table in an expected fashion.
There's also guidance about whether cells themselves, or the elements inside the cells, should be focused:
-> ARIA: "For assistive technology users, the quality of experience when navigating a grid heavily depends on both what a cell contains and on where keyboard focus is set. For example, if a cell contains a button and a grid navigation key places focus on the cell instead of the button, screen readers announce the button label but do not tell users a button is present.\
+> ARIA: "For assistive technology users, the quality of experience when navigating a grid heavily depends on both what a cell contains and on where keyboard focus is set. For example, if a cell contains a button and a grid navigation key places focus on the cell instead of the button, screen readers announce the button label but do not tell users a button is present.
> There are two optimal cell design and focus behavior combinations:
>
> - When a cell contains _one widget_ whose operation _does not require arrow keys_, the grid navigation keys **will set focus on that widget**. Examples of such widgets include link, button, menubutton, toggle button, radio button (not radio group), switch, and checkbox.
diff --git a/packages/nimble-components/src/wafer-map/specs/README.md b/packages/nimble-components/src/wafer-map/specs/README.md
index 4c13c64ad9..61008dc3ab 100644
--- a/packages/nimble-components/src/wafer-map/specs/README.md
+++ b/packages/nimble-components/src/wafer-map/specs/README.md
@@ -84,7 +84,7 @@ _The key elements of the component's public API surface:_
- Component Name: `nimble-wafer-map`
- Props/Attrs:
- - `dies` - this represents the input data, an array of `WaferMapDie`, which fills the wafer map with content.\
+ - `dies` - this represents the input data, an array of `WaferMapDie`, which fills the wafer map with content.
The **WaferMapDie** object contains the following attributes:
- x: number
- y: number
@@ -100,9 +100,9 @@ _The key elements of the component's public API surface:_
- `gridMinY` - represents the Y coordinate of the minimum corner of the the grid bounding box for rendering the wafer map. Leaving the value `undefined` will set the value to the minimum Y value of the bounding box of the input dies coordinates.
- `gridMaxX` - represents the X coordinate of the maximum corner of the the grid bounding box for rendering the wafer map. Leaving the value `undefined` will set the value to the maximum X value of the bounding box of the input dies coordinates.
- `gridMaxY` - represents the Y coordinate of the maximum corner of the the grid bounding box for rendering the wafer map. Leaving the value `undefined` will set the value to the maximum Y value of the bounding box of the input dies coordinates.
- - `colorScale` - represents the color spectrum which shows the status of the dies on the wafer.\
+ - `colorScale` - represents the color spectrum which shows the status of the dies on the wafer.
The objects we use internally for the colorScale are [d3.scaleOrdinal](https://observablehq.com/@d3/d3-scaleordinal) and [d3.scaleLinear](https://observablehq.com/@d3/d3-scalelinear). Basically, what this does is it associates a specific string (or in our case a value) with a specific color. The values which are not specified in the array, will be calculated as a interpolation from the provided colors for the linear scale or will be assigned to one of the specified color values from the provided colors for the ordinal scale.
- In the following example the colorScale object is defined as `WaferMapColorScale(['red', 'blue', 'green'], [1, 2, 8]);` and uses an internal linear scale\
+ In the following example the colorScale object is defined as `WaferMapColorScale(['red', 'blue', 'green'], [1, 2, 8]);` and uses an internal linear scale
The generated wafer using this color scale is: 
- `maxCharacters` - represents the number of characters allowed to be displayed within a single die, including the label suffix. As the die values are strings, we must have the liberty of limiting how many characters we are willing to display within a single die.
- `dieLabelsHidden` - a boolean value that determines if the die labels in the wafer map view are shown or not. Default value is false.
@@ -217,7 +217,7 @@ Whenever the loading of the wafer data (can and will happen in case we have many
### Accessibility
-Important: this is out of scope for the current implementation.\
+Important: this is out of scope for the current implementation.
Since the `nimble-wafer-map` component was designed to display tens of thousands of data points, it's challenging to provide Accessibility functionality which can read out loud the values displayed in a meaningful manner.
Based on the WAI documentation on [Complex Images](https://www.w3.org/WAI/tutorials/images/complex/), in the future we could provide a paragraph containing information about the name of the wafer that is displayed, the LOT where the wafer comes from and a general overview (e.g. % of the faulty dies on the wafer) of the status. This might give a pretty good description about what the displayed nimble component shows to the user. In order to achieve this, the ["img"](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/img_role) role will be set for the `` tag.
Please note that in the initial implementation we do not plan to gather and summarize any of this information so this will be part of future updates to this component.
From 27907ab0b7cfa70a02e5b0328e34f747e9690744 Mon Sep 17 00:00:00 2001
From: rajsite
Date: Sat, 6 Dec 2025 21:35:51 -0600
Subject: [PATCH 6/7] Manually apply space break changes
---
CONTRIBUTING.md | 4 ++--
docs/nimble-spright-requirements-adr.md | 6 +++---
specs/labels-and-localization/README.md | 6 +++---
specs/nimble-blazor/blazor-net8-upgrade-hld.md | 4 ++--
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0ee8f9bd78..93df46fef6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -74,8 +74,8 @@ Bare minimum requirements for each library (though components in each library ar
| Minimal tech debt | 🟢 | 🟡 | 🟡 |
| Mobile support | 🟡 | 🟡 | 🟡 |
-🟢 = required\
-🟡 = optional\
+🟢 = required
+🟡 = optional
\* = By an interaction and / or visual designer
### Adding a new component
diff --git a/docs/nimble-spright-requirements-adr.md b/docs/nimble-spright-requirements-adr.md
index 550696a626..ff3391e17f 100644
--- a/docs/nimble-spright-requirements-adr.md
+++ b/docs/nimble-spright-requirements-adr.md
@@ -51,9 +51,9 @@ The following table compares the requirements for developing a component in diff
| `nimble-components` (incubating) | 🟢 | 🟢 | 🟢 | 🟢 | 🟡 | 🟡 | 🟢 | 🟡 | 🟡 | 🟡 | 🟡
| `spright-components` | 🟢 | 🟢 | 🟢 | 🟢 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡
-🟢 = required\
-🟡 = optional\
-*SB = Storybook\
+🟢 = required
+🟡 = optional
+*SB = Storybook
**By an interaction and/or visual designer
## Consequences
diff --git a/specs/labels-and-localization/README.md b/specs/labels-and-localization/README.md
index a0f0cdde55..f34b0b2571 100644
--- a/specs/labels-and-localization/README.md
+++ b/specs/labels-and-localization/README.md
@@ -121,12 +121,12 @@ We'll define a base class (prototype: [i18n-base.ts](https://github.com/ni/nimbl
**nimble-angular**
-Each label-provider will have its own Angular directive and module (prototype: [nimble-i18n-core.directive](https://github.com/ni/nimble/blob/cf6a2e1ae010d00dc7253c25658dd5a17b5f6215/angular-workspace/projects/ni/nimble-angular/i18n/core/nimble-i18n-core.directive.ts) and [nimble-i18n-core.module](https://github.com/ni/nimble/blob/cf6a2e1ae010d00dc7253c25658dd5a17b5f6215/angular-workspace/projects/ni/nimble-angular/i18n/core/nimble-i18n-core.module.ts) for `label-provider-core`.)\
+Each label-provider will have its own Angular directive and module (prototype: [nimble-i18n-core.directive](https://github.com/ni/nimble/blob/cf6a2e1ae010d00dc7253c25658dd5a17b5f6215/angular-workspace/projects/ni/nimble-angular/i18n/core/nimble-i18n-core.directive.ts) and [nimble-i18n-core.module](https://github.com/ni/nimble/blob/cf6a2e1ae010d00dc7253c25658dd5a17b5f6215/angular-workspace/projects/ni/nimble-angular/i18n/core/nimble-i18n-core.module.ts) for `label-provider-core`.)
We will probably also want to create secondary entry points in nimble-angular for each label-provider, which ensures that client apps won't necessary pull in all the Nimble labels from all label providers (unless they import them explicitly).
In order to make it easy/automatic for clients to pick up new localized strings/labels when they uptake new nimble-angular versions, each label-provider has an additional directive that will set all of the Nimble-defined labels/strings, using Angular's `$localize` function on the English strings.
-Prototype: [nimble-i18n-core-with-defaults.directive](https://github.com/ni/nimble/blob/cf6a2e1ae010d00dc7253c25658dd5a17b5f6215/angular-workspace/projects/ni/nimble-angular/i18n/core/nimble-i18n-core-with-defaults.directive.ts)\
+Prototype: [nimble-i18n-core-with-defaults.directive](https://github.com/ni/nimble/blob/cf6a2e1ae010d00dc7253c25658dd5a17b5f6215/angular-workspace/projects/ni/nimble-angular/i18n/core/nimble-i18n-core-with-defaults.directive.ts)
If we define descriptions for each string, we can include it so it appears in the message files, such as: ``$localize`:Nimble number-field increment button label:Increment` ``.
For each label-provider that an Angular app will use:
@@ -147,7 +147,7 @@ We expect most apps in SystemLink to consume both `nimble-label-provider-core` a
We can consider codegen-ing the Angular directives, which would let us avoid copy-pasting the English strings/ descriptions at the nimble-angular level, but at the expense of obfucscating some of the code (in the generator scripts).
-**nimble-blazor**\
+**nimble-blazor**
We currently don't have a good solution for Blazor clients to automatically pick up or localize our labels/strings.
We do still plan to create Razor components for each label-provider, so that Blazor clients can manually specify/localize the labels if desired.
diff --git a/specs/nimble-blazor/blazor-net8-upgrade-hld.md b/specs/nimble-blazor/blazor-net8-upgrade-hld.md
index ce7b6b4050..967ca41b97 100644
--- a/specs/nimble-blazor/blazor-net8-upgrade-hld.md
+++ b/specs/nimble-blazor/blazor-net8-upgrade-hld.md
@@ -84,8 +84,8 @@ Once we update to target .NET 8, remaining .NET 6 clients of Nimble Blazor can o
### Target both .NET 6 and .NET 8
-It's possible for .NET projects to [target multiple framework versions](https://learn.microsoft.com/en-us/dotnet/standard/frameworks#how-to-specify-a-target-framework), meaning we could target both .NET 6 and .NET 8 with the following `csproj` configuration:\
-`net8.0;net6.0`
+It's possible for .NET projects to [target multiple framework versions](https://learn.microsoft.com/en-us/dotnet/standard/frameworks#how-to-specify-a-target-framework), meaning we could target both .NET 6 and .NET 8 with the following `csproj` configuration:
+`net8.0;net6.0`
We've elected not to do this for the following reasons:
- Additional maintenance burden. Each target framework version can specify different dependencies/ dependency versions - we'd probably depend on different versions of `Microsoft.AspNetCore.Components.Web` for each .NET version, for example. This approach would require separate testing going forward. We would most likely need different JS initialization scripts for each .NET version (also implying that all of our Playwright tests would need to run against both versions).
From ec0d33055ea427e17f682ddc1e5ac0b1ef224426 Mon Sep 17 00:00:00 2001
From: Milan Raj
Date: Mon, 8 Dec 2025 16:31:01 -0600
Subject: [PATCH 7/7] Update packages/nimble-components/CONTRIBUTING.md
---
packages/nimble-components/CONTRIBUTING.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/nimble-components/CONTRIBUTING.md b/packages/nimble-components/CONTRIBUTING.md
index 7ce4787677..1a20ab15e4 100644
--- a/packages/nimble-components/CONTRIBUTING.md
+++ b/packages/nimble-components/CONTRIBUTING.md
@@ -452,7 +452,7 @@ Test utilties located in [`/src/utilities/tests`](/packages/nimble-components/sr
#### Fixtures
-The jasmine unit tests utilize [`fixture.ts`](/packages/nimble-components/src/utilities/tests/fixture.ts) for component tests. The fixture utility gives tools for managing the component lifecycle. For some usage examples see [`fixture.spec.ts`](/packages/ok-components/src/utilities/tests/tests/fixture.spec.ts).
+The jasmine unit tests utilize [`fixture.ts`](/packages/nimble-components/src/utilities/tests/fixture.ts) for component tests. The fixture utility gives tools for managing the component lifecycle. For some usage examples see [`fixture.spec.ts`](/packages/nimble-components/src/utilities/tests/tests/fixture.spec.ts).
### Disabling tests