-
Notifications
You must be signed in to change notification settings - Fork 8
Mapping anchor column HLD #2533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,197 @@ | ||||||||||
# Mapping Anchor Table Column | ||||||||||
|
||||||||||
## Overview | ||||||||||
|
||||||||||
The `nimble-table-column-mapping-anchor` is a component that supports rendering specific number, boolean, or string values as an icon or a spinner, with an accompanying text anchor element. The mappings are defined by child elements of `nimble-mapping-icon`, `nimble-mapping-spinner`, or `nimble-mapping-empty`. | ||||||||||
|
||||||||||
### Background | ||||||||||
|
||||||||||
[Icon with anchor column](https://github.com/ni/nimble/issues/2531) | ||||||||||
|
||||||||||
### Features | ||||||||||
|
||||||||||
- Supported input: | ||||||||||
- string | ||||||||||
- number | ||||||||||
- boolean | ||||||||||
Comment on lines
+13
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This statement is a bit confusing (at least to me). Since there are multiple inputs to the column that support different types, it might be more helpful to split out the "Supported input" section into what is supported for a given input. Something like:
|
||||||||||
- Supported output: | ||||||||||
- Icon with text link | ||||||||||
- Spinner with text link | ||||||||||
- text link | ||||||||||
|
||||||||||
### Non-goals | ||||||||||
|
||||||||||
- Non-Nimble icon support | ||||||||||
- Arbitrary icon colors | ||||||||||
- Non-icon, non-spinner Nimble components | ||||||||||
- Specifying different text for an icon/spinner's label than the overall text of the mapping | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lol, I think that is the exact goal of this PR, to specify text outside the mapping :P There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe Milan's right, that's the main reason we created that issue. The current requirement is to have both the text next to the icon, as well as the text displayed in the tooltip when hovered over display the same text. If a different decision is taken for this feature, I would like to get the confirmation of the PO first that this is acceptable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops...that was just a copy-pasta goof. |
||||||||||
|
||||||||||
--- | ||||||||||
|
||||||||||
## Design | ||||||||||
|
||||||||||
Below is an example of how these elements would be used within a `nimble-table`: | ||||||||||
|
||||||||||
```HTML | ||||||||||
<nimble-table> | ||||||||||
<nimble-table-column-mapping-anchor field-name="status" key-type="string" label-field-name="status" href-field-name="status-url"> | ||||||||||
Status | ||||||||||
<nimble-mapping-icon key="fail" icon="nimble-icon-xmark" severity="error" text="Failed"></nimble-mapping-icon> | ||||||||||
<nimble-mapping-icon key="error" icon="nimble-icon-xmark" severity="error" text="Errored"></nimble-mapping-icon> | ||||||||||
<nimble-mapping-icon key="pass" icon="nimble-icon-check" severity="success" text="Passed"></nimble-mapping-icon> | ||||||||||
<nimble-mapping-spinner key="running" text="Running"></nimble-mapping-spinner> | ||||||||||
</nimble-table-column-mapping-anchor> | ||||||||||
</nimble-table> | ||||||||||
``` | ||||||||||
|
||||||||||
The notable distinction between this column type and the `nimble-table-column-mapping` is the `label-field-name` and `href-field-name` attributes, and the absence of supporting the `nimble-mapping-text` as one of its mapping types. The two new attributes are aligned with the `nimble-table-column-anchor` API, and provide the fields in the table record for the text and URL for the displayed link. The `nimble-mapping-text` mapping will not be supported as it seems unnecessary for the use-cases needed. | ||||||||||
|
||||||||||
See the [Mapping Table Column spec](./table-column-mapping.md#design), and the [Anchor Table Column spec](./table-column-anchor-hld.md#implementation--design) for more details related to the design. | ||||||||||
|
||||||||||
### API | ||||||||||
|
||||||||||
#### Enum column element: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Suggested change
|
||||||||||
|
||||||||||
_Component Name_ | ||||||||||
|
||||||||||
- `nimble-table-column-mapping-anchor` | ||||||||||
|
||||||||||
_Props/Attrs_ | ||||||||||
|
||||||||||
##### Attributes inherited from TableColumnEnumBase | ||||||||||
|
||||||||||
- `field-name`: string | ||||||||||
- `key-type`: 'string' | 'number' | 'boolean' | ||||||||||
|
||||||||||
##### Attributes "copied" from TableColumnAnchor (intend to move to mixin) | ||||||||||
|
||||||||||
- `label-field-name`: string | ||||||||||
- `href-field-name`: string | ||||||||||
- `appearance`: string | ||||||||||
- `underline-hidden`: string | ||||||||||
- `hreflang` | ||||||||||
- `ping` | ||||||||||
- `referrerpolicy` | ||||||||||
- `rel` | ||||||||||
- `target` | ||||||||||
- `type` | ||||||||||
- `download` | ||||||||||
Comment on lines
+66
to
+78
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might too much detail for HLD but was thinking:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool. I think I'll leave that out of this HLD. May want to discuss details of this idea out-of-band. |
||||||||||
|
||||||||||
Attributes from [`FractionalWidth`](https://github.com/ni/nimble/blob/main/packages/nimble-components/src/table-column/mixins/fractional-width-column.ts), [`GroupableColumn`](https://github.com/ni/nimble/blob/main/packages/nimble-components/src/table-column/mixins/groupable-column.ts), and [`Placeholder`](https://github.com/ni/nimble/blob/main/packages/nimble-components/src/table-column/mixins/placeholder.ts) mixins. | ||||||||||
|
||||||||||
_Content_ | ||||||||||
|
||||||||||
- column title (icon and/or text) | ||||||||||
- 1 or more `nimble-mapping-icon`, `nimble-mapping-spinner`, or `nimble-mapping-empty` elements | ||||||||||
|
||||||||||
### Cell Template | ||||||||||
|
||||||||||
The cell template will essentially be a combination of the `TableColumnMappingCellView` and `TableColumnAnchorCellView`. | ||||||||||
|
||||||||||
```html | ||||||||||
<span class="reserve-icon-size"> ${x => x.visualizationTemplate} </span> | ||||||||||
When cellRecord.href present | ||||||||||
<nimble-anchor | ||||||||||
href="${x => x.cellRecord.href}" | ||||||||||
hreflang="${x => x.columnConfig.hreflang}" | ||||||||||
ping="${x => x.columnConfig.ping}" | ||||||||||
referrerpolicy="${x => x.columnConfig.referrerpolicy}" | ||||||||||
rel="${x => x.columnConfig.rel}" | ||||||||||
target="${x => x.columnConfig.target}" | ||||||||||
type="${x => x.columnConfig.type}" | ||||||||||
download="${x => x.columnConfig.download}" | ||||||||||
underline-hidden | ||||||||||
@mouseover="${(x, c) => setTitleWhenOverflow(...)}" | ||||||||||
@mouseout="${(x, c) => removeTitle(...)}" | ||||||||||
> | ||||||||||
${cellState.cellRecord.label ?? cellState.cellRecord.href} | ||||||||||
</nimble-anchor> | ||||||||||
When cellRecord.href is missing | ||||||||||
<span | ||||||||||
@mouseover="${(x, c) => setTitleWhenOverflow(...)}" | ||||||||||
@mouseout="${(_x, c) => removeTitle(...)}" | ||||||||||
> | ||||||||||
${cellState.cellRecord.label} | ||||||||||
</span> | ||||||||||
``` | ||||||||||
|
||||||||||
### Sorting | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a similar section for grouping behavior? |
||||||||||
|
||||||||||
Sorting will be based on the record value, following what is described in the [Mapping Table Column spec](./table-column-mapping.md#sorting), meaning the column will ultimately be sorted according to the icon "value" and not by the label or URL (as it is with the anchor column). | ||||||||||
|
||||||||||
### Sizing | ||||||||||
|
||||||||||
The column should support the same sizing modes as the text column, which is fractional widths plus minimum pixel widths. | ||||||||||
|
||||||||||
### Keyboard Interactions | ||||||||||
|
||||||||||
Arrowing to a anchor table cell should focus the link (if it is actually a link and not just a text span). Pressing `Enter` on a focused link will trigger navigation. | ||||||||||
|
||||||||||
### Accessibility Roles | ||||||||||
|
||||||||||
In the accessibility tree, the cells of an anchor column are instances of [`nimble-table-cell`](https://github.com/ni/nimble/blob/f663c38741e731bef91aa58e8fb2d1cec653b679/packages/nimble-components/src/table/components/cell/template.ts#L6) which has a `role` of [`cell`](https://w3c.github.io/aria/#cell). The cell then has a child `nimble-anchor`, which has a `role` of [`link`](https://w3c.github.io/aria/#link). | ||||||||||
|
||||||||||
### Angular integration | ||||||||||
|
||||||||||
Angular directives will be created for the column component. No component has form association, so a `ControlValueAccessor` will not be created. | ||||||||||
|
||||||||||
#### Angular Routing support | ||||||||||
|
||||||||||
Using the `TableColumnAnchor` in Angular requires the use of the [`NavigationGuard`](https://github.com/ni/nimble/blob/main/packages/angular-workspace/nimble-angular/table-column/anchor/nimble-table-column-anchor-navigation-guard.directive.ts) in order to allow proper routing within the Angular application. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this say "Using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think the intention was something along the lines of |
||||||||||
|
||||||||||
### Blazor integration | ||||||||||
|
||||||||||
Blazor wrappers will be created for the components. Columns will be generic in the type of the key, and will cascade that type parameter to contained mapping elements (see [`CascadingTypeParameter`](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/generic-type-support?view=aspnetcore-7.0#cascaded-generic-type-support)): | ||||||||||
|
||||||||||
```HTML | ||||||||||
<NimbleTableColumnMappingAnchor TKey=string Field="Status" LabelField="StatusField" HrefField="StatusURL"> | ||||||||||
<NimbleMappingIcon | ||||||||||
Key="@("success")" | ||||||||||
Icon="nimble-icon-check" | ||||||||||
Severity="IconSeverity.Success"> | ||||||||||
</NimbleMappingIcon> | ||||||||||
<NimbleMappingSpinner | ||||||||||
Key=@("calculating")> | ||||||||||
</NimbleMappingSpinner> | ||||||||||
</NimbleTableColumnMapping> | ||||||||||
``` | ||||||||||
|
||||||||||
### Globalization | ||||||||||
|
||||||||||
All text will be provided by the client and is expected to be localized. | ||||||||||
|
||||||||||
### Security | ||||||||||
|
||||||||||
N/A | ||||||||||
|
||||||||||
### Performance | ||||||||||
|
||||||||||
N/A | ||||||||||
|
||||||||||
### Dependencies | ||||||||||
|
||||||||||
None | ||||||||||
|
||||||||||
### Test Plan | ||||||||||
|
||||||||||
- Unit tests will be written verifying the usual component expectations, plus: | ||||||||||
- renders mapping matching the cell value (string, number, and boolean) | ||||||||||
- nothing rendered when value matches no mappings | ||||||||||
- validation error when non-unique mapping keys exist | ||||||||||
- validation error when invalid icon name given | ||||||||||
- grouping header for icon column includes text | ||||||||||
- Verify manually that the column content appears in the accessibility tree and can be read by a screen reader. | ||||||||||
- Verify manually that several mapping columns with thousands of elements scrolls performantly. | ||||||||||
- Visual Chromatic tests will be created | ||||||||||
|
||||||||||
### Tooling | ||||||||||
|
||||||||||
N/A | ||||||||||
|
||||||||||
### Documentation | ||||||||||
|
||||||||||
Documented in Storybook | ||||||||||
|
||||||||||
--- | ||||||||||
|
||||||||||
## Open Issues | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we think we will have a visual design pass? My biggest question was how an icon + icon text + link should look together @fredvisser There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we should support both plain text and a hyperlink in this column (which would make the need for a design moot).
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The icon with it's text description is our recommended configuration: https://nimble.ni.dev/storybook/index.html?path=/docs/components-table-column-mapping--docs#choosing-a-mapping-style It is conceptual mapping + metadata. The mapping is ideally icon + text but can also be just icon. They together describe the state. The metadata is a hyperlink, plain text, or placeholder text.
I didn't think I agree, the metadata is a distinct thing from the icon, I.e. state of a system itself vs link to error log. I think some concrete examples would help me understand your proposals There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be stale information, but I thought one of the goals was to have a compact icon-only representation while still seeing per-row status information in a tooltip. From the Proposed Solution on #2531:
I assume in this case the desire would be to have the icon be clickable. We could push back on that if we think it's not a good direction, but I can see it being useful for the same reasons that If this is something we support, it'd be another visual design question about how to present the mapping text and the per-row label in the same tooltip. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That is not the goal I'm aware of or aligned with discussions in offline threads. To reproduce those resolved discussions here:
I do not think a This could change with a rich toggle tip that has already defined patterns around keyboard + touch + mouse interactions for rich content in the toggle tip (anchors), but that does not exist yet / is not on the backlog in any expected timeframe. And I'd argue at least for this use case there is more value in seeing descriptive text in the table at a glance vs requiring an interaction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depending on which way we go on visual design, if we end up not wanting to show icon text for the icon mappings I propose we enforce that with validation. Require in mapping validation that all the icon mappings have "text-hidden" true (as opposed to ignoring the attribute on the mapping or creating a new icon mapping that does not have the unused attribute). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once this is closer to ready for approval, we should add Stefan as a required reviewer.