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

[Select] Add labelId to implement proper labelling #17892

Merged
merged 6 commits into from
Oct 24, 2019

Conversation

eps1lon
Copy link
Member

@eps1lon eps1lon commented Oct 15, 2019

How to properly label a Select:

<InputLabel id="label">Age</InputLabel>
<Select labelId="label" id="select" value="20" />

will create a proper Age 20 accessible name following

or a complete solution

<TextField id="select" label="Age" value="20" />

Closes #16409

Follows https://www.w3.org/TR/wai-aria-practices/examples/listbox/listbox-collapsible.html

The previous solution did properly label the hidden input which doesn't make much sense and was partially motivated by lighthouse complaining. Either it removed this behavior or now properly recognizes the combobox.

I also simplified the demos to use a single value type. This gets rid of structures like
{ ...rest, [key]: value } or curried functions which is pretty advanced JS syntax and not appropriate for demos.

Argos failure is expected. A reviewer should accept these changes.

@eps1lon eps1lon added accessibility a11y component: select This is the name of the generic UI component, not the React module! labels Oct 15, 2019
@mui-pr-bot
Copy link

mui-pr-bot commented Oct 15, 2019

@material-ui/core: parsed: +0.08% , gzip: +0.11%

Details of bundle changes.

Comparing: 1e4d2db...c5b1f66

bundle Size Change Size Gzip Change Gzip
TextField ▲ +281 B (+0.23% ) 122 kB ▲ +130 B (+0.37% ) 35.6 kB
@material-ui/core ▲ +281 B (+0.08% ) 348 kB ▲ +109 B (+0.11% ) 95.3 kB
@material-ui/core[umd] ▲ +268 B (+0.09% ) 307 kB ▲ +97 B (+0.11% ) 88.4 kB
Select ▲ +177 B (+0.16% ) 113 kB ▲ +84 B (+0.25% ) 33.6 kB
TablePagination ▲ +177 B (+0.13% ) 140 kB ▲ +74 B (+0.18% ) 40.8 kB
@material-ui/lab -- 145 kB -- 45 kB
@material-ui/styles -- 51.8 kB -- 15.6 kB
@material-ui/system -- 15.7 kB -- 4.37 kB
AppBar -- 63.9 kB -- 19.9 kB
Avatar -- 62.7 kB -- 19.6 kB
Backdrop -- 67.7 kB -- 20.9 kB
Badge -- 65.4 kB -- 20.2 kB
BottomNavigation -- 62.4 kB -- 19.5 kB
BottomNavigationAction -- 75.3 kB -- 23.8 kB
Box -- 70.8 kB -- 21.4 kB
Breadcrumbs -- 68 kB -- 21.3 kB
Button -- 79.3 kB -- 24.5 kB
ButtonBase -- 73.8 kB -- 23.1 kB
ButtonGroup -- 64.2 kB -- 20 kB
Card -- 62.9 kB -- 19.6 kB
CardActionArea -- 74.9 kB -- 23.6 kB
CardActions -- 62 kB -- 19.3 kB
CardContent -- 62 kB -- 19.3 kB
CardHeader -- 65.1 kB -- 20.4 kB
CardMedia -- 62.4 kB -- 19.5 kB
Checkbox -- 81.6 kB -- 25.6 kB
Chip -- 70.6 kB -- 21.8 kB
CircularProgress -- 64.1 kB -- 20.1 kB
ClickAwayListener -- 3.85 kB -- 1.55 kB
Collapse -- 67.8 kB -- 20.9 kB
colorManipulator -- 3.83 kB -- 1.52 kB
Container -- 63.1 kB -- 19.6 kB
CssBaseline -- 57.6 kB -- 18 kB
Dialog -- 82.5 kB -- 25.6 kB
DialogActions -- 62.1 kB -- 19.4 kB
DialogContent -- 62.2 kB -- 19.4 kB
DialogContentText -- 64 kB -- 20 kB
DialogTitle -- 64.3 kB -- 20.1 kB
Divider -- 62.6 kB -- 19.6 kB
docs.landing -- 54.8 kB -- 14.5 kB
docs.main -- 599 kB -- 191 kB
Drawer -- 84.4 kB -- 26 kB
ExpansionPanel -- 71.1 kB -- 22.1 kB
ExpansionPanelActions -- 62.1 kB -- 19.4 kB
ExpansionPanelDetails -- 61.9 kB -- 19.3 kB
ExpansionPanelSummary -- 77.9 kB -- 24.5 kB
Fab -- 76.7 kB -- 23.8 kB
Fade -- 23.1 kB -- 8.05 kB
FilledInput -- 73.1 kB -- 22.6 kB
FormControl -- 64.3 kB -- 19.9 kB
FormControlLabel -- 65.5 kB -- 20.5 kB
FormGroup -- 62 kB -- 19.3 kB
FormHelperText -- 63.3 kB -- 19.7 kB
FormLabel -- 63.3 kB -- 19.5 kB
Grid -- 65.1 kB -- 20.3 kB
GridList -- 62.5 kB -- 19.5 kB
GridListTile -- 63.7 kB -- 19.9 kB
GridListTileBar -- 63.2 kB -- 19.7 kB
Grow -- 23.7 kB -- 8.17 kB
Hidden -- 66.1 kB -- 20.6 kB
Icon -- 62.8 kB -- 19.6 kB
IconButton -- 76 kB -- 23.7 kB
Input -- 72 kB -- 22.4 kB
InputAdornment -- 65.1 kB -- 20.4 kB
InputBase -- 70.2 kB -- 22 kB
InputLabel -- 65.1 kB -- 20.2 kB
LinearProgress -- 65.3 kB -- 20.3 kB
Link -- 66.6 kB -- 21 kB
List -- 62.4 kB -- 19.3 kB
ListItem -- 77 kB -- 24 kB
ListItemAvatar -- 62.1 kB -- 19.4 kB
ListItemIcon -- 62.2 kB -- 19.4 kB
ListItemSecondaryAction -- 62 kB -- 19.3 kB
ListItemText -- 65 kB -- 20.4 kB
ListSubheader -- 62.8 kB -- 19.6 kB
Menu -- 88.3 kB -- 27.6 kB
MenuItem -- 78 kB -- 24.3 kB
MenuList -- 66 kB -- 20.6 kB
MobileStepper -- 67.7 kB -- 21.1 kB
Modal -- 14.3 kB -- 4.96 kB
NativeSelect -- 76.4 kB -- 24 kB
NoSsr -- 2.19 kB -- 1.04 kB
OutlinedInput -- 73.7 kB -- 22.9 kB
Paper -- 62.4 kB -- 19.3 kB
Popover -- 82.7 kB -- 25.4 kB
Popper -- 28.3 kB -- 10.2 kB
Portal -- 2.87 kB -- 1.29 kB
Radio -- 82.5 kB -- 25.9 kB
RadioGroup -- 63.2 kB -- 19.7 kB
Rating -- 69.9 kB -- 22.3 kB
RootRef -- 4.43 kB -- 1.67 kB
Skeleton -- 62.5 kB -- 19.6 kB
Slide -- 25.1 kB -- 8.68 kB
Slider -- 75.4 kB -- 23.7 kB
Snackbar -- 77.1 kB -- 24 kB
SnackbarContent -- 65.8 kB -- 20.6 kB
SpeedDial -- 85.9 kB -- 27 kB
SpeedDialAction -- 115 kB -- 36.4 kB
SpeedDialIcon -- 64.6 kB -- 20.2 kB
Step -- 62.6 kB -- 19.6 kB
StepButton -- 82.2 kB -- 25.8 kB
StepConnector -- 62.7 kB -- 19.6 kB
StepContent -- 69 kB -- 21.4 kB
StepIcon -- 64.7 kB -- 20.1 kB
StepLabel -- 68.6 kB -- 21.4 kB
Stepper -- 64.9 kB -- 20.3 kB
styles/createMuiTheme -- 16.3 kB -- 5.79 kB
SvgIcon -- 63 kB -- 19.6 kB
SwipeableDrawer -- 90.7 kB -- 28 kB
Switch -- 80.8 kB -- 25.1 kB
Tab -- 76.2 kB -- 24.1 kB
Table -- 62.6 kB -- 19.5 kB
TableBody -- 62.1 kB -- 19.3 kB
TableCell -- 64.1 kB -- 20.1 kB
TableFooter -- 62.1 kB -- 19.3 kB
TableHead -- 62.1 kB -- 19.3 kB
TableRow -- 62.5 kB -- 19.5 kB
TableSortLabel -- 77.2 kB -- 24.4 kB
Tabs -- 85.3 kB -- 27.1 kB
TextareaAutosize -- 5.06 kB -- 2.11 kB
ToggleButton -- 76 kB -- 24 kB
ToggleButtonGroup -- 63.2 kB -- 19.8 kB
Toolbar -- 62.3 kB -- 19.5 kB
Tooltip -- 99.1 kB -- 31.4 kB
TreeItem -- 73.4 kB -- 23.1 kB
TreeView -- 66 kB -- 20.6 kB
Typography -- 63.7 kB -- 19.8 kB
useMediaQuery -- 2.49 kB -- 1.05 kB
Zoom -- 23.1 kB -- 8.06 kB

Generated by 🚫 dangerJS against c5b1f66

@codesandbox-ci
Copy link

codesandbox-ci bot commented Oct 15, 2019

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit f88a550:

Sandbox Source
create-react-app Configuration
create-react-app-with-typescript Configuration

@eps1lon eps1lon marked this pull request as ready for review October 15, 2019 19:13
Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

Great to follow the WAI-ARIA.


It seems that selects/SimpleSelect.tsx and selects/NativeSelects.tsx demos are no longer "in sync". Should we care? Should we demonstrate the same cases? Should we break the demo into smaller ones?

Historically, having almost identical demos helped to make sure the behavior where almost native prop invariant.


We have a couple of errors/warnings in https://validator.w3.org/nu/?doc=https%3A%2F%2Fdeploy-preview-17892--material-ui.netlify.com%2Fcomponents%2Fselects%2F

@@ -282,15 +285,15 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
tabIndex={tabIndex}
role="button"
aria-expanded={open ? 'true' : undefined}
Copy link
Member

Choose a reason for hiding this comment

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

Side question, would it work with?

Suggested change
aria-expanded={open ? 'true' : undefined}
aria-expanded={open}

(smaller)

Copy link
Member Author

Choose a reason for hiding this comment

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

It's explicitly defined that way in the apg:

Set by the JavaScript when the listbox is displayed.
Otherwise, is not present.

Though it is quite at odds with how aria-expanded is defined

undefined (default) | The element, or another grouping element it controls, is neither expandable nor collapsible; all its child elements are shown or there are no child elements.
-- | --

I would wait for w3c/aria-practices#618 to be resolved.

Copy link
Member

@oliviertassinari oliviertassinari Oct 19, 2019

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

As I said: The original APG section unsets it and the regarding issue is not resolved. Same goes for the issue what a select size="1" should be mapped to (listbox vs combobox).

<Select aria-describedby={helperTextId} value={value} input={InputElement} {...SelectProps}>
<Select
aria-describedby={helperTextId}
id={id}
Copy link
Member

Choose a reason for hiding this comment

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

Is this needed? I expect it to already come from the InputElement element.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll add a test/try without it. I think I considered this but it might have been in another context.

Copy link
Member Author

Choose a reason for hiding this comment

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

It is required. But it helped uncover another bug where the input[type="hidden"] had a (colliding) id and aria-describedby. Neither of which are required anymore.

@eps1lon
Copy link
Member Author

eps1lon commented Oct 18, 2019

We have a couple of errors/warnings in validator.w3.org/nu/?doc=https%3A%2F%2Fdeploy-preview-17892--material-ui.netlify.com%2Fcomponents%2Fselects%2F

I'll check again. I was under the assumption that this doesn't matter i.e. if the attribute is empty nothing bad happens. Conditional string concatenation is always so unwieldy so I tried to take as much shortcuts as possible

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 20, 2019

@eps1lon The wave chrome browser extension reports 4 issues:

Capture d’écran 2019-10-20 à 16 45 07

Do they signal the same issue than the W3 org HTML validator?

@eps1lon
Copy link
Member Author

eps1lon commented Oct 20, 2019

I don't know these tools. What issues are they reporting and what is the rationale for these rules?

@oliviertassinari
Copy link
Member

The tool is https://wave.webaim.org/, it's the one used in #17931.

@eps1lon
Copy link
Member Author

eps1lon commented Oct 21, 2019

The tool is wave.webaim.org, it's the one used in #17931.

Ok I looked at the rationale and it does not apply

ARIA labels and descriptions will not be presented if the element referenced does not exist in the page.

This was/is the point of the demo (which explicitly reads "without a label"). The issue is expected. Same for the placeholder.

For accessible name computation empty attributes or incorrect references will not block other alternatives. Only valid IDREFs are considered. I can add special logic but then a legitimate issue is less obvious.

One issue was a true positive though.

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 21, 2019

@eps1lon What do you think of the following incentive to fix false positive?

Developers use accessibility automation tools to assist them in authoring accessible interfaces. These tools have flaws and can report false positives. However, each false positive adds noise and needs to be verified. If we know that it's a false positive, we have an opportunity to solve it and void it to bug a developer that uses the component.

@eps1lon
Copy link
Member Author

eps1lon commented Oct 22, 2019

If we know that it's a false positive, we have an opportunity to solve it and void it to bug a developer that uses the component.

I just don't have the time and fix every issue upstream, sorry. This demo was there before and it never bothered you which is why I guess this is still a low priority.

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 22, 2019

@eps1lon Sounds good 👍 .

@oliviertassinari oliviertassinari merged commit fdafbc5 into mui:master Oct 24, 2019
@eps1lon eps1lon deleted the fix/Select/label branch November 7, 2019 14:44
@ahharvey
Copy link

ahharvey commented Nov 13, 2019

@eps1lon I have recently started seeing the below issue in my code, and am trying to track down the cause. Could it be related to this patch?

A Select field written as follows:

<TextField select id="my_select"> ...options ...</TextField>

Previously when the user interacts with this field, a menu dropdown was rendered with <div id='menu-my_select' ...>.

After updating material-ui, this menu is no longer attributed with the correct id: <div id='menu-' ....>

As we use the id in several of our tests, this change has caused some breakages.

Grateful for guidance on these questions:

  1. Is the incorrect menu ID a result of this patch?
  2. If so, is it intentional?
  3. If so, what is the new recommended way of assigning an ID to the menu div?

Thanks!

@eps1lon
Copy link
Member Author

eps1lon commented Nov 13, 2019

If so, what is the new recommended way of assigning an ID to the menu div?

If you need an id for testing I recommend using some data-* attribute e.g. data-testid which is commonly used in @testing-library/react. My question would be what you needed it for? The container is purely for visuals not behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accessibility a11y component: select This is the name of the generic UI component, not the React module!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Select] Should have role='listbox' or 'combobox' instead of 'button'
4 participants