diff --git a/src/components/image/__snapshots__/image.test.tsx.snap b/src/components/image/__snapshots__/image.test.tsx.snap index 12a116636bf..0f72150156c 100644 --- a/src/components/image/__snapshots__/image.test.tsx.snap +++ b/src/components/image/__snapshots__/image.test.tsx.snap @@ -22,7 +22,6 @@ exports[`EuiImage props allowFullScreen 1`] = ` class="euiImageWrapper emotion-euiImageWrapper-allowFullScreen" > -
@@ -98,7 +96,6 @@ exports[`EuiImage props fullScreenIconColor 1`] = ` class="euiImageWrapper emotion-euiImageWrapper-allowFullScreen" > -
@@ -136,7 +132,6 @@ exports[`EuiImage props hasShadow 1`] = ` class="euiImageWrapper emotion-euiImageWrapper-allowFullScreen-fullWidth" > -
diff --git a/src/components/image/image.test.tsx b/src/components/image/image.test.tsx index 93fe88a22c3..5853d05bb4d 100644 --- a/src/components/image/image.test.tsx +++ b/src/components/image/image.test.tsx @@ -124,6 +124,7 @@ describe('EuiImage', () => { ); diff --git a/src/components/image/image.tsx b/src/components/image/image.tsx index 10469f85f1f..3fe4d48a904 100644 --- a/src/components/image/image.tsx +++ b/src/components/image/image.tsx @@ -76,6 +76,7 @@ export const EuiImage: FunctionComponent = ({ fullScreenIconColor, isFullWidth, allowFullScreen, + alt, caption, float, margin, diff --git a/src/components/image/image_button.styles.ts b/src/components/image/image_button.styles.ts index 946d805690a..219409f9ec2 100644 --- a/src/components/image/image_button.styles.ts +++ b/src/components/image/image_button.styles.ts @@ -73,10 +73,12 @@ export const euiImageButtonStyles = (euiThemeContext: UseEuiTheme) => { export const euiImageButtonIconStyles = ({ euiTheme }: UseEuiTheme) => ({ // Base euiImageButton__icon: css` - opacity: 0; position: absolute; ${logicalCSS('top', euiTheme.size.base)}; ${logicalCSS('right', euiTheme.size.base)}; + `, + openFullScreen: css` + opacity: 0; cursor: pointer; ${euiCanAnimate} { @@ -84,4 +86,8 @@ export const euiImageButtonIconStyles = ({ euiTheme }: UseEuiTheme) => ({ ${euiTheme.animation.resistance}; } `, + closeFullScreen: css` + // Fullscreen close event handled by EuiOverlayMask + pointer-events: none; + `, }); diff --git a/src/components/image/image_button.tsx b/src/components/image/image_button.tsx index ce73a201bf2..796cc4caf54 100644 --- a/src/components/image/image_button.tsx +++ b/src/components/image/image_button.tsx @@ -7,13 +7,16 @@ */ import React, { FunctionComponent } from 'react'; + import { useEuiTheme } from '../../services'; +import { useEuiI18n } from '../i18n'; +import { EuiIcon } from '../icon'; +import { EuiScreenReaderOnly } from '../accessibility'; import { euiImageButtonStyles, euiImageButtonIconStyles, } from './image_button.styles'; -import { EuiIcon } from '../icon'; import type { EuiImageButtonProps, EuiImageButtonIconColor, @@ -27,13 +30,13 @@ const fullScreenIconColorMap: { }; export const EuiImageButton: FunctionComponent = ({ + hasAlt, hasShadow, children, onClick, onKeyDown, isFullScreen, isFullWidth, - allowFullScreen, fullScreenIconColor = 'light', ...rest }) => { @@ -48,25 +51,58 @@ export const EuiImageButton: FunctionComponent = ({ ]; const iconStyles = euiImageButtonIconStyles(euiTheme); - const cssIconStyles = [iconStyles.euiImageButton__icon]; + const cssIconStyles = [ + iconStyles.euiImageButton__icon, + !isFullScreen && iconStyles.openFullScreen, + isFullScreen && iconStyles.closeFullScreen, + ]; + + const openFullScreenInstructions = useEuiI18n( + 'euiImageButton.openFullScreen', + 'Click to open this image in fullscreen mode' + ); + const closeFullScreenInstructions = useEuiI18n( + 'euiImageButton.closeFullScreen', + 'Press Escape or click to close image fullscreen mode' + ); const iconColor = fullScreenIconColorMap[fullScreenIconColor as EuiImageButtonIconColor]; return ( - + <> + + ); }; diff --git a/src/components/image/image_fullscreen_wrapper.styles.ts b/src/components/image/image_fullscreen_wrapper.styles.ts index da8d832c202..69fc9e6033e 100644 --- a/src/components/image/image_fullscreen_wrapper.styles.ts +++ b/src/components/image/image_fullscreen_wrapper.styles.ts @@ -43,19 +43,6 @@ export const euiImageFullscreenWrapperStyles = ( }; }; -export const euiImageFullscreenWrapperFullScreenCloseIconStyles = ({ - euiTheme, -}: UseEuiTheme) => ({ - // Base - euiImageFullscreenWrapper__fullScreenCloseIcon: css` - position: absolute; - ${logicalCSS('top', euiTheme.size.base)}; - ${logicalCSS('right', euiTheme.size.base)}; - pointer-events: none; - fill: ${euiTheme.colors.ghost} !important; - `, -}); - const euiImageFullScreen = (size: string) => keyframes` 0% { opacity: 0; diff --git a/src/components/image/image_fullscreen_wrapper.tsx b/src/components/image/image_fullscreen_wrapper.tsx index 00b2a720c20..8a8c0755d35 100644 --- a/src/components/image/image_fullscreen_wrapper.tsx +++ b/src/components/image/image_fullscreen_wrapper.tsx @@ -9,31 +9,28 @@ import React, { FunctionComponent } from 'react'; import classNames from 'classnames'; -import { EuiIcon } from '../icon'; import { EuiFocusTrap } from '../focus_trap'; import { EuiOverlayMask } from '../overlay_mask'; -import { EuiI18n } from '../i18n'; -import { useEuiTheme, useGeneratedHtmlId, keys } from '../../services'; +import { EuiIcon } from '../icon'; +import { useEuiTheme, keys } from '../../services'; import { useInnerText } from '../inner_text'; -import { - euiImageFullscreenWrapperStyles, - euiImageFullscreenWrapperFullScreenCloseIconStyles, -} from './image_fullscreen_wrapper.styles'; - +import { euiImageFullscreenWrapperStyles } from './image_fullscreen_wrapper.styles'; import type { EuiImageWrapperProps } from './image_types'; import { EuiImageButton } from './image_button'; +import { euiImageButtonIconStyles } from './image_button.styles'; + import { EuiImageCaption } from './image_caption'; export const EuiImageFullScreenWrapper: FunctionComponent = ({ + alt, hasShadow, caption, children, isFullScreen, setIsFullScreen, wrapperProps, - allowFullScreen, isFullWidth, fullScreenIconColor, }) => { @@ -43,13 +40,6 @@ export const EuiImageFullScreenWrapper: FunctionComponent const cssStyles = [styles.euiImageFullscreenWrapper]; - const fullScreenCloseIconStyles = euiImageFullscreenWrapperFullScreenCloseIconStyles( - euiTheme - ); - const cssFullScreenCloseIconStyles = [ - fullScreenCloseIconStyles.euiImageFullscreenWrapper__fullScreenCloseIcon, - ]; - const classes = classNames( 'euiImageFullScreenWrapper', wrapperProps && wrapperProps.className @@ -68,7 +58,12 @@ export const EuiImageFullScreenWrapper: FunctionComponent }; const [optionalCaptionRef, optionalCaptionText] = useInnerText(); - const describedById = useGeneratedHtmlId(); + + const iconStyles = euiImageButtonIconStyles(euiTheme); + const cssIconStyles = [ + iconStyles.euiImageButton__icon, + iconStyles.closeFullScreen, + ]; return ( css={cssStyles} > {children} - - + {/* Must be outside the `figure` element in order to escape the translateY transition. see https://www.w3.org/TR/css-transforms-1/#transform-rendering */} + diff --git a/src/components/image/image_types.ts b/src/components/image/image_types.ts index 78bc6ef288f..9f904af5c6b 100644 --- a/src/components/image/image_types.ts +++ b/src/components/image/image_types.ts @@ -83,6 +83,7 @@ export type EuiImageProps = CommonProps & export type EuiImageWrapperProps = Pick< EuiImageProps, + | 'alt' | 'caption' | 'float' | 'margin' @@ -98,8 +99,9 @@ export type EuiImageWrapperProps = Pick< export type EuiImageButtonProps = Pick< EuiImageProps, - 'hasShadow' | 'allowFullScreen' | 'fullScreenIconColor' + 'hasShadow' | 'fullScreenIconColor' > & { + hasAlt: boolean; onClick: () => void; onKeyDown?: (e: React.KeyboardEvent) => void; isFullWidth: boolean; diff --git a/src/components/image/image_wrapper.tsx b/src/components/image/image_wrapper.tsx index b29842eda5a..dbbedb1109e 100644 --- a/src/components/image/image_wrapper.tsx +++ b/src/components/image/image_wrapper.tsx @@ -9,8 +9,7 @@ import React, { FunctionComponent } from 'react'; import classNames from 'classnames'; -import { EuiI18n } from '../i18n'; -import { useEuiTheme, useGeneratedHtmlId } from '../../services'; +import { useEuiTheme } from '../../services'; import { useInnerText } from '../inner_text'; import type { EuiImageWrapperProps } from './image_types'; @@ -20,6 +19,7 @@ import { EuiImageButton } from './image_button'; import { EuiImageCaption } from './image_caption'; export const EuiImageWrapper: FunctionComponent = ({ + alt, caption, hasShadow, allowFullScreen, @@ -53,7 +53,6 @@ export const EuiImageWrapper: FunctionComponent = ({ ]; const [optionalCaptionRef, optionalCaptionText] = useInnerText(); - const describedById = useGeneratedHtmlId(); return (
= ({ {allowFullScreen ? ( <> {children} - ) : ( children