diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c8ea41f742..4b0283283ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Created `EuiSuggest` component ([#2270](https://github.com/elastic/eui/pull/2270)) - Added missing `compressed` styling to `EuiSwitch` ([#2327](https://github.com/elastic/eui/pull/2327)) - Migrate `EuiBottomBar`, `EuiHealth` and `EuiImage` to TS ([#2328](https://github.com/elastic/eui/pull/2328)) +- Added hover and focus states when `allowFullScreen` is true in `EuiImage`([#2287](https://github.com/elastic/eui/pull/2287)) - Converted `EuiColorPicker` to TypeScript ([#2340](https://github.com/elastic/eui/pull/2340)) - Added inline rendering option to `EuiColorPicker` ([#2340](https://github.com/elastic/eui/pull/2340)) diff --git a/src/components/image/__snapshots__/image.test.tsx.snap b/src/components/image/__snapshots__/image.test.tsx.snap index 3154b1c1983..5b1ab605f54 100644 --- a/src/components/image/__snapshots__/image.test.tsx.snap +++ b/src/components/image/__snapshots__/image.test.tsx.snap @@ -1,12 +1,26 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`EuiImage is rendered 1`] = ` +
+ alt +
+`; + +exports[`EuiImage is rendered and allows full screen 1`] = ` `; diff --git a/src/components/image/_image.scss b/src/components/image/_image.scss index 4c819c9a430..8a747e63141 100644 --- a/src/components/image/_image.scss +++ b/src/components/image/_image.scss @@ -17,14 +17,40 @@ } } - &.euiImage--allowFullScreen:hover { - .euiImage__img { - cursor: pointer; + &.euiImage--allowFullScreen { + &:focus .euiImage__img { + outline: 2px solid $euiFocusRingColor; } - .euiImage__icon { + &:hover .euiImage__icon { visibility: visible; - opacity: 1; + fill-opacity: 1; + } + + &:hover .euiImage__caption, + &:focus .euiImage__caption { + text-decoration: underline; + } + + &:not(.euiImage--hasShadow):hover, + &:not(.euiImage--hasShadow):focus { + .euiImage__img { + @include euiBottomShadowMedium; + } + } + + &.euiImage--hasShadow:hover, + &.euiImage--hasShadow:focus { + .euiImage__img { + @include euiBottomShadow; + } + } + + .euiImage__img { + cursor: pointer; + + // transition the shadow + transition: all $euiAnimSpeedFast $euiAnimSlightResistance; } } @@ -62,31 +88,48 @@ .euiImage__icon { visibility: hidden; - opacity: 0; + fill-opacity: 0; position: absolute; right: $euiSize; top: $euiSize; - transition: opacity $euiAnimSpeedSlow $euiAnimSlightResistance ; + transition: fill-opacity $euiAnimSpeedSlow $euiAnimSlightResistance; cursor: pointer; } // The FullScreen image that optionally pops up on click. -.euiImageFullScreen { +.euiImage-isFullScreen { + position: relative; max-height: 80vh; max-width: 80vw; animation: euiImageFullScreen $euiAnimSpeedExtraSlow $euiAnimSlightBounce; - .euiImageFullScreen__img { + .euiImage-isFullScreen__icon { + position: absolute; + right: $euiSize; + top: $euiSize; + } + + .euiImage-isFullScreen__img { max-height: 80vh; max-width: 80vw; cursor: pointer; + transition: all $euiAnimSpeedFast $euiAnimSlightResistance; } - &:hover .euiImageFullScreen__img { + &:hover .euiImage-isFullScreen__img { + @include euiBottomShadow; cursor: pointer; } -} + &:focus .euiImage-isFullScreen__img { + outline: 2px solid $euiFocusRingColor; + } + + &:hover .euiImage__caption, + &:focus-within .euiImage__caption { + text-decoration: underline; + } +} @keyframes euiImageFullScreen { 0% { diff --git a/src/components/image/image.test.tsx b/src/components/image/image.test.tsx index 7c1630a7494..6e3ce827001 100644 --- a/src/components/image/image.test.tsx +++ b/src/components/image/image.test.tsx @@ -12,4 +12,18 @@ describe('EuiImage', () => { expect(component).toMatchSnapshot(); }); + + test('is rendered and allows full screen', () => { + const component = render( + + ); + + expect(component).toMatchSnapshot(); + }); }); diff --git a/src/components/image/image.tsx b/src/components/image/image.tsx index 6bd97d271e3..659b1bc88f8 100644 --- a/src/components/image/image.tsx +++ b/src/components/image/image.tsx @@ -41,12 +41,12 @@ interface EuiImageProps extends CommonProps, HTMLAttributes { } interface State { - isFullScreen: boolean; + isFullScreenActive: boolean; } export class EuiImage extends Component { state: State = { - isFullScreen: false, + isFullScreenActive: false, }; onKeyDown = (event: React.KeyboardEvent) => { @@ -59,13 +59,13 @@ export class EuiImage extends Component { closeFullScreen = () => { this.setState({ - isFullScreen: false, + isFullScreenActive: false, }); }; openFullScreen = () => { this.setState({ - isFullScreen: true, + isFullScreenActive: true, }); }; @@ -82,6 +82,8 @@ export class EuiImage extends Component { ...rest } = this.props; + const { isFullScreenActive } = this.state; + const classes = classNames( 'euiImage', sizeToClassNameMap[size], @@ -99,54 +101,55 @@ export class EuiImage extends Component { ); } - let optionalIcon; + const allowFullScreenIcon = ( + + ); - if (allowFullScreen) { - optionalIcon = ( - - ); - } + const fullScreenDisplay = ( + + + + + + ); - let fullScreenDisplay; - - if (this.state.isFullScreen) { - fullScreenDisplay = ( - - - - - + if (allowFullScreen) { + return ( + ); - } - - return ( - - ); + ); + } } }