mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
A11y: Fix fastpass issues for annotation/variables settings (#40364)
* A11y: Fix fastpass issues for annotation/variables settings * Chore: fixes fastpass for annotations * Chore: updates after PR comments * Chore: readd div
This commit is contained in:
parent
281d60095f
commit
a512dcf1bb
@ -88,6 +88,9 @@ export const Pages = {
|
|||||||
General: {
|
General: {
|
||||||
headerLink: 'Variable editor Header link',
|
headerLink: 'Variable editor Header link',
|
||||||
modeLabelNew: 'Variable editor Header mode New',
|
modeLabelNew: 'Variable editor Header mode New',
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
modeLabelEdit: 'Variable editor Header mode Edit',
|
modeLabelEdit: 'Variable editor Header mode Edit',
|
||||||
generalNameInput: 'Variable editor Form Name field',
|
generalNameInput: 'Variable editor Form Name field',
|
||||||
generalTypeSelect: 'Variable editor Form Type select',
|
generalTypeSelect: 'Variable editor Form Type select',
|
||||||
|
@ -29,6 +29,12 @@ export interface FieldProps extends HTMLAttributes<HTMLDivElement> {
|
|||||||
validationMessageHorizontalOverflow?: boolean;
|
validationMessageHorizontalOverflow?: boolean;
|
||||||
|
|
||||||
className?: string;
|
className?: string;
|
||||||
|
/**
|
||||||
|
* A unique id that associates the label of the Field component with the control with the unique id.
|
||||||
|
* If the `htmlFor` property is missing the `htmlFor` will be inferred from the `id` or `inputId` property of the first child.
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label#attr-for
|
||||||
|
*/
|
||||||
|
htmlFor?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getFieldStyles = stylesFactory((theme: GrafanaTheme2) => {
|
export const getFieldStyles = stylesFactory((theme: GrafanaTheme2) => {
|
||||||
@ -72,11 +78,12 @@ export const Field: React.FC<FieldProps> = ({
|
|||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
validationMessageHorizontalOverflow,
|
validationMessageHorizontalOverflow,
|
||||||
|
htmlFor,
|
||||||
...otherProps
|
...otherProps
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme2();
|
const theme = useTheme2();
|
||||||
const styles = getFieldStyles(theme);
|
const styles = getFieldStyles(theme);
|
||||||
const inputId = getChildId(children);
|
const inputId = htmlFor ?? getChildId(children);
|
||||||
|
|
||||||
const labelElement =
|
const labelElement =
|
||||||
typeof label === 'string' ? (
|
typeof label === 'string' ? (
|
||||||
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
|||||||
import { Checkbox, CollapsableSection, ColorValueEditor, Field, HorizontalGroup, Input } from '@grafana/ui';
|
import { Checkbox, CollapsableSection, ColorValueEditor, Field, HorizontalGroup, Input } from '@grafana/ui';
|
||||||
import { DashboardModel } from '../../state/DashboardModel';
|
import { DashboardModel } from '../../state/DashboardModel';
|
||||||
import { AnnotationQuery, DataSourceInstanceSettings } from '@grafana/data';
|
import { AnnotationQuery, DataSourceInstanceSettings } from '@grafana/data';
|
||||||
import { getDataSourceSrv, DataSourcePicker } from '@grafana/runtime';
|
import { DataSourcePicker, getDataSourceSrv } from '@grafana/runtime';
|
||||||
import { useAsync } from 'react-use';
|
import { useAsync } from 'react-use';
|
||||||
import StandardAnnotationQueryEditor from 'app/features/annotations/components/StandardAnnotationQueryEditor';
|
import StandardAnnotationQueryEditor from 'app/features/annotations/components/StandardAnnotationQueryEditor';
|
||||||
import { AngularEditorLoader } from './AngularEditorLoader';
|
import { AngularEditorLoader } from './AngularEditorLoader';
|
||||||
@ -78,7 +78,7 @@ export const AnnotationSettingsEdit: React.FC<Props> = ({ editIdx, dashboard })
|
|||||||
width={50}
|
width={50}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
<Field label="Data source">
|
<Field label="Data source" htmlFor="data-source-picker">
|
||||||
<DataSourcePicker
|
<DataSourcePicker
|
||||||
width={50}
|
width={50}
|
||||||
annotations
|
annotations
|
||||||
|
@ -74,7 +74,11 @@ export const AnnotationSettingsList: React.FC<Props> = ({ dashboard, onNew, onEd
|
|||||||
) : null}
|
) : null}
|
||||||
</td>
|
</td>
|
||||||
<td style={{ width: '1%' }}>
|
<td style={{ width: '1%' }}>
|
||||||
<DeleteButton size="sm" onConfirm={() => onDelete(idx)} />
|
<DeleteButton
|
||||||
|
size="sm"
|
||||||
|
onConfirm={() => onDelete(idx)}
|
||||||
|
aria-label={`Delete query with title "${annotation.name}"`}
|
||||||
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
|
@ -148,7 +148,7 @@ describe('AnnotationsSettings', () => {
|
|||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
expect(screen.queryByRole('button', { name: /new query/i })).not.toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: /new query/i })).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /delete/i }));
|
userEvent.click(screen.getByRole('button', { name: /^delete$/i }));
|
||||||
|
|
||||||
expect(screen.queryAllByRole('row').length).toBe(0);
|
expect(screen.queryAllByRole('row').length).toBe(0);
|
||||||
expect(
|
expect(
|
||||||
|
@ -335,6 +335,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
|
|||||||
const containerClassNames = classnames(styles.dashboardContainer, {
|
const containerClassNames = classnames(styles.dashboardContainer, {
|
||||||
'panel-in-fullscreen': viewPanel,
|
'panel-in-fullscreen': viewPanel,
|
||||||
});
|
});
|
||||||
|
const showSubMenu = !editPanel && kioskMode === KioskMode.Off && !this.props.queryParams.editview;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={containerClassNames}>
|
<div className={containerClassNames}>
|
||||||
@ -364,7 +365,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
|
|||||||
>
|
>
|
||||||
<div className={styles.dashboardContent}>
|
<div className={styles.dashboardContent}>
|
||||||
{initError && <DashboardFailed />}
|
{initError && <DashboardFailed />}
|
||||||
{!editPanel && kioskMode === KioskMode.Off && (
|
{showSubMenu && (
|
||||||
<section aria-label={selectors.pages.Dashboard.SubMenu.submenu}>
|
<section aria-label={selectors.pages.Dashboard.SubMenu.submenu}>
|
||||||
<SubMenu dashboard={dashboard} annotations={dashboard.annotations.list} links={dashboard.links} />
|
<SubMenu dashboard={dashboard} annotations={dashboard.annotations.list} links={dashboard.links} />
|
||||||
</section>
|
</section>
|
||||||
|
@ -85,10 +85,7 @@ class VariableEditorContainerUnconnected extends PureComponent<Props> {
|
|||||||
</a>
|
</a>
|
||||||
{this.props.idInEditor && (
|
{this.props.idInEditor && (
|
||||||
<span>
|
<span>
|
||||||
<Icon
|
<Icon name="angle-right" />
|
||||||
name="angle-right"
|
|
||||||
aria-label={selectors.pages.Dashboard.Settings.Variables.Edit.General.modeLabelEdit}
|
|
||||||
/>
|
|
||||||
Edit
|
Edit
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
@ -25,14 +25,16 @@ export function VariableSelectField({
|
|||||||
labelWidth,
|
labelWidth,
|
||||||
}: PropsWithChildren<VariableSelectFieldProps<any>>): ReactElement {
|
}: PropsWithChildren<VariableSelectFieldProps<any>>): ReactElement {
|
||||||
const styles = useStyles(getStyles);
|
const styles = useStyles(getStyles);
|
||||||
|
const inputId = `variable-select-input-${name}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<InlineFormLabel width={labelWidth ?? 6} tooltip={tooltip}>
|
<InlineFormLabel width={labelWidth ?? 6} tooltip={tooltip} htmlFor={inputId}>
|
||||||
{name}
|
{name}
|
||||||
</InlineFormLabel>
|
</InlineFormLabel>
|
||||||
<div aria-label={ariaLabel}>
|
<div aria-label={ariaLabel}>
|
||||||
<Select
|
<Select
|
||||||
|
inputId={inputId}
|
||||||
menuShouldPortal
|
menuShouldPortal
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
value={value}
|
value={value}
|
||||||
|
@ -161,7 +161,7 @@ export class QueryVariableEditorUnConnected extends PureComponent<Props, State>
|
|||||||
<VerticalGroup spacing="lg">
|
<VerticalGroup spacing="lg">
|
||||||
<VerticalGroup spacing="none">
|
<VerticalGroup spacing="none">
|
||||||
<InlineFieldRow>
|
<InlineFieldRow>
|
||||||
<InlineField label="Data source" labelWidth={20}>
|
<InlineField label="Data source" labelWidth={20} htmlFor="data-source-picker">
|
||||||
<DataSourcePicker
|
<DataSourcePicker
|
||||||
current={this.props.variable.datasource}
|
current={this.props.variable.datasource}
|
||||||
onChange={this.onDataSourceChange}
|
onChange={this.onDataSourceChange}
|
||||||
|
Loading…
Reference in New Issue
Block a user