Skip to content

Commit

Permalink
Notifications page - toasts (epicmaxco#95)
Browse files Browse the repository at this point in the history
* feat(toasts): toasts form UI

* feat(toasts): toasts styles

* feat(toasts): vuestic-toasted mixin

* feat(toasts): notifications page - sample toast

* feat(toasts): notifications page controls bindings

* fix(toasts): full-screen mode

* fix(toasts): toasts swipe opacity fix

* fix(toasts): toasts swipe opacity fix epicmaxco#2

* feat(toasts): fix some styles

* feat(toasts): toasts i18n

* feat(dashboard): epicmax toast

* feat(toasts): disabble epicmax toast
  • Loading branch information
smartapant committed Feb 8, 2018
1 parent 35aea6b commit 47b71b0
Show file tree
Hide file tree
Showing 12 changed files with 323 additions and 2 deletions.
2 changes: 2 additions & 0 deletions build/webpack.base.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ module.exports = {
'components': resolve('src/components'),
'services': resolve('src/services'),
'directives': resolve('src/directives'),
'vuestic-mixins': resolve('src/vuestic-mixins'),
'vuestic-components': resolve('src/components/vuestic-components'),
'data': resolve('src/data'),
'vuex-store': resolve('src/store')
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"vue-chartjs": "^2.8.1",
"vue-router": "^3.0.1",
"vue-slider-component": "2.3.3",
"vue-toasted": "^1.1.24",
"vue2-circle-progress": "^1.0.3",
"vuetable-2": "1.7.0",
"vuex": "^3.0.1",
Expand Down
15 changes: 15 additions & 0 deletions src/components/dashboard/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@
SetupProfileTab,
FeaturesTab,
DashboardBottomWidgets
},
methods: {
launchEpicmaxToast () {
this.showToast(`Let's work together!`, {
icon: 'fa-star-o',
position: 'top-right',
duration: Infinity,
action: {
text: 'Hire us',
href: 'http://epicmax.co/#/contact',
class: 'vuestic-toasted-link'
}
})
}
}
}
</script>
Expand Down
90 changes: 89 additions & 1 deletion src/components/ui/notifications/Notifications.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,67 @@
</vuestic-widget>
</div>
</div>

<div class="row">
<div class="col-md-12">
<vuestic-widget :headerText="'notificationsPage.toasts.title' | translate">
<div class="row">
<div class="col-md-6">
<fieldset>
<div class="form-group">
<div class="input-group">
<input id="toast-text" v-model="toastText" required/>
<label class="control-label" for="toast-text">{{'notificationsPage.toasts.textLabel' | translate}}</label><i class="bar"></i>
</div>
</div>
<div class="form-group">
<div class="input-group">
<input id="toast-duration" type="number" v-model="toastDuration" required/>
<label class="control-label" for="toast-duration">{{'notificationsPage.toasts.durationLabel' | translate}}</label><i class="bar"></i>
</div>
</div>
<div class="form-group">
<div class="input-group">
<input id="toast-icon" v-model="toastIcon" required/>
<label class="control-label" for="toast-icon">{{'notificationsPage.toasts.iconLabel' | translate}}</label><i class="bar"></i>
</div>
</div>
<div class="form-group toasts-position-group d-flex flex-row">
<toast-position-picker v-model="toastPosition" />
<div class="form-check abc-checkbox abc-checkbox-primary">
<input class="form-check-input" id="toast-fullwidth" v-model="isToastFullWidth" type="checkbox">
<label class="form-check-label" for="toast-fullwidth">
<span class="abc-label-text">{{'notificationsPage.toasts.fullWidthLabel' | translate}}</span>
</label>
</div>
</div>
<button slot="trigger" class="btn btn-sm btn-primary" @click="launchToast">
{{'notificationsPage.toasts.launchToast' | translate}}
</button>
</fieldset>
</div>
<div class="col-md-6 justify-content-center align-items-center d-none d-md-flex">
<div class="toasted-container sample-toasted-container" v-if="isToastContentPresent">
<div class="toasted vuestic-toast primary default">
<i class="fa" :class="toastIcon" v-if="toastIcon"></i>{{toastText}}
</div>
</div>
</div>
</div>
</vuestic-widget>
</div>
</div>
</div>
</template>

<script>
import ToastPositionPicker from './ToastPositionPicker.vue'
export default {
name: 'notifications',
components: {ToastPositionPicker},
data () {
return {
popoverTitle: 'Hey!',
Expand All @@ -107,7 +161,18 @@
bottomTooltipOptions: {
content: 'Bottom tooltip text',
placement: 'bottom'
}
},
toastText: 'This toast is awesome!',
toastDuration: 2500,
toastIcon: 'fa-star-o',
toastPosition: 'bottom-right',
isToastFullWidth: false
}
},
computed: {
isToastContentPresent () {
return !!(this.toastText || this.toastIcon)
}
},
Expand All @@ -118,11 +183,34 @@
} else {
this.isPopoverDisabled = false
}
},
launchToast () {
this.showToast(this.toastText, {
icon: this.toastIcon,
position: this.toastPosition,
duration: this.toastDuration,
fullWidth: this.isToastFullWidth
})
}
}
}
</script>

<style lang="scss" scoped>
.toast-position-picker {
margin-right: 2rem;
}
.toasted-container.sample-toasted-container {
position: static;
transform: translateX(0);
.toasted {
position: static;
transform: translateY(0);
}
}
</style>
94 changes: 94 additions & 0 deletions src/components/ui/notifications/ToastPositionPicker.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<template>
<div class="toast-position-picker">
<div class="position-boxes-row">
<div class="position-box"
@click="updatePosition('top-left')"
:class="{'selected': isBoxSelected('top-left')}">
</div>
<div class="position-box"
@click="updatePosition('top-center')"
:class="{'selected': isBoxSelected('top-center')}">
</div>
<div class="position-box"
@click="updatePosition('top-right')"
:class="{'selected': isBoxSelected('top-right')}">
</div>
</div>
<div class="position-boxes-row">
<div class="position-box"
@click="updatePosition('bottom-left')"
:class="{'selected': isBoxSelected('bottom-left')}">
</div>
<div class="position-box"
@click="updatePosition('bottom-center')"
:class="{'selected': isBoxSelected('bottom-center')}">
</div>
<div class="position-box"
@click="updatePosition('bottom-right')"
:class="{'selected': isBoxSelected('bottom-right')}">
</div>
</div>
</div>
</template>

<script>
export default {
name: 'toast-position-picker',
props: {
value: {
type: String,
default: 'bottom-center'
}
},
methods: {
updatePosition (position) {
this.$emit('input', position)
},
isBoxSelected (position) {
return this.value === position
}
}
}
</script>

<style lang='scss' scoped>
@import '../../../sass/_variables.scss';
.toast-position-picker {
width: 112px;
height: 76px;
}
.position-boxes-row {
display: flex;
flex-direction: row;
&:first-child {
margin-bottom: 2px;
}
}
.position-box {
height: 36px;
width: 36px;
margin-right: 2px;
cursor: pointer;
background-color: $brand-primary;
opacity: 0.3;
&:last-child {
margin-right: 0;
}
&:hover {
opacity: 0.6;
}
&.selected {
opacity: 1;
}
}
</style>
8 changes: 8 additions & 0 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@
"rightTooltip": "rightside tooltip",
"leftTooltip": "left",
"bottomTooltip": "below"
},
"toasts": {
"title": "Toasts",
"textLabel": "Text",
"durationLabel": "Duration (milliseconds)",
"iconLabel": "Icon (fontawesome)",
"fullWidthLabel": "Fullwidth",
"launchToast": "Launch toast"
}
},
"extra": {
Expand Down
8 changes: 8 additions & 0 deletions src/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@
"rightTooltip": "derecha tooltip",
"leftTooltip": "izquierda",
"bottomTooltip": "fondo"
},
"Toasts": {
"title": "tostadas",
"textLabel": "Texto",
"durationLabel": "Duración (milisegundos)",
"iconLabel": "Icono (fontawesome)",
"fullWidthLabel": "Ancho total",
"launchToast": "Lanzar tostadas"
}
},
"extra": {
Expand Down
4 changes: 3 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import App from './App'
import store from './store'
import router from './router'
import { sync } from 'vuex-router-sync'
import VuesticPlugin from 'src/components/vuestic-components/vuestic-components-plugin'
import VuesticPlugin from 'vuestic-components/vuestic-components-plugin'
import VuesticMixinsPlugin from 'vuestic-mixins/vuestic-mixins-plugin'
import './i18n'

Vue.use(VuesticPlugin)
Vue.use(VuesticMixinsPlugin)

// NOTE: workaround for VeeValidate + vuetable-2
Vue.use(VeeValidate, {fieldsBagName: 'formFields'})
Expand Down
53 changes: 53 additions & 0 deletions src/sass/_override-custom-libs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
padding-left: 20px;

label{
padding-left: 0;

&::before{
border-radius: 0;
@include transition(border 0.15s ease-in-out, color 0.15s ease-in-out, background-color 0.15s ease-in-out);
Expand Down Expand Up @@ -59,6 +61,7 @@
.abc-radio {

label {
padding-left: 0;

&::after {
width: 10px;
Expand Down Expand Up @@ -254,3 +257,53 @@
}
}
}

//vue-toasted

.toasted-container {
&.full-width {
max-width: 100%;
width: calc(100% - #{$layout-padding} - #{$layout-padding-right});
transform: translateX(0);
left: 0;

.toasted.vuestic-toast {
max-width: 100%;
width: 100%;
left: $layout-padding;
justify-content: normal;
}

@include media-breakpoint-down(md) {
width: calc(100% - #{$content-mobile-wrap-pl} - #{$content-mobile-wrap-pr});
left: 0;

.toasted.vuestic-toast {
left: $content-mobile-wrap-pl;
}
}
}
}

.toasted.vuestic-toast {
min-height: $toast-min-height;
padding: $toast-padding-y $toast-padding-x;
font-size: $toast-font-size;
font-weight: $toast-font-weight;
line-height: $toast-line-height;
background: rgba($toast-bg, 0.9);
box-shadow: $toast-box-shadow;
color: $toast-color;
border-radius: $toast-border-radius;

i, i.fa {
font-size: $toast-icon-size;
color: $toast-icon-color;
margin-left: $toast-icon-ml;
margin-right: $toast-icon-mr;
}

a.action:hover {
text-decoration: none;
}
}
Loading

0 comments on commit 47b71b0

Please sign in to comment.