fix: accessibility fixes (#236)

This commit is contained in:
Mehak Nasir
2022-08-07 01:10:35 +05:00
committed by GitHub
parent b7d436fe2f
commit e34ebdbeed
8 changed files with 59 additions and 30 deletions

View File

@@ -6,6 +6,7 @@ module.exports = createConfig('eslint',
"rules": {
'import/no-extraneous-dependencies': 'off',
'react-hooks/exhaustive-deps': 'off',
'jsx-a11y/no-noninteractive-element-interactions': 'off',
'simple-import-sort/imports': [
'error', {
groups: [

View File

@@ -54,8 +54,7 @@ function LearnerPostsView({ intl }) {
// Add a spacing after the group of pinned posts
return (
<React.Fragment key={post.id}>
<div className="p-1 bg-light-400" />
<PostLink post={post} key={post.id} isSelected={checkIsSelected} learnerTab />
<PostLink post={post} key={post.id} isSelected={checkIsSelected} learnerTab showDivider />
</React.Fragment>
);
}

View File

@@ -22,8 +22,10 @@ const ActionItem = ({
}) => (
<label
htmlFor={id}
className="focus border-bottom-0 d-flex align-items-center w-100 py-2 m-0 font-weight-500"
className="focus border-bottom-0 d-flex align-items-center w-100 py-2 m-0 font-weight-500 filter-menu"
data-testid={value === selected ? 'selected' : null}
style={{ cursor: 'pointer' }}
aria-checked={value === selected}
>
<Icon src={Check} className={classNames('text-success mr-2', { invisible: value !== selected })} />
<Form.Radio id={id} className="sr-only sr-only-focusable" value={value} tabIndex={0}>
@@ -56,7 +58,6 @@ function LearnerFilterBar({
if (name === 'sort') {
dispatch(setSortedBy(value));
}
setOpen(false);
};
return (

View File

@@ -62,12 +62,11 @@ function PostsList({ posts, topics, intl }) {
// Add a spacing after the group of pinned posts
return (
<React.Fragment key={post.id}>
<div className="p-1 bg-light-400" />
<PostLink post={post} key={post.id} isSelected={checkIsSelected} />
<PostLink post={post} key={post.id} isSelected={checkIsSelected} showDivider idx={idx} />
</React.Fragment>
);
}
return (<PostLink post={post} key={post.id} isSelected={checkIsSelected} />);
return (<PostLink post={post} key={post.id} isSelected={checkIsSelected} idx={idx} />);
});
return (

View File

@@ -59,13 +59,27 @@ function PostsView() {
postsListComponent = <AllPostsList />;
}
const handleKeyDown = (event) => {
const { key } = event;
if (key !== 'ArrowDown' && key !== 'ArrowUp') { return; }
const option = event.target;
let selectedOption;
if (key === 'ArrowDown') { selectedOption = option.nextElementSibling; }
if (key === 'ArrowUp') { selectedOption = option.previousElementSibling; }
if (selectedOption) {
selectedOption.focus();
}
};
return (
<div className="discussion-posts d-flex flex-column">
{
searchString && <SearchInfo count={resultsFound} text={searchString} onClear={() => dispatch(setSearchQuery(''))} />
}
<PostFilterBar filterSelfPosts={showOwnPosts} />
<div className="list-group list-group-flush" role="list">
<div className="list-group list-group-flush" role="list" onKeyDown={e => handleKeyDown(e)}>
{postsListComponent}
</div>
</div>

View File

@@ -33,8 +33,10 @@ const ActionItem = ({
}) => (
<label
htmlFor={id}
className="focus border-bottom-0 d-flex align-items-center w-100 py-2 m-0 font-weight-500"
className="focus border-bottom-0 d-flex align-items-center w-100 py-2 m-0 font-weight-500 filter-menu"
data-testid={value === selected ? 'selected' : null}
style={{ cursor: 'pointer' }}
aria-checked={value === selected}
>
<Icon src={Check} className={classNames('text-success mr-2', { invisible: value !== selected })} />
<Form.Radio id={id} className="sr-only sr-only-focusable" value={value} tabIndex={0}>
@@ -101,7 +103,6 @@ function PostFilterBar({
if (name === 'cohort') {
dispatch(setCohortFilter(value));
}
setOpen(false);
};
useEffect(() => {

View File

@@ -22,6 +22,8 @@ function PostLink({
isSelected,
intl,
learnerTab,
showDivider,
idx,
}) {
const {
page,
@@ -41,20 +43,24 @@ function PostLink({
const showAnsweredBadge = post.hasEndorsed && post.type === ThreadType.QUESTION;
const authorLabelColor = AvatarOutlineAndLabelColors[post.authorLabel];
const postReported = post.abuseFlagged || post.abuseFlaggedCount;
return (
<Link
className="discussion-post list-group-item list-group-item-action p-0 text-decoration-none text-gray-900"
to={linkUrl}
aria-current={isSelected(post.id) ? 'page' : undefined}
onClick={() => isSelected(post.id)}
style={{ lineHeight: '21px' }}
role="listitem"
aria-current={isSelected(post.id) ? 'page' : undefined}
role="option"
tabindex={(isSelected(post.id) || idx === 0) ? 0 : -1}
>
{showDivider && <div className="p-1 bg-light-400" /> }
<div
className={
classNames('d-flex flex-row pt-2.5 pb-2 px-4 border-primary-500',
{ 'bg-light-300': post.read })
}
classNames('d-flex flex-row pt-2.5 pb-2 px-4 border-primary-500',
{ 'bg-light-300': post.read })
}
style={post.id === postId ? {
borderRightWidth: '4px',
borderRightStyle: 'solid',
@@ -66,33 +72,33 @@ function PostLink({
<div className="d-flex align-items-center pb-0 mb-0 flex-fill font-weight-500">
<div
className={
classNames('text-truncate font-weight-500 font-size-14 text-primary-500 font-style-normal font-family-inter',
{ 'font-weight-bolder': !post.read })
classNames('text-truncate font-weight-500 font-size-14 text-primary-500 font-style-normal font-family-inter',
{ 'font-weight-bolder': !post.read })
}
>
{post.title}
</div>
{showAnsweredBadge && (
<Badge variant="success" className="font-weight-500 ml-auto badge-padding">
{intl.formatMessage(messages.answered)}
<span className="sr-only">{' '}answered</span>
</Badge>
<Badge variant="success" className="font-weight-500 ml-auto badge-padding">
{intl.formatMessage(messages.answered)}
<span className="sr-only">{' '}answered</span>
</Badge>
)}
{postReported && (
<Badge
variant="danger"
data-testid="reported-post"
className={`font-weight-500 badge-padding ${showAnsweredBadge ? 'ml-2' : 'ml-auto'}`}
>
{intl.formatMessage(messages.contentReported)}
<span className="sr-only">{' '}reported</span>
</Badge>
<Badge
variant="danger"
data-testid="reported-post"
className={`font-weight-500 badge-padding ${showAnsweredBadge ? 'ml-2' : 'ml-auto'}`}
>
{intl.formatMessage(messages.contentReported)}
<span className="sr-only">{' '}reported</span>
</Badge>
)}
{post.pinned && (
<Icon src={PushPin} className={`icon-size ${postReported || showAnsweredBadge ? 'ml-2' : 'ml-auto'}`} />
<Icon src={PushPin} className={`icon-size ${postReported || showAnsweredBadge ? 'ml-2' : 'ml-auto'}`} />
)}
</div>
</div>
@@ -124,10 +130,14 @@ PostLink.propTypes = {
isSelected: PropTypes.func.isRequired,
intl: intlShape.isRequired,
learnerTab: PropTypes.bool,
showDivider: PropTypes.bool,
idx: PropTypes.number,
};
PostLink.defaultProps = {
learnerTab: false,
showDivider: false,
idx: -1,
};
export default injectIntl(PostLink);

View File

@@ -126,3 +126,7 @@ header nav.nav.secondary-menu-container {
.sidebar-XL-width {
min-width: 29rem;
}
.filter-menu:focus-within {
background-color: #e9e6e4 !important;
}