Skip to content

Commit

Permalink
fix(components): fix carousel component (#260)
Browse files Browse the repository at this point in the history
* fix(components): fix carousel component

* v0.0.4
  • Loading branch information
laurentlp committed Nov 26, 2021
1 parent de8f08a commit 91e7627
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 58 deletions.
5 changes: 3 additions & 2 deletions packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@botpress/messaging-components",
"version": "0.0.2",
"version": "0.0.4",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"source": "src/index.tsx",
Expand All @@ -22,7 +22,8 @@
"build": "yarn --silent && tsc --build",
"watch": "yarn --silent && tsc --build --watch",
"storybook": "start-storybook -p 6006 -c story/config",
"build-storybook": "build-storybook -c story/config"
"build-storybook": "build-storybook -c story/config",
"prepublishOnly": "yarn build"
},
"files": [
"dist"
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/content-typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export interface CardContent extends BaseContent<'card'> {
title: string
subtitle?: string
image?: string
actions: ActionButton<ActionType>[]
actions?: ActionButton<ActionType>[]
}

export interface LocationContent extends BaseContent<'location'> {
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { FC } from 'react'
import { Content, MessageType } from './content-typings'
import defaultRenderer, { Renderer } from './renderer'
import { MessageConfig } from './typings'
import { defaultMessageConfig } from './utils'

export interface ReactMessageRendererProps {
content: Content<MessageType>
Expand All @@ -14,3 +15,4 @@ const ReactMessageRenderer: FC<ReactMessageRendererProps> = ({ content, config,
}

export default ReactMessageRenderer
export { defaultMessageConfig, Content, MessageType, MessageConfig, Renderer }
104 changes: 53 additions & 51 deletions packages/components/src/renderer/carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,57 +64,59 @@ export const Card: React.FC<MessageTypeHandlerProps<'card'>> = ({ image, title,
<div className={'bpw-card-title'}>{title}</div>
{subtitle && <div className={'bpw-card-subtitle'}>{subtitle}</div>}
</div>
<div className={'bpw-card-buttons'}>
{actions.map((btn: ActionButton<ActionType>) => {
if (btn.action === 'Open URL') {
const { url } = btn as ActionButton<'Open URL'>
return (
<a
href={url}
key={`1-${btn.title}`}
target={/^javascript:/.test(url || '') ? '_self' : '_blank'}
className={'bpw-card-action'}
>
{btn.title || btn}
{/^javascript:/.test(url || '') ? null : <i className={'bpw-card-external-icon'} />}
</a>
)
} else if (btn.action === 'Say something') {
const { text } = btn as ActionButton<'Say something'>
return (
<a
onClick={async () => {
await config.onSendData({ type: 'say_something', text })
}}
key={`2-${btn.title}`}
className={'bpw-card-action'}
>
{btn.title || btn}
</a>
)
} else if (btn.action === 'Postback') {
const { payload } = btn as ActionButton<'Postback'>
return (
<a
onClick={async () => {
await config.onSendData({ type: 'postback', payload })
}}
key={`2-${btn.title}`}
className={'bpw-card-action'}
>
{btn.title || btn}
</a>
)
} else {
return (
<a href={'#'} key={`3-${btn.title}`} target={'_blank'} className={'bpw-card-action'}>
{btn.title || btn}
<i className={'bpw-card-external-icon'} />
</a>
)
}
})}
</div>
{actions && (
<div className={'bpw-card-buttons'}>
{actions.map((btn: ActionButton<ActionType>) => {
if (btn.action === 'Open URL') {
const { url } = btn as ActionButton<'Open URL'>
return (
<a
href={url}
key={`1-${btn.title}`}
target={/^javascript:/.test(url || '') ? '_self' : '_blank'}
className={'bpw-card-action'}
>
{btn.title || btn}
{/^javascript:/.test(url || '') ? null : <i className={'bpw-card-external-icon'} />}
</a>
)
} else if (btn.action === 'Say something') {
const { text } = btn as ActionButton<'Say something'>
return (
<a
onClick={async () => {
await config.onSendData({ type: 'say_something', text })
}}
key={`2-${btn.title}`}
className={'bpw-card-action'}
>
{btn.title || btn}
</a>
)
} else if (btn.action === 'Postback') {
const { payload } = btn as ActionButton<'Postback'>
return (
<a
onClick={async () => {
await config.onSendData({ type: 'postback', payload })
}}
key={`2-${btn.title}`}
className={'bpw-card-action'}
>
{btn.title || btn}
</a>
)
} else {
return (
<a href={'#'} key={`3-${btn.title}`} target={'_blank'} className={'bpw-card-action'}>
{btn.title || btn}
<i className={'bpw-card-external-icon'} />
</a>
)
}
})}
</div>
)}
</div>
</div>
)
Expand Down
5 changes: 5 additions & 0 deletions packages/components/story/carousel.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ Primary.args = {
payload: 'button_clicked'
}
]
},
{
title: 'Card 2',
subtitle: 'Subtitle 2',
image: 'https://via.placeholder.com/150/150'
}
],
config: {
Expand Down
36 changes: 33 additions & 3 deletions packages/components/test/unit/carousel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,37 @@ describe('Carousel & Card renderer', () => {
expect(container.querySelector('.bpw-card-subtitle')).toHaveTextContent(card.subtitle!)

const btnEl = container.querySelector('.bpw-card-action')
expect(btnEl).toHaveTextContent(card.actions[0].title)
expect(btnEl).toHaveTextContent(card.actions![0].title)
})

test('it renders a card with image, title, subtitle and no button', () => {
const noBtnMessageData: Message<'carousel'> = {
content: {
type: 'carousel',
items: [
{
title: 'Card 1',
subtitle: 'Subtitle 1',
image: 'https://via.placeholder.com/150/150'
}
]
},
config: defaultMessageConfig
}

const card = noBtnMessageData.content.items[0]
const component = renderer.render(noBtnMessageData)

expect(component).toBeTruthy()

const { container } = render(component)

expect(container.querySelector('.slick-slider')).toBeInTheDocument()
expect(container.querySelector('.bpw-card-picture')).toHaveStyle(`background-image: url(${card.image})`)
expect(container.querySelector('.bpw-card-title')).toHaveTextContent(card.title)
expect(container.querySelector('.bpw-card-subtitle')).toHaveTextContent(card.subtitle!)

expect(container.querySelector('.bpw-card-action')).not.toBeInTheDocument()
})

test('it calls onSendData with postback payload on postback button click', () => {
Expand All @@ -58,7 +88,7 @@ describe('Carousel & Card renderer', () => {

const card = messageData.content.items[0]
expect(mockOnSendData).toHaveBeenCalledWith({
payload: (card.actions[0] as ActionButton<'Postback'>).payload,
payload: (card.actions![0] as ActionButton<'Postback'>).payload,
type: 'postback'
})
})
Expand Down Expand Up @@ -92,7 +122,7 @@ describe('Carousel & Card renderer', () => {

expect(btnEl).toHaveAttribute(
'href',
(urlBtnMessageData.content.items[0].actions[0] as ActionButton<'Open URL'>).url
(urlBtnMessageData.content.items[0].actions![0] as ActionButton<'Open URL'>).url
)
expect(btnEl).toHaveAttribute('target', '_blank')
})
Expand Down
2 changes: 1 addition & 1 deletion packages/webchat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
],
"dependencies": {
"@blueprintjs/core": "^3.23.1",
"@botpress/messaging-components": "0.0.2",
"@botpress/messaging-components": "*",
"@botpress/messaging-socket": "0.0.2",
"@juggle/resize-observer": "^3.0.2",
"date-fns": "^1.30.1",
Expand Down

0 comments on commit 91e7627

Please sign in to comment.