-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Add aria-describedby attribute to date input #266
Conversation
@backwardok or @wyattdanger would you mind taking a look at this PR as our resident a11y experts? |
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.
Thanks, @allanpope! Overall implementation looks good, but I have a few requests
test/components/DateInput_spec.jsx
Outdated
@@ -58,6 +58,46 @@ describe('DateInput', () => { | |||
}); | |||
}); | |||
|
|||
describe('screen reader message', () => { |
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.
Looks like we'll need similar specs for the other components touched in the PR
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.
Just had another look at the tests. I'm unsure what other components I could test?
All the tests files use enzymes shallow rendering, so I can only test that level of the component. The changes I've added to them are pretty simple. All they do is take a screenReaderMessage prop and pass it to a child component. This prop is passed all the way down until it gets to the DateInput
component, which the above tests cover.
Happy to add more tests but need some further instruction, thanks.
README.md
Outdated
@@ -194,6 +194,11 @@ If the `required` prop is set to true, the input will have to be filled before t | |||
required: PropTypes.bool, | |||
``` | |||
|
|||
The `screenReaderInputMessage` prop allows you to write a message for screen readers. When the prop is added a `aria-describedby` attribute will be added to the input box and the value will be read by screen readers. Take advantage of this to inform users about constraints your component has, such as the date format, minimum nights and blocked out dates etc. |
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.
Would like to see a few grammatical changes here, but overall looks like reasonable documentation! Thanks for including this. Maybe something a bit more in this direction?
The
screenReaderInputMessage
prop accepts a contextual message for screen readers. When an input is focused, thescreenReaderInputMessage
prop value is read. This can inform users about constraints, such as the date format, minimum nights, blocked out dates, etc.
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.
No problem. Thanks that reads a lot better.
src/components/DateInput.jsx
Outdated
@@ -128,8 +131,15 @@ export default class DateInput extends React.Component { | |||
disabled={disabled} | |||
readOnly={this.isTouchDevice} | |||
required={required} | |||
aria-describedby={screenReaderMessage && `DateInput__screen-reader-message-${id}`} |
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.
Would prefer to see this string interpolated only once per render, perhaps at the top of the render method
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.
Ah good pickup, I didn't consider that.
@@ -333,6 +333,7 @@ export default class SingleDatePicker extends React.Component { | |||
phrases, | |||
withPortal, | |||
withFullScreenPortal, | |||
screenReaderInputMessage, |
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.
Please add this prop to propTypes/defaultProps
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.
Completely missed this one, have added it for this and DateRangePicker.
stories/DateRangePicker.js
Outdated
)) | ||
.addWithInfo('with screen reader message', () => ( | ||
<DateRangePickerWrapper | ||
screenReaderInputMessage='Here you could inform screen reader users of the date format, minimum nights, blocked out dates etc' |
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.
Please use an Oxford comma after "dates" :-)
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.
Added.
stories/SingleDatePicker.js
Outdated
)) | ||
.addWithInfo('with screen reader message', () => ( | ||
<SingleDatePickerWrapper | ||
screenReaderInputMessage='Here you could inform screen reader users of the date format, minimum nights, blocked out dates etc' |
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.
Same here
test/components/DateInput_spec.jsx
Outdated
const id = 'date'; | ||
const screenReaderMessage = 'My screen reader message'; | ||
const screenReaderMessageName = `DateInput__screen-reader-message-${id}`; | ||
const screenReaderMessageId = `#${screenReaderMessageName}`; |
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.
Technically the ID is line 75, and this is the "selector" - could we improve the var names a bit?
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.
Yeah your correct, I've updated the names of these variables.
I also moved the creation of the wrappers into a before loop since they were all the same, which reduces the duplication and makes it easier to read.
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.
That's fine - although duplication in tests often helps.
Great! Please rebase, squash, write a solid commit message, and then we'll be good to ship. Thank you Allan |
@wyattdanger @ljharb Thanks for taking a look at it. I've just rebased, squashed & committed. |
…f the date component. New prop has been added called screenReaderInputMessage. It's value will be read outloud by a screen reader when the input is focused on. * Add ability to pass down a screen reader message to the date input, taking advantage of the aria-describedby attribute. * Add an example of how to attach a screen read message to an date input. * Append component id to screen reader message to make sure its unique, incase multiple date pickers are on a page. * Add tests to make sure screen reader text is displays correctly. * Add documentation about screenReaderInputMessage prop. * Make grammatical changes to screenReaderInputMessage docs * Move string interpolation out into a const so that it only happens once per a render. * Pull shared variables up a level to reduce amount of times string interpolation needs to happen * Add screen reader input message prop to propTypes & defaultPropTypes * Pull out wrapper creation into before loop since they are all the same.
Confirmed offline that this is good to go!
When using a screen reader you are able to type in a date but you don't know about any restrictions the date component might have.
This pull request adds the ability to inform screen reader users about the constraints of the component they are using via the
aria-describedby
attribute.Any text passed into the new
screenReaderInputMessage
prop will be read out when a screen reader user interacts with the input.Closes #261