Skip to content
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

[EuiDataGrid] Provide row elements to wrap cells #5285

Conversation

chandlerprall
Copy link
Contributor

@chandlerprall chandlerprall commented Oct 19, 2021

Replaces #5213

Summary

Fixes #4474 and fixes #4483 by providing div[role=row]s to wrap the cells. This is done by portalling the cells into divs that are created on-demand. Technically this adds a side-effect to rendering which is a no-no, but the timing works out and doesn't add a noticeable delay.

@1Copenut I'd like help testing impact on screen readers & other assistive tech. AXE is happy, but that doesn't always mean Ship It 🦑

AXE before

Screen Shot 2021-09-23 at 1 29 17 PM

AXE after

Screen Shot 2021-09-23 at 1 29 27 PM

Checklist

- [ ] Check against all themes for compatibility in both light and dark modes
- [ ] Checked in mobile
- [ ] Checked in Chrome, Safari, Edge, and Firefox
- [ ] Props have proper autodocs and playground toggles
- [ ] Added documentation
- [ ] Checked Code Sandbox works for any docs examples

  • Added or updated jest tests
  • Checked for breaking changes and labeled appropriately
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

@chandlerprall chandlerprall changed the title Bug/4474 datagrid row accessibility alternate [EuiDataGrid] Provide row elements to wrap cells Oct 19, 2021
@chandlerprall
Copy link
Contributor Author

from #5213 (comment)

Design request if possible, and feel free to say "shove off", but can we also get "highlight" rows (opt-in functionality) to highlight an entire row both on selection and hover?

This PR brings back highlight-on-hover, the ability to highlight based on selection (& other criteria) can be followed up with, tracked by #4483 as that needs an addition to the API.

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5285/

Copy link
Contributor

@1Copenut 1Copenut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This version tested a lot better than the other version. I have a few additional suggestions that fall outside the scope of this PR with regard to screen reader announcements, but I'll file those as separate issue tickets.

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5285/

@chandlerprall
Copy link
Contributor Author

Pushed up a cypress test to validate all cells belong to a row or columnheader

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5285/

@cee-chen
Copy link
Member

cee-chen commented Nov 1, 2021

Looks like there's still 3 failing axe tests on datagrid pages that's causing the CI job to be red:

13:17:59 Errors on tp://localhost:9999/#/tabular-content/data-grid-styling-and-control
13:20:03 [landmark-unique]: Landmarks must have a unique role or role/label/title (i.e. accessible name) combination
13:20:03   Help: https://dequeuniversity.com/rules/axe/4.1/landmark-unique?application=axe-puppeteer
13:20:03   Elements:
13:20:03     - .euiPanel--paddingMedium.euiSplitPanel__inner.euiPanel--borderRadiusNone > div > .euiPanel--hasShadow.euiPanel--borderRadiusMedium.euiPanel--plain > .euiDataGrid__focusWrap[data-focus-lock-disabled="disabled"] > .euiDataGrid--bordersHorizontal.euiDataGrid--headerUnderline.euiDataGrid--rowHoverHighlight > .euiDataGrid__pagination > .euiFlexGroup--justifyContentSpaceBetween.euiFlexGroup--gutterLarge.euiFlexGroup--alignItemsCenter > .euiFlexItem--flexGrowZero.euiFlexItem:nth-child(2) > .euiPagination
13:20:03 Errors on tp://localhost:9999/#/tabular-content/data-grid-virtualization
13:20:16 [landmark-unique]: Landmarks must have a unique role or role/label/title (i.e. accessible name) combination
13:20:16   Help: https://dequeuniversity.com/rules/axe/4.1/landmark-unique?application=axe-puppeteer
13:20:16   Elements:
13:20:16     - .euiPanel--paddingMedium.euiSplitPanel__inner.euiPanel--plain > div > .euiDataGrid__focusWrap[data-focus-lock-disabled="disabled"] > .euiDataGrid.euiDataGrid--bordersAll.euiDataGrid--headerShade > .euiDataGrid__pagination > .euiFlexGroup--justifyContentSpaceBetween.euiFlexGroup--gutterLarge.euiFlexGroup--alignItemsCenter > .euiFlexItem--flexGrowZero.euiFlexItem:nth-child(2) > .euiPagination
13:20:16 Errors on tp://localhost:9999/#/tabular-content/data-grid-row-heights-options
13:20:26 [landmark-unique]: Landmarks must have a unique role or role/label/title (i.e. accessible name) combination
13:20:26   Help: https://dequeuniversity.com/rules/axe/4.1/landmark-unique?application=axe-puppeteer
13:20:26   Elements:
13:20:26     - #setting-a-default-height-and-line-height-for-rows > .euiPanel--borderRadiusMedium.euiPanel--hasBorder.euiPanel--flexGrowZero > .euiPanel--paddingMedium.euiSplitPanel__inner.euiPanel--plain > div > .euiDataGrid__focusWrap[data-focus-lock-disabled="disabled"] > .euiDataGrid.euiDataGrid--bordersAll.euiDataGrid--headerShade > .euiDataGrid__pagination > .euiFlexGroup--justifyContentSpaceBetween.euiFlexGroup--gutterLarge.euiFlexGroup--alignItemsCenter > .euiFlexItem--flexGrowZero.euiFlexItem:nth-child(2) > .euiPagination

They're likely related to pagination and not this PR however, so if you want feel free to re-add in these specific 3 datagrid pages to the axe ignore list and we can address the a11y issues in a separate PR!

@@ -673,13 +688,27 @@ export const EuiDataGridBody: FunctionComponent<EuiDataGridBodyProps> = (
finalWidth = window.innerWidth;
}

const [dataItemsRendered, setDataItemsRendered] = useState('');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not totally clear on what this dataItemsRendered or the data-itemsrendered attribute is being used for - is it just for Cypress testing? TBH, I'd almost rather do visual snapshot testing over this approach. 1) it feels like it'd be more intuitive to compare outputs & state, and 2) it wouldn't impact realtime performance

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was to provide a way for the test to determine when the rendering is stable. The hooks + virtualization means the shell of the grid + header row is rendered at the initial pass, but then a second (maybe even a third) pass is needed to draw the cells. I couldn't think of a non-hacky way to do this and everything in Cypress's docs + googling said there should be some signal in the DOM to wait for, so I added the data attribute with the virtualization state to hook into.

Totally open to other ideas!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh gotcha, sorry! I was totally off on what this was doing in that case, apologies (I thought it was a way of determining cell content 🙈)

I think my worry is potential impact for production grids with lots of data / if this bit of code is overengineered for its purpose. Alternatives:

  • Can we opt for a simple true/false bool after the first time onItemsRendered gets called instead?
  • Can we put a data-test-subj on our individual cells and check that the expected number of cells exists instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was anticipating this full information would be useful in future tests against virtualization. Scroll & verify the row&column indices, set the overscanCount prop and verify, etc.

Maybe, to handle the perf impacts as this does update the attribute quite aggressively (though I didn't notice any lag when testing), we enable this with a debug flag on the component? This could open/enable other console logs or other ways of exposing info around the inner workings.

A true/false flag may work, but some tests may need that flag to toggle back to false until reaching stability again.

Can we put a data-test-subj on our individual cells and check that the expected number of cells exists instead?

I can't find a (non-horrible hacky) way to have Cypress wait for a number of elements. We can select for [role=gridcell], but from what I can tell trying to wait for N of them is an anti-pattern. We could add a data-test-subj with ${row},${col} and select/wait for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a data-test-subj with ${row},${col} and select/wait for that.

Oo, I like this option a lot! A debug/cypress flag would be fine, but between the two I think the row,col data-test-subj is elegant and could be helpful in general / potentially even in prod debugging.

trying to wait for N of them is an anti-pattern

Ha I have yolo'd too many Cypress anti-patterns in my day attempting to wait for the flakily-un-waitable (recursive xhr polls waiting server side asynchronous cron jobs probably being my least favorite)... 🙈 I definitely appreciate the dialogue and compromise and think we have a few solid approaches here (for the future as well)!

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5285/

@cee-chen
Copy link
Member

cee-chen commented Nov 3, 2021

@chandlerprall Shoot sorry, you'll need to grab latest master to fix the failing a11y CI test as well to fix the merge conflicts I just made for you 🙈

Copy link
Member

@cee-chen cee-chen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM once latest master is merged in - really appreciate the new direction taken with the cell data-test-subjs, the diffs feel super clean to me now :)

src/components/datagrid/data_grid.spec.tsx Outdated Show resolved Hide resolved
src/components/datagrid/body/data_grid_row_manager.ts Outdated Show resolved Hide resolved
src/components/datagrid/body/data_grid_cell.tsx Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5285/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5285/

@chandlerprall chandlerprall merged commit 51cfbb7 into elastic:main Nov 5, 2021
@chandlerprall chandlerprall deleted the bug/4474-datagrid-row-accessibility-alternate branch November 5, 2021 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants