mirror of
https://github.com/grafana/grafana.git
synced 2024-11-30 04:34:23 -06:00
A11y : Fix option panes not accessible when collapsed (#46405)
* Turned div into text button to make it accessible * Only icon as button to avoid embedded buttons with overrides delete button * use icon in Button directly * Removed unused import * moving id for labelledBy to h6 elem instead of icon * Tweaking style, bigger caret * Fixed aria-expanded * Modifying and using CollapseToggle from unified alerting * Added restOfProps to CollapseToggle
This commit is contained in:
parent
2409405c34
commit
0b0d612372
@ -1,43 +1,45 @@
|
||||
import React, { FC, HTMLAttributes } from 'react';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { IconSize, useStyles, Icon } from '@grafana/ui';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { IconSize, useStyles2, Button } from '@grafana/ui';
|
||||
|
||||
interface Props extends HTMLAttributes<HTMLButtonElement> {
|
||||
isCollapsed: boolean;
|
||||
onToggle: (isCollapsed: boolean) => void;
|
||||
// Todo: this should be made compulsory for a11y purposes
|
||||
idControlled?: string;
|
||||
size?: IconSize;
|
||||
className?: string;
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export const CollapseToggle: FC<Props> = ({ isCollapsed, onToggle, className, text, size = 'xl', ...restOfProps }) => {
|
||||
const styles = useStyles(getStyles);
|
||||
export const CollapseToggle: FC<Props> = ({
|
||||
isCollapsed,
|
||||
onToggle,
|
||||
idControlled,
|
||||
className,
|
||||
text,
|
||||
size = 'xl',
|
||||
...restOfProps
|
||||
}) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
<button
|
||||
aria-label={`${isCollapsed ? 'Expand' : 'Collapse'} alert group`}
|
||||
<Button
|
||||
fill="text"
|
||||
aria-expanded={!isCollapsed}
|
||||
aria-controls={idControlled}
|
||||
className={cx(styles.expandButton, className)}
|
||||
icon={isCollapsed ? 'angle-right' : 'angle-down'}
|
||||
onClick={() => onToggle(!isCollapsed)}
|
||||
{...restOfProps}
|
||||
>
|
||||
<Icon size={size} name={isCollapsed ? 'angle-right' : 'angle-down'} />
|
||||
{text}
|
||||
</button>
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const getStyles = () => ({
|
||||
export const getStyles = (theme: GrafanaTheme2) => ({
|
||||
expandButton: css`
|
||||
background: none;
|
||||
border: none;
|
||||
|
||||
outline: none !important;
|
||||
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
svg {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
color: ${theme.colors.text.secondary};
|
||||
margin-right: ${theme.spacing(1)};
|
||||
`,
|
||||
});
|
||||
|
@ -1,11 +1,12 @@
|
||||
import React, { FC, ReactNode, useCallback, useEffect, useState, useRef } from 'react';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Counter, Icon, useStyles2 } from '@grafana/ui';
|
||||
import { Counter, useStyles2 } from '@grafana/ui';
|
||||
import { PANEL_EDITOR_UI_STATE_STORAGE_KEY } from './state/reducers';
|
||||
import { useLocalStorage } from 'react-use';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import { CollapseToggle } from 'app/features/alerting/unified/components/CollapseToggle';
|
||||
|
||||
export interface OptionsPaneCategoryProps {
|
||||
id: string;
|
||||
@ -101,12 +102,16 @@ export const OptionsPaneCategory: FC<OptionsPaneCategoryProps> = React.memo(
|
||||
ref={ref}
|
||||
>
|
||||
<div className={headerStyles} onClick={onToggle} aria-label={selectors.components.OptionsGroup.toggle(id)}>
|
||||
<div className={cx(styles.toggle, 'editor-options-group-toggle')}>
|
||||
<Icon name={isExpanded ? 'angle-down' : 'angle-right'} />
|
||||
</div>
|
||||
<h6 className={styles.title}>{renderTitle(isExpanded)}</h6>
|
||||
<CollapseToggle isCollapsed={!isExpanded} idControlled={id} onToggle={onToggle} />
|
||||
<h6 id={`button-${id}`} className={styles.title}>
|
||||
{renderTitle(isExpanded)}
|
||||
</h6>
|
||||
</div>
|
||||
{isExpanded && <div className={bodyStyles}>{children}</div>}
|
||||
{isExpanded && (
|
||||
<div className={bodyStyles} id={id} aria-labelledby={`button-${id}`}>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -122,10 +127,6 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
boxNestedExpanded: css`
|
||||
margin-bottom: ${theme.spacing(2)};
|
||||
`,
|
||||
toggle: css`
|
||||
color: ${theme.colors.text.secondary};
|
||||
margin-right: ${theme.spacing(1)};
|
||||
`,
|
||||
title: css`
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
@ -138,7 +139,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: baseline;
|
||||
padding: ${theme.spacing(1)};
|
||||
padding: ${theme.spacing(0.5)};
|
||||
color: ${theme.colors.text.primary};
|
||||
font-weight: ${theme.typography.fontWeightMedium};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user