From 380416a5c7d917df9ae3f65d9c304b9b58c303b7 Mon Sep 17 00:00:00 2001 From: Jakub Janczyk Date: Tue, 20 Apr 2021 18:00:29 +0200 Subject: [PATCH 1/4] Resize the image to fit the boundaries and set sizes to avoid UI jumping after loading image --- src/components/MessageCard/MessageCard.css.js | 4 ++ src/components/MessageCard/MessageCard.jsx | 60 ++++++++++++++++--- .../MessageCard/MessageCard.stories.mdx | 2 + .../MessageCard/MessageCard.test.js | 37 +++++++++++- 4 files changed, 92 insertions(+), 11 deletions(-) diff --git a/src/components/MessageCard/MessageCard.css.js b/src/components/MessageCard/MessageCard.css.js index 7935da46b..5b1a6ccae 100644 --- a/src/components/MessageCard/MessageCard.css.js +++ b/src/components/MessageCard/MessageCard.css.js @@ -271,6 +271,9 @@ export const ActionButtonUI = styled(Button)` export const ImageUI = styled(Image)` border-radius: 3px; + height: ${({ height }) => height || 'auto'}; + width: ${({ width }) => width || '100%'}; + max-height: 278px; ` export const ImageContainerUI = styled('div')` @@ -279,4 +282,5 @@ export const ImageContainerUI = styled('div')` width: 100%; margin-top: 20px; padding: 0 10px; + max-height: 278px; ` diff --git a/src/components/MessageCard/MessageCard.jsx b/src/components/MessageCard/MessageCard.jsx index 1b694afbf..6b10b664b 100644 --- a/src/components/MessageCard/MessageCard.jsx +++ b/src/components/MessageCard/MessageCard.jsx @@ -6,16 +6,29 @@ import { classNames } from '../../utilities/classNames' import { noop } from '../../utilities/other' import Animate from '../Animate' import { - MessageCardUI, - TitleUI, - SubtitleUI, - BodyUI, ActionUI, - ImageUI, + BodyUI, ImageContainerUI, + ImageUI, + MessageCardUI, + SubtitleUI, + TitleUI, } from './MessageCard.css' import Truncate from '../Truncate' +const MAX_IMAGE_SIZE = 278 + +const sizeWithRatio = ( + recalculatedSide, + otherSide, + defaultValue = recalculatedSide +) => + // Check if other side is smaller than max size to not recalculate unnecessarily this side as it doesn't need any scaling + // other condition checks that the image fits the boundaries + otherSide < MAX_IMAGE_SIZE + ? defaultValue + : (recalculatedSide / otherSide) * MAX_IMAGE_SIZE + export class MessageCard extends React.PureComponent { static className = 'c-MessageCard' static Button = MessageCardButton @@ -86,16 +99,45 @@ export class MessageCard extends React.PureComponent { renderImage() { const { image } = this.props - return image ? ( + if (!image) { + return null + } + + const { height, width } = this.calculateSize(image) + + return ( - ) : null + ) + } + + // Calculate size of image to keep the original aspect ratio, but fit within 278x278 square for image + calculateSize = image => { + if (!image.width || !image.height) { + return {} + } + const width = parseInt(image.width) + const height = parseInt(image.height) + + // Not necessary to recalculate if it fits within boundaries + if (width < MAX_IMAGE_SIZE && height < MAX_IMAGE_SIZE) { + return { width, height } + } + + if (width > height) { + return { height: sizeWithRatio(height, width), width: '100%' } + } else { + return { + width: sizeWithRatio(width, height, '100%'), + height: Math.min(height, MAX_IMAGE_SIZE), + } + } } renderAction() { diff --git a/src/components/MessageCard/MessageCard.stories.mdx b/src/components/MessageCard/MessageCard.stories.mdx index 98ee59503..370828acb 100644 --- a/src/components/MessageCard/MessageCard.stories.mdx +++ b/src/components/MessageCard/MessageCard.stories.mdx @@ -50,6 +50,8 @@ This component renders a Message Card Notification with (optional) Title, Subtit subtitle={text('Subtitle', 'The J&G Team is here')} title={text('Title', 'Need help?')} image={{ + height: '230', + width: '800', url: 'http://matthewjamestaylor.com/img/illustrations/large/how-to-convert-a-liquid-layout-to-fixed-width.jpg', }} diff --git a/src/components/MessageCard/MessageCard.test.js b/src/components/MessageCard/MessageCard.test.js index 5f36751cd..4aad3bfd2 100644 --- a/src/components/MessageCard/MessageCard.test.js +++ b/src/components/MessageCard/MessageCard.test.js @@ -7,6 +7,7 @@ import { BodyUI, ActionUI, ImageUI, + ImageContainerUI, } from './MessageCard.css' import { Animate } from '../index' import { MessageCardButton as Button } from './MessageCard.Button' @@ -191,8 +192,40 @@ describe('image', () => { ) const image = wrapper.find(ImageUI) - expect(image.prop('width')).toEqual('100') - expect(image.prop('height')).toEqual('200') + expect(image.prop('width')).toEqual(100) + expect(image.prop('height')).toEqual(200) + }) + + test('Scales size of image when larger than fits and width is bigger', () => { + const wrapper = mount( + + ) + const image = wrapper.find(ImageUI) + + expect(image.prop('height')).toEqual(104.25) + expect(image.prop('width')).toEqual('100%') + }) + + test('Scales size of image when larger than fits and height is bigger', () => { + const wrapper = mount( + + ) + const image = wrapper.find(ImageUI) + + expect(image.prop('height')).toEqual(278) + expect(image.prop('width')).toEqual(104.25) }) test('Sets default size of image when not provided', () => { From d8f38056c18863d3982045e4b2c52b67911743bf Mon Sep 17 00:00:00 2001 From: Jakub Janczyk Date: Tue, 20 Apr 2021 18:14:51 +0200 Subject: [PATCH 2/4] fix style values --- src/components/MessageCard/MessageCard.css.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MessageCard/MessageCard.css.js b/src/components/MessageCard/MessageCard.css.js index 5b1a6ccae..4ef0eb92a 100644 --- a/src/components/MessageCard/MessageCard.css.js +++ b/src/components/MessageCard/MessageCard.css.js @@ -271,8 +271,8 @@ export const ActionButtonUI = styled(Button)` export const ImageUI = styled(Image)` border-radius: 3px; - height: ${({ height }) => height || 'auto'}; - width: ${({ width }) => width || '100%'}; + height: ${({ height }) => `${height}px` || 'auto'}; + width: ${({ width }) => `${width}px` || '100%'}; max-height: 278px; ` From 7606f591e9c6a64005f68a328ed4f6933e9fc387 Mon Sep 17 00:00:00 2001 From: Jakub Janczyk Date: Tue, 20 Apr 2021 18:49:39 +0200 Subject: [PATCH 3/4] adjusts the paddings for a Card --- src/components/MessageCard/MessageCard.css.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/MessageCard/MessageCard.css.js b/src/components/MessageCard/MessageCard.css.js index 4ef0eb92a..2a78a76ae 100644 --- a/src/components/MessageCard/MessageCard.css.js +++ b/src/components/MessageCard/MessageCard.css.js @@ -14,7 +14,7 @@ export const MessageCardUI = styled(Card)` background-color: white; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); border-radius: 8px; - padding: 20px 0 25px; + padding: 12px 0 10px; width: 300px; word-break: break-word; display: flex; @@ -59,7 +59,6 @@ export const MessageCardUI = styled(Card)` export const TitleUI = styled(Heading)` ${fontFamily}; line-height: 22px !important; - margin-top: 5px; padding: 0 20px; flex: 0 0 auto; ` From e6e8687a7dda91e80581d500174cfce07a1743ca Mon Sep 17 00:00:00 2001 From: Jakub Janczyk Date: Wed, 21 Apr 2021 10:10:02 +0200 Subject: [PATCH 4/4] change setting of width and height to avoid strange results like `100%px` --- src/components/MessageCard/MessageCard.css.js | 4 ++-- src/components/MessageCard/MessageCard.jsx | 17 ++++++++--------- src/components/MessageCard/MessageCard.test.js | 12 ++++++------ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/components/MessageCard/MessageCard.css.js b/src/components/MessageCard/MessageCard.css.js index 2a78a76ae..a83235fcc 100644 --- a/src/components/MessageCard/MessageCard.css.js +++ b/src/components/MessageCard/MessageCard.css.js @@ -270,8 +270,8 @@ export const ActionButtonUI = styled(Button)` export const ImageUI = styled(Image)` border-radius: 3px; - height: ${({ height }) => `${height}px` || 'auto'}; - width: ${({ width }) => `${width}px` || '100%'}; + height: ${({ height }) => height}; + width: ${({ width }) => width}; max-height: 278px; ` diff --git a/src/components/MessageCard/MessageCard.jsx b/src/components/MessageCard/MessageCard.jsx index 6b10b664b..3afe2d3ca 100644 --- a/src/components/MessageCard/MessageCard.jsx +++ b/src/components/MessageCard/MessageCard.jsx @@ -18,11 +18,7 @@ import Truncate from '../Truncate' const MAX_IMAGE_SIZE = 278 -const sizeWithRatio = ( - recalculatedSide, - otherSide, - defaultValue = recalculatedSide -) => +const sizeWithRatio = (recalculatedSide, otherSide, defaultValue) => // Check if other side is smaller than max size to not recalculate unnecessarily this side as it doesn't need any scaling // other condition checks that the image fits the boundaries otherSide < MAX_IMAGE_SIZE @@ -110,8 +106,8 @@ export class MessageCard extends React.PureComponent { ) @@ -131,10 +127,13 @@ export class MessageCard extends React.PureComponent { } if (width > height) { - return { height: sizeWithRatio(height, width), width: '100%' } + return { + height: sizeWithRatio(height, width, height), + width: Math.min(width, MAX_IMAGE_SIZE), + } } else { return { - width: sizeWithRatio(width, height, '100%'), + width: sizeWithRatio(width, height, MAX_IMAGE_SIZE), height: Math.min(height, MAX_IMAGE_SIZE), } } diff --git a/src/components/MessageCard/MessageCard.test.js b/src/components/MessageCard/MessageCard.test.js index 4aad3bfd2..c46b8c5c0 100644 --- a/src/components/MessageCard/MessageCard.test.js +++ b/src/components/MessageCard/MessageCard.test.js @@ -192,8 +192,8 @@ describe('image', () => { ) const image = wrapper.find(ImageUI) - expect(image.prop('width')).toEqual(100) - expect(image.prop('height')).toEqual(200) + expect(image.prop('width')).toEqual('100px') + expect(image.prop('height')).toEqual('200px') }) test('Scales size of image when larger than fits and width is bigger', () => { @@ -208,8 +208,8 @@ describe('image', () => { ) const image = wrapper.find(ImageUI) - expect(image.prop('height')).toEqual(104.25) - expect(image.prop('width')).toEqual('100%') + expect(image.prop('height')).toEqual('104.25px') + expect(image.prop('width')).toEqual('278px') }) test('Scales size of image when larger than fits and height is bigger', () => { @@ -224,8 +224,8 @@ describe('image', () => { ) const image = wrapper.find(ImageUI) - expect(image.prop('height')).toEqual(278) - expect(image.prop('width')).toEqual(104.25) + expect(image.prop('height')).toEqual('278px') + expect(image.prop('width')).toEqual('104.25px') }) test('Sets default size of image when not provided', () => {