mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
UI/Alert: Infer the role
property based on the severity
(#61242)
* feat(UI/Alert): add two new optional properties: 'ariaLabel' and 'role' * docs(UI/Alert): add some docs to the props * feat: infer the role based on the severity * fix: stop overriding props * fix: fix a test depending on the wrong alert role
This commit is contained in:
parent
6c566a391d
commit
29119a7d08
@ -4,8 +4,34 @@ import React from 'react';
|
||||
import { Alert } from './Alert';
|
||||
|
||||
describe('Alert', () => {
|
||||
it('sets the accessible label correctly based on the title', () => {
|
||||
it('sets the accessible label correctly based on the title if there is no aria-label set', () => {
|
||||
render(<Alert title="Uh oh spagghettios!" />);
|
||||
expect(screen.getByRole('alert', { name: 'Uh oh spagghettios!' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('prefers the aria-label attribute over the title if it is set', () => {
|
||||
render(<Alert title="Uh oh spagghettios!" aria-label="A fancy label" />);
|
||||
expect(screen.queryByRole('alert', { name: 'Uh oh spagghettios!' })).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('alert', { name: 'A fancy label' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('infers the role based on the severity in case it is not set manually', () => {
|
||||
render(<Alert title="Error message" severity="error" />);
|
||||
expect(screen.getByRole('alert', { name: 'Error message' })).toBeInTheDocument();
|
||||
|
||||
render(<Alert title="Warning message" severity="warning" />);
|
||||
expect(screen.getByRole('alert', { name: 'Warning message' })).toBeInTheDocument();
|
||||
|
||||
render(<Alert title="Success message" severity="success" />);
|
||||
expect(screen.getByRole('status', { name: 'Success message' })).toBeInTheDocument();
|
||||
|
||||
render(<Alert title="Info message" severity="info" />);
|
||||
expect(screen.getByRole('status', { name: 'Info message' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('is possible to set the role manually', () => {
|
||||
render(<Alert title="Error message" severity="error" role="status" />);
|
||||
expect(screen.queryByRole('alert', { name: 'Error message' })).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('status', { name: 'Error message' })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { useId } from '@react-aria/utils';
|
||||
import React, { HTMLAttributes, ReactNode } from 'react';
|
||||
import React, { AriaRole, HTMLAttributes, ReactNode } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
@ -56,15 +55,22 @@ export const Alert = React.forwardRef<HTMLDivElement, Props>(
|
||||
const theme = useTheme2();
|
||||
const hasTitle = Boolean(title);
|
||||
const styles = getStyles(theme, severity, hasTitle, elevated, bottomSpacing, topSpacing);
|
||||
const titleId = useId();
|
||||
const rolesBySeverity: Record<AlertVariant, AriaRole> = {
|
||||
error: 'alert',
|
||||
warning: 'alert',
|
||||
info: 'status',
|
||||
success: 'status',
|
||||
};
|
||||
const role = restProps['role'] || rolesBySeverity[severity];
|
||||
const ariaLabel = restProps['aria-label'] || title;
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cx(styles.alert, className)}
|
||||
data-testid={selectors.components.Alert.alertV2(severity)}
|
||||
role="alert"
|
||||
aria-labelledby={titleId}
|
||||
role={role}
|
||||
aria-label={ariaLabel}
|
||||
{...restProps}
|
||||
>
|
||||
<div className={styles.icon}>
|
||||
@ -72,9 +78,7 @@ export const Alert = React.forwardRef<HTMLDivElement, Props>(
|
||||
</div>
|
||||
|
||||
<div className={styles.body}>
|
||||
<div id={titleId} className={styles.title}>
|
||||
{title}
|
||||
</div>
|
||||
<div className={styles.title}>{title}</div>
|
||||
{children && <div className={styles.content}>{children}</div>}
|
||||
</div>
|
||||
|
||||
|
@ -69,7 +69,7 @@ describe('QueryEditorField', () => {
|
||||
it('shows an info alert when no datasource is selected', async () => {
|
||||
renderWithContext(<QueryEditorField name="query" />);
|
||||
|
||||
expect(await screen.findByRole('alert', { name: 'No data source selected' })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('status', { name: 'No data source selected' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows an info alert when datasaource does not export a query editor', async () => {
|
||||
|
Loading…
Reference in New Issue
Block a user