-
Notifications
You must be signed in to change notification settings - Fork 1
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
Input Label Accessibility Updates #514
Conversation
@danparnella Can you do an analysis on how this will impact styling (both in storybook and in the client template)? |
# Conflicts: # .storybook/styles/application.scss # .storybook/styles/base/_typography.scss # .storybook/styles/components/_activity.scss # .storybook/styles/components/_buttons.scss # .storybook/styles/components/_due-dates.scss # .storybook/styles/components/_expander.scss # .storybook/styles/components/_forms.scss # .storybook/styles/components/_grid.scss # .storybook/styles/components/_invites.scss # .storybook/styles/components/_navigation.scss # .storybook/styles/components/_profile-card.scss # .storybook/styles/components/_profile-section.scss # .storybook/styles/components/_purchased-profile-blade.scss # .storybook/styles/components/_recruiter-search.scss # .storybook/styles/components/_reminders.scss # .storybook/styles/components/_search-results-and-filtering.scss # .storybook/styles/components/_sidebar-content.scss # .storybook/styles/components/_sign-up-blocks.scss # .storybook/styles/components/_spinner.scss # .storybook/styles/components/_summit-list.scss # .storybook/styles/components/_tabs.scss # .storybook/styles/pages/_main.scss # .storybook/styles/pages/_styleguide.scss # .storybook/styles/settings/mixins/_layout.scss # .storybook/styles/settings/variables/_colors.scss # package.json # src/controls/color-picker.js # src/controls/nav-link.js # src/controls/tab-bar/tab-bar.js # src/forms/buttons/button.js # src/forms/helpers/blur-dirty.js # src/forms/helpers/button-classes.js # src/forms/helpers/dropdown-select.js # src/forms/helpers/field-prop-types.js # src/forms/helpers/replace-empty-string-value.js # src/forms/inputs/checkbox-group.js # src/forms/inputs/checkbox.js # src/forms/inputs/cloudinary-file-input.js # src/forms/inputs/color-input.js # src/forms/inputs/date-input.js # src/forms/inputs/dropdown-checkbox-group.js # src/forms/inputs/file-input/file-input.js # src/forms/inputs/file-input/file-preview.js # src/forms/inputs/input.js # src/forms/inputs/masked-input.js # src/forms/inputs/radio-group.js # src/forms/inputs/range-input.js # src/forms/inputs/setter-link.js # src/forms/inputs/switch.js # src/forms/labels/input-error.js # src/forms/labels/input-label.js # src/forms/labels/labeled-field.js # src/indicators/spinner.js # src/routes/authorized-route.js # src/routes/index.js # src/routes/unauthorized-route.js # src/tables/components/table-row.js # src/tables/sortable-table.js # stories/controls/nav-link.story.js # stories/controls/tab-bar.story.js # stories/dynamic-input.js # stories/forms/inputs/checkbox-group.story.js # stories/forms/inputs/file-input.story.js # stories/forms/inputs/input.story.js # stories/forms/inputs/radio-group.story.js # stories/forms/inputs/range-input.story.js # stories/forms/inputs/setter-link.story.js # stories/forms/labels/labeled-field.story.js # stories/tables/sortable-table.story.js # stories/tables/table.story.js
…ents, add stories, add tests
@@ -48,10 +48,8 @@ $output-bourbon-deprecation-warnings: false; | |||
@import 'components/progress-circle'; | |||
@import 'components/login'; | |||
@import 'components/pagination'; | |||
@import 'components/sidebar-content'; |
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.
I noticed a couple style files were no longer being used. Not sure if they should still be there for reference?
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.
I'm fine with deleting them!
fieldset, | ||
.field-wrapper { |
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.
My hope is that this might ease some of the style changes (just swapping fieldset
for .field-wrapper
in stylesheets). Hopefully most projects can just find and replace in their stylesheets without too much auditing.
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.
Can you add this documentation to a migration guide?
.input-wrapper { | ||
position: relative; | ||
|
||
i { | ||
@include position(absolute, 3px null null 10px); | ||
background-repeat: no-repeat; | ||
background-size: 15px; | ||
display: inline-block; | ||
height: 20px; | ||
width: 20px; | ||
} | ||
} |
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.
This was included further down in a duplicate "Input Icon" section.
@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "@launchpadlab/lp-components", | |||
"version": "8.0.0", | |||
"version": "9.0.0", |
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.
I figured I'd hold off on writing a migration guide until the code changes are approved.
<div> | ||
<FieldsetLegend {...{ label, name }} id={inputId} /> | ||
<DropdownSelect selectedValues={value} className="checkboxes"> | ||
<CheckboxGroup {...props} label={false} /> | ||
<CheckboxGroup {...props} label={false} ariaLabelledby={inputId} /> | ||
</DropdownSelect> | ||
</fieldset> | ||
</div> |
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.
The checkbox group is actually the fieldset
so div
should be correct here and since a label/legend isn't provided, I'm using the id
on the "outer" legend to provide the aria labelledby.
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.
If we aren't using a fieldset
, is legend
the semantically appropriate tag? Or would p
/span
suffice?
Looking at the specs, the only Permitted parent is a fieldset
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend#technical_summary
* This component is used within {@link LabeledFieldset}, and therefore is incorporated into most fieldset grouped input components ({@link RadioGroup}, {@link CheckboxGroup}) by default. | ||
* | ||
* The text of the legend is set using the following rules: | ||
* - If the `label` prop is set to `false`, the legend is hidden completely |
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.
I kept debating whether to change "label" fully to "legend", but I was thinking for backwards compatibility (potentially in code, but also in terms of consistency mentally), sticking with label
as the prop might be better. It's also still a "label", just a different kind of one. BUT, that's just my two cents.
@jhp0621 Tagging you for visibility! |
{...props} | ||
> | ||
{optionObjects.map((option, i) => { | ||
<LabeledFieldset className={className} {...props}> |
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.
@danparnella what happens if label
is false
? Pretty certain <fieldset>
must have a unique <legend>
; if a radio group has label
set to false
, I believe we would still be rendering a <fieldset>
but without a <legend>
?
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.
Yep, that's correct. If the design requires label={false}
, then the developer should use aria-labelledby
to specify which element to use as the "legend". It might be good for me to add that as an example in the story though.
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.
It sounds like Ji ran into some issues where aria-labelledby
on a fieldset still fails accessibility checks because a legend is required when using a fieldset
(reference). An alternative might be to have <div role="group" aria-labelledby="">
in this instance.
The reference above is a technique which isn't required to meet WCAG, but is rather a guideline. We might need to dig more into the actual Success Criterion to see if this is a strict requirement or rather a strict interpretation on the accessibility tool. Maybe we could do testing with SiteImprove and Axe's accessibility testing extensions?
@jhp0621 Am I remembering correctly? Do you have more information/resources that you can share?
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.
@@ -48,10 +48,8 @@ $output-bourbon-deprecation-warnings: false; | |||
@import 'components/progress-circle'; | |||
@import 'components/login'; | |||
@import 'components/pagination'; | |||
@import 'components/sidebar-content'; |
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.
I'm fine with deleting them!
fieldset, | ||
.field-wrapper { |
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.
Can you add this documentation to a migration guide?
@@ -145,8 +159,7 @@ Radio | |||
Checkbox | |||
-----------------------*/ | |||
.checkbox { | |||
@include rem(margin-top, 15px); | |||
width: auto; | |||
@include rem(margin-top, 3px); |
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.
Can you explain this change?
@@ -567,7 +557,7 @@ Custom Dropdown Select | |||
} | |||
} | |||
|
|||
fieldset.checkbox, | |||
.field-wrapper.checkbox, |
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.
I don't think this is a one-for-one change. If we have rules for fieldset.checkbox
and fieldset.CheckboxGroup
, then I believe we would additionally need field-wrapper.checkbox
and field-wrapper.CheckboxGroup
, eh?
return ( | ||
<Checkbox // eslint-disable-line react/jsx-key | ||
<Checkbox | ||
key={option.value} |
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.
😎
.add('with custom label', () => { | ||
// eslint-disable-next-line | ||
const CustomLabel = ({ onClickLabel }) => ( | ||
<legend onClick={onClickLabel} htmlFor="inputName"> |
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.
Can we pass a different custom prop (or use it in a different way)? I don't want to encourage inappropriate onClick
handler usage
}) | ||
.add('with custom error', () => { | ||
const CustomError = (props) => ( | ||
<span id="inputError"> |
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.
Can we change this to inputNameError
or use the generate input error id util here? I don't want to encourage the wrong usage of a custom error component (the aria-describedby
that's added to the input won't match this id
)
const onClick = jest.fn() | ||
const wrapper = mount( | ||
<FieldsetLegend name={name}> | ||
Are you <span onClick={onClick}>sure</span>? |
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.
Can we use the semantically appropriate <button>
here instead?
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.
Or remove it? Doesn't seem relevant to the test 🤔
const wrapper = mount( | ||
<FieldsetLegend name={name}> | ||
Are you{' '} | ||
<span id="click" onClick={onClick}> |
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 a semantically appropriate element (i.e., button
)
</LabeledFieldset> | ||
) | ||
expect(wrapper.find('fieldset').exists()).toEqual(true) | ||
expect(wrapper.find('fieldset').hasClass('error')).toEqual(false) |
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.
This doesn't align with the test description 🤔 . Can we create a separate test for this?
Closing in favor of #595 |
Plan is also to add aria props to anyinput
based componentAuthor Checklist