mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
A11y: Make the Library Panel "clear filter" buttons accessible (#46341)
* swap span for button + add aria-label * swap span for button + add aria-label * add new style + increase padding * fix typo * switch to link variant + trim custom css
This commit is contained in:
parent
73ba04cda6
commit
ec84b7bd23
@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import debounce from 'debounce-promise';
|
||||
import { AsyncMultiSelect, Icon, useStyles2 } from '@grafana/ui';
|
||||
import { AsyncMultiSelect, Icon, Button, useStyles2 } from '@grafana/ui';
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
|
||||
import { FolderInfo, PermissionLevelString } from 'app/types';
|
||||
@ -44,9 +44,16 @@ export function FolderFilter({ onChange: propsOnChange, maxMenuHeight }: FolderF
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{value.length > 0 && (
|
||||
<span className={styles.clear} onClick={() => onChange([])}>
|
||||
<Button
|
||||
size="xs"
|
||||
icon="trash-alt"
|
||||
variant="link"
|
||||
className={styles.clear}
|
||||
onClick={() => onChange([])}
|
||||
aria-label="Clear folders"
|
||||
>
|
||||
Clear folders
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
<AsyncMultiSelect
|
||||
menuShouldPortal
|
||||
@ -90,17 +97,10 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
`,
|
||||
clear: css`
|
||||
label: clear;
|
||||
text-decoration: underline;
|
||||
font-size: ${theme.spacing(1.5)};
|
||||
position: absolute;
|
||||
top: -${theme.spacing(2.75)};
|
||||
top: -${theme.spacing(4.5)};
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
color: ${theme.colors.text.link};
|
||||
|
||||
&:hover {
|
||||
color: ${theme.colors.text.maxContrast};
|
||||
}
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data';
|
||||
import { getAllPanelPluginMeta } from 'app/features/panel/state/util';
|
||||
import { Icon, MultiSelect, useStyles2 } from '@grafana/ui';
|
||||
import { Icon, Button, MultiSelect, useStyles2 } from '@grafana/ui';
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
export interface Props {
|
||||
@ -51,9 +51,16 @@ export const PanelTypeFilter = ({ onChange: propsOnChange, maxMenuHeight }: Prop
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{value.length > 0 && (
|
||||
<span className={styles.clear} onClick={() => onChange([])}>
|
||||
<Button
|
||||
size="xs"
|
||||
icon="trash-alt"
|
||||
variant="link"
|
||||
className={styles.clear}
|
||||
onClick={() => onChange([])}
|
||||
aria-label="Clear types"
|
||||
>
|
||||
Clear types
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
<MultiSelect menuShouldPortal {...selectOptions} prefix={<Icon name="filter" />} aria-label="Panel Type filter" />
|
||||
</div>
|
||||
@ -70,17 +77,10 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
`,
|
||||
clear: css`
|
||||
label: clear;
|
||||
text-decoration: underline;
|
||||
font-size: ${theme.spacing(1.5)};
|
||||
position: absolute;
|
||||
top: -${theme.spacing(2.75)};
|
||||
top: -${theme.spacing(4.5)};
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
color: ${theme.colors.text.link};
|
||||
|
||||
&:hover {
|
||||
color: ${theme.colors.text.maxContrast};
|
||||
}
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
@ -66,18 +66,23 @@ export const LibraryPanelsSearch = ({
|
||||
placeholder={'Search by name or description'}
|
||||
width={0}
|
||||
/>
|
||||
<HorizontalGroup
|
||||
spacing="sm"
|
||||
justify={(showSort && showPanelFilter) || showFolderFilter ? 'space-between' : 'flex-end'}
|
||||
>
|
||||
{showSort && (
|
||||
<SortPicker value={sortDirection} onChange={onSortChange} filter={['alpha-asc', 'alpha-desc']} />
|
||||
)}
|
||||
<HorizontalGroup spacing="sm" justify={showFolderFilter && showPanelFilter ? 'space-between' : 'flex-end'}>
|
||||
{showFolderFilter && <FolderFilter onChange={onFolderFilterChange} />}
|
||||
{showPanelFilter && <PanelTypeFilter onChange={onPanelFilterChange} />}
|
||||
<div className={styles.buttonRow}>
|
||||
<HorizontalGroup
|
||||
spacing="sm"
|
||||
justify={(showSort && showPanelFilter) || showFolderFilter ? 'space-between' : 'flex-end'}
|
||||
>
|
||||
{showSort && (
|
||||
<SortPicker value={sortDirection} onChange={onSortChange} filter={['alpha-asc', 'alpha-desc']} />
|
||||
)}
|
||||
<HorizontalGroup
|
||||
spacing="sm"
|
||||
justify={showFolderFilter && showPanelFilter ? 'space-between' : 'flex-end'}
|
||||
>
|
||||
{showFolderFilter && <FolderFilter onChange={onFolderFilterChange} />}
|
||||
{showPanelFilter && <PanelTypeFilter onChange={onPanelFilterChange} />}
|
||||
</HorizontalGroup>
|
||||
</HorizontalGroup>
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
<div className={styles.libraryPanelsView}>
|
||||
<LibraryPanelsView
|
||||
onClickCard={onClick}
|
||||
@ -98,7 +103,7 @@ export const LibraryPanelsSearch = ({
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<VerticalGroup spacing="xs">
|
||||
<div className={styles.buttonRow}>
|
||||
<div className={styles.tightButtonRow}>
|
||||
<div className={styles.tightFilter}>
|
||||
<FilterInput value={searchQuery} onChange={onFilterChange} placeholder={'Search by name'} width={0} />
|
||||
</div>
|
||||
@ -136,7 +141,13 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
margin-top: ${theme.spacing(1.5)}; // Clear types link
|
||||
margin-top: ${theme.spacing(2)}; // Clear types link
|
||||
`,
|
||||
tightButtonRow: css`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
margin-top: ${theme.spacing(4)}; // Clear types link
|
||||
`,
|
||||
tightFilter: css`
|
||||
flex-grow: 1;
|
||||
|
Loading…
Reference in New Issue
Block a user