Improve spotlight accessibility by adding context menus (#8907)
* Extract room general context menu from roomtile * Create hook to access and change a room’s notification state * Extract room notification context menu from roomtile * Add room context menus to rooms in spotlight * Make arrow movement apply to the whole dialog, not just the input box
This commit is contained in:
parent
6a125d5a1d
commit
780a903e2f
12 changed files with 632 additions and 283 deletions
|
@ -88,6 +88,7 @@ import FeedbackDialog from "../FeedbackDialog";
|
|||
import { IDialogProps } from "../IDialogProps";
|
||||
import { Option } from "./Option";
|
||||
import { PublicRoomResultDetails } from "./PublicRoomResultDetails";
|
||||
import { RoomResultContextMenus } from "./RoomResultContextMenus";
|
||||
import { RoomContextDetails } from "../../rooms/RoomContextDetails";
|
||||
import { TooltipOption } from "./TooltipOption";
|
||||
|
||||
|
@ -506,8 +507,11 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
let otherSearchesSection: JSX.Element;
|
||||
if (trimmedQuery || filter !== Filter.PublicRooms) {
|
||||
otherSearchesSection = (
|
||||
<div className="mx_SpotlightDialog_section mx_SpotlightDialog_otherSearches" role="group">
|
||||
<h4>
|
||||
<div
|
||||
className="mx_SpotlightDialog_section mx_SpotlightDialog_otherSearches"
|
||||
role="group"
|
||||
aria-labelledby="mx_SpotlightDialog_section_otherSearches">
|
||||
<h4 id="mx_SpotlightDialog_section_otherSearches">
|
||||
{ trimmedQuery
|
||||
? _t('Use "%(query)s" to search', { query })
|
||||
: _t("Search for") }
|
||||
|
@ -544,7 +548,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
const unreadLabel = roomAriaUnreadLabel(result.room, notification);
|
||||
const ariaProperties = {
|
||||
"aria-label": unreadLabel ? `${result.room.name} ${unreadLabel}` : result.room.name,
|
||||
"aria-details": `mx_SpotlightDialog_button_result_${result.room.roomId}_details`,
|
||||
"aria-describedby": `mx_SpotlightDialog_button_result_${result.room.roomId}_details`,
|
||||
};
|
||||
return (
|
||||
<Option
|
||||
|
@ -553,6 +557,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
onClick={(ev) => {
|
||||
viewRoom(result.room.roomId, true, ev?.type !== "click");
|
||||
}}
|
||||
endAdornment={<RoomResultContextMenus room={result.room} />}
|
||||
{...ariaProperties}
|
||||
>
|
||||
<DecoratedRoomAvatar
|
||||
|
@ -948,8 +953,10 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
tabIndex={-1}
|
||||
aria-labelledby="mx_SpotlightDialog_section_recentSearches"
|
||||
>
|
||||
<h4 id="mx_SpotlightDialog_section_recentSearches">
|
||||
{ _t("Recent searches") }
|
||||
<h4>
|
||||
<span id="mx_SpotlightDialog_section_recentSearches">
|
||||
{ _t("Recent searches") }
|
||||
</span>
|
||||
<AccessibleButton kind="link" onClick={clearRecentSearches}>
|
||||
{ _t("Clear") }
|
||||
</AccessibleButton>
|
||||
|
@ -960,7 +967,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
const unreadLabel = roomAriaUnreadLabel(room, notification);
|
||||
const ariaProperties = {
|
||||
"aria-label": unreadLabel ? `${room.name} ${unreadLabel}` : room.name,
|
||||
"aria-details": `mx_SpotlightDialog_button_recentSearch_${room.roomId}_details`,
|
||||
"aria-describedby": `mx_SpotlightDialog_button_recentSearch_${room.roomId}_details`,
|
||||
};
|
||||
return (
|
||||
<Option
|
||||
|
@ -969,6 +976,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
onClick={(ev) => {
|
||||
viewRoom(room.roomId, true, ev?.type !== "click");
|
||||
}}
|
||||
endAdornment={<RoomResultContextMenus room={room} />}
|
||||
{...ariaProperties}
|
||||
>
|
||||
<DecoratedRoomAvatar
|
||||
|
@ -1034,6 +1042,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
break;
|
||||
}
|
||||
|
||||
let ref: RefObject<HTMLElement>;
|
||||
const accessibilityAction = getKeyBindingsManager().getAccessibilityAction(ev);
|
||||
switch (accessibilityAction) {
|
||||
case KeyBindingAction.Escape:
|
||||
|
@ -1041,22 +1050,6 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
ev.preventDefault();
|
||||
onFinished();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const onKeyDown = (ev: KeyboardEvent) => {
|
||||
let ref: RefObject<HTMLElement>;
|
||||
|
||||
const action = getKeyBindingsManager().getAccessibilityAction(ev);
|
||||
|
||||
switch (action) {
|
||||
case KeyBindingAction.Backspace:
|
||||
if (!query && filter !== null) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
setFilter(null);
|
||||
}
|
||||
break;
|
||||
case KeyBindingAction.ArrowUp:
|
||||
case KeyBindingAction.ArrowDown:
|
||||
ev.stopPropagation();
|
||||
|
@ -1075,7 +1068,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
}
|
||||
|
||||
const idx = refs.indexOf(rovingContext.state.activeRef);
|
||||
ref = findSiblingElement(refs, idx + (action === KeyBindingAction.ArrowUp ? -1 : 1));
|
||||
ref = findSiblingElement(refs, idx + (accessibilityAction === KeyBindingAction.ArrowUp ? -1 : 1));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1092,14 +1085,9 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
|
||||
const refs = rovingContext.state.refs.filter(refIsForRecentlyViewed);
|
||||
const idx = refs.indexOf(rovingContext.state.activeRef);
|
||||
ref = findSiblingElement(refs, idx + (action === KeyBindingAction.ArrowLeft ? -1 : 1));
|
||||
ref = findSiblingElement(refs, idx + (accessibilityAction === KeyBindingAction.ArrowLeft ? -1 : 1));
|
||||
}
|
||||
break;
|
||||
case KeyBindingAction.Enter:
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
rovingContext.state.activeRef?.current?.click();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
|
@ -1113,6 +1101,25 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
}
|
||||
};
|
||||
|
||||
const onKeyDown = (ev: KeyboardEvent) => {
|
||||
const action = getKeyBindingsManager().getAccessibilityAction(ev);
|
||||
|
||||
switch (action) {
|
||||
case KeyBindingAction.Backspace:
|
||||
if (!query && filter !== null) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
setFilter(null);
|
||||
}
|
||||
break;
|
||||
case KeyBindingAction.Enter:
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
rovingContext.state.activeRef?.current?.click();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const openFeedback = SdkConfig.get().bug_report_endpoint_url ? () => {
|
||||
Modal.createDialog(FeedbackDialog, {
|
||||
feature: "spotlight",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue