diff --git a/src/components/index.d.ts b/src/components/index.d.ts
index 0841f75163c..47da07187d0 100644
--- a/src/components/index.d.ts
+++ b/src/components/index.d.ts
@@ -3,7 +3,6 @@
///
///
///
-///
///
declare module '@elastic/eui' {
diff --git a/src/components/modal/__snapshots__/confirm_modal.test.js.snap b/src/components/modal/__snapshots__/confirm_modal.test.tsx.snap
similarity index 97%
rename from src/components/modal/__snapshots__/confirm_modal.test.js.snap
rename to src/components/modal/__snapshots__/confirm_modal.test.tsx.snap
index ec4fc631bb1..cdfebf3a559 100644
--- a/src/components/modal/__snapshots__/confirm_modal.test.js.snap
+++ b/src/components/modal/__snapshots__/confirm_modal.test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`renders EuiConfirmModal 1`] = `
+exports[`EuiConfirmModal renders EuiConfirmModal 1`] = `
Array [
,
- ,
- ,
- ,
-]
-`;
diff --git a/src/components/modal/confirm_modal.tsx b/src/components/modal/confirm_modal.tsx
index 4b79ffc6a4a..1eac57d229e 100644
--- a/src/components/modal/confirm_modal.tsx
+++ b/src/components/modal/confirm_modal.tsx
@@ -1,7 +1,12 @@
-import React, { FunctionComponent, ReactNode, useEffect } from 'react';
+import React, {
+ FunctionComponent,
+ ReactNode,
+ useEffect,
+ useState,
+} from 'react';
import classnames from 'classnames';
-import { EuiModal } from './modal';
+import { EuiModal, EuiModalProps } from './modal';
import { EuiModalFooter } from './modal_footer';
import { EuiModalHeader } from './modal_header';
import { EuiModalHeaderTitle } from './modal_header_title';
@@ -11,12 +16,20 @@ import { EuiButton, EuiButtonEmpty } from '../button';
import { EuiText } from '../text';
-export interface EuiConfirmModalProps {
+export interface EuiConfirmModalProps
+ extends Omit<
+ EuiModalProps,
+ 'children' | 'initialFocus' | 'onClose' | 'title'
+ > {
children?: ReactNode;
title?: ReactNode;
cancelButtonText?: ReactNode;
confirmButtonText?: ReactNode;
- onCancel: (event: React.MouseEvent) => void;
+ onCancel: (
+ event?:
+ | React.KeyboardEvent
+ | React.MouseEvent
+ ) => void;
onConfirm?: (event: React.MouseEvent) => void;
confirmButtonDisabled?: boolean;
className?: string;
@@ -42,31 +55,29 @@ export interface EuiConfirmModalProps {
export const CONFIRM_BUTTON = 'confirm';
export const CANCEL_BUTTON = 'cancel';
-export const EuiConfirmModal: FunctionComponent = (
- props: EuiConfirmModalProps
-) => {
- const {
- children,
- title,
- onCancel,
- onConfirm,
- cancelButtonText,
- confirmButtonText,
- confirmButtonDisabled,
- className,
- buttonColor = 'primary',
- defaultFocusedButton,
- ...rest
- } = props;
-
- let cancelButton: any;
- let confirmButton: any;
+export const EuiConfirmModal: FunctionComponent = ({
+ children,
+ title,
+ onCancel,
+ onConfirm,
+ cancelButtonText,
+ confirmButtonText,
+ confirmButtonDisabled,
+ className,
+ buttonColor = 'primary',
+ defaultFocusedButton,
+ ...rest
+}) => {
+ const [cancelButton, setCancelButton] = useState<
+ HTMLButtonElement | HTMLAnchorElement | null
+ >(null);
+ const [confirmButton, setConfirmButton] = useState(
+ null
+ );
useEffect(() => {
// We have to do this instead of using `autoFocus` because React's polyfill for auto-focusing
// elements conflicts with the focus-trap logic we have on EuiModal.
- const { defaultFocusedButton } = props;
-
// Wait a beat for the focus-trap to complete, and then set focus to the right button. Check that
// the buttons exist first, because it's possible the modal has been closed already.
requestAnimationFrame(() => {
@@ -76,10 +87,11 @@ export const EuiConfirmModal: FunctionComponent = (
confirmButton.focus();
}
});
- }, [cancelButton, confirmButton, props]);
+ });
- const confirmRef = (node: any) => (confirmButton = node);
- const cancelRef = (node: any) => (cancelButton = node);
+ const confirmRef = (node: HTMLButtonElement | null) => setConfirmButton(node);
+ const cancelRef = (node: HTMLButtonElement | HTMLAnchorElement | null) =>
+ setCancelButton(node);
const classes = classnames('euiModal--confirmation', className);
diff --git a/src/components/modal/index.d.ts b/src/components/modal/index.d.ts
deleted file mode 100644
index 970a0f4e334..00000000000
--- a/src/components/modal/index.d.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import { CommonProps } from '../common';
-import { FocusTarget } from '../focus_trap';
-
-import { ReactNode, FunctionComponent, HTMLAttributes } from 'react';
-
-import { ButtonColor } from '../button';
-
-import { EuiModalFooterProps } from './modal_footer';
-import { EuiModalHeaderProps } from './modal_header';
-import { EuiModalBodyProps } from './modal_body';
-import { EuiModalHeaderTitleProps } from './modal_header_title';
-
-declare module '@elastic/eui' {
- /**
- * Modal type defs
- *
- * @see './modal.js'
- */
- export interface EuiModalProps {
- onClose: () => void;
- /**
- * Sets the max-width of the modal,
- * set to `true` to use the default size,
- * set to `false` to not restrict the width,
- * set to a number for a custom width in px,
- * set to a string for a custom width in custom measurement.
- */
- maxWidth?: boolean | number | string;
-
- /**
- * Specifies what element should initially have focus;
- * Can be a DOM node, or a selector string (which will be passed to document.querySelector() to find the DOM node), or a function that returns a DOM node.
- */
- initialFocus?: FocusTarget;
- }
-
- export const EuiModal: FunctionComponent<
- CommonProps & HTMLAttributes & EuiModalProps
- >;
-
- /**
- * Confirm modal type defs
- *
- * @see './confirm_modal.js'
- */
-
- // index.js re-exports values from confirm_modal.js with these names.
- export const EUI_MODAL_CONFIRM_BUTTON: 'confirm';
- export const EUI_MODAL_CANCEL_BUTTON: 'cancel';
-
- export interface EuiConfirmModalProps {
- buttonColor?: ButtonColor;
- cancelButtonText?: ReactNode;
- confirmButtonText?: ReactNode;
- confirmButtonDisabled?: boolean;
- defaultFocusedButton?: 'confirm' | 'cancel';
- title?: ReactNode;
- onCancel?: () => void;
- onConfirm?: () => void;
- /**
- * Sets the max-width of the modal,
- * set to `true` to use the default size,
- * set to `false` to not restrict the width,
- * set to a number for a custom width in px,
- * set to a string for a custom width in custom measurement.
- */
- maxWidth?: boolean | number | string;
- }
-
- // `title` from the React defs conflicts with our definition above
- export const EuiConfirmModal: FunctionComponent<
- CommonProps &
- Omit, 'title'> &
- EuiConfirmModalProps
- >;
-
- /**
- * Modal body type defs
- *
- * @see './modal_body.js'
- */
- export const EuiModalBody: EuiModalBodyProps;
-
- /**
- * Modal footer type defs
- *
- * @see './modal_footer.js'
- */
- export const EuiModalFooter: EuiModalFooterProps;
-
- /**
- * Modal header type defs
- *
- * @see './modal_header.js'
- */
- export const EuiModalHeader: EuiModalHeaderProps;
-
- /**
- * Modal header title type defs
- *
- * @see './modal_header_title.js'
- */
- export const EuiModalHeaderTitle: EuiModalHeaderTitleProps;
-}
diff --git a/src/components/modal/index.ts b/src/components/modal/index.ts
index 7446470c826..de7fb9a2e59 100644
--- a/src/components/modal/index.ts
+++ b/src/components/modal/index.ts
@@ -5,7 +5,10 @@ export {
CANCEL_BUTTON as EUI_MODAL_CANCEL_BUTTON,
} from './confirm_modal';
export { EuiModal, EuiModalProps } from './modal';
-export { EuiModalFooter } from './modal_footer';
-export { EuiModalHeader } from './modal_header';
-export { EuiModalBody } from './modal_body';
-export { EuiModalHeaderTitle } from './modal_header_title';
+export { EuiModalFooter, EuiModalFooterProps } from './modal_footer';
+export { EuiModalHeader, EuiModalHeaderProps } from './modal_header';
+export { EuiModalBody, EuiModalBodyProps } from './modal_body';
+export {
+ EuiModalHeaderTitle,
+ EuiModalHeaderTitleProps,
+} from './modal_header_title';
diff --git a/src/components/modal/modal.tsx b/src/components/modal/modal.tsx
index fcc9c559f8d..6ba0ec5067e 100644
--- a/src/components/modal/modal.tsx
+++ b/src/components/modal/modal.tsx
@@ -12,7 +12,11 @@ import { EuiI18n } from '../i18n';
export interface EuiModalProps extends HTMLAttributes {
className?: string;
children: ReactNode;
- onClose: (event?: any) => void;
+ onClose: (
+ event?:
+ | React.KeyboardEvent
+ | React.MouseEvent
+ ) => void;
/**
* Sets the max-width of the modal.
* Set to `true` to use the default (`euiBreakpoints 'm'`),
@@ -25,19 +29,15 @@ export interface EuiModalProps extends HTMLAttributes {
initialFocus?: HTMLElement | (() => HTMLElement) | string;
}
-export const EuiModal: FunctionComponent = (
- props: EuiModalProps
-) => {
- const {
- className,
- children,
- initialFocus,
- onClose, // eslint-disable-line no-unused-vars
- maxWidth = true,
- style,
- ...rest
- } = props;
-
+export const EuiModal: FunctionComponent = ({
+ className,
+ children,
+ initialFocus,
+ onClose,
+ maxWidth = true,
+ style,
+ ...rest
+}) => {
const onKeyDown = (event: React.KeyboardEvent) => {
if (event.keyCode === keyCodes.ESCAPE) {
event.preventDefault();
@@ -70,7 +70,7 @@ export const EuiModal: FunctionComponent = (
style={newStyle || style}
{...rest}>
- {(closeModal: any) => (
+ {(closeModal: string) => (