Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Commit

Permalink
Merge branch 'master' into refactor/emojipicker
Browse files Browse the repository at this point in the history
  • Loading branch information
tinkertrain committed Apr 21, 2021
2 parents f6d13c5 + 4c32502 commit 0e94ae6
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 16 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@helpscout/hsds-react",
"version": "3.12.4",
"version": "3.12.5",
"private": false,
"main": "dist/index.js",
"module": "dist/index.es.js",
Expand Down
10 changes: 8 additions & 2 deletions src/components/MessageCard/MessageCard.css.js
Expand Up @@ -7,14 +7,17 @@ import Card from '../Card'
import Button from '../Button'
import Heading from '../Heading'
import Image from '../Image'

export const MAX_IMAGE_SIZE = 278

const fontFamily = makeFontFamily('Barlow')

export const MessageCardUI = styled(Card)`
border-color: transparent !important;
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;
Expand Down Expand Up @@ -59,7 +62,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;
`
Expand Down Expand Up @@ -271,6 +273,9 @@ export const ActionButtonUI = styled(Button)`

export const ImageUI = styled(Image)`
border-radius: 3px;
height: ${({ height }) => height};
width: ${({ width }) => width};
max-height: ${MAX_IMAGE_SIZE}px;
`

export const ImageContainerUI = styled('div')`
Expand All @@ -279,4 +284,5 @@ export const ImageContainerUI = styled('div')`
width: 100%;
margin-top: 20px;
padding: 0 10px;
max-height: ${MAX_IMAGE_SIZE}px;
`
58 changes: 49 additions & 9 deletions src/components/MessageCard/MessageCard.jsx
Expand Up @@ -6,16 +6,24 @@ import { classNames } from '../../utilities/classNames'
import { noop } from '../../utilities/other'
import Animate from '../Animate'
import {
MessageCardUI,
TitleUI,
SubtitleUI,
BodyUI,
ActionUI,
ImageUI,
BodyUI,
ImageContainerUI,
ImageUI,
MAX_IMAGE_SIZE,
MessageCardUI,
SubtitleUI,
TitleUI,
} from './MessageCard.css'
import Truncate from '../Truncate'

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
? defaultValue
: (recalculatedSide / otherSide) * MAX_IMAGE_SIZE

export class MessageCard extends React.PureComponent {
static className = 'c-MessageCard'
static Button = MessageCardButton
Expand Down Expand Up @@ -86,16 +94,48 @@ export class MessageCard extends React.PureComponent {
renderImage() {
const { image } = this.props

return image ? (
if (!image) {
return null
}

const { height, width } = this.calculateSize(image)

return (
<ImageContainerUI>
<ImageUI
src={image.url}
alt={image.altText || 'Message image'}
width={image.width || '100%'}
height={image.height || 'auto'}
width={width ? `${width}px` : '100%'}
height={height ? `${height}px` : 'auto'}
/>
</ImageContainerUI>
) : 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, height),
width: Math.min(width, MAX_IMAGE_SIZE),
}
} else {
return {
width: sizeWithRatio(width, height, MAX_IMAGE_SIZE),
height: Math.min(height, MAX_IMAGE_SIZE),
}
}
}

renderAction() {
Expand Down
2 changes: 2 additions & 0 deletions src/components/MessageCard/MessageCard.stories.mdx
Expand Up @@ -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',
}}
Expand Down
37 changes: 35 additions & 2 deletions src/components/MessageCard/MessageCard.test.js
Expand Up @@ -7,6 +7,7 @@ import {
BodyUI,
ActionUI,
ImageUI,
ImageContainerUI,
} from './MessageCard.css'
import { Animate } from '../index'
import { MessageCardButton as Button } from './MessageCard.Button'
Expand Down Expand Up @@ -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('100px')
expect(image.prop('height')).toEqual('200px')
})

test('Scales size of image when larger than fits and width is bigger', () => {
const wrapper = mount(
<MessageCard
image={{
url: 'https://path.to/image.png',
width: '800',
height: '300',
}}
/>
)
const image = wrapper.find(ImageUI)

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', () => {
const wrapper = mount(
<MessageCard
image={{
url: 'https://path.to/image.png',
width: '300',
height: '800',
}}
/>
)
const image = wrapper.find(ImageUI)

expect(image.prop('height')).toEqual('278px')
expect(image.prop('width')).toEqual('104.25px')
})

test('Sets default size of image when not provided', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/pkg.js
@@ -1,3 +1,3 @@
export default {
version: '3.12.4',
version: '3.12.5',
}

0 comments on commit 0e94ae6

Please sign in to comment.