From 52d664874ebac299940b675878c09b221b0990ed Mon Sep 17 00:00:00 2001
From: Greg Thompson
Date: Thu, 28 Jul 2022 14:04:19 -0500
Subject: [PATCH 01/10] add fade in animation
---
src/global_styling/index.ts | 1 +
src/global_styling/utility/animations.ts | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
create mode 100644 src/global_styling/utility/animations.ts
diff --git a/src/global_styling/index.ts b/src/global_styling/index.ts
index 5fc347eaf52..fbd28be2dff 100644
--- a/src/global_styling/index.ts
+++ b/src/global_styling/index.ts
@@ -10,3 +10,4 @@ export * from './reset/global_styles';
export * from './functions';
export * from './variables';
export * from './mixins';
+export * from './utility/animations';
diff --git a/src/global_styling/utility/animations.ts b/src/global_styling/utility/animations.ts
new file mode 100644
index 00000000000..bedd2330ecc
--- /dev/null
+++ b/src/global_styling/utility/animations.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { keyframes } from '@emotion/react';
+
+export const euiAnimFadeIn = keyframes`
+ 0% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+`;
From acc2e7a13ce04dabdc7ab67c1c06f6e150c1f42d Mon Sep 17 00:00:00 2001
From: Greg Thompson
Date: Thu, 28 Jul 2022 14:12:12 -0500
Subject: [PATCH 02/10] emotion styles; remove onClick handler; useEuiPortal
---
.../overlay_mask/overlay_mask.styles.ts | 41 +++++++
src/components/overlay_mask/overlay_mask.tsx | 107 ++++++------------
2 files changed, 76 insertions(+), 72 deletions(-)
create mode 100644 src/components/overlay_mask/overlay_mask.styles.ts
diff --git a/src/components/overlay_mask/overlay_mask.styles.ts b/src/components/overlay_mask/overlay_mask.styles.ts
new file mode 100644
index 00000000000..af522ddf2f2
--- /dev/null
+++ b/src/components/overlay_mask/overlay_mask.styles.ts
@@ -0,0 +1,41 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { css } from '@emotion/react';
+import { logicalCSS, euiAnimFadeIn } from '../../global_styling';
+import { transparentize, UseEuiTheme } from '../../services';
+
+export const euiOverlayMaskStyles = ({ euiTheme }: UseEuiTheme) => ({
+ euiOverlayMask: css`
+ .euiOverlayMask {
+ position: fixed;
+ ${logicalCSS('top', 0)}
+ ${logicalCSS('left', 0)}
+ ${logicalCSS('right', 0)}
+ ${logicalCSS('bottom', 0)}
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ ${logicalCSS('padding-bottom', '10vh')};
+ animation: ${euiAnimFadeIn} ${euiTheme.animation.fast} ease-in;
+ background: ${transparentize(euiTheme.colors.ink, 0.5)};
+ }
+ `,
+ aboveHeader: css`
+ z-index: ${euiTheme.levels.mask};
+ `,
+ belowHeader: css`
+ z-index: ${euiTheme.levels.maskBelowHeader};
+ `,
+});
+
+export const euiOverlayMaskBodyStyles = css`
+ body {
+ overflow: hidden;
+ }
+`;
diff --git a/src/components/overlay_mask/overlay_mask.tsx b/src/components/overlay_mask/overlay_mask.tsx
index dc51bb8c0c9..b014ed8cd03 100644
--- a/src/components/overlay_mask/overlay_mask.tsx
+++ b/src/components/overlay_mask/overlay_mask.tsx
@@ -18,19 +18,19 @@ import React, {
ReactNode,
Ref,
useEffect,
- useRef,
useState,
} from 'react';
-import { createPortal } from 'react-dom';
import classNames from 'classnames';
+import { Global } from '@emotion/react';
import { CommonProps, keysOf } from '../common';
-import { useCombinedRefs } from '../../services';
+import { useCombinedRefs, useEuiTheme } from '../../services';
+import { EuiPortal } from '../portal';
+import {
+ euiOverlayMaskStyles,
+ euiOverlayMaskBodyStyles,
+} from './overlay_mask.styles';
export interface EuiOverlayMaskInterface {
- /**
- * Function that applies to clicking the mask itself and not the children
- */
- onClick?: () => void;
/**
* ReactNode to render as this component's content
*/
@@ -55,85 +55,48 @@ export type EuiOverlayMaskProps = CommonProps &
export const EuiOverlayMask: FunctionComponent = ({
className,
children,
- onClick,
headerZindexLocation = 'above',
maskRef,
...rest
}) => {
- const overlayMaskNode = useRef();
- const combinedMaskRef = useCombinedRefs([overlayMaskNode, maskRef]);
- const [isPortalTargetReady, setIsPortalTargetReady] = useState(false);
-
- useEffect(() => {
- document.body.classList.add('euiBody-hasOverlayMask');
-
- return () => {
- document.body.classList.remove('euiBody-hasOverlayMask');
- };
- }, []);
+ const [overlayMaskNode, setOverlayMaskNode] = useState(
+ null
+ );
+ const combinedMaskRef = useCombinedRefs([
+ setOverlayMaskNode,
+ maskRef,
+ ]);
+ const euiTheme = useEuiTheme();
+ const styles = euiOverlayMaskStyles(euiTheme);
+ const cssStyles = [
+ styles.euiOverlayMask,
+ styles[`${headerZindexLocation}Header`],
+ ];
useEffect(() => {
- if (typeof document !== 'undefined') {
- combinedMaskRef(document.createElement('div'));
- }
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
-
- useEffect(() => {
- const portalTarget = overlayMaskNode.current;
-
- if (portalTarget) {
- document.body.appendChild(portalTarget);
- }
-
- setIsPortalTargetReady(true);
-
- return () => {
- if (portalTarget) {
- document.body.removeChild(portalTarget);
- }
- };
- }, []);
-
- useEffect(() => {
- if (!overlayMaskNode.current) return;
+ if (!overlayMaskNode) return;
keysOf(rest).forEach((key) => {
if (typeof rest[key] !== 'string') {
throw new Error(
`Unhandled property type. EuiOverlayMask property ${key} is not a string.`
);
}
- if (overlayMaskNode.current) {
- overlayMaskNode.current.setAttribute(key, rest[key]!);
+ if (overlayMaskNode) {
+ overlayMaskNode.setAttribute(key, rest[key]!);
}
});
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
-
- useEffect(() => {
- if (!overlayMaskNode.current) return;
- overlayMaskNode.current.className = classNames(
- 'euiOverlayMask',
- `euiOverlayMask--${headerZindexLocation}Header`,
- className
- );
- }, [className, headerZindexLocation]);
+ }, [overlayMaskNode]); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
- const portalTarget = overlayMaskNode.current;
- if (!portalTarget || !onClick) return;
-
- const listener = (e: Event) => {
- if (e.target === portalTarget) {
- onClick();
- }
- };
- portalTarget.addEventListener('click', listener);
-
- return () => {
- portalTarget.removeEventListener('click', listener);
- };
- }, [onClick]);
-
- return isPortalTargetReady ? (
- <>{createPortal(children, overlayMaskNode.current!)}>
- ) : null;
+ if (!overlayMaskNode) return;
+ overlayMaskNode.className = classNames('euiOverlayMask', className);
+ }, [overlayMaskNode, className]);
+
+ return (
+
+
+
+ {children}
+
+ );
};
From 1030abc9e33b4ce28f3ec0f75376f38f572016f0 Mon Sep 17 00:00:00 2001
From: Greg Thompson
Date: Thu, 28 Jul 2022 14:12:47 -0500
Subject: [PATCH 03/10] remove unused sass
---
src/components/index.scss | 1 -
src/components/overlay_mask/_index.scss | 1 -
.../overlay_mask/_overlay_mask.scss | 33 -------------------
src/themes/amsterdam/overrides/_index.scss | 1 -
.../amsterdam/overrides/_overlay_mask.scss | 3 --
5 files changed, 39 deletions(-)
delete mode 100644 src/components/overlay_mask/_index.scss
delete mode 100644 src/components/overlay_mask/_overlay_mask.scss
delete mode 100644 src/themes/amsterdam/overrides/_overlay_mask.scss
diff --git a/src/components/index.scss b/src/components/index.scss
index 7a31b112fa0..f1cee509e8d 100644
--- a/src/components/index.scss
+++ b/src/components/index.scss
@@ -27,7 +27,6 @@
@import 'markdown_editor/index';
@import 'modal/index';
@import 'notification/index';
-@import 'overlay_mask/index';
@import 'pagination/index';
@import 'panel/index';
@import 'page/index'; // Page needs to come after Panel for cascade specificity
diff --git a/src/components/overlay_mask/_index.scss b/src/components/overlay_mask/_index.scss
deleted file mode 100644
index 67f52e40e69..00000000000
--- a/src/components/overlay_mask/_index.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import 'overlay_mask';
diff --git a/src/components/overlay_mask/_overlay_mask.scss b/src/components/overlay_mask/_overlay_mask.scss
deleted file mode 100644
index 2a61db1836a..00000000000
--- a/src/components/overlay_mask/_overlay_mask.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-.euiOverlayMask {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- padding-bottom: 10vh;
- animation: euiAnimFadeIn $euiAnimSpeedFast ease-in;
-
- $backgroundColor: $euiColorEmptyShade;
-
- @if (lightness($euiTextColor) > 50) {
- $backgroundColor: $euiColorLightShade;
- }
-
- background: transparentize($backgroundColor, .2);
-}
-
-.euiBody-hasOverlayMask {
- overflow: hidden;
-}
-
-// Handling the z-index based on whether it should be displayed above or below the header
-.euiOverlayMask--aboveHeader {
- z-index: $euiZMask;
-}
-
-.euiOverlayMask--belowHeader {
- z-index: $euiZMaskBelowHeader;
-}
diff --git a/src/themes/amsterdam/overrides/_index.scss b/src/themes/amsterdam/overrides/_index.scss
index a00673ceb9f..53d912afeb1 100644
--- a/src/themes/amsterdam/overrides/_index.scss
+++ b/src/themes/amsterdam/overrides/_index.scss
@@ -22,7 +22,6 @@
@import 'markdown_editor';
@import 'modal';
@import 'notification_badge';
-@import 'overlay_mask';
@import 'range';
@import 'range_draggable';
@import 'range_highlight';
diff --git a/src/themes/amsterdam/overrides/_overlay_mask.scss b/src/themes/amsterdam/overrides/_overlay_mask.scss
deleted file mode 100644
index 022a18082f6..00000000000
--- a/src/themes/amsterdam/overrides/_overlay_mask.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.euiOverlayMask {
- background: transparentize($euiColorInk, .5);
-}
\ No newline at end of file
From bc7488e58b42f450f3f7624dde6931c959a0bae7 Mon Sep 17 00:00:00 2001
From: Greg Thompson
Date: Thu, 28 Jul 2022 14:13:13 -0500
Subject: [PATCH 04/10] update imagewrapper click to close
---
src/components/image/image.test.tsx | 6 +++++-
src/components/image/image_fullscreen_wrapper.tsx | 7 ++-----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/components/image/image.test.tsx b/src/components/image/image.test.tsx
index 5853d05bb4d..d006f715b37 100644
--- a/src/components/image/image.test.tsx
+++ b/src/components/image/image.test.tsx
@@ -191,7 +191,11 @@ describe('EuiImage', () => {
expect(overlayMask).toBeFalsy();
});
- test('close using overlay mask', () => {
+ // Clicking the mask to close is now handled by EuiFocusTrap
+ // and we can't use Enzyme to test this behavior.
+ // A Cypress test exists in the EuiFocusTrap suite that
+ // sufficiently covers this behavior
+ test.skip('close using overlay mask', () => {
let overlayMask = document.querySelectorAll(
'[data-test-subj=fullScreenOverlayMask]'
);
diff --git a/src/components/image/image_fullscreen_wrapper.tsx b/src/components/image/image_fullscreen_wrapper.tsx
index 7d2887aa063..e31ed0d3960 100644
--- a/src/components/image/image_fullscreen_wrapper.tsx
+++ b/src/components/image/image_fullscreen_wrapper.tsx
@@ -65,11 +65,8 @@ export const EuiImageFullScreenWrapper: FunctionComponent
];
return (
-
-
+
+
<>
Date: Thu, 28 Jul 2022 14:13:21 -0500
Subject: [PATCH 05/10] docs
---
.../src/views/overlay_mask/overlay_mask.js | 31 ++++++++++---------
.../overlay_mask/overlay_mask_example.js | 7 +++--
2 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/src-docs/src/views/overlay_mask/overlay_mask.js b/src-docs/src/views/overlay_mask/overlay_mask.js
index 60a502bebc3..94981dd1ef5 100644
--- a/src-docs/src/views/overlay_mask/overlay_mask.js
+++ b/src-docs/src/views/overlay_mask/overlay_mask.js
@@ -5,6 +5,7 @@ import {
EuiButton,
EuiSpacer,
EuiTitle,
+ EuiFocusTrap,
} from '../../../../src/components';
export default () => {
@@ -13,20 +14,22 @@ export default () => {
const modal = (
- {
- changeMask(false);
- }}
- >
-
-
Click anywhere to close overlay.
-
+
+ {
+ changeMask(false);
+ }}
+ >
+
+
Click anywhere to close overlay.
+
+
);
const maskWithClick = (
-
+ {
changeMaskWithClick(false);
@@ -39,16 +42,16 @@ export default () => {
return (
+ changeMaskWithClick(true)}>
+ Overlay with button
+
+ {
changeMask(true);
}}
>
- Overlay with onClick
-
-
- changeMaskWithClick(true)}>
- Overlay with button
+ Overlay with EuiFocusTrap click-to-close
{maskOpen ? modal : undefined}
{maskWithClickOpen ? maskWithClick : undefined}
diff --git a/src-docs/src/views/overlay_mask/overlay_mask_example.js b/src-docs/src/views/overlay_mask/overlay_mask_example.js
index ef6a91a4db5..48bd4220216 100644
--- a/src-docs/src/views/overlay_mask/overlay_mask_example.js
+++ b/src-docs/src/views/overlay_mask/overlay_mask_example.js
@@ -39,8 +39,11 @@ export const OverlayMaskExample = {
{' '}
to make before choosing to use an overlay. At the very least, you
must provide a visible button to close the overlay. You can also
- pass an onClick handler to handle closing the
- overlay.
+ nest an{' '}
+
+ EuiFocusTrap
+ {' '}
+ to handle closing the overlay.