Tweak rendering of icons for accessibility (#31346)
* Tweak rendering of icons in dropdowns Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tweak rendering of icons in composer format bar Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tweak rendering of icons in jump to bottom button Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tweak rendering of icons in quick settings button Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tweak rendering of icons in left panel search Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update snapshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix margin Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update snapshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tweak rendering of icons in security user settings tab Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tweak rendering of icons in space hierarchy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update screenshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Simplify Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tidy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update snapshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
committed by
GitHub
parent
771696e0f0
commit
5869c519ed
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import classNames from "classnames";
|
||||
import React, { type JSX, type FunctionComponent, type Key, type PropsWithChildren, type ReactNode } from "react";
|
||||
import { ChevronDownIcon, CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { MenuItemRadio } from "../../accessibility/context_menu/MenuItemRadio";
|
||||
import { type ButtonEvent } from "../views/elements/AccessibleButton";
|
||||
@@ -42,9 +43,10 @@ export function GenericDropdownMenuOption<T extends Key>({
|
||||
className="mx_GenericDropdownMenu_Option mx_GenericDropdownMenu_Option--item"
|
||||
onClick={onClick}
|
||||
>
|
||||
{isSelected && <CheckIcon className="mx_GenericDropdownMenu_Option--checkIcon" />}
|
||||
<div className="mx_GenericDropdownMenu_Option--label">
|
||||
<span>{label}</span>
|
||||
<span>{description}</span>
|
||||
{description && <span>{description}</span>}
|
||||
</div>
|
||||
{adornment}
|
||||
</MenuItemRadio>
|
||||
@@ -202,6 +204,7 @@ export function GenericDropdownMenu<T>({
|
||||
}}
|
||||
>
|
||||
{selectedLabel(selected)}
|
||||
<ChevronDownIcon />
|
||||
</ContextMenuButton>
|
||||
{contextMenu}
|
||||
</>
|
||||
|
||||
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import { SearchIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { ALTERNATE_KEY_NAME } from "../../accessibility/KeyboardShortcuts";
|
||||
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||
@@ -34,8 +35,6 @@ export default class RoomSearch extends React.PureComponent<IProps> {
|
||||
"mx_RoomSearch_spotlightTrigger",
|
||||
);
|
||||
|
||||
const icon = <div className="mx_RoomSearch_icon" />;
|
||||
|
||||
const shortcutPrompt = (
|
||||
<kbd className="mx_RoomSearch_shortcutPrompt">
|
||||
{IS_MAC ? "⌘ K" : _t(ALTERNATE_KEY_NAME[Key.CONTROL]) + " K"}
|
||||
@@ -44,7 +43,7 @@ export default class RoomSearch extends React.PureComponent<IProps> {
|
||||
|
||||
return (
|
||||
<AccessibleButton onClick={this.openSpotlight} className={classes} aria-label={_t("action|search")}>
|
||||
{icon}
|
||||
<SearchIcon className="mx_RoomSearch_icon" />
|
||||
{!this.props.isMinimized && (
|
||||
<div className="mx_RoomSearch_spotlightTriggerText">{_t("action|search")}</div>
|
||||
)}
|
||||
|
||||
@@ -40,6 +40,7 @@ import classNames from "classnames";
|
||||
import { sortBy, uniqBy } from "lodash";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { KnownMembership, type SpaceChildEventContent } from "matrix-js-sdk/src/types";
|
||||
import { ChevronDownIcon, CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||
import { _t } from "../../languageHandler";
|
||||
@@ -251,7 +252,12 @@ const Tile: React.FC<ITileProps> = ({
|
||||
|
||||
let joinedSection: ReactElement | undefined;
|
||||
if (joinedRoom) {
|
||||
joinedSection = <div className="mx_SpaceHierarchy_roomTile_joined">{_t("common|joined")}</div>;
|
||||
joinedSection = (
|
||||
<div className="mx_SpaceHierarchy_roomTile_joined">
|
||||
<CheckIcon />
|
||||
{_t("common|joined")}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let suggestedSection: ReactElement | undefined;
|
||||
@@ -294,7 +300,9 @@ const Tile: React.FC<ITileProps> = ({
|
||||
ev.stopPropagation();
|
||||
toggleShowChildren();
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<ChevronDownIcon />
|
||||
</div>
|
||||
);
|
||||
|
||||
if (showChildren) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import { without } from "lodash";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { MatrixError } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { MenuItemRadio } from "../../../accessibility/context_menu/MenuItemRadio";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import Modal from "../../../Modal";
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
type AdditionalOptionsProps,
|
||||
GenericDropdownMenu,
|
||||
type GenericDropdownMenuItem,
|
||||
GenericDropdownMenuOption,
|
||||
} from "../../structures/GenericDropdownMenu";
|
||||
import TextInputDialog from "../dialogs/TextInputDialog";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
@@ -200,9 +200,8 @@ export const NetworkDropdown: React.FC<IProps> = ({ protocols, config, setConfig
|
||||
({ closeMenu }: AdditionalOptionsProps) => (
|
||||
<>
|
||||
<span className="mx_GenericDropdownMenu_divider" />
|
||||
<MenuItemRadio
|
||||
active={false}
|
||||
className="mx_GenericDropdownMenu_Option mx_GenericDropdownMenu_Option--item"
|
||||
<GenericDropdownMenuOption
|
||||
key="add-server"
|
||||
onClick={async (): Promise<void> => {
|
||||
closeMenu();
|
||||
const { finished } = Modal.createDialog(
|
||||
@@ -229,13 +228,9 @@ export const NetworkDropdown: React.FC<IProps> = ({ protocols, config, setConfig
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="mx_GenericDropdownMenu_Option--label">
|
||||
<span className="mx_NetworkDropdown_addServer">
|
||||
{_t("spotlight|public_rooms|network_dropdown_add_server_option")}
|
||||
</span>
|
||||
</div>
|
||||
</MenuItemRadio>
|
||||
isSelected={false}
|
||||
label={_t("spotlight|public_rooms|network_dropdown_add_server_option")}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
[allServers, setConfig, setUserDefinedServers, userDefinedServers],
|
||||
|
||||
@@ -17,6 +17,7 @@ import React, {
|
||||
type Ref,
|
||||
} from "react";
|
||||
import classnames from "classnames";
|
||||
import { ChevronDownIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import AccessibleButton, { type ButtonEvent } from "./AccessibleButton";
|
||||
import { _t } from "../../../languageHandler";
|
||||
@@ -411,7 +412,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
||||
onKeyDown={this.onKeyDown}
|
||||
>
|
||||
{currentValue}
|
||||
<span className="mx_Dropdown_arrow" />
|
||||
<ChevronDownIcon className="mx_Dropdown_arrow" />
|
||||
{menu}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React from "react";
|
||||
import classNames from "classnames";
|
||||
import { ChevronDownIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import AccessibleButton, { type ButtonEvent } from "../elements/AccessibleButton";
|
||||
@@ -32,7 +33,9 @@ const JumpToBottomButton: React.FC<IProps> = (props) => {
|
||||
className="mx_JumpToBottomButton_scrollDown"
|
||||
title={_t("room|jump_to_bottom_button")}
|
||||
onClick={props.onScrollToBottomClick}
|
||||
/>
|
||||
>
|
||||
<ChevronDownIcon />
|
||||
</AccessibleButton>
|
||||
{badge}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -6,8 +6,16 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { createRef } from "react";
|
||||
import React, { createRef, type JSX } from "react";
|
||||
import classNames from "classnames";
|
||||
import {
|
||||
BoldIcon,
|
||||
ItalicIcon,
|
||||
StrikethroughIcon,
|
||||
InlineCodeIcon,
|
||||
QuoteIcon,
|
||||
LinkIcon,
|
||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { RovingAccessibleButton } from "../../../accessibility/RovingTabIndex";
|
||||
@@ -54,41 +62,41 @@ export default class MessageComposerFormatBar extends React.PureComponent<IProps
|
||||
<FormatButton
|
||||
label={_t("composer|format_bold")}
|
||||
onClick={() => this.props.onAction(Formatting.Bold)}
|
||||
icon="Bold"
|
||||
icon={<BoldIcon />}
|
||||
shortcut={this.props.shortcuts.bold}
|
||||
visible={this.state.visible}
|
||||
/>
|
||||
<FormatButton
|
||||
label={_t("composer|format_italics")}
|
||||
onClick={() => this.props.onAction(Formatting.Italics)}
|
||||
icon="Italic"
|
||||
icon={<ItalicIcon />}
|
||||
shortcut={this.props.shortcuts.italics}
|
||||
visible={this.state.visible}
|
||||
/>
|
||||
<FormatButton
|
||||
label={_t("composer|format_strikethrough")}
|
||||
onClick={() => this.props.onAction(Formatting.Strikethrough)}
|
||||
icon="Strikethrough"
|
||||
icon={<StrikethroughIcon />}
|
||||
visible={this.state.visible}
|
||||
/>
|
||||
<FormatButton
|
||||
label={_t("composer|format_code_block")}
|
||||
onClick={() => this.props.onAction(Formatting.Code)}
|
||||
icon="Code"
|
||||
icon={<InlineCodeIcon />}
|
||||
shortcut={this.props.shortcuts.code}
|
||||
visible={this.state.visible}
|
||||
/>
|
||||
<FormatButton
|
||||
label={_t("action|quote")}
|
||||
onClick={() => this.props.onAction(Formatting.Quote)}
|
||||
icon="Quote"
|
||||
icon={<QuoteIcon />}
|
||||
shortcut={this.props.shortcuts.quote}
|
||||
visible={this.state.visible}
|
||||
/>
|
||||
<FormatButton
|
||||
label={_t("composer|format_insert_link")}
|
||||
onClick={() => this.props.onAction(Formatting.InsertLink)}
|
||||
icon="InsertLink"
|
||||
icon={<LinkIcon />}
|
||||
shortcut={this.props.shortcuts.insert_link}
|
||||
visible={this.state.visible}
|
||||
/>
|
||||
@@ -116,7 +124,7 @@ export default class MessageComposerFormatBar extends React.PureComponent<IProps
|
||||
|
||||
interface IFormatButtonProps {
|
||||
label: string;
|
||||
icon: string;
|
||||
icon: JSX.Element;
|
||||
shortcut?: string;
|
||||
visible?: boolean;
|
||||
onClick(): void;
|
||||
@@ -124,8 +132,6 @@ interface IFormatButtonProps {
|
||||
|
||||
class FormatButton extends React.PureComponent<IFormatButtonProps> {
|
||||
public render(): React.ReactNode {
|
||||
const className = `mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIcon${this.props.icon}`;
|
||||
|
||||
// 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 (
|
||||
@@ -136,8 +142,10 @@ class FormatButton extends React.PureComponent<IFormatButtonProps> {
|
||||
aria-label={this.props.label}
|
||||
title={this.props.label}
|
||||
caption={this.props.shortcut}
|
||||
className={className}
|
||||
/>
|
||||
className="mx_MessageComposerFormatBar_button"
|
||||
>
|
||||
{this.props.icon}
|
||||
</RovingAccessibleButton>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import { type Room, RoomEvent, type IServerVersions } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership, type Membership } from "matrix-js-sdk/src/types";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { WarningIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||
@@ -305,6 +306,7 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
||||
if (!privateShouldBeEncrypted(MatrixClientPeg.safeGet())) {
|
||||
warning = (
|
||||
<div className="mx_SecurityUserSettingsTab_warning">
|
||||
<WarningIcon />
|
||||
{_t("settings|security|e2ee_default_disabled_warning")}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -13,7 +13,9 @@ import {
|
||||
UserProfileSolidIcon,
|
||||
FavouriteSolidIcon,
|
||||
PinSolidIcon,
|
||||
SettingsSolidIcon,
|
||||
} from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { IconButton, Text, Tooltip } from "@vector-im/compound-web";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import ContextMenu, { alwaysAboveRightOf, ChevronFace, useContextMenu } from "../../structures/ContextMenu";
|
||||
@@ -34,7 +36,7 @@ import { ReleaseAnnouncement } from "../../structures/ReleaseAnnouncement";
|
||||
const QuickSettingsButton: React.FC<{
|
||||
isPanelCollapsed: boolean;
|
||||
}> = ({ isPanelCollapsed = false }) => {
|
||||
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu<HTMLDivElement>();
|
||||
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu<HTMLButtonElement>();
|
||||
|
||||
const { [MetaSpace.Favourites]: favouritesEnabled, [MetaSpace.People]: peopleEnabled } =
|
||||
useSettingValue("Spaces.enabledMetaSpaces");
|
||||
@@ -136,6 +138,35 @@ const QuickSettingsButton: React.FC<{
|
||||
);
|
||||
}
|
||||
|
||||
let button = (
|
||||
<IconButton
|
||||
aria-label={_t("quick_settings|title")}
|
||||
className={classNames("mx_QuickSettingsButton", { expanded: !isPanelCollapsed })}
|
||||
onClick={openMenu}
|
||||
title={isPanelCollapsed ? _t("quick_settings|title") : undefined}
|
||||
ref={handle}
|
||||
aria-expanded={!isPanelCollapsed}
|
||||
>
|
||||
<>
|
||||
<SettingsSolidIcon />
|
||||
{/* This is dirty, but we need to add the label to the indicator icon */}
|
||||
{!isPanelCollapsed && (
|
||||
<Text className="mx_QuickSettingsButton_label" as="span" size="md" title={_t("common|settings")}>
|
||||
{_t("common|settings")}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
</IconButton>
|
||||
);
|
||||
|
||||
if (isPanelCollapsed) {
|
||||
button = (
|
||||
<Tooltip label={_t("quick_settings|title")} placement="right">
|
||||
{button}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ReleaseAnnouncement
|
||||
@@ -145,16 +176,7 @@ const QuickSettingsButton: React.FC<{
|
||||
closeLabel={_t("room_list|release_announcement|done")}
|
||||
placement="right"
|
||||
>
|
||||
<AccessibleButton
|
||||
className={classNames("mx_QuickSettingsButton", { expanded: !isPanelCollapsed })}
|
||||
onClick={openMenu}
|
||||
aria-label={_t("quick_settings|title")}
|
||||
title={isPanelCollapsed ? _t("quick_settings|title") : undefined}
|
||||
ref={handle}
|
||||
aria-expanded={!isPanelCollapsed}
|
||||
>
|
||||
{!isPanelCollapsed ? _t("common|settings") : null}
|
||||
</AccessibleButton>
|
||||
{button}
|
||||
</ReleaseAnnouncement>
|
||||
|
||||
{contextMenu}
|
||||
|
||||
Reference in New Issue
Block a user