fix(devtools-view): Fix selectable menu section role (#23177)

[Previous PR](https://github.com/microsoft/FluidFramework/pull/23093)
attempted to fix this by setting the "button" role via style properties,
but apparently this doesn't actually work. Confirmed that the role did
not appear in the browser devtools view previously but does with the new
pattern.

Also updates styling to highlight selectable menu headers the same way
we highlight sub-heading selections.
This commit is contained in:
Joshua Smithrud 2024-11-22 10:44:46 -08:00 коммит произвёл GitHub
Родитель cae07b5c8c
Коммит bea8dd5332
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 45 добавлений и 12 удалений

Просмотреть файл

@ -4,6 +4,10 @@
<!-- Enumerate unpublished changes here. They can be merged into release sections when the next release is published. -->
# 1.0.2
Enhance selection styling in main menu of the devtools view and fix menu item roles for accessibility.
# 1.0.1
Update extension name to omit the " (preview)" postfix.

Просмотреть файл

@ -3,7 +3,7 @@
"name": "Fluid Framework Developer Tools",
"description": "Devtools extension for viewing live data about your Fluid application.",
"author": "Microsoft",
"version": "1.0.1",
"version": "1.0.2",
"action": {
"default_icon": {
"16": "icons/icon_16.png",

Просмотреть файл

@ -237,7 +237,9 @@ function _DevtoolsView(props: _DevtoolsViewProps): React.ReactElement {
const { supportedFeatures } = props;
const [containers, setContainers] = React.useState<ContainerKey[] | undefined>();
const [menuSelection, setMenuSelection] = React.useState<MenuSelection | undefined>();
const [menuSelection, setMenuSelection] = React.useState<MenuSelection>({
type: "homeMenuSelection",
});
const messageRelay = useMessageRelay();
React.useEffect(() => {

Просмотреть файл

@ -247,6 +247,11 @@ export interface MenuSectionButtonHeaderProps extends MenuSectionLabelHeaderProp
* Button alt text.
*/
altText: string;
/**
* Whether or not this selectable heading is the current selection.
*/
isActive: boolean;
}
const useMenuSectionButtonHeaderStyles = makeStyles({
@ -256,7 +261,18 @@ const useMenuSectionButtonHeaderStyles = makeStyles({
flexDirection: "row",
fontWeight: "bold",
cursor: "pointer",
role: "button",
"&:hover": {
color: tokens.colorNeutralForeground1Hover,
backgroundColor: tokens.colorNeutralBackground1Hover,
},
},
active: {
color: tokens.colorNeutralForeground1Selected,
backgroundColor: tokens.colorNeutralBackground1Selected,
},
inactive: {
color: tokens.colorNeutralForeground1,
backgroundColor: tokens.colorNeutralBackground1,
},
});
@ -266,8 +282,9 @@ const useMenuSectionButtonHeaderStyles = makeStyles({
export function MenuSectionButtonHeader(
props: MenuSectionButtonHeaderProps,
): React.ReactElement {
const { label, icon, onClick, altText } = props;
const { label, icon, onClick, altText, isActive } = props;
const styles = useMenuSectionButtonHeaderStyles();
const style = mergeClasses(styles.root, isActive ? styles.active : styles.inactive);
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {
if ((event.key === "Enter" || event.key === " ") && onClick) {
@ -277,11 +294,12 @@ export function MenuSectionButtonHeader(
return (
<div
className={styles.root}
className={style}
onClick={onClick}
onKeyDown={handleKeyDown}
aria-label={altText}
tabIndex={0}
role="button"
>
{label}
{icon}
@ -353,16 +371,14 @@ export function MenuItem(props: MenuItemProps): React.ReactElement {
*/
export interface MenuProps {
/**
* The current menu selection (if any).
* The current menu selection.
*/
currentSelection?: MenuSelection | undefined;
currentSelection: MenuSelection;
/**
* Sets the menu selection to the specified value.
*
* @remarks Passing `undefined` clears the selection.
*/
setSelection(newSelection: MenuSelection | undefined): void;
setSelection(newSelection: MenuSelection): void;
/**
* Set of features supported by the {@link @fluidframework/devtools-core#IFluidDevtools}
@ -491,7 +507,14 @@ export function Menu(props: MenuProps): React.ReactElement {
menuSections.push(
<MenuSection
header={<MenuSectionButtonHeader label="Home" altText="Home" onClick={onHomeClicked} />}
header={
<MenuSectionButtonHeader
label="Home"
altText="Home"
onClick={onHomeClicked}
isActive={currentSelection.type === "homeMenuSelection"}
/>
}
key="home-menu-section"
/>,
<ContainersMenuSection
@ -530,6 +553,7 @@ export function Menu(props: MenuProps): React.ReactElement {
label="Op Latency"
altText="Op Latency"
onClick={onOpLatencyClicked}
isActive={currentSelection?.type === "opLatencyMenuSelection"}
/>
}
key="op-latency-menu-section"
@ -544,6 +568,7 @@ export function Menu(props: MenuProps): React.ReactElement {
label="Settings"
altText="Settings"
onClick={onSettingsClicked}
isActive={currentSelection?.type === "settingsMenuSelection"}
/>
}
key="settings-menu-section"

Просмотреть файл

@ -35,7 +35,9 @@ describe("Menu Accessibility Check", () => {
};
});
const MenuWrapper: React.FC = () => {
const [menuSelection, setMenuSelection] = React.useState<MenuSelection | undefined>();
const [menuSelection, setMenuSelection] = React.useState<MenuSelection>({
type: "homeMenuSelection",
});
return (
<MessageRelayContext.Provider value={mockMessageRelay}>