Enable jsx-a11y/click-events-have-key-events
eslint rule (#10362)
* enable "jsx-a11y/alt-text" lint rule * enable "jsx-a11y/label-has-associated-control" * make Spoilers keyboard accessible * make invite reason keyboard accessible * make invite suggestions keyboard accessible * make avatar upload in space basic settings keyboard accessible * ignore jsx-a11y/click-events-have-key-events issues in tests * Update test expectation --------- Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
fe907ed66a
commit
e0d498e338
9 changed files with 28 additions and 10 deletions
|
@ -173,7 +173,7 @@ describe("Composer", () => {
|
||||||
cy.findByRole("textbox").type("this is the spoiler text ");
|
cy.findByRole("textbox").type("this is the spoiler text ");
|
||||||
cy.findByRole("button", { name: "Send message" }).click();
|
cy.findByRole("button", { name: "Send message" }).click();
|
||||||
// Check that a spoiler item has appeared in the timeline and contains the spoiler command text
|
// Check that a spoiler item has appeared in the timeline and contains the spoiler command text
|
||||||
cy.get("span.mx_EventTile_spoiler").should("exist");
|
cy.get("button.mx_EventTile_spoiler").should("exist");
|
||||||
cy.findByText("this is the spoiler text").should("exist");
|
cy.findByText("this is the spoiler text").should("exist");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -809,6 +809,16 @@ $left-gutter: 64px;
|
||||||
.mx_EventTile_spoiler {
|
.mx_EventTile_spoiler {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
// clear button styles
|
||||||
|
appearance: none;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
|
||||||
.mx_EventTile_spoiler_reason {
|
.mx_EventTile_spoiler_reason {
|
||||||
color: $event-timestamp-color;
|
color: $event-timestamp-color;
|
||||||
font-size: $font-11px;
|
font-size: $font-11px;
|
||||||
|
@ -821,6 +831,7 @@ $left-gutter: 64px;
|
||||||
|
|
||||||
&.visible > .mx_EventTile_spoiler_content {
|
&.visible > .mx_EventTile_spoiler_content {
|
||||||
filter: none;
|
filter: none;
|
||||||
|
user-select: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -274,7 +274,7 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
|
||||||
: this.highlightName(userIdentifier || this.props.member.userId);
|
: this.highlightName(userIdentifier || this.props.member.userId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_InviteDialog_tile mx_InviteDialog_tile--room" onClick={this.onClick}>
|
<AccessibleButton className="mx_InviteDialog_tile mx_InviteDialog_tile--room" onClick={this.onClick}>
|
||||||
{stackedAvatar}
|
{stackedAvatar}
|
||||||
<span className="mx_InviteDialog_tile_nameStack">
|
<span className="mx_InviteDialog_tile_nameStack">
|
||||||
<div className="mx_InviteDialog_tile_nameStack_name">
|
<div className="mx_InviteDialog_tile_nameStack_name">
|
||||||
|
@ -283,7 +283,7 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
|
||||||
<div className="mx_InviteDialog_tile_nameStack_userId">{caption}</div>
|
<div className="mx_InviteDialog_tile_nameStack_userId">{caption}</div>
|
||||||
</span>
|
</span>
|
||||||
{timestamp}
|
{timestamp}
|
||||||
</div>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import React from "react";
|
||||||
|
|
||||||
import { sanitizedHtmlNode } from "../../../HtmlUtils";
|
import { sanitizedHtmlNode } from "../../../HtmlUtils";
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
|
import AccessibleButton from "./AccessibleButton";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
reason: string;
|
reason: string;
|
||||||
|
@ -56,9 +57,9 @@ export default class InviteReason extends React.PureComponent<IProps, IState> {
|
||||||
<div className="mx_InviteReason_reason">
|
<div className="mx_InviteReason_reason">
|
||||||
{this.props.htmlReason ? sanitizedHtmlNode(this.props.htmlReason) : this.props.reason}
|
{this.props.htmlReason ? sanitizedHtmlNode(this.props.htmlReason) : this.props.reason}
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_InviteReason_view" onClick={this.onViewClick}>
|
<AccessibleButton kind="link_inline" className="mx_InviteReason_view" onClick={this.onViewClick}>
|
||||||
{_t("View message")}
|
{_t("View message")}
|
||||||
</div>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ export default class Spoiler extends React.Component<IProps, IState> {
|
||||||
// as such, we pass the this.props.contentHtml instead and then set the raw
|
// as such, we pass the this.props.contentHtml instead and then set the raw
|
||||||
// HTML content. This is secure as the contents have already been parsed previously
|
// HTML content. This is secure as the contents have already been parsed previously
|
||||||
return (
|
return (
|
||||||
<span
|
<button
|
||||||
className={"mx_EventTile_spoiler" + (this.state.visible ? " visible" : "")}
|
className={"mx_EventTile_spoiler" + (this.state.visible ? " visible" : "")}
|
||||||
onClick={this.toggleVisible}
|
onClick={this.toggleVisible}
|
||||||
>
|
>
|
||||||
|
@ -60,7 +60,7 @@ export default class Spoiler extends React.Component<IProps, IState> {
|
||||||
className="mx_EventTile_spoiler_content"
|
className="mx_EventTile_spoiler_content"
|
||||||
dangerouslySetInnerHTML={{ __html: this.props.contentHtml }}
|
dangerouslySetInnerHTML={{ __html: this.props.contentHtml }}
|
||||||
/>
|
/>
|
||||||
</span>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,11 @@ export const SpaceAvatar: React.FC<Pick<IProps, "avatarUrl" | "avatarDisabled" |
|
||||||
} else {
|
} else {
|
||||||
avatarSection = (
|
avatarSection = (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className="mx_SpaceBasicSettings_avatar" onClick={() => avatarUploadRef.current?.click()} />
|
<AccessibleButton
|
||||||
|
className="mx_SpaceBasicSettings_avatar"
|
||||||
|
onClick={() => avatarUploadRef.current?.click()}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
onClick={() => avatarUploadRef.current?.click()}
|
onClick={() => avatarUploadRef.current?.click()}
|
||||||
kind="link"
|
kind="link"
|
||||||
|
|
|
@ -92,6 +92,7 @@ describe("PictureInPictureDragger", () => {
|
||||||
<PictureInPictureDragger draggable={true}>
|
<PictureInPictureDragger draggable={true}>
|
||||||
{[
|
{[
|
||||||
({ onStartMoving }) => (
|
({ onStartMoving }) => (
|
||||||
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
|
||||||
<div onMouseDown={onStartMoving} onClick={clickSpy}>
|
<div onMouseDown={onStartMoving} onClick={clickSpy}>
|
||||||
Hello
|
Hello
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -60,6 +60,7 @@ describe("<Pill>", () => {
|
||||||
} as PillProps;
|
} as PillProps;
|
||||||
// wrap Pill with a div to allow testing of event bubbling
|
// wrap Pill with a div to allow testing of event bubbling
|
||||||
renderResult = render(
|
renderResult = render(
|
||||||
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
|
||||||
<div onClick={pillParentClickHandler}>
|
<div onClick={pillParentClickHandler}>
|
||||||
<Pill {...withDefault} />
|
<Pill {...withDefault} />
|
||||||
</div>,
|
</div>,
|
||||||
|
|
|
@ -293,10 +293,10 @@ describe("<TextualBody />", () => {
|
||||||
expect(content).toContainHTML(
|
expect(content).toContainHTML(
|
||||||
'<span class="mx_EventTile_body markdown-body" dir="auto">' +
|
'<span class="mx_EventTile_body markdown-body" dir="auto">' +
|
||||||
"Hey <span>" +
|
"Hey <span>" +
|
||||||
'<span class="mx_EventTile_spoiler">' +
|
'<button class="mx_EventTile_spoiler">' +
|
||||||
'<span class="mx_EventTile_spoiler_reason">(movie)</span> ' +
|
'<span class="mx_EventTile_spoiler_reason">(movie)</span> ' +
|
||||||
'<span class="mx_EventTile_spoiler_content"><span>the movie was awesome</span></span>' +
|
'<span class="mx_EventTile_spoiler_content"><span>the movie was awesome</span></span>' +
|
||||||
"</span></span></span>",
|
"</span></button></span>",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue