mirror of https://github.com/vector-im/riot-web
Make composer format bar an aria toolbar (#10583)
* Make composer format bar an aria toolbar * Iterate * Iterate * Update snapshotpull/28788/head^2
parent
d179956af8
commit
e5b1b7b632
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React, { forwardRef } from "react";
|
||||||
|
|
||||||
import { RovingTabIndexProvider } from "./RovingTabIndex";
|
import { RovingTabIndexProvider } from "./RovingTabIndex";
|
||||||
import { getKeyBindingsManager } from "../KeyBindingsManager";
|
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.
|
// 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
|
// https://www.w3.org/TR/wai-aria-practices-1.1/#toolbar
|
||||||
// All buttons passed in children must use RovingTabIndex to set `onFocus`, `isActive`, `ref`
|
// 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 onKeyDown = (ev: React.KeyboardEvent): void => {
|
||||||
const target = ev.target as HTMLElement;
|
const target = ev.target as HTMLElement;
|
||||||
// Don't interfere with input default keydown behaviour
|
// Don't interfere with input default keydown behaviour
|
||||||
|
@ -56,12 +56,12 @@ const Toolbar: React.FC<IProps> = ({ children, ...props }) => {
|
||||||
return (
|
return (
|
||||||
<RovingTabIndexProvider handleHomeEnd handleLeftRight onKeyDown={onKeyDown}>
|
<RovingTabIndexProvider handleHomeEnd handleLeftRight onKeyDown={onKeyDown}>
|
||||||
{({ onKeyDownHandler }) => (
|
{({ onKeyDownHandler }) => (
|
||||||
<div {...props} onKeyDown={onKeyDownHandler} role="toolbar">
|
<div {...props} onKeyDown={onKeyDownHandler} role="toolbar" ref={ref}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</RovingTabIndexProvider>
|
</RovingTabIndexProvider>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default Toolbar;
|
export default Toolbar;
|
||||||
|
|
|
@ -18,7 +18,8 @@ import React, { createRef } from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
import { RovingAccessibleTooltipButton } from "../../../accessibility/RovingTabIndex";
|
||||||
|
import Toolbar from "../../../accessibility/Toolbar";
|
||||||
|
|
||||||
export enum Formatting {
|
export enum Formatting {
|
||||||
Bold = "bold",
|
Bold = "bold",
|
||||||
|
@ -51,7 +52,7 @@ export default class MessageComposerFormatBar extends React.PureComponent<IProps
|
||||||
mx_MessageComposerFormatBar_shown: this.state.visible,
|
mx_MessageComposerFormatBar_shown: this.state.visible,
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<div className={classes} ref={this.formatBarRef}>
|
<Toolbar className={classes} ref={this.formatBarRef} aria-label={_t("Formatting")}>
|
||||||
<FormatButton
|
<FormatButton
|
||||||
label={_t("Bold")}
|
label={_t("Bold")}
|
||||||
onClick={() => this.props.onAction(Formatting.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}
|
shortcut={this.props.shortcuts.insert_link}
|
||||||
visible={this.state.visible}
|
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,
|
// 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
|
// otherwise the text is deselected before onClick can ever be called
|
||||||
return (
|
return (
|
||||||
<AccessibleTooltipButton
|
<RovingAccessibleTooltipButton
|
||||||
element="button"
|
element="button"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={this.props.onClick}
|
onClick={this.props.onClick}
|
||||||
|
|
|
@ -1952,6 +1952,7 @@
|
||||||
"Poll": "Poll",
|
"Poll": "Poll",
|
||||||
"Hide formatting": "Hide formatting",
|
"Hide formatting": "Hide formatting",
|
||||||
"Show formatting": "Show formatting",
|
"Show formatting": "Show formatting",
|
||||||
|
"Formatting": "Formatting",
|
||||||
"Italics": "Italics",
|
"Italics": "Italics",
|
||||||
"Strikethrough": "Strikethrough",
|
"Strikethrough": "Strikethrough",
|
||||||
"Code block": "Code block",
|
"Code block": "Code block",
|
||||||
|
|
|
@ -446,7 +446,9 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||||
class="mx_BasicMessageComposer"
|
class="mx_BasicMessageComposer"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
aria-label="Formatting"
|
||||||
class="mx_MessageComposerFormatBar"
|
class="mx_MessageComposerFormatBar"
|
||||||
|
role="toolbar"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
aria-label="Bold"
|
aria-label="Bold"
|
||||||
|
@ -459,35 +461,35 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||||
aria-label="Italics"
|
aria-label="Italics"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
aria-label="Strikethrough"
|
aria-label="Strikethrough"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
aria-label="Code block"
|
aria-label="Code block"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
aria-label="Quote"
|
aria-label="Quote"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
aria-label="Insert link"
|
aria-label="Insert link"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -706,7 +708,9 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
||||||
class="mx_BasicMessageComposer"
|
class="mx_BasicMessageComposer"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
aria-label="Formatting"
|
||||||
class="mx_MessageComposerFormatBar"
|
class="mx_MessageComposerFormatBar"
|
||||||
|
role="toolbar"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
aria-label="Bold"
|
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"
|
aria-label="Italics"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
aria-label="Strikethrough"
|
aria-label="Strikethrough"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
aria-label="Code block"
|
aria-label="Code block"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
aria-label="Quote"
|
aria-label="Quote"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
aria-label="Insert link"
|
aria-label="Insert link"
|
||||||
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
|
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue