feat: Add an extended bubble design for the widget (#1123)
* feat: Add a new design for chat bubble Signed-off-by: Pranav Raj Sreepuram <pranavrajs@gmail.com> * Add i18n * Fix stye issues * Set fixed font-size * Update docs for bubble
This commit is contained in:
parent
a04ca24def
commit
0adbc346df
16 changed files with 164 additions and 84 deletions
|
@ -1,4 +1,4 @@
|
|||
import { SDK_CSS } from '../widget/assets/scss/sdk';
|
||||
import { SDK_CSS } from './sdk.js';
|
||||
|
||||
export const loadCSS = () => {
|
||||
const css = document.createElement('style');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Cookies from 'js-cookie';
|
||||
import { wootOn, loadCSS, addClass, removeClass } from './DOMHelpers';
|
||||
import { wootOn, addClass, loadCSS, removeClass } from './DOMHelpers';
|
||||
import {
|
||||
body,
|
||||
widgetHolder,
|
||||
|
@ -12,6 +12,7 @@ import {
|
|||
createNotificationBubble,
|
||||
onClickChatBubble,
|
||||
onBubbleClick,
|
||||
setBubbleText,
|
||||
} from './bubbleHelpers';
|
||||
import { dispatchWindowEvent } from 'shared/helpers/CustomEventHelper';
|
||||
|
||||
|
@ -32,8 +33,9 @@ export const IFrameHelper = {
|
|||
|
||||
iframe.id = 'chatwoot_live_chat_widget';
|
||||
iframe.style.visibility = 'hidden';
|
||||
const HolderclassName = `woot-widget-holder woot--hide woot-elements--${window.$chatwoot.position}`;
|
||||
addClass(widgetHolder, HolderclassName);
|
||||
|
||||
const holderClassName = `woot-widget-holder woot--hide woot-elements--${window.$chatwoot.position}`;
|
||||
addClass(widgetHolder, holderClassName);
|
||||
widgetHolder.appendChild(iframe);
|
||||
body.appendChild(widgetHolder);
|
||||
IFrameHelper.initPostMessageCommunication();
|
||||
|
@ -69,9 +71,7 @@ export const IFrameHelper = {
|
|||
};
|
||||
},
|
||||
initWindowSizeListener: () => {
|
||||
wootOn(window, 'resize', () => {
|
||||
IFrameHelper.toggleCloseButton();
|
||||
});
|
||||
wootOn(window, 'resize', () => IFrameHelper.toggleCloseButton());
|
||||
},
|
||||
preventDefaultScroll: () => {
|
||||
widgetHolder.addEventListener('wheel', event => {
|
||||
|
@ -100,7 +100,9 @@ export const IFrameHelper = {
|
|||
position: window.$chatwoot.position,
|
||||
hideMessageBubble: window.$chatwoot.hideMessageBubble,
|
||||
});
|
||||
IFrameHelper.onLoad(message.config.channelConfig);
|
||||
IFrameHelper.onLoad({
|
||||
widgetColor: message.config.channelConfig.widgetColor,
|
||||
});
|
||||
IFrameHelper.setCurrentUrl();
|
||||
IFrameHelper.toggleCloseButton();
|
||||
|
||||
|
@ -110,6 +112,10 @@ export const IFrameHelper = {
|
|||
dispatchWindowEvent(EVENT_NAME);
|
||||
},
|
||||
|
||||
setBubbleLabel(message) {
|
||||
setBubbleText(message.label);
|
||||
},
|
||||
|
||||
toggleBubble: () => {
|
||||
onBubbleClick();
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { addClass, toggleClass, wootOn } from './DOMHelpers';
|
||||
import { IFrameHelper } from './IFrameHelper';
|
||||
import { BUBBLE_DESIGN } from './constants';
|
||||
|
||||
export const bubbleImg =
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAUVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////8IN+deAAAAGnRSTlMAAwgJEBk0TVheY2R5eo+ut8jb5OXs8fX2+cjRDTIAAADsSURBVHgBldZbkoMgFIThRgQv8SKKgGf/C51UnJqaRI30/9zfe+NQUQ3TvG7bOk9DVeCmshmj/CuOTYnrdBfkUOg0zlOtl9OWVuEk4+QyZ3DIevmSt/ioTvK1VH/s5bY3YdM9SBZ/mUUyWgx+U06ycgp7D8msxSvtc4HXL9BLdj2elSEfhBJAI0QNgJEBI1BEBsQClVBVGDgwYOLAhJkDM1YOrNg4sLFAsLJgZsHEgoEFFQt0JAFGFjQsKAMJ0LFAexKgZYFyJIDxJIBNJEDNAtSJBLCeBDCOBFAPzwFA94ED+zmhwDO9358r8ANtIsMXi7qVAwAAAABJRU5ErkJggg==';
|
||||
|
@ -10,14 +11,34 @@ export const widgetHolder = document.createElement('div');
|
|||
export const bubbleHolder = document.createElement('div');
|
||||
export const chatBubble = document.createElement('div');
|
||||
export const closeBubble = document.createElement('div');
|
||||
|
||||
export const notificationBubble = document.createElement('span');
|
||||
|
||||
export const getBubbleView = type =>
|
||||
BUBBLE_DESIGN.includes(type) ? type : BUBBLE_DESIGN[0];
|
||||
export const isExpandedView = type => getBubbleView(type) === BUBBLE_DESIGN[1];
|
||||
|
||||
export const setBubbleText = bubbleText => {
|
||||
if (isExpandedView(window.$chatwoot.type)) {
|
||||
const textNode = document.getElementById('woot-widget--expanded__text');
|
||||
textNode.innerHTML = bubbleText;
|
||||
}
|
||||
};
|
||||
|
||||
export const createBubbleIcon = ({ className, src, target }) => {
|
||||
target.className = `${className} woot-elements--${window.$chatwoot.position}`;
|
||||
let bubbleClassName = `${className} woot-elements--${window.$chatwoot.position}`;
|
||||
const bubbleIcon = document.createElement('img');
|
||||
bubbleIcon.src = src;
|
||||
target.appendChild(bubbleIcon);
|
||||
|
||||
if (isExpandedView(window.$chatwoot.type)) {
|
||||
const textNode = document.createElement('div');
|
||||
textNode.id = 'woot-widget--expanded__text';
|
||||
textNode.innerHTML = '';
|
||||
target.appendChild(textNode);
|
||||
bubbleClassName += ' woot-widget--expanded';
|
||||
}
|
||||
|
||||
target.className = bubbleClassName;
|
||||
return target;
|
||||
};
|
||||
|
||||
|
|
1
app/javascript/sdk/constants.js
Normal file
1
app/javascript/sdk/constants.js
Normal file
|
@ -0,0 +1 @@
|
|||
export const BUBBLE_DESIGN = ['standard', 'expanded_bubble'];
|
142
app/javascript/sdk/sdk.js
Normal file
142
app/javascript/sdk/sdk.js
Normal file
|
@ -0,0 +1,142 @@
|
|||
export const SDK_CSS = `.woot-widget-holder {
|
||||
box-shadow: 0 5px 40px rgba(0, 0, 0, .16) !important;
|
||||
opacity: 1;
|
||||
overflow: hidden !important;
|
||||
position: fixed !important;
|
||||
transition-duration: 0.5s, 0.5s;
|
||||
transition-property: opacity, bottom;
|
||||
z-index: 2147483000 !important;
|
||||
}
|
||||
|
||||
.woot-widget-holder iframe {
|
||||
border: 0;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.woot-widget-holder.has-unread-view {
|
||||
border-radius: 0 !important;
|
||||
bottom: 94px;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.woot-widget-bubble {
|
||||
background: #1f93ff;
|
||||
border-radius: 100px !important;
|
||||
bottom: 20px;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, .16) !important;
|
||||
cursor: pointer;
|
||||
height: 64px !important;
|
||||
position: fixed;
|
||||
width: 64px !important;
|
||||
z-index: 2147483000 !important;
|
||||
}
|
||||
|
||||
.woot-widget-bubble.woot-widget--expanded {
|
||||
bottom: 24px;
|
||||
display: flex;
|
||||
height: 48px !important;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.woot-widget-bubble.woot-widget--expanded div {
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
justify-content: center;
|
||||
padding-right: 20px;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.woot-widget-bubble.woot-widget--expanded img {
|
||||
height: 20px;
|
||||
margin: 14px 8px 14px 16px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.woot-widget-bubble.woot-elements--left {
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.woot-widget-bubble.woot-elements--right {
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.woot-widget-bubble:hover {
|
||||
background: #1f93ff;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, .4) !important;
|
||||
}
|
||||
|
||||
.woot-widget-bubble img {
|
||||
height: 24px;
|
||||
margin: 20px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 667px) {
|
||||
.woot-widget-holder.woot-elements--left {
|
||||
left: 20px;
|
||||
}
|
||||
.woot-widget-holder.woot-elements--right {
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.woot--close:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.woot--close::before, .woot--close::after {
|
||||
background-color: #fff;
|
||||
content: ' ';
|
||||
height: 24px;
|
||||
left: 32px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
.woot--close::before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.woot--close::after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.woot--hide {
|
||||
bottom: -20000px;
|
||||
opacity: 0;
|
||||
visibility: hidden !important;
|
||||
z-index: -1 !important;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 667px) {
|
||||
.woot-widget-holder {
|
||||
height: 100%;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.woot-widget-bubble.woot--close {
|
||||
bottom: 60px;
|
||||
opacity: 0;
|
||||
visibility: hidden !important;
|
||||
z-index: -1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 667px) {
|
||||
.woot-widget-holder {
|
||||
border-radius: 16px !important;
|
||||
bottom: 104px;
|
||||
height: calc(85% - 64px - 20px);
|
||||
max-height: 590px !important;
|
||||
min-height: 250px !important;
|
||||
width: 400px !important;
|
||||
}
|
||||
}
|
||||
`;
|
17
app/javascript/sdk/specs/bubbleHelpers.spec.js
Normal file
17
app/javascript/sdk/specs/bubbleHelpers.spec.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { getBubbleView, isExpandedView } from '../bubbleHelpers';
|
||||
|
||||
describe('#getBubbleView', () => {
|
||||
it('returns correct view', () => {
|
||||
expect(getBubbleView('')).toEqual('standard');
|
||||
expect(getBubbleView('standard')).toEqual('standard');
|
||||
expect(getBubbleView('expanded_bubble')).toEqual('expanded_bubble');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#isExpandedView', () => {
|
||||
it('returns true if it is expanded view', () => {
|
||||
expect(isExpandedView('')).toEqual(false);
|
||||
expect(isExpandedView('standard')).toEqual(false);
|
||||
expect(isExpandedView('expanded_bubble')).toEqual(true);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue