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

[TreeView] Focus selected when tree receives focus #20205

Closed
wants to merge 1 commit into from
Closed

[TreeView] Focus selected when tree receives focus #20205

wants to merge 1 commit into from

Conversation

tonyhallett
Copy link
Contributor

@tonyhallett tonyhallett commented Mar 21, 2020

In addition to making the tree view agree with aria practices this pull request also resolves some other outstanding issues.

TreeItem hijacks focus when typing on an input box that updates it
This code is present in this codesandbox that replicates the one in the issue. The steps below that result in the issue behaviour as seen in the original sandbox are no longer an issue.

  1. Focus apples
  2. Type b in the input ( to remove apples )
  3. Remove the search - apples is focused

TreeView programmatic focus does not change tab indices inconsistent behaviour is no longer an issue as it selection and not last focus that determines what is focused when the tree receives focus ( as per aria practices ).

TreeView cannot be controlled by keyboard after item removal is also no longer an issue.

Note that there is no longer a need for tabbable state.

Remarks on the tests :
Tests that conditionally render a tree item have to render a span - due to bug
I corrected the tests regarding this focus behaviour - but perhaps the tests should be in TreeView.test.js instead of TreeItem.test.js.

Remarks on the code :
The aria practices does not describe what should happen if the tree receives focus and the selected tree item is in a collapsed parent. I decided to expand the tree to make it visible for now ( I have not raised the event - if this behaviour is agreed I will change ), the alternative is to focus the first item.
https://github.com/tonyhallett/material-ui/blob/bebcef3ff8da24ee3daa04eed50d095da585ef89/packages/material-ui-lab/src/TreeView/TreeView.js#L483

The clean up of selected can probably be improved upon.
https://github.com/tonyhallett/material-ui/blob/bebcef3ff8da24ee3daa04eed50d095da585ef89/packages/material-ui-lab/src/TreeView/TreeView.js#L514

When a focused item is removed I have decided to refocus the tree view. I can change this to making the TreeView tabbable again.
https://github.com/tonyhallett/material-ui/blob/bebcef3ff8da24ee3daa04eed50d095da585ef89/packages/material-ui-lab/src/TreeView/TreeView.js#L574

You can see this code on this sandbox

@mui-pr-bot
Copy link

@material-ui/lab: parsed: +0.39% , gzip: +0.43%

Details of bundle changes.

Comparing: 978381d...bebcef3

Details of page changes
bundle Size Change Size Gzip Change Gzip
/performance/table-emotion ▲ +10 B (+0.34% ) 2.97 kB -- -1 B
/_app -- 33.9 kB -- -1 B
/api-docs/alert-title -- 1.14 kB -- -1 B
/api-docs/alert -- 2.15 kB -- -1 B
/api-docs/app-bar -- 1.69 kB -- -1 B
/api-docs/autocomplete -- 3.89 kB -- -1 B
/api-docs/avatar-group -- 1.26 kB -- -1 B
/api-docs/avatar -- 1.61 kB -- -1 B
/api-docs/backdrop -- 1.38 kB -- -1 B
/api-docs/badge -- 1.88 kB -- -1 B
/api-docs/bottom-navigation-action -- 1.55 kB -- -1 B
/api-docs/bottom-navigation -- 1.43 kB -- -1 B
/api-docs/breadcrumbs -- 1.59 kB -- -1 B
/api-docs/button-base -- 2.08 kB -- -1 B
/api-docs/button-group -- 1.95 kB -- -1 B
/api-docs/button -- 2.32 kB -- -1 B
/api-docs/card-action-area -- 1.32 kB -- -1 B
/api-docs/card-actions -- 1.22 kB -- -1 B
/api-docs/card-content -- 1.2 kB -- -1 B
/api-docs/card-header -- 1.53 kB -- -1 B
/api-docs/card-media -- 1.43 kB -- -1 B
/api-docs/card -- 1.25 kB -- -1 B
/api-docs/checkbox -- 2.07 kB -- -1 B
/api-docs/chip -- 2.19 kB -- -1 B
/api-docs/circular-progress -- 1.8 kB -- -1 B
/api-docs/click-away-listener -- 1.13 kB -- -1 B
/api-docs/collapse -- 1.76 kB -- -1 B
/api-docs/container -- 1.62 kB -- -1 B
/api-docs/css-baseline -- 1.14 kB -- -1 B
/api-docs/dialog-actions -- 1.22 kB -- -1 B
/api-docs/dialog-content-text -- 1.23 kB -- -1 B
/api-docs/dialog-content -- 1.2 kB -- -1 B
/api-docs/dialog-title -- 1.26 kB -- -1 B
/api-docs/dialog -- 2.48 kB -- -1 B
/api-docs/divider -- 1.55 kB -- -1 B
/api-docs/drawer -- 1.87 kB -- -1 B
/api-docs/expansion-panel-actions -- 1.25 kB -- -1 B
/api-docs/expansion-panel-details -- 1.18 kB -- -1 B
/api-docs/expansion-panel-summary -- 1.46 kB -- -1 B
/api-docs/expansion-panel -- 1.7 kB -- -1 B
/api-docs/fab -- 1.86 kB -- -1 B
/api-docs/fade -- 1.17 kB -- -1 B
/api-docs/filled-input -- 2.65 kB -- -1 B
/api-docs/form-control-label -- 1.73 kB -- -1 B
/api-docs/form-control -- 2.1 kB -- -1 B
/api-docs/form-group -- 1.3 kB -- -1 B
/api-docs/form-helper-text -- 1.66 kB -- -1 B
/api-docs/form-label -- 1.59 kB -- -1 B
/api-docs/grid-list-tile-bar -- 1.54 kB -- -1 B
/api-docs/grid-list-tile -- 1.46 kB -- -1 B
/api-docs/grid-list -- 1.37 kB -- -1 B
/api-docs/grid -- 2.29 kB -- -1 B
/api-docs/grow -- 1.23 kB -- -1 B
/api-docs/hidden -- 1.32 kB -- -1 B
/api-docs/icon-button -- 1.85 kB -- -1 B
/api-docs/icon -- 1.54 kB -- -1 B
/api-docs/input-adornment -- 1.68 kB -- -1 B
/api-docs/input-base -- 2.74 kB -- -1 B
/api-docs/input-label -- 1.82 kB -- -1 B
/api-docs/input -- 2.61 kB -- -1 B
/api-docs/linear-progress -- 1.78 kB -- -1 B
/api-docs/link -- 1.68 kB -- -1 B
/api-docs/list-item-avatar -- 1.25 kB -- -1 B
/api-docs/list-item-icon -- 1.27 kB -- -1 B
/api-docs/list-item-secondary-action -- 1.22 kB -- -1 B
/api-docs/list-item-text -- 1.54 kB -- -1 B
/api-docs/list-item -- 2 kB -- -1 B
/api-docs/list-subheader -- 1.51 kB -- -1 B
/api-docs/list -- 1.44 kB -- -1 B
/api-docs/menu-item -- 1.46 kB -- -1 B
/api-docs/menu-list -- 1.33 kB -- -1 B
/api-docs/menu -- 2.12 kB -- -1 B
/api-docs/mobile-stepper -- 1.67 kB -- -1 B
/api-docs/modal -- 2.14 kB -- -1 B
/api-docs/native-select -- 1.83 kB -- -1 B
/api-docs/no-ssr -- 1.09 kB -- -1 B
/api-docs/outlined-input -- 2.76 kB -- -1 B
/api-docs/pagination-item -- 1.71 kB -- -1 B
/api-docs/pagination -- 1.98 kB -- -1 B
/api-docs/paper -- 1.61 kB -- -1 B
/api-docs/popover -- 2.5 kB -- -1 B
/api-docs/popper -- 1.76 kB -- -1 B
/api-docs/portal -- 1.12 kB -- -1 B
/api-docs/radio-group -- 1.2 kB -- -1 B
/api-docs/radio -- 1.89 kB -- -1 B
/api-docs/rating -- 2.25 kB -- -1 B
/api-docs/root-ref -- 1.2 kB -- -1 B
/api-docs/scoped-css-baseline -- 1.15 kB -- -1 B
/api-docs/select -- 2.65 kB -- -1 B
/api-docs/skeleton -- 1.52 kB -- -1 B
/api-docs/slide -- 1.31 kB -- -1 B
/api-docs/slider -- 2.85 kB -- -1 B
/api-docs/snackbar-content -- 1.36 kB -- -1 B
/api-docs/snackbar -- 2.46 kB -- -1 B
/api-docs/speed-dial-action -- 1.67 kB -- -1 B
/api-docs/speed-dial-icon -- 1.29 kB -- -1 B
/api-docs/speed-dial -- 2.05 kB -- -1 B
/api-docs/step-button -- 1.38 kB -- -1 B
/api-docs/step-connector -- 1.29 kB -- -1 B
/api-docs/step-content -- 1.47 kB -- -1 B
/api-docs/step-icon -- 1.33 kB -- -1 B
/api-docs/step-label -- 1.64 kB -- -1 B
/api-docs/step -- 1.38 kB -- -1 B
/api-docs/stepper -- 1.6 kB -- -1 B
/api-docs/svg-icon -- 2.01 kB -- -1 B
/api-docs/swipeable-drawer -- 1.78 kB -- -1 B
/api-docs/switch -- 2.22 kB -- -1 B
/api-docs/tab -- 1.74 kB -- -1 B
/api-docs/table-body -- 1.21 kB -- -1 B
/api-docs/table-cell -- 1.87 kB -- -1 B
/api-docs/table-container -- 1.22 kB -- -1 B
/api-docs/table-footer -- 1.22 kB -- -1 B
/api-docs/table-head -- 1.21 kB -- -1 B
/api-docs/table-pagination -- 2.21 kB -- -1 B
/api-docs/table-row -- 1.43 kB -- -1 B
/api-docs/table-sort-label -- 1.57 kB -- -1 B
/api-docs/table -- 1.43 kB -- -1 B
/api-docs/tabs -- 2.28 kB -- -1 B
/api-docs/text-field -- 2.94 kB -- -1 B
/api-docs/textarea-autosize -- 908 B -- -1 B
/api-docs/toggle-button-group -- 1.56 kB -- -1 B
/api-docs/toggle-button -- 1.55 kB -- -1 B
/api-docs/toolbar -- 1.4 kB -- -1 B
/api-docs/tooltip -- 2.3 kB -- -1 B
/api-docs/tree-item -- 1.53 kB -- -1 B
/api-docs/tree-view -- 1.67 kB -- -1 B
/api-docs/typography -- 2.33 kB -- -1 B
/api-docs/zoom -- 1.19 kB -- -1 B
/blog/2019-developer-survey-results -- 5.97 kB -- -1 B
/blog/2019 -- 3.86 kB -- -1 B
/blog/april-2019-update -- 2.75 kB -- -1 B
/blog/august-2019-update -- 1.86 kB -- -1 B
/blog/december-2019-update -- 2 kB -- -1 B
/blog/july-2019-update -- 1.75 kB -- -1 B
/blog/june-2019-update -- 1.62 kB -- -1 B
/blog/march-2019-update -- 2.15 kB -- -1 B
/blog/material-ui-v1-is-out -- 6.28 kB -- -1 B
/blog/material-ui-v4-is-out -- 9.31 kB -- -1 B
/blog/may-2019-update -- 1.95 kB -- -1 B
/blog/november-2019-update -- 2.36 kB -- -1 B
/blog/october-2019-update -- 2.1 kB -- -1 B
/blog/september-2019-update -- 2.29 kB -- -1 B
/company/about -- 1.56 kB -- -1 B
/company/contact -- 1.14 kB -- -1 B
/company/jobs -- 1.15 kB -- -1 B
/company/software-engineer -- 5.07 kB -- -1 B
/components/about-the-lab -- 3.19 kB -- -1 B
/components/alert -- 11.1 kB -- -1 B
/components/app-bar -- 30.9 kB -- -1 B
/components/autocomplete -- 106 kB -- -1 B
/components/avatars -- 8.5 kB -- -1 B
/components/backdrop -- 3.52 kB -- -1 B
/components/badges -- 14.2 kB -- -1 B
/components/bottom-navigation -- 6.22 kB -- -1 B
/components/box -- 7.96 kB -- -1 B
/components/breadcrumbs -- 14.4 kB -- -1 B
/components/button-group -- 6.56 kB -- -1 B
/components/buttons -- 17.6 kB -- -1 B
/components/cards -- 16.8 kB -- -1 B
/components/checkboxes -- 16.8 kB -- -1 B
/components/chips -- 21.6 kB -- -1 B
/components/click-away-listener -- 3.39 kB -- -1 B
/components/container -- 3.6 kB -- -1 B
/components/css-baseline -- 5.86 kB -- -1 B
/components/dialogs -- 42.1 kB -- -1 B
/components/dividers -- 12.1 kB -- -1 B
/components/drawers -- 29.4 kB -- -1 B
/components/expansion-panels -- 20.1 kB -- -1 B
/components/floating-action-button -- 10.2 kB -- -1 B
/components/grid-list -- 11.9 kB -- -1 B
/components/grid -- 33.4 kB -- -1 B
/components/hidden -- 10.5 kB -- -1 B
/components/icons -- 22.3 kB -- -1 B
/components/links -- 6.83 kB -- -1 B
/components/lists -- 33 kB -- -1 B
/components/material-icons -- 707 kB -- -1 B
/components/menus -- 23.3 kB -- -1 B
/components/modal -- 11.5 kB -- -1 B
/components/no-ssr -- 5.02 kB -- -1 B
/components/pagination -- 6.75 kB -- -1 B
/components/paper -- 3.34 kB -- -1 B
/components/pickers -- 38.1 kB -- -1 B
/components/popover -- 14.7 kB -- -1 B
/components/popper -- 22.5 kB -- -1 B
/components/portal -- 3.29 kB -- -1 B
/components/progress -- 21.8 kB -- -1 B
/components/radio-buttons -- 15.5 kB -- -1 B
/components/rating -- 10.7 kB -- -1 B
/components/selects -- 25.2 kB -- -1 B
/components/skeleton -- 10.1 kB -- -1 B
/components/slider -- 14.5 kB -- -1 B
/components/snackbars -- 24.8 kB -- -1 B
/components/speed-dial -- 14.5 kB -- -1 B
/components/steppers -- 35.9 kB -- -1 B
/components/switches -- 16.3 kB -- -1 B
/components/tables -- 176 kB -- -1 B
/components/tabs -- 19.3 kB -- -1 B
/components/text-fields -- 53 kB -- -1 B
/components/textarea-autosize -- 2.81 kB -- -1 B
/components/toggle-button -- 10.6 kB -- -1 B
/components/tooltips -- 17.3 kB -- -1 B
/components/transfer-list -- 9.3 kB -- -1 B
/components/transitions -- 10.8 kB -- -1 B
/components/tree-view -- 11.1 kB -- -1 B
/components/typography -- 9.67 kB -- -1 B
/components/use-media-query -- 13.1 kB -- -1 B
/customization/breakpoints -- 15.2 kB -- -1 B
/customization/color -- 21.6 kB -- -1 B
/customization/components -- 37.9 kB -- -1 B
/customization/default-theme -- 7.99 kB -- -1 B
/customization/density -- 9.16 kB -- -1 B
/customization/globals -- 4.65 kB -- -1 B
/customization/palette -- 11.8 kB -- -1 B
/customization/spacing -- 2.51 kB -- -1 B
/customization/theming -- 17.4 kB -- -1 B
/customization/typography -- 10.9 kB -- -1 B
/customization/z-index -- 3.03 kB -- -1 B
/discover-more/backers -- 2.89 kB -- -1 B
/discover-more/changelog -- 1.37 kB -- -1 B
/discover-more/languages -- 3.32 kB -- -1 B
/discover-more/related-projects -- 6.02 kB -- -1 B
/discover-more/roadmap -- 3.67 kB -- -1 B
/discover-more/showcase -- 13.3 kB -- -1 B
/discover-more/team -- 6.51 kB -- -1 B
/discover-more/vision -- 7.03 kB -- -1 B
/getting-started/example-projects -- 6.17 kB -- -1 B
/getting-started/faq -- 31.8 kB -- -1 B
/getting-started/installation -- 7.05 kB -- -1 B
/getting-started/learn -- 7.88 kB -- -1 B
/getting-started/support -- 9.7 kB -- -1 B
/getting-started/supported-components -- 6.19 kB -- -1 B
/getting-started/supported-platforms -- 5.69 kB -- -1 B
/getting-started/templates -- 8.1 kB -- -1 B
/getting-started/templates/album -- 5.65 kB -- -1 B
/getting-started/templates/blog -- 7.43 kB -- -1 B
/getting-started/templates/checkout -- 11.2 kB -- -1 B
/getting-started/templates/dashboard -- 8.55 kB -- -1 B
/getting-started/templates/pricing -- 7.86 kB -- -1 B
/getting-started/templates/sign-in-side -- 9.31 kB -- -1 B
/getting-started/templates/sign-in -- 9.54 kB -- -1 B
/getting-started/templates/sign-up -- 9.65 kB -- -1 B
/getting-started/templates/sticky-footer -- 1.54 kB -- -1 B
/getting-started/usage -- 9.38 kB -- -1 B
/guides/api -- 17.4 kB -- -1 B
/guides/composition -- 14 kB -- -1 B
/guides/flow -- 2.21 kB -- -1 B
/guides/interoperability -- 10.8 kB -- -1 B
/guides/localization -- 19.7 kB -- -1 B
/guides/migration-v0x -- 7.23 kB -- -1 B
/guides/migration-v3 -- 20.8 kB -- -1 B
/guides/minimizing-bundle-size -- 8.86 kB -- -1 B
/guides/responsive-ui -- 4.16 kB -- -1 B
/guides/right-to-left -- 6.7 kB -- -1 B
/guides/server-rendering -- 8.38 kB -- -1 B
/guides/testing -- 8.33 kB -- -1 B
/guides/typescript -- 12.8 kB -- -1 B
/performance/table-component -- 1.44 kB -- -1 B
/performance/table-hook -- 2.22 kB -- -1 B
/performance/table-mui -- 4.41 kB -- -1 B
/performance/table-raw -- 613 B -- -1 B
/performance/table-styled-components -- 2.61 kB -- -1 B
/premium-themes/onepirate -- 7.11 kB -- -1 B
/premium-themes/onepirate/forgot-password -- 1.01 kB -- -1 B
/premium-themes/onepirate/privacy -- 4.44 kB -- -1 B
/premium-themes/onepirate/sign-in -- 1.07 kB -- -1 B
/premium-themes/onepirate/sign-up -- 1.12 kB -- -1 B
/premium-themes/onepirate/terms -- 11.8 kB -- -1 B
/premium-themes/paperbase -- 8.72 kB -- -1 B
/styles/advanced -- 30.2 kB -- -1 B
/styles/api -- 16 kB -- -1 B
/styles/basics -- 17.2 kB -- -1 B
/system/api -- 5.85 kB -- -1 B
/system/basics -- 25.2 kB -- -1 B
/system/borders -- 4.04 kB -- -1 B
/system/display -- 6.2 kB -- -1 B
/system/flexbox -- 5.71 kB -- -1 B
/system/palette -- 4.29 kB -- -1 B
/system/positions -- 2.46 kB -- -1 B
/system/shadows -- 3.44 kB -- -1 B
/system/sizing -- 3.34 kB -- -1 B
/system/spacing -- 6.05 kB -- -1 B
/system/typography -- 4.22 kB -- -1 B
/versions -- 22.7 kB -- -1 B
docs:chunk:shared -- 68.2 kB -- -1 B
docs:shared:chunk/commons -- 5.99 kB -- -1 B
docs:shared:chunk/framework -- 42.3 kB -- -1 B
docs:shared:runtime/main -- 6.78 kB -- -1 B
docs:shared:runtime/webpack -- 1.24 kB -- -1 B
bundle Size Change Size Gzip Change Gzip
TreeView ▲ +1.05 kB (+1.47% ) 72.6 kB ▲ +325 B (+1.45% ) 22.7 kB
@material-ui/lab ▲ +792 B (+0.39% ) 202 kB ▲ +254 B (+0.43% ) 59.9 kB
TreeItem ▲ +85 B (+0.11% ) 78.6 kB ▲ +23 B (+0.09% ) 24.8 kB
NativeSelect -- 80.1 kB ▲ +8 B (+0.03% ) 25.3 kB
ButtonBase -- 77.3 kB ▲ +7 B (+0.03% ) 24.2 kB
Slide -- 29.1 kB ▼ -7 B (-0.07% ) 9.77 kB
ButtonGroup -- 86.5 kB ▲ +6 B (+0.02% ) 26.6 kB
ListItem -- 80.4 kB ▲ +6 B (+0.02% ) 25.1 kB
Menu -- 91.8 kB ▲ +6 B (+0.02% ) 28.3 kB
MenuItem -- 81.4 kB ▲ +6 B (+0.02% ) 25.4 kB
Select -- 119 kB ▼ -6 B (-0.02% ) 35.3 kB
InputBase -- 74 kB ▲ +5 B (+0.02% ) 23.2 kB
Popover -- 86.3 kB ▲ +5 B (+0.02% ) 26.7 kB
Snackbar -- 78.6 kB ▲ +5 B (+0.02% ) 24.5 kB
SpeedDial -- 89.5 kB ▲ +5 B (+0.02% ) 28.3 kB
@material-ui/core -- 360 kB ▼ -4 B (-0.00% ) 99 kB
FilledInput -- 76.9 kB ▲ +4 B (+0.02% ) 23.9 kB
Grow -- 27.7 kB ▲ +4 B (+0.04% ) 9.25 kB
styles/createMuiTheme -- 20.9 kB ▼ -4 B (-0.06% ) 7.26 kB
Switch -- 84.6 kB ▼ -4 B (-0.02% ) 26.6 kB
TablePagination -- 145 kB ▼ -4 B (-0.01% ) 42.7 kB
Breadcrumbs -- 83.7 kB ▲ +3 B (+0.01% ) 26.5 kB
Checkbox -- 85.4 kB ▼ -3 B (-0.01% ) 27 kB
Dialog -- 86.2 kB ▲ +3 B (+0.01% ) 26.9 kB
FormHelperText -- 66.7 kB ▼ -3 B (-0.01% ) 20.7 kB
ToggleButton -- 79.4 kB ▲ +3 B (+0.01% ) 25.1 kB
Tooltip -- 105 kB ▲ +3 B (+0.01% ) 33.1 kB
ExpansionPanel -- 74.9 kB ▲ +2 B (+0.01% ) 23.5 kB
Fab -- 80.1 kB ▲ +2 B (+0.01% ) 24.9 kB
IconButton -- 79.4 kB ▲ +2 B (+0.01% ) 24.8 kB
Input -- 75.9 kB ▲ +2 B (+0.01% ) 23.7 kB
OutlinedInput -- 77.9 kB ▲ +2 B (+0.01% ) 24.3 kB
Pagination -- 87.6 kB ▲ +2 B (+0.01% ) 27 kB
Popper -- 28.8 kB ▼ -2 B (-0.02% ) 10.3 kB
Slider -- 79.1 kB ▲ +2 B (+0.01% ) 25.2 kB
SwipeableDrawer -- 95.3 kB ▲ +2 B (+0.01% ) 29.9 kB
TableSortLabel -- 80.7 kB ▼ -2 B (-0.01% ) 25.5 kB
TextareaAutosize -- 5.19 kB ▼ -2 B (-0.09% ) 2.16 kB
Zoom -- 27.1 kB ▼ -2 B (-0.02% ) 9.17 kB
Alert -- 86.6 kB ▼ -1 B (-0.00% ) 27.3 kB
AlertTitle -- 67.5 kB ▲ +1 B (0.00% ) 21.2 kB
Autocomplete -- 135 kB ▲ +1 B (0.00% ) 42.2 kB
Avatar -- 68.5 kB ▲ +1 B (0.00% ) 21.4 kB
AvatarGroup -- 69.5 kB ▲ +1 B (0.00% ) 22 kB
Badge -- 68.7 kB ▲ +1 B (0.00% ) 21.3 kB
BottomNavigationAction -- 78.8 kB ▲ +1 B (0.00% ) 24.9 kB
Button -- 83 kB ▲ +1 B (0.00% ) 25.4 kB
Card -- 66.2 kB ▼ -1 B (-0.00% ) 20.7 kB
CardActionArea -- 78.4 kB ▲ +1 B (0.00% ) 24.8 kB
CardActions -- 65.4 kB ▲ +1 B (0.00% ) 20.5 kB
ClickAwayListener -- 3.84 kB ▲ +1 B (+0.07% ) 1.54 kB
Collapse -- 71.4 kB ▼ -1 B (-0.00% ) 22 kB
CssBaseline -- 65.3 kB ▲ +1 B (0.00% ) 20.5 kB
DialogActions -- 65.5 kB ▲ +1 B (0.00% ) 20.5 kB
DialogContent -- 65.6 kB ▲ +1 B (0.00% ) 20.5 kB
DialogTitle -- 67.6 kB ▲ +1 B (0.00% ) 21.2 kB
Divider -- 66.1 kB ▲ +1 B (0.00% ) 20.7 kB
Drawer -- 87.9 kB ▲ +1 B (0.00% ) 26.8 kB
ExpansionPanelSummary -- 81.4 kB ▲ +1 B (0.00% ) 25.7 kB
Fade -- 27.1 kB ▲ +1 B (+0.01% ) 9.04 kB
FormControl -- 67.7 kB ▲ +1 B (0.00% ) 21.1 kB
FormControlLabel -- 68.8 kB ▲ +1 B (0.00% ) 21.6 kB
FormLabel -- 66.8 kB ▲ +1 B (0.00% ) 20.7 kB
GridListTile -- 67.1 kB ▲ +1 B (0.00% ) 21 kB
GridListTileBar -- 66.6 kB ▲ +1 B (0.00% ) 20.8 kB
InputAdornment -- 68.4 kB ▲ +1 B (0.00% ) 21.6 kB
LinearProgress -- 68.7 kB ▲ +1 B (0.00% ) 21.2 kB
Link -- 69.9 kB ▼ -1 B (-0.00% ) 22.1 kB
List -- 65.7 kB ▼ -1 B (-0.00% ) 20.4 kB
ListItemIcon -- 65.5 kB ▲ +1 B (0.00% ) 20.5 kB
ListItemText -- 68.3 kB ▼ -1 B (-0.00% ) 21.5 kB
MenuList -- 69.3 kB ▼ -1 B (-0.00% ) 21.7 kB
PaginationItem -- 84 kB ▲ +1 B (0.00% ) 25.9 kB
Paper -- 65.7 kB ▼ -1 B (-0.00% ) 20.5 kB
Radio -- 86.4 kB ▲ +1 B (0.00% ) 27.3 kB
RootRef -- 4.61 kB ▼ -1 B (-0.06% ) 1.77 kB
SpeedDialAction -- 121 kB ▲ +1 B (0.00% ) 38.4 kB
Step -- 66 kB ▲ +1 B (0.00% ) 20.7 kB
StepButton -- 85.6 kB ▼ -1 B (-0.00% ) 27 kB
StepConnector -- 66.1 kB ▲ +1 B (0.00% ) 20.8 kB
StepContent -- 72.5 kB ▲ +1 B (0.00% ) 22.6 kB
StepLabel -- 71.9 kB ▲ +1 B (0.00% ) 22.2 kB
Stepper -- 68.2 kB ▼ -1 B (-0.00% ) 21.5 kB
SvgIcon -- 66.4 kB ▲ +1 B (0.00% ) 20.7 kB
Tab -- 79.6 kB ▲ +1 B (0.00% ) 25.3 kB
TableBody -- 65.5 kB ▼ -1 B (-0.00% ) 20.5 kB
TableCell -- 67.4 kB ▲ +1 B (0.00% ) 21.2 kB
TableContainer -- 65.3 kB ▲ +1 B (0.00% ) 20.4 kB
TableFooter -- 65.5 kB ▼ -1 B (-0.00% ) 20.5 kB
TableRow -- 65.8 kB ▲ +1 B (0.00% ) 20.6 kB
Tabs -- 88.6 kB ▼ -1 B (-0.00% ) 28.3 kB
TextField -- 127 kB ▼ -1 B (-0.00% ) 37.4 kB
ToggleButtonGroup -- 66.6 kB ▲ +1 B (0.00% ) 20.9 kB
Toolbar -- 65.7 kB ▲ +1 B (0.00% ) 20.6 kB
useAutocomplete -- 15 kB ▲ +1 B (+0.02% ) 5.41 kB
@material-ui/core[umd] -- 318 kB -- 92.4 kB
@material-ui/styles -- 51.4 kB -- 15.4 kB
@material-ui/system -- 16.6 kB -- 4.31 kB
AppBar -- 67.4 kB -- 21.1 kB
Backdrop -- 71.2 kB -- 22 kB
BottomNavigation -- 65.8 kB -- 20.6 kB
Box -- 72.3 kB -- 21.8 kB
CardContent -- 65.3 kB -- 20.4 kB
CardHeader -- 68.4 kB -- 21.5 kB
CardMedia -- 65.7 kB -- 20.6 kB
Chip -- 85.9 kB -- 26.3 kB
CircularProgress -- 67.5 kB -- 21.2 kB
colorManipulator -- 3.88 kB -- 1.52 kB
Container -- 66.5 kB -- 20.8 kB
DialogContentText -- 67.4 kB -- 21.1 kB
docs:/ -- 10.4 kB -- -1 B
docs:/_app -- 33.9 kB -- -1 B
ExpansionPanelActions -- 65.4 kB -- 20.5 kB
ExpansionPanelDetails -- 65.3 kB -- 20.4 kB
FormGroup -- 65.4 kB -- 20.5 kB
Grid -- 68.5 kB -- 21.4 kB
GridList -- 65.8 kB -- 20.6 kB
Hidden -- 69.3 kB -- 21.7 kB
Icon -- 66.2 kB -- 20.7 kB
InputLabel -- 68.6 kB -- 21.2 kB
ListItemAvatar -- 65.5 kB -- 20.5 kB
ListItemSecondaryAction -- 65.4 kB -- 20.4 kB
ListSubheader -- 66.1 kB -- 20.8 kB
MobileStepper -- 71.2 kB -- 22.3 kB
Modal -- 14.3 kB -- 5.04 kB
NoSsr -- 2.17 kB -- 1.03 kB
Portal -- 2.87 kB -- 1.29 kB
RadioGroup -- 67.1 kB -- 20.8 kB
Rating -- 73.8 kB -- 23.7 kB
ScopedCssBaseline -- 66.2 kB -- 20.7 kB
Skeleton -- 66.4 kB -- 20.9 kB
SnackbarContent -- 66.9 kB -- 21 kB
SpeedDialIcon -- 67.9 kB -- 21.3 kB
StepIcon -- 67.9 kB -- 21.2 kB
Table -- 65.9 kB -- 20.6 kB
TableHead -- 65.5 kB -- 20.4 kB
Typography -- 67 kB -- 20.9 kB
useMediaQuery -- 2.56 kB -- 1.06 kB

Generated by 🚫 dangerJS against bebcef3

@oliviertassinari oliviertassinari added the component: tree view TreeView, TreeItem. This is the name of the generic UI component, not the React module! label Mar 21, 2020
Copy link
Member

@eps1lon eps1lon left a comment

Choose a reason for hiding this comment

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

The aria practices does not describe what should happen if the tree receives focus and the selected tree item is in a collapsed parent.

Because the tree itself is not focusable. It doesn't make sense to make the widget container focusable and its children. In that case you want a focusable container and aria-activedescendant.

If you want to use our Treeview implementation and a focusable role="tree" then focus handling is your responsibility. It sounds like we don't have a good customization story for this?

It seems like you're trying to fix multiple issues at the same time. Feel free to fix #19882 but any change that affects the a11y story needs more research.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 22, 2020
@tonyhallett
Copy link
Contributor Author

Because the tree itself is not focusable. It doesn't make sense to make the widget container focusable and its children.

I agree. In my implementation, like yours, at any one time the user experience is that the tree is not focusable just the tree items. I move focus to the selected item when the tree is focused. To the user they are tabbing to the tree item. I hide the focus outline so there is no flicker.

This behaviour adheres to https://www.w3.org/TR/wai-aria-practices/#TreeView.

When a single-select tree receives focus:
If none of the nodes are selected before the tree receives focus, focus is set on the first node.
If a node is selected before the tree receives focus, focus is set on the selected node.
When a multi-select tree receives focus:
If none of the nodes are selected before the tree receives focus, focus is set on the first node.
If one or more nodes are selected before the tree receives focus, focus is set on the first selected node.

Your current tests would suggest that you are following this and there is no change to the a11y story in this regard.
https://github.com/mui-org/material-ui/blob/27471b4564eb40ff769352d73a29938d25804e45/packages/material-ui-lab/src/TreeItem/TreeItem.test.js#L233

describe('when a tree receives focus', () => {
      it('should focus the first node if none of the nodes are selected before the tree receives focus',
      it('should focus the selected node if a node is selected before the tree receives focus', () 

As I have already mentioned your code does not 'focus the selected node if a node is selected before the tree receives focus'. The test only passes because the selected node happens to be the focused node. If the test had selected 'two' and navigated to 'three', before focusing away and back again, the test will fail.

My code does pass these tests ( and all other tests ), it literally does 'focus the selected node when the tree receives focus'.
To a user my code would appear to be exactly the same as yours with the exception of focusing the selected node when the 'tree' receives focus.

The aria practices does not describe what should happen if the tree receives focus and the selected tree item is in a collapsed parent.

Because the tree itself is not focusable.

The 'tree' is focusable.

When a single-select tree receives focus:

describe('when a tree receives focus'

If you were to get your code to pass the test 'should focus the selected node if a node is selected before the tree receives focus' what would you do if the selected node was in a collapsed parent ?

When a focused item is removed I have decided to refocus the tree view. I can change this to making the TreeView tabbable again.

If I change the code to make the TreeView tabbable ( thus allowing for 'when a tree receives focus...' ) then my code will conform to blur behaviour.
Again, please look at #20204 - your code, under certain dynamic circumstances, will leave the tree in a state where all of the tree items have tabindex=-1 rendering the keyboard useless. This does not occur with my code.

To reiterate - my code behaves the same as your tests suggest that your code should behave.

@oliviertassinari oliviertassinari changed the title [TreeView] focus selected when tree receives focus [TreeView] Focus selected when tree receives focus Mar 25, 2020
@eps1lon
Copy link
Member

eps1lon commented Mar 29, 2020

@tonyhallett Please update this branch.

@joshwooding
Copy link
Member

joshwooding commented Jun 26, 2020

This is interesting. The guideline says one thing but the demos on the guideline showcase the current behaviour. I've also only seen that the last focus is what next receives focus on all other tree views.

@joshwooding
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: tree view TreeView, TreeItem. This is the name of the generic UI component, not the React module! PR: out-of-date The pull request has merge conflicts and can't be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants