Make composer format bar an aria toolbar (#10583)

* Make composer format bar an aria toolbar

* Iterate

* Iterate

* Update snapshot
This commit is contained in:
Michael Telatynski 2023-04-12 14:58:38 +01:00 committed by GitHub
parent d179956af8
commit e5b1b7b632
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 18 deletions

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { forwardRef } from "react";
import { RovingTabIndexProvider } from "./RovingTabIndex";
import { getKeyBindingsManager } from "../KeyBindingsManager";
@ -25,7 +25,7 @@ interface IProps extends Omit<React.HTMLProps<HTMLDivElement>, "onKeyDown"> {}
// This component implements the Toolbar design pattern from the WAI-ARIA Authoring Practices guidelines.
// https://www.w3.org/TR/wai-aria-practices-1.1/#toolbar
// All buttons passed in children must use RovingTabIndex to set `onFocus`, `isActive`, `ref`
const Toolbar: React.FC<IProps> = ({ children, ...props }) => {
const Toolbar = forwardRef<HTMLDivElement, IProps>(({ children, ...props }, ref) => {
const onKeyDown = (ev: React.KeyboardEvent): void => {
const target = ev.target as HTMLElement;
// Don't interfere with input default keydown behaviour
@ -56,12 +56,12 @@ const Toolbar: React.FC<IProps> = ({ children, ...props }) => {
return (
<RovingTabIndexProvider handleHomeEnd handleLeftRight onKeyDown={onKeyDown}>
{({ onKeyDownHandler }) => (
<div {...props} onKeyDown={onKeyDownHandler} role="toolbar">
<div {...props} onKeyDown={onKeyDownHandler} role="toolbar" ref={ref}>
{children}
</div>
)}
</RovingTabIndexProvider>
);
};
});
export default Toolbar;

View file

@ -18,7 +18,8 @@ import React, { createRef } from "react";
import classNames from "classnames";
import { _t } from "../../../languageHandler";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { RovingAccessibleTooltipButton } from "../../../accessibility/RovingTabIndex";
import Toolbar from "../../../accessibility/Toolbar";
export enum Formatting {
Bold = "bold",
@ -51,7 +52,7 @@ export default class MessageComposerFormatBar extends React.PureComponent<IProps
mx_MessageComposerFormatBar_shown: this.state.visible,
});
return (
<div className={classes} ref={this.formatBarRef}>
<Toolbar className={classes} ref={this.formatBarRef} aria-label={_t("Formatting")}>
<FormatButton
label={_t("Bold")}
onClick={() => this.props.onAction(Formatting.Bold)}
@ -93,7 +94,7 @@ export default class MessageComposerFormatBar extends React.PureComponent<IProps
shortcut={this.props.shortcuts.insert_link}
visible={this.state.visible}
/>
</div>
</Toolbar>
);
}
@ -140,7 +141,7 @@ class FormatButton extends React.PureComponent<IFormatButtonProps> {
// element="button" and type="button" are necessary for the buttons to work on WebKit,
// otherwise the text is deselected before onClick can ever be called
return (
<AccessibleTooltipButton
<RovingAccessibleTooltipButton
element="button"
type="button"
onClick={this.props.onClick}

View file

@ -1952,6 +1952,7 @@
"Poll": "Poll",
"Hide formatting": "Hide formatting",
"Show formatting": "Show formatting",
"Formatting": "Formatting",
"Italics": "Italics",
"Strikethrough": "Strikethrough",
"Code block": "Code block",

View file

@ -446,7 +446,9 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
class="mx_BasicMessageComposer"
>
<div
aria-label="Formatting"
class="mx_MessageComposerFormatBar"
role="toolbar"
>
<button
aria-label="Bold"
@ -459,35 +461,35 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
aria-label="Italics"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
<button
aria-label="Strikethrough"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
<button
aria-label="Code block"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
<button
aria-label="Quote"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
<button
aria-label="Insert link"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
</div>
@ -706,7 +708,9 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
class="mx_BasicMessageComposer"
>
<div
aria-label="Formatting"
class="mx_MessageComposerFormatBar"
role="toolbar"
>
<button
aria-label="Bold"
@ -719,35 +723,35 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
aria-label="Italics"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
<button
aria-label="Strikethrough"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
<button
aria-label="Code block"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
<button
aria-label="Quote"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
<button
aria-label="Insert link"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
role="button"
tabindex="0"
tabindex="-1"
type="button"
/>
</div>