Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiCard] Allow custom component for image prop #3370

Merged
merged 11 commits into from
Apr 23, 2020
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Applies `max-width: 100%` to `EuiPageBody` so inner flex-based items don't overflow their containers ([#3375](https://github.com/elastic/eui/pull/3375))
- Added `ReactElement` to `EuiCard` `image` property to allow custom component
cchaos marked this conversation as resolved.
Show resolved Hide resolved


## [`23.1.0`](https://github.com/elastic/eui/tree/v23.1.0)

Expand Down
11 changes: 9 additions & 2 deletions src-docs/src/views/card/card_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,15 @@ export const CardExample = {
Make sure that all images are the{' '}
<strong>same proportions</strong> when used in a singular row.
</span>
}
/>
}>
<p>
Also, when passing an <strong>element</strong> to the{' '}
<EuiCode>image</EuiCode> prop that consists solely of inline
elements or does not contain an
<EuiCode>{'<img />'}</EuiCode> element, each element will require
a style of <EuiCode>width: 100%</EuiCode>.
</p>
</EuiCallOut>
</div>
),
props: { EuiCard },
Expand Down
9 changes: 8 additions & 1 deletion src-docs/src/views/card/card_image.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ export default () => (
<EuiFlexItem>
<EuiCard
textAlign="left"
image="https://source.unsplash.com/400x200/?Nature"
image={
<div>
<img
src="https://source.unsplash.com/400x200/?Nature"
alt="Nature"
/>
</div>
}
title="Elastic in Nature"
description="Example of a card's description. Stick to one or two sentences."
footer={cardFooterContent}
Expand Down
4 changes: 4 additions & 0 deletions src/components/card/_card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@
border-top-left-radius: $euiBorderRadius - 1px;
border-top-right-radius: $euiBorderRadius - 1px;

img {
width: 100%;
}

// IF both exist, position the icon centered on top of image
+ .euiCard__icon {
position: absolute;
Expand Down
21 changes: 17 additions & 4 deletions src/components/card/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
* under the License.
*/

import React, { FunctionComponent, ReactElement, ReactNode } from 'react';
import React, {
FunctionComponent,
ReactElement,
ReactNode,
isValidElement,
} from 'react';
import classNames from 'classnames';

import { CommonProps, keysOf } from '../common';
Expand Down Expand Up @@ -89,9 +94,9 @@ type EuiCardProps = Omit<CommonProps, 'aria-label'> & {
icon?: ReactElement<EuiIconProps>;

/**
* Accepts a url in string form
* Accepts a url in string form or ReactElement for custom image component
cchaos marked this conversation as resolved.
Show resolved Hide resolved
*/
image?: string;
image?: string | ReactElement;

/**
* Content to be rendered between the description and the footer
Expand Down Expand Up @@ -229,7 +234,15 @@ export const EuiCard: FunctionComponent<EuiCardProps> = ({

let imageNode;
if (image && layout === 'vertical') {
imageNode = <img className="euiCard__image" src={image} alt="" />;
if (isValidElement(image) || typeof image === 'string') {
TAYTS marked this conversation as resolved.
Show resolved Hide resolved
imageNode = (
<div className="euiCard__image">
{isValidElement(image) ? image : <img src={image} alt="" />}
</div>
);
} else {
imageNode = null;
}
}

let iconNode;
Expand Down