Feature: Widget design update (#426)

This commit is contained in:
Nithin David Thomas 2020-01-17 13:36:05 +05:30 committed by Pranav Raj S
parent cc180b77ce
commit f7f7a6b9c7
18 changed files with 186 additions and 66 deletions

View file

@ -21,7 +21,7 @@ table {
tr {
.show-if-hover {
opacity: 0;
transition: all .2s $ease-in-out-cubic;
transition: all 0.2s $ease-in-out-cubic;
}
&:hover {

View file

@ -140,19 +140,21 @@ const IFrameHelper = {
'*'
);
},
events: {
loaded: message => {
Cookies.set('cw_conversation', message.config.authToken);
IFrameHelper.sendMessage('config-set', {});
IFrameHelper.onLoad(message.config.channelConfig);
IFrameHelper.setCurrentUrl();
},
set_auth_token: message => {
Cookies.set('cw_conversation', message.authToken);
},
toggleBubble: () => {
bubbleClickCallback();
},
},
initPostMessageCommunication: () => {
const events = {
loaded: message => {
Cookies.set('cw_conversation', message.config.authToken);
IFrameHelper.sendMessage('config-set', {});
IFrameHelper.onLoad(message.config.channelConfig);
IFrameHelper.setCurrentUrl();
},
set_auth_token: message => {
Cookies.set('cw_conversation', message.authToken);
},
};
window.onmessage = e => {
if (
typeof e.data !== 'string' ||
@ -161,8 +163,8 @@ const IFrameHelper = {
return;
}
const message = JSON.parse(e.data.replace('chatwoot-widget:', ''));
if (typeof events[message.event] === 'function') {
events[message.event](message);
if (typeof IFrameHelper.events[message.event] === 'function') {
IFrameHelper.events[message.event](message);
}
};
},

View file

@ -6,17 +6,8 @@
<script>
import { mapActions } from 'vuex';
import { setHeader } from './helpers/axios';
export const IFrameHelper = {
isIFrame: () => window.self !== window.top,
sendMessage: msg => {
window.parent.postMessage(
`chatwoot-widget:${JSON.stringify({ ...msg })}`,
'*'
);
},
};
import { setHeader } from 'widget/helpers/axios';
import { IFrameHelper } from 'widget/helpers/utils';
export default {
name: 'App',

View file

@ -4,6 +4,11 @@ $shadow-color-2: rgba(0, 0, 0, 0.07);
$shadow-color-3: rgba(50, 50, 93, .08);
$shadow-color-4: rgba(0, 0, 0, .05);
$color-shadow-medium: rgba(0, 0, 0, 0.1);
$color-shadow-light: rgba(0, 0, 0, 0.06);
$color-shadow-large: rgba(0, 0, 0, 0.25);
$color-shadow-outline: rgba(66, 153, 225, 0.5);
@mixin normal-shadow {
box-shadow: 0 $space-small $space-normal $shadow-color-1, 0 $space-smaller $space-slab $shadow-color-2;
}
@ -13,8 +18,59 @@ $shadow-color-4: rgba(0, 0, 0, .05);
}
@mixin placeholder {
&::-webkit-input-placeholder {@content}
&:-moz-placeholder {@content}
&::-moz-placeholder {@content}
&:-ms-input-placeholder {@content}
&::-webkit-input-placeholder {
@content
}
&:-moz-placeholder {
@content
}
&::-moz-placeholder {
@content
}
&:-ms-input-placeholder {
@content
}
}
@mixin shadow {
box-shadow: 0 1px 10px -4 $color-shadow-medium,
0 1px 5px 2px $color-shadow-light;
}
@mixin shadow-medium {
box-shadow: 0 4px 6px -8px $color-shadow-medium,
0 2px 4px -4px $color-shadow-light;
}
@mixin shadow-large {
box-shadow: 0 10px 15px -16px $color-shadow-medium,
0 4px 6px -8px $color-shadow-light;
}
@mixin shadow-big {
box-shadow: 0 20px 25px -20px $color-shadow-medium,
0 10px 10px -10px $color-shadow-light;
}
@mixin shadow-mega {
box-shadow: 0 25px 50px -12px $color-shadow-big;
}
@mixin shadow-inner {
box-shadow: inset 0 2px 4px 0 $color-shadow-light;
}
@mixin shadow-outline {
box-shadow: 0 0 0 3px $color-shadow-outline;
}
@mixin shadow-none {
box-shadow: none;
}

View file

@ -91,9 +91,20 @@ $line-height: 1;
$footer-height: 11.2rem;
$header-expanded-height: $space-medium * 10;
$font-family: 'Inter', -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
$font-family: 'Inter',
-apple-system,
system-ui,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif;
$ionicons-font-path: '~ionicons/fonts';
$spinkit-spinner-color: $color-white !default;
$spinkit-spinner-margin: 0 0 0 1.6rem !default;
$spinkit-size: 1.6rem !default;
// Break points
$break-point-medium: 667px;

View file

@ -55,10 +55,10 @@ export const SDK_CSS = ` .woot-widget-holder {
}
.woot--close:before, .woot--close:after {
position: absolute;
left: 30px;
top: 15px;
left: 32px;
top: 20px;
content: ' ';
height: 33px;
height: 24px;
width: 2px;
background-color: white;
}
@ -86,17 +86,10 @@ export const SDK_CSS = ` .woot-widget-holder {
}
.woot-widget-bubble.woot--close {
top: 8px;
right: 8px;
box-shadow: none !important;
-moz-box-shadow: none !important;
-o-box-shadow: none !important;
-webkit-box-shadow: none !important;
background: transparent !important;
}
.woot--close:before, .woot--close:after {
background-color: black;
visibility: hidden !important;
z-index: -1 !important;
opacity: 0;
bottom: 60px;
}
}

View file

@ -71,7 +71,7 @@ export default {
max-width: 88%;
& + .agent-message {
margin-bottom: $space-smaller;
margin-bottom: $space-micro;
.chat-bubble {
border-top-left-radius: $space-smaller;
@ -101,10 +101,10 @@ export default {
.agent-name {
color: $color-body;
font-size: $font-size-default;
font-size: $font-size-small;
font-weight: $font-weight-medium;
margin-bottom: $space-small;
margin-top: $space-small;
margin: $space-small 0;
padding-left: $space-micro;
}
}
</style>

View file

@ -24,7 +24,7 @@
justify-content: center;
text-align: center;
text-decoration: none;
padding: $space-slab 0;
padding: $space-normal 0 $space-slab;
cursor: pointer;
&:hover {

View file

@ -27,6 +27,7 @@ export default {
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
@import '~widget/assets/scss/variables.scss';
@import '~widget/assets/scss/mixins.scss';
.footer {
background: $color-white;
@ -34,8 +35,7 @@ export default {
padding: $space-small $space-slab;
width: 100%;
border-radius: 7px;
box-shadow: 0 20px 25px -10px rgba(0, 0, 0, 0.1),
0 10px 10px -10px rgba(0, 0, 0, 0.04) !important;
@include shadow-big;
}
.branding {

View file

@ -1,15 +1,15 @@
<template>
<header class="header-collapsed" :style="{ background: widgetColor }">
<div>
<h2 class="title">
{{ title }}
</h2>
</div>
<header class="header-collapsed">
<h2 class="title">
{{ title }}
</h2>
<span class="close" @click="closeWindow"></span>
</header>
</template>
<script>
import { mapGetters } from 'vuex';
import { IFrameHelper } from 'widget/helpers/utils';
export default {
name: 'ChatHeader',
@ -24,22 +24,60 @@ export default {
default: '',
},
},
methods: {
closeWindow() {
if (IFrameHelper.isIFrame()) {
IFrameHelper.sendMessage({
event: 'toggleBubble',
});
}
},
},
};
</script>
<style scoped lang="scss">
@import '~widget/assets/scss/variables.scss';
@import '~widget/assets/scss/mixins.scss';
.header-collapsed {
background: $color-woot;
display: flex;
justify-content: space-between;
background: $color-white;
padding: $space-two $space-medium;
width: 100%;
box-sizing: border-box;
color: $color-white;
border-bottom-left-radius: $space-small;
border-bottom-right-radius: $space-small;
@include shadow-large;
.title {
font-size: $font-size-big;
font-size: $font-size-large;
font-weight: $font-weight-medium;
color: $color-heading;
}
.close {
position: relative;
margin-right: $space-small;
&:before,
&:after {
position: absolute;
left: 0;
top: $space-smaller;
content: ' ';
height: $space-normal;
width: 2px;
background-color: $color-heading;
}
&:before {
transform: rotate(45deg);
}
&:after {
transform: rotate(-45deg);
}
}
}
</style>

View file

@ -41,15 +41,15 @@ export default {
<style scoped lang="scss">
@import '~widget/assets/scss/variables.scss';
@import '~widget/assets/scss/mixins.scss';
.header-expanded {
background: $color-white;
padding: $space-larger $space-medium $space-large;
width: 100%;
box-sizing: border-box;
border-radius: 1.6rem;
box-shadow: 0 10px 15px -16px rgba(0, 0, 0, 0.1),
0 4px 6px -8px rgba(0, 0, 0, 0.05) !important;
border-radius: $space-normal;
@include shadow-large;
@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
border-radius: 0;

View file

@ -46,6 +46,7 @@ export default {
}
& + .agent-message {
margin-top: $space-normal;
margin-bottom: $space-micro;
}
.message-wrap {
margin-right: $space-small;

View file

@ -44,7 +44,7 @@ export default {
font-size: $font-size-default;
line-height: 1.5;
max-width: 80%;
padding: $space-small $space-two;
padding: $space-small $space-normal;
text-align: left;
a {

View file

@ -17,7 +17,7 @@
:disabled="$v.email.$invalid"
:style="{ background: widgetColor, borderColor: widgetColor }"
>
<i v-if="!uiFlags.isUpdating" class="ion-android-arrow-forward" />
<i v-if="!uiFlags.isUpdating" class="ion-ios-arrow-forward" />
<spinner v-else />
</button>
</form>

View file

@ -8,3 +8,13 @@ export const arrayToHashById = array =>
newMap[obj.id] = obj;
return newMap;
}, {});
export const IFrameHelper = {
isIFrame: () => window.self !== window.top,
sendMessage: msg => {
window.parent.postMessage(
`chatwoot-widget:${JSON.stringify({ ...msg })}`,
'*'
);
},
};

View file

@ -75,6 +75,21 @@ export default {
width: 100%;
display: flex;
flex-direction: column;
position: relative;
&:before {
content: '';
position: absolute;
top: -$space-normal;
left: 0;
width: 100%;
height: $space-normal;
background: linear-gradient(
to top,
$color-background,
rgba($color-background, 0)
);
}
}
.input-wrap {

View file

@ -1,3 +1,5 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<script>
(function(d,t) {
var BASE_URL = '';

View file

@ -8,7 +8,8 @@
"test": "jest --no-cache",
"test:watch": "jest --watch --no-cache",
"test:coverage": "jest --no-cache --collectCoverage",
"webpacker-start": "webpack-dev-server -d --config webpack.dev.config.js --content-base public/ --progress --colors"
"webpacker-start": "webpack-dev-server -d --config webpack.dev.config.js --content-base public/ --progress --colors",
"start:dev": "foreman start -f ./Procfile.dev"
},
"dependencies": {
"@babel/polyfill": "^7.6.0",