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

Update Intercom component to accept style-related props #101

Closed
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# React Live Chat Loader

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-)

[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-)
benschwarz marked this conversation as resolved.
Show resolved Hide resolved

<!-- ALL-CONTRIBUTORS-BADGE:END -->

[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](CODE_OF_CONDUCT.md)
Expand Down Expand Up @@ -191,8 +193,8 @@ export default class App extends React.Component {
}
```

You can customise the color of the Intercom widget by passing a `color` prop to
the `Intercom` component.
You can customise the Intercom widget by passing `color`, `alignment`, `verticalPadding`, or `horizontalPadding` props to
the `Intercom` component. Any props provided to the Intercom component are set on `window.intercomSettings` to ensure there is no style mismatch between the facade and the loaded widget. To mirror [the loaded widget behavior](https://www.intercom.com/help/en/articles/2894-customize-the-intercom-messenger-technical) on screen sizes smaller than 900px wide the vertical and horizontal padding will be the default of 20px.

User or Company context data can be set using `window.intercomSettings`. See the [official Intercom documentation](https://developers.intercom.com/installing-intercom/docs/javascript-api-attributes-objects#section-data-attributes) for more details.

Expand Down
58 changes: 52 additions & 6 deletions src/components/Intercom/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { CSSProperties } from 'react'
import React, { CSSProperties, useEffect, useState } from 'react'

import useChat from '../../hooks/useChat'
import useWindowWidth from '../../hooks/useWindowWidth'

const styles: {
wrapper: CSSProperties
Expand All @@ -12,9 +13,7 @@ const styles: {
wrapper: {
zIndex: 2147483004, // 1 more than the actual widget
position: 'fixed',
bottom: '20px',
display: 'block',
right: '20px',
width: '60px',
height: '60px',
borderRadius: '50%',
Expand Down Expand Up @@ -90,11 +89,47 @@ const styles: {

interface Props {
color?: string
alignment?: 'left' | 'right'
verticalPadding?: number
horizontalPadding?: number
}

const Intercom = ({ color }: Props): JSX.Element | null => {
const DEFAULT_PADDING = 20
const DEFAULT_ALIGNMENT = 'right'
const INTERCOM_MOBILE_WIDTH = 900

const Intercom = ({
color = '#333333',
alignment = DEFAULT_ALIGNMENT,
verticalPadding = DEFAULT_PADDING,
horizontalPadding = DEFAULT_PADDING
}: Props): JSX.Element | null => {
const [state, loadChat] = useChat({ loadWhenIdle: true })

const [{ xPadding, yPadding }, setPaddingValues] = useState({
yPadding: Math.max(DEFAULT_PADDING, verticalPadding),
xPadding: Math.max(DEFAULT_PADDING, horizontalPadding)
})
const windowWidth = useWindowWidth()

useEffect(() => {
window.intercomSettings = {
...(window.intercomSettings || {}),
alignment,
background_color: color,
vertical_padding: yPadding,
horizontal_padding: xPadding
}
}, [])

useEffect(() => {
let padding = { yPadding: verticalPadding, xPadding: horizontalPadding }
if (windowWidth <= INTERCOM_MOBILE_WIDTH) {
padding = { yPadding: DEFAULT_PADDING, xPadding: DEFAULT_PADDING }
}
setPaddingValues(padding)
}, [windowWidth])

if (state === 'complete') {
return null
}
Expand All @@ -103,6 +138,8 @@ const Intercom = ({ color }: Props): JSX.Element | null => {
<div
style={{
...styles.wrapper,
bottom: `${yPadding}px`,
[alignment]: `${xPadding}px`,
background: color
}}
>
Expand Down Expand Up @@ -138,7 +175,13 @@ const Intercom = ({ color }: Props): JSX.Element | null => {
transform: state === 'initial' ? 'rotate(-30deg)' : 'rotate(0deg)'
}}
>
<svg focusable="false" viewBox="0 0 16 14" width="28" height="25" style={{ width : '16px' }}>
<svg
focusable="false"
viewBox="0 0 16 14"
width="28"
height="25"
style={{ width: '16px' }}
>
<path
fill="rgb(255, 255, 255)"
fillRule="evenodd"
Expand All @@ -154,7 +197,10 @@ const Intercom = ({ color }: Props): JSX.Element | null => {
}

Intercom.defaultProps = {
color: '#333333'
color: '#333333',
alignment: DEFAULT_ALIGNMENT,
verticalPadding: DEFAULT_PADDING,
horizontalPadding: DEFAULT_PADDING
}

export default Intercom
2 changes: 1 addition & 1 deletion src/providers/intercom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ declare global {
interface Window {
//eslint-disable-next-line @typescript-eslint/no-explicit-any
Intercom: any
intercomSettings: () => void
intercomSettings: Record<string, unknown>
}
}

Expand Down