Skip to content

Commit

Permalink
Add floats to EuiImage (#4209)
Browse files Browse the repository at this point in the history
Adds props for `float` and `margin` to `EuiImage`. This is needed for long-form text content, like documentation where an image compliments the text in an article format.
  • Loading branch information
snide authored Nov 2, 2020
1 parent c067b3c commit fcda1ac
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added `labelWidth` and `descriptionDisplay` props to `EuiSuggestItem` ([#4180](https://github.com/elastic/eui/pull/4180))
- Added `float` and `margin` props to `EuiImage` ([#4209](https://github.com/elastic/eui/pull/4209))

**Bug fixes**

Expand Down
34 changes: 34 additions & 0 deletions src-docs/src/views/image/float.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';

import { EuiImage, EuiText } from '../../../../src/components';
import { fake } from 'faker';

export default () => (
<EuiText>
<EuiImage
size="l"
float="right"
margin="l"
hasShadow
caption="Random nature image"
allowFullScreen
alt="Random nature image"
url="https://picsum.photos/800/500"
/>
<p>{fake('{{lorem.paragraphs}}')}</p>
<p>{fake('{{lorem.paragraphs}}')}</p>
<p>{fake('{{lorem.paragraphs}}')}</p>
<EuiImage
size="l"
float="left"
margin="l"
hasShadow
allowFullScreen
caption="Another random image"
alt="Random nature image"
url="https://picsum.photos/300/300"
/>
<p>{fake('{{lorem.paragraphs}}')}</p>
<p>{fake('{{lorem.paragraphs}}')}</p>
</EuiText>
);
45 changes: 45 additions & 0 deletions src-docs/src/views/image/image_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ const imageZoomSnippet = `<EuiImage
/>
`;

import ImageFloat from './float';
import { EuiCallOut } from '../../../../src/components/call_out';
import { Fragment } from 'react-is';
const imageFloatSource = require('!!raw-loader!./float');
const imageFloatHtml = renderToHtml(ImageFloat);
const imageFloatSnippet = `<EuiImage
alt={description}
url={someUrl}
float="left"
margin="l"
/>
`;

export const ImageExample = {
title: 'Image',
sections: [
Expand Down Expand Up @@ -115,6 +128,38 @@ export const ImageExample = {
demo: <ImageSizes />,
snippet: imageSizesSnippet,
},
{
title: 'Float images within text',
source: [
{
type: GuideSectionTypes.JS,
code: imageFloatSource,
},
{
type: GuideSectionTypes.HTML,
code: imageFloatHtml,
},
],
text: (
<Fragment>
<p>
When using <EuiCode>EuiImage</EuiCode> within{' '}
<EuiCode>EuiText</EuiCode> it is often useful to apply floats.
Almost always you&apos;ll want to pair the <EuiCode>float</EuiCode>{' '}
prop usage, with a <EuiCode>margin</EuiCode> prop usage to give
space around your image. Margins, when used in combo with floats,
will adjust depending upon the position of the float.
</p>
<EuiCallOut title="Be careful with floats" color="warning">
Floats should only be used on images within <strong>large</strong>{' '}
bodies of text. Specifically, we only suggest using them with{' '}
<EuiCode>EuiText</EuiCode> which comes automatically clears floats.
</EuiCallOut>
</Fragment>
),
demo: <ImageFloat />,
snippet: imageFloatSnippet,
},
],
playground: imageConfig,
};
24 changes: 24 additions & 0 deletions src/components/image/__snapshots__/image.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,30 @@ exports[`EuiImage is rendered and allows full screen 1`] = `
</figure>
`;

exports[`EuiImage is rendered with a float 1`] = `
<figure
class="euiImage euiImage--floatLeft "
>
<img
alt="alt"
class="euiImage__img"
src="/cat.jpg"
/>
</figure>
`;

exports[`EuiImage is rendered with a margin 1`] = `
<figure
class="euiImage euiImage--marginLarge "
>
<img
alt="alt"
class="euiImage__img"
src="/cat.jpg"
/>
</figure>
`;

exports[`EuiImage is rendered with a node as the caption 1`] = `
<figure
class="euiImage "
Expand Down
67 changes: 63 additions & 4 deletions src/components/image/_image.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
min-height: 1px; /* 1 */
line-height: 0; // Fixes cropping when image is resized by forcing its height to be determined by the image not line-height

// Required for common usage of nesting within EuiText
.euiImage__img {
margin-bottom: 0;
}

&.euiImage--hasShadow {
.euiImage__img {
@include euiBottomShadowMedium;
Expand Down Expand Up @@ -50,25 +55,60 @@
}

// These sizes are mostly suggestions. Don't look too hard for meaning in their values.
&.euiImage--small {
// Size is applied to the image, rather than the figure to work better with floats
&.euiImage--small .euiImage__img {
width: convertToRem(120px);
}

&.euiImage--medium {
&.euiImage--medium .euiImage__img {
width: convertToRem(200px);
}

&.euiImage--large {
&.euiImage--large .euiImage__img {
width: convertToRem(360px);
}

&.euiImage--xlarge {
&.euiImage--xlarge .euiImage__img {
width: convertToRem(600px);
}

&.euiImage--fullWidth {
width: 100%;
}

&.euiImage--floatLeft {
float: left;

&[class*='euiImage--margin'] {
margin-left: 0;
margin-top: 0;
}
}

&.euiImage--floatRight {
float: right;

&[class*='euiImage--margin'] {
margin-right: 0;
margin-top: 0;
}
}

&.euiImage--marginSmall {
margin: $euiSizeS;
}

&.euiImage--marginMedium {
margin: $euiSize;
}

&.euiImage--marginLarge {
margin: $euiSizeL;
}

&.euiImage--marginXlarge {
margin: $euiSizeXL;
}
}

// The image itself is full width within the container.
Expand All @@ -79,6 +119,7 @@

.euiImage__caption {
@include euiFontSizeS;
margin-top: $euiSizeXS;
text-align: center;
}

Expand Down Expand Up @@ -136,3 +177,21 @@
}
}

@include euiBreakpoint('xs', 's', 'm') {

.euiImage {

&.euiImage--floatLeft,
&.euiImage--floatRight {
float: none;

// Return back to whatever margin settings were set without the float
&[class*='euiImage--margin'] {
margin-top: inherit;
margin-right: inherit;
margin-bottom: inherit;
margin-left: inherit;
}
}
}
}
14 changes: 14 additions & 0 deletions src/components/image/image.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ describe('EuiImage', () => {
expect(component).toMatchSnapshot();
});

test('is rendered with a float', () => {
const component = render(
<EuiImage alt="alt" float="left" url="/cat.jpg" />
);

expect(component).toMatchSnapshot();
});

test('is rendered with a margin', () => {
const component = render(<EuiImage alt="alt" margin="l" url="/cat.jpg" />);

expect(component).toMatchSnapshot();
});

test('is rendered with custom size', () => {
const component = render(<EuiImage alt="alt" size={50} url="/cat.jpg" />);

Expand Down
26 changes: 26 additions & 0 deletions src/components/image/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import { keys } from '../../services';
import { useInnerText } from '../inner_text';

type ImageSize = 's' | 'm' | 'l' | 'xl' | 'fullWidth' | 'original';
type Floats = 'left' | 'right';
type Margins = 's' | 'm' | 'l' | 'xl';

const sizeToClassNameMap: { [size in ImageSize]: string } = {
s: 'euiImage--small',
Expand All @@ -48,6 +50,18 @@ const sizeToClassNameMap: { [size in ImageSize]: string } = {
original: '',
};

const marginToClassNameMap: { [margin in Margins]: string } = {
s: 'euiImage--marginSmall',
m: 'euiImage--marginMedium',
l: 'euiImage--marginLarge',
xl: 'euiImage--marginXlarge',
};

const floatToClassNameMap: { [float in Floats]: string } = {
left: 'euiImage--floatLeft',
right: 'euiImage--floatRight',
};

export const SIZES = Object.keys(sizeToClassNameMap);

type FullScreenIconColor = 'light' | 'dark';
Expand Down Expand Up @@ -87,6 +101,14 @@ interface EuiImageProps extends CommonProps, HTMLAttributes<HTMLImageElement> {
* When set to `true` will make the image clickable to a larger version
*/
allowFullScreen?: boolean;
/**
* Float the image to the left or right. Useful in large text blocks.
*/
float?: Floats;
/**
* Margin around the image.
*/
margin?: Margins;
}

export const EuiImage: FunctionComponent<EuiImageProps> = ({
Expand All @@ -99,6 +121,8 @@ export const EuiImage: FunctionComponent<EuiImageProps> = ({
fullScreenIconColor = 'light',
alt,
style,
float,
margin,
...rest
}) => {
const [isFullScreenActive, setIsFullScreenActive] = useState(false);
Expand Down Expand Up @@ -127,6 +151,8 @@ export const EuiImage: FunctionComponent<EuiImageProps> = ({
'euiImage--hasShadow': hasShadow,
'euiImage--allowFullScreen': allowFullScreen,
},
margin ? marginToClassNameMap[margin] : null,
float ? floatToClassNameMap[float] : null,
className
);

Expand Down
2 changes: 2 additions & 0 deletions src/components/text/_text.scss
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@
// of other styling concerns, we should inherit their coloring. The default
// coloring will likely coming from the reset.scss anyway.
color: inherit;
// EuiImage with floats are often used within EuiText.
clear: both;

// Style anchors that don't have a class. This prevents overwriting "buttons"
// and other stylized elements passed in.
Expand Down

0 comments on commit fcda1ac

Please sign in to comment.