Allow to bypass modal focus trap (#43974)

This commit is contained in:
Andres Martinez Gotor 2022-01-13 12:55:54 +01:00 committed by GitHub
parent 4a88b8f66c
commit 0a17048316
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 9 deletions

View File

@ -1,13 +1,14 @@
import React, { PropsWithChildren, useCallback, useEffect } from 'react';
import { cx } from '@emotion/css'; import { cx } from '@emotion/css';
import { useTheme2 } from '../../themes';
import { IconName } from '../../types';
import { getModalStyles } from './getModalStyles';
import { ModalHeader } from './ModalHeader';
import { IconButton } from '../IconButton/IconButton';
import { HorizontalGroup } from '../Layout/Layout';
import { FocusScope } from '@react-aria/focus'; import { FocusScope } from '@react-aria/focus';
import { OverlayContainer } from '@react-aria/overlays'; import { OverlayContainer } from '@react-aria/overlays';
import React, { PropsWithChildren, useCallback, useEffect } from 'react';
import { useTheme2 } from '../../themes';
import { IconName } from '../../types';
import { IconButton } from '../IconButton/IconButton';
import { HorizontalGroup } from '../Layout/Layout';
import { getModalStyles } from './getModalStyles';
import { ModalHeader } from './ModalHeader';
export interface Props { export interface Props {
/** @deprecated no longer used */ /** @deprecated no longer used */
@ -20,6 +21,7 @@ export interface Props {
contentClassName?: string; contentClassName?: string;
closeOnEscape?: boolean; closeOnEscape?: boolean;
closeOnBackdropClick?: boolean; closeOnBackdropClick?: boolean;
trapFocus?: boolean;
isOpen?: boolean; isOpen?: boolean;
onDismiss?: () => void; onDismiss?: () => void;
@ -39,6 +41,7 @@ export function Modal(props: PropsWithChildren<Props>) {
contentClassName, contentClassName,
onDismiss: propsOnDismiss, onDismiss: propsOnDismiss,
onClickBackdrop, onClickBackdrop,
trapFocus = true,
} = props; } = props;
const theme = useTheme2(); const theme = useTheme2();
const styles = getModalStyles(theme); const styles = getModalStyles(theme);
@ -76,7 +79,7 @@ export function Modal(props: PropsWithChildren<Props>) {
className={styles.modalBackdrop} className={styles.modalBackdrop}
onClick={onClickBackdrop || (closeOnBackdropClick ? onDismiss : undefined)} onClick={onClickBackdrop || (closeOnBackdropClick ? onDismiss : undefined)}
/> />
<FocusScope contain autoFocus restoreFocus> <FocusScope contain={trapFocus} autoFocus restoreFocus>
<div className={cx(styles.modal, className)}> <div className={cx(styles.modal, className)}>
<div className={headerClass}> <div className={headerClass}>
{typeof title === 'string' && <DefaultModalHeader {...props} title={title} />} {typeof title === 'string' && <DefaultModalHeader {...props} title={title} />}

View File

@ -2,6 +2,7 @@ import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Button, Icon, Modal, useStyles2 } from '@grafana/ui'; import { Button, Icon, Modal, useStyles2 } from '@grafana/ui';
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import Datasource from '../../datasource'; import Datasource from '../../datasource';
import { AzureQueryEditorFieldProps, AzureResourceSummaryItem } from '../../types'; import { AzureQueryEditorFieldProps, AzureResourceSummaryItem } from '../../types';
import { Field } from '../Field'; import { Field } from '../Field';
@ -49,7 +50,15 @@ const ResourceField: React.FC<AzureQueryEditorFieldProps> = ({ query, datasource
return ( return (
<> <>
<Modal className={styles.modal} title="Select a resource" isOpen={pickerIsOpen} onDismiss={closePicker}> <Modal
className={styles.modal}
title="Select a resource"
isOpen={pickerIsOpen}
onDismiss={closePicker}
// The growing number of rows added to the modal causes a focus
// error in the modal, making it impossible to click on new elements
trapFocus={false}
>
<ResourcePicker <ResourcePicker
resourcePickerData={datasource.resourcePickerData} resourcePickerData={datasource.resourcePickerData}
resourceURI={resource} resourceURI={resource}