diff --git a/.storybook/addons.js b/.storybook/addons.js
index 6aed412d..a77bd590 100644
--- a/.storybook/addons.js
+++ b/.storybook/addons.js
@@ -1,2 +1,3 @@
-import '@storybook/addon-actions/register';
-import '@storybook/addon-links/register';
+import '@storybook/addon-actions/register'
+import '@storybook/addon-links/register'
+import '@storybook/addon-knobs/register'
diff --git a/README.md b/README.md
index ea2d345e..323f19f2 100644
--- a/README.md
+++ b/README.md
@@ -96,17 +96,23 @@ Currently there are two supported providers:
To use HelpScout set the `provider` prop as `helpScout` and set the
`providerKey` prop as your Beacon API Key.
+You can customise the HelpScout beacon by passing the following props to the
+`HelpScout` component:
+
+- `color`: The background color of the beacon
+- `icon`: Choose from `message`, `antenna`, `search`, `question`, `beacon`
+- `zIndex`: Changes the CSS index value of how the Beacon relates to other objects
+- `horizontalPosition`: Choose from `left` or `right`
+
#### Intercom
To use Intercom set the `provider` as `intercom` and set the `providerKey` props
as your Intercom App ID.
-### Options
-
You can customise the color of the Intercom widget by passing a `color` prop to
-the `LiveChatLoaderProvider`.
+the `Intercom` component.
### Todo
-- Add customisation options for HelpScout
+- Add further customisation options for HelpScout: `buttonStyle`, `text`, `textAlign`
- Add tests
diff --git a/package.json b/package.json
index 3271a50d..dc462a2c 100644
--- a/package.json
+++ b/package.json
@@ -22,8 +22,7 @@
"url": "https://github.com/calibreapp/react-live-chat-loader.git"
},
"peerDependencies": {
- "react": "^16.8.5",
- "styled-components": "^4.2.0"
+ "react": "^16.8.5"
},
"devDependencies": {
"@babel/cli": "^7.5.0",
@@ -31,6 +30,7 @@
"@babel/preset-env": "^7.5.0",
"@babel/preset-react": "^7.0.0",
"@storybook/addon-actions": "^5.1.9",
+ "@storybook/addon-knobs": "^5.2.6",
"@storybook/addon-links": "^5.1.9",
"@storybook/addons": "^5.1.9",
"@storybook/react": "^5.1.9",
@@ -44,8 +44,7 @@
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-react": "^7.14.2",
"eslint-plugin-react-hooks": "^1.0.1",
- "react": "^16.8.5",
- "styled-components": "^4.2.0"
+ "react": "^16.8.5"
},
"files": [
"dist/*"
diff --git a/src/components/HelpScout/index.js b/src/components/HelpScout/index.js
index a837084d..c97d6c40 100644
--- a/src/components/HelpScout/index.js
+++ b/src/components/HelpScout/index.js
@@ -1,170 +1,222 @@
-import React from 'react'
-import styled, { keyframes } from 'styled-components'
+import React, { useEffect, useState } from 'react'
import { useChat } from '../../'
+import useWindowHeight from '../../hooks/useWindowHeight'
import STATES from '../../utils/states'
-const animation = keyframes`
- from {
- transform: scale(0);
+const styles = {
+ wrapper: {
+ borderRadius: '55px',
+ height: '60px',
+ width: '60px',
+ bottom: '40px',
+ boxShadow: 'rgba(0, 0, 0, 0.1) 0px 4px 7px',
+ position: 'fixed',
+ right: '40px',
+ top: 'auto',
+ borderStyle: 'none',
+ transition:
+ 'box-shadow 250ms ease 0s, opacity 0.4s ease 0s, scale 1000ms ease-in-out 0s, transform 0.2s ease-in-out 0s'
+ },
+ button: {
+ appearance: 'none',
+ alignItems: 'center',
+ bottom: '0px',
+ display: 'block',
+ justifyContent: 'center',
+ position: 'relative',
+ userSelect: 'none',
+ zIndex: '999',
+ color: 'white',
+ cursor: 'pointer',
+ minWidth: '60px',
+ WebkitTapHighlightColor: 'transparent',
+ height: '60px',
+ lineHeight: '60px',
+ borderRadius: '120px',
+ margin: '0px',
+ outline: 'none',
+ padding: '0px',
+ borderStyle: 'none',
+ transition: 'background-color 200ms linear 0s, transform 200ms linear 0s'
+ },
+ icon: {
+ alignItems: 'center',
+ color: 'white',
+ cursor: 'pointer',
+ display: 'flex',
+ height: '100%',
+ WebkitBoxPack: 'center',
+ justifyContent: 'center',
+ pointerEvents: 'none',
+ position: 'absolute',
+ textIndent: '-99999px',
+ top: '0px',
+ width: '60px',
+ willChange: 'opacity, transform',
+ left: 'auto',
+ right: '0px',
+ opacity: '1 !important',
+ transition: 'opacity 80ms linear 0s, transform 160ms linear 0s'
+ },
+ close: {
+ WebkitBoxAlign: 'center',
+ alignItems: 'center',
+ color: 'white',
+ cursor: 'pointer',
+ display: 'flex',
+ height: '100%',
+ WebkitBoxPack: 'center',
+ justifyContent: 'center',
+ pointerEvents: 'none',
+ position: 'absolute',
+ textIndent: '-99999px',
+ top: '0px',
+ width: '60px',
+ willChange: 'opacity, transform',
+ left: 'auto',
+ right: '0px',
+ transition: 'opacity 80ms linear 0s, transform 160ms linear 0s'
}
+}
- to {
- transform: scale(1);
- }
-`
-
-const Wrapper = styled.div`
- border-radius: 55px;
- height: 55px;
- transform: scale(1);
- width: 105px;
- z-index: 1050; // One more than the script Beacon
- bottom: 40px;
- box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 7px;
- position: fixed;
- right: 40px;
- top: auto;
- border-width: initial;
- border-style: none;
- border-color: initial;
- border-image: initial;
- transition: box-shadow 250ms ease 0s, opacity 0.4s ease 0s,
- scale 1000ms ease-in-out 0s, transform 0.2s ease-in-out 0s;
- animation-duration: 250ms;
- animation-timing-function: ease;
- animation-delay: initial;
- animation-iteration-count: initial;
- animation-direction: initial;
- animation-fill-mode: initial;
- animation-play-state: initial;
- animation-name: ${animation};
-
- @media (max-height: 740px) {
- bottom: 10px;
- right: 20px;
- }
-`
-
-const Button = styled.button`
- appearance: none;
- align-items: center;
- bottom: 0px;
- display: block;
- justify-content: center;
- position: relative;
- user-select: none;
- z-index: 999;
- background-color: rgb(35, 146, 236);
- color: white;
- cursor: pointer;
- min-width: 60px;
- -webkit-tap-highlight-color: transparent;
- height: 55px;
- line-height: 55px;
- border-radius: 200px;
- margin: 0px;
- outline: none;
- padding: 0px;
- border-width: initial;
- border-style: none;
- border-color: initial;
- border-image: initial;
- transition: background-color 200ms linear 0s, transform 200ms linear 0s;
-
- &:focus,
- &:hover {
- background-color: rgb(27, 138, 228);
- box-shadow: rgba(0, 0, 0, 0.06) 0px 0px 0px 30px inset;
+const getIcon = icon => {
+ switch (icon) {
+ case 'message':
+ return (
+
+ )
+ case 'antenna':
+ return (
+
+ )
+ case 'search':
+ return (
+
+ )
+ case 'question':
+ return (
+
+ )
+ case 'beacon':
+ return (
+
+ )
+ case 'close':
+ default:
+ return (
+
+ )
}
-`
-
-const Icon = styled.span`
- align-items: center;
- color: white;
- cursor: pointer;
- display: flex;
- height: 100%;
- -webkit-box-pack: center;
- justify-content: center;
- pointer-events: none;
- position: absolute;
- text-indent: -99999px;
- top: 0px;
- width: 60px;
- will-change: opacity, transform;
- left: auto;
- right: 0px;
- opacity: 1 !important;
- transform: ${({ state }) =>
- state === STATES.INITIAL
- ? 'rotate(0deg) scale(1)'
- : 'rotate(30deg) scale(0)'};
- transition: opacity 80ms linear 0s, transform 160ms linear 0s;
-`
+}
-const Close = styled.span`
- -webkit-box-align: center;
- align-items: center;
- color: white;
- cursor: pointer;
- display: flex;
- height: 100%;
- -webkit-box-pack: center;
- justify-content: center;
- opacity: ${({ state }) => (state === STATES.INITIAL ? 0 : 1)};
- transform: ${({ state }) =>
- state === STATES.INITIAL
- ? 'rotate(30deg) scale(0)'
- : 'rotate(0deg) scale(1)'};
- pointer-events: none;
- position: absolute;
- text-indent: -99999px;
- top: 0px;
- width: 60px;
- will-change: opacity, transform;
- left: auto;
- right: 0px;
- transition: opacity 80ms linear 0s, transform 160ms linear 0s;
-`
+const HelpScout = ({ color, icon, zIndex, horizontalPosition }) => {
+ const [scale, setScale] = useState(0)
+ const [state, loadChat] = useChat()
+ const windowHeight = useWindowHeight()
-const Text = styled.span`
- color: white;
- display: block;
- font-size: 14px;
- font-weight: 600;
- white-space: nowrap;
- padding: 0px 54px 0px 20px;
-`
+ useEffect(() => {
+ setScale(1)
+ }, [])
-const HelpScout = () => {
- const [state, loadChat] = useChat({ toggle: true })
if (state === STATES.COMPLETE) return null
+
return (
-
-
-
+
+
+
)
}
+HelpScout.defaultProps = {
+ color: '#976ad4',
+ icon: 'beacon',
+ zIndex: '1050',
+ horizontalPosition: 'left'
+}
+
export default HelpScout
diff --git a/src/components/Intercom/index.js b/src/components/Intercom/index.js
index 41c34946..29f2aac2 100644
--- a/src/components/Intercom/index.js
+++ b/src/components/Intercom/index.js
@@ -1,180 +1,153 @@
-import React, { useContext } from 'react'
-import styled, { keyframes } from 'styled-components'
+import React, { useEffect, useState } from 'react'
-import { useChat, LiveChatLoaderContext } from '../../'
+import { useChat } from '../../'
import STATES from '../../utils/states'
-const animation = keyframes`
- from {
- transform: scale(0);
+const styles = {
+ wrapper: {
+ zIndex: 2147483000,
+ position: 'fixed',
+ bottom: '20px',
+ display: 'block',
+ right: '20px',
+ width: '60px',
+ height: '60px',
+ borderRadius: '50%',
+ transition: 'transform 0.3s ease',
+ transform: 'scale(1)',
+ boxShadow:
+ 'rgba(0, 0, 0, 0.0588235) 0px 1px 6px 0px, rgba(0, 0, 0, 0.156863) 0px 2px 32px 0px'
+ },
+ region: {
+ fontFamily:
+ "intercom-font, 'Helvetica Neue', 'Apple Color Emoji', Helvetica, Arial, sans-serif",
+ fontSize: '100%',
+ fontStyle: 'normal',
+ letterSpacing: 'normal',
+ fontStretch: 'normal',
+ fontVariantLigatures: 'normal',
+ fontVariantCaps: 'normal',
+ fontVariantEastAsian: 'normal',
+ fontVariantPosition: 'normal',
+ fontWeight: 'normal',
+ textAlign: 'left',
+ textDecorationLine: 'none',
+ textDecorationStyle: 'initial',
+ textDecorationColor: 'initial',
+ textDecoration: 'none',
+ textIndent: '0px',
+ textShadow: 'none',
+ textTransform: 'none',
+ boxSizing: 'content-box',
+ WebkitTextEmphasisRtyle: 'none',
+ WebkitTextEmphasisColor: 'initial',
+ WebkitFontSmoothing: 'antialiased',
+ lineHeight: 1
+ },
+ launcher: {
+ position: 'absolute',
+ top: '0px',
+ left: '0px',
+ width: '60px',
+ height: '60px',
+ borderRadius: '50%',
+ cursor: 'pointer',
+ transformOriginX: 'center',
+ transformOriginY: 'center',
+ overflowX: 'hidden',
+ overflowY: 'hidden',
+ WebkitBackfaceVisibility: 'hidden',
+ WebkitFontSmoothing: 'antialiased'
+ },
+ logo: {
+ display: 'flex',
+ WebkitBoxAlign: 'center',
+ alignItems: 'center',
+ WebkitBoxPack: 'center',
+ justifyContent: 'center',
+ position: 'absolute',
+ top: '0px',
+ bottom: '0px',
+ width: '100%',
+ transform: 'rotate(0deg) scale(1)',
+ transition: 'transform 0.16s linear 0s, opacity 0.08s linear 0s'
+ },
+ close: {
+ display: 'flex',
+ WebkitBoxAlign: 'center',
+ alignItems: 'center',
+ WebkitBoxPack: 'center',
+ justifyContent: 'center',
+ position: 'absolute',
+ top: '0px',
+ bottom: '0px',
+ width: '100%',
+ transition: 'transform 0.16s linear 0s, opacity 0.08s linear 0s'
}
-
- to {
- transform: scale(1);
- }
-`
-
-const Wrapper = styled.div`
- z-index: 2147483001; //One more than real widget
- position: fixed;
- bottom: 20px;
- display: block;
- right: 20px;
- width: 60px;
- height: 60px;
- border-top-left-radius: 50%;
- border-top-right-radius: 50%;
- border-bottom-right-radius: 50%;
- border-bottom-left-radius: 50%;
- background-image: initial;
- background-position-x: initial;
- background-position-y: initial;
- background-size: initial;
- background-repeat-x: initial;
- background-repeat-y: initial;
- background-attachment: initial;
- background-origin: initial;
- background-clip: initial;
- background-color: ${({ color }) => color};
- animation-duration: 250ms;
- animation-timing-function: ease;
- animation-delay: initial;
- animation-iteration-count: initial;
- animation-direction: initial;
- animation-fill-mode: initial;
- animation-play-state: initial;
- animation-name: ${animation};
- transition-duration: 0.3s;
- transition-timing-function: initial;
- transition-delay: initial;
- transition-property: opacity;
- box-shadow: rgba(0, 0, 0, 0.0588235) 0px 1px 6px 0px,
- rgba(0, 0, 0, 0.156863) 0px 2px 32px 0px;
-`
-Wrapper.defaultProps = {
- color: 'rgb(0, 113, 178)'
}
-const Region = styled.div`
- font-family: intercom-font, 'Helvetica Neue', 'Apple Color Emoji', Helvetica,
- Arial, sans-serif;
- font-size: 100%;
- font-style: normal;
- letter-spacing: normal;
- font-stretch: normal;
- font-variant-ligatures: normal;
- font-variant-caps: normal;
- font-variant-east-asian: normal;
- font-variant-position: normal;
- font-weight: normal;
- text-align: left;
- text-decoration-line: none;
- text-decoration-style: initial;
- text-decoration-color: initial;
- text-decoration: none;
- -webkit-text-emphasis-style: none;
- -webkit-text-emphasis-color: initial;
- text-indent: 0px;
- text-shadow: none;
- text-transform: none;
- box-sizing: content-box;
- -webkit-font-smoothing: antialiased;
- line-height: 1;
-`
-
-const Launcher = styled.div`
- position: absolute;
- top: 0px;
- left: 0px;
- width: 60px;
- height: 60px;
- border-top-left-radius: 50%;
- border-top-right-radius: 50%;
- border-bottom-right-radius: 50%;
- border-bottom-left-radius: 50%;
- cursor: pointer;
- transform-origin-x: center;
- transform-origin-y: center;
- -webkit-backface-visibility: hidden;
- overflow-x: hidden;
- overflow-y: hidden;
- -webkit-font-smoothing: antialiased;
-`
-
-const Logo = styled.div`
- display: flex;
- -webkit-box-align: center;
- align-items: center;
- -webkit-box-pack: center;
- justify-content: center;
- position: absolute;
- top: 0px;
- bottom: 0px;
- width: 100%;
- opacity: ${({ state }) => (state === STATES.INITIAL ? 1 : 0)};
- transform: rotate(0deg) scale(1);
- transition: transform 0.16s linear 0s, opacity 0.08s linear 0s;
-
- svg {
- height: 28px;
- width: 32px;
-
- path {
- fill: rgb(255, 255, 255);
- }
- }
-`
-
-const Close = styled.div`
- display: flex;
- -webkit-box-align: center;
- align-items: center;
- -webkit-box-pack: center;
- justify-content: center;
- position: absolute;
- top: 0px;
- bottom: 0px;
- width: 100%;
- opacity: ${({ state }) => (state === STATES.INITIAL ? 0 : 1)};
- transform: ${({ state }) =>
- state === STATES.INITIAL ? 'rotate(-30deg)' : 'rotate(0deg)'};
- transition: transform 0.16s linear 0s, opacity 0.08s linear 0s;
+const Intercom = ({ color = '#333333' }) => {
+ const [scale, setScale] = useState(0)
+ const [state, loadChat] = useChat()
- svg {
- width: 14px;
- height: 14px;
-
- path {
- fill: rgb(255, 255, 255);
- }
- }
-`
-
-const Intercom = () => {
- const [state, loadChat] = useChat({ toggle: true })
- const { color } = useContext(LiveChatLoaderContext)
+ useEffect(() => {
+ setScale(1)
+ }, [])
if (state === STATES.COMPLETE) return null
return (
-
-
-
-
-