@ -1,92 +1,93 @@
|
|||||||
import MeshkeeToast from './MeshkeeToast.vue'
|
import MeshkeeToast from './components/MeshkeeToast.vue'
|
||||||
import { createComponent } from './helpers';
|
import { createComponent } from './utils/helpers.js';
|
||||||
import eventBus from './bus.js';
|
import eventBus from './utils/bus.js';
|
||||||
import Positions from './positions.js';
|
import Positions from './utils/positions.js';
|
||||||
|
|
||||||
let parentTop = document.querySelector('.v-toast.v-toast--top');
|
let parentTop = document.querySelector('.me-toast.me-toast--top');
|
||||||
let parentBottom = document.querySelector('.v-toast.v-toast--bottom');
|
let parentBottom = document.querySelector('.me-toast.me-toast--bottom');
|
||||||
|
|
||||||
const correctParent = (position) => {
|
const correctParent = (position) => {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case Positions.TOP:
|
case Positions.TOP:
|
||||||
case Positions.TOP_RIGHT:
|
case Positions.TOP_RIGHT:
|
||||||
case Positions.TOP_LEFT:
|
case Positions.TOP_LEFT:
|
||||||
return parentTop;
|
return parentTop;
|
||||||
|
|
||||||
case Positions.BOTTOM:
|
case Positions.BOTTOM:
|
||||||
case Positions.BOTTOM_RIGHT:
|
case Positions.BOTTOM_RIGHT:
|
||||||
case Positions.BOTTOM_LEFT:
|
case Positions.BOTTOM_LEFT:
|
||||||
return parentBottom;
|
return parentBottom;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const setupContainer = () => {
|
const setupContainer = () => {
|
||||||
// No need to create them, they already exists
|
// No need to create them, they already exists
|
||||||
if (parentTop && parentBottom) return;
|
if (parentTop && parentBottom) return;
|
||||||
|
|
||||||
if (!parentTop) {
|
if (!parentTop) {
|
||||||
parentTop = document.createElement('div');
|
parentTop = document.createElement('div');
|
||||||
parentTop.className = 'v-toast v-toast--top';
|
parentTop.className = 'me-toast me-toast--top';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parentBottom) {
|
if (!parentBottom) {
|
||||||
parentBottom = document.createElement('div');
|
parentBottom = document.createElement('div');
|
||||||
parentBottom.className = 'v-toast v-toast--bottom'
|
parentBottom.className = 'me-toast me-toast--bottom'
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = document.body;
|
const container = document.body;
|
||||||
container.appendChild(parentTop);
|
container.appendChild(parentTop);
|
||||||
container.appendChild(parentBottom);
|
container.appendChild(parentBottom);
|
||||||
};
|
};
|
||||||
export const useToast = (globalProps = {}) => {
|
export const useToast = (globalProps = {}) => {
|
||||||
return {
|
return {
|
||||||
open(options) {
|
open(options) {
|
||||||
let message = null;
|
let message = null;
|
||||||
if (typeof options === 'string') message = options;
|
if (typeof options === 'string') message = options;
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
message
|
message
|
||||||
};
|
};
|
||||||
|
|
||||||
const propsData = Object.assign({}, defaultProps, globalProps, options);
|
const propsData = Object.assign({}, defaultProps, globalProps, options);
|
||||||
setupContainer();
|
setupContainer();
|
||||||
console.log(propsData.position, correctParent(propsData.position ? propsData.position : 'bottom'));
|
const instance = createComponent(MeshkeeToast, propsData, correctParent(propsData.position ? propsData.position : 'bottom'));
|
||||||
const instance = createComponent(MeshkeeToast, propsData, correctParent(propsData.position ? propsData.position : 'bottom'));
|
return {
|
||||||
return {
|
dismiss: instance.dismiss
|
||||||
dismiss: instance.dismiss
|
}
|
||||||
}
|
},
|
||||||
},
|
clear() {
|
||||||
clear() {
|
eventBus.emit('toast-clear')
|
||||||
eventBus.emit('toast-clear')
|
},
|
||||||
},
|
success(title, message, options = {}) {
|
||||||
success(message, options = {}) {
|
return this.open(Object.assign({}, {
|
||||||
return this.open(Object.assign({}, {
|
title,
|
||||||
message,
|
message,
|
||||||
type: 'success'
|
type: 'success',
|
||||||
}, options))
|
borderColor: '#EDEDED'
|
||||||
},
|
}, options))
|
||||||
error(message, options = {}) {
|
},
|
||||||
return this.open(Object.assign({}, {
|
error(title, message, options = {}) {
|
||||||
message,
|
return this.open(Object.assign({}, {
|
||||||
type: 'error'
|
title,
|
||||||
}, options))
|
message,
|
||||||
},
|
type: 'error',
|
||||||
info(message, options = {}) {
|
borderColor: '#EDEDED'
|
||||||
return this.open(Object.assign({}, {
|
}, options))
|
||||||
message,
|
},
|
||||||
type: 'info'
|
info(title, message, options = {}) {
|
||||||
}, options))
|
return this.open(Object.assign({}, {
|
||||||
},
|
title,
|
||||||
warning(message, options = {}) {
|
message,
|
||||||
return this.open(Object.assign({}, {
|
type: 'info'
|
||||||
message,
|
}, options))
|
||||||
type: 'warning'
|
},
|
||||||
}, options))
|
preset(title, message, options = {}) {
|
||||||
},
|
return this.open(Object.assign({}, {
|
||||||
default(message, options = {}) {
|
title,
|
||||||
return this.open(Object.assign({}, {
|
message,
|
||||||
message,
|
titleColor: 'black',
|
||||||
type: 'default'
|
messageColor: 'black',
|
||||||
}, options))
|
type: 'default'
|
||||||
}
|
}, options))
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
@ -1,206 +1,254 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition :enter-active-class="transition.enter" :leave-active-class="transition.leave">
|
<transition :enter-active-class="transition.enter" :leave-active-class="transition.leave">
|
||||||
<div ref="root" role="alert" v-show="isActive" class="v-toast__item"
|
<div ref="root" role="alert" v-show="isActive" :class="[`me-toast__root me-toast__root--${position}`]">
|
||||||
:class="[`v-toast__item--${type}`, `v-toast__item--${direction}`, `v-toast__item--${position}`]"
|
<div :class="`me-toast__item--${direction}`">
|
||||||
@mouseover="toggleTimer(true)" @mouseleave="toggleTimer(false)" @click="whenClicked">
|
<div @mouseenter="toggleTimer(true)" @mouseleave="toggleTimer(false)"
|
||||||
<div :class="['v-toast__icon', `v-toast__icon--${type}-light`]">
|
:class="[`me-toast__item me-toast__item--${type}-light`]">
|
||||||
<div class="v-toast__icon--image"></div>
|
<div class="me-toast__box">
|
||||||
</div>
|
<div :class="['me-toast__icon', `me-toast__icon--${type}`]">
|
||||||
<div class="mx-2 toast__title" v-html="title"></div>
|
<div class="me-toast__icon--image"></div>
|
||||||
<p class="v-toast__text" v-html="message"></p>
|
</div>
|
||||||
</div>
|
<div class="me-toast__title"
|
||||||
</transition>
|
:style="`color: ${titleColor};font-family: ${titleFontFamily}; ${direction == 'rtl' ? `border-left: 0.5px dashed ${borderColor};` : `border-right: 0.5px dashed ${borderColor};`}`"
|
||||||
</template>
|
v-html="title">
|
||||||
|
</div>
|
||||||
<script>
|
<p class="me-toast__message" :style="`color: ${messageColor};font-family: ${messageFontFamily};`"
|
||||||
import { defineComponent } from 'vue';
|
v-html="message"></p>
|
||||||
import { removeElement } from './helpers.js';
|
</div>
|
||||||
import Timer from "./timer.js";
|
<!-- close button -->
|
||||||
import Positions from './positions.js'
|
<div class="me-toast__close" @click="whenClicked"></div>
|
||||||
import eventBus from './bus.js'
|
</div>
|
||||||
|
<div :class="[`me-toast__progress me-toast__progress--${type}-light`]">
|
||||||
export default defineComponent({
|
<div ref="progress_bar" :class="[`me-toast__bar me-toast__bar--${type}`]"></div>
|
||||||
name: 'Toast',
|
</div>
|
||||||
props: {
|
</div>
|
||||||
title: {
|
</div>
|
||||||
type: String,
|
</transition>
|
||||||
default: 'توجه'
|
</template>
|
||||||
},
|
|
||||||
message: {
|
<script>
|
||||||
type: String,
|
import { defineComponent } from 'vue';
|
||||||
required: true
|
import { removeElement } from '../utils/helpers.js';
|
||||||
},
|
import Timer from "../utils/timer.js";
|
||||||
type: {
|
import Positions from '../utils/positions.js'
|
||||||
type: String,
|
import eventBus from '../utils/bus.js';
|
||||||
default: 'success'
|
|
||||||
},
|
export default defineComponent({
|
||||||
position: {
|
name: 'Toast',
|
||||||
type: String,
|
props: {
|
||||||
default: Positions.BOTTOM_RIGHT,
|
title: {
|
||||||
validator(value) {
|
type: String,
|
||||||
return Object.values(Positions).includes(value)
|
default: 'توجه'
|
||||||
}
|
},
|
||||||
},
|
message: {
|
||||||
duration: {
|
type: String,
|
||||||
type: Number,
|
required: true
|
||||||
default: 3000
|
},
|
||||||
},
|
type: {
|
||||||
direction: {
|
type: String,
|
||||||
type: String,
|
default: 'success'
|
||||||
default: 'rtl'
|
},
|
||||||
},
|
titleFontFamily: {
|
||||||
dismissible: {
|
type: String,
|
||||||
type: Boolean,
|
default: 'IranYekan-Regular'
|
||||||
default: true
|
},
|
||||||
},
|
messageFontFamily: {
|
||||||
onDismiss: {
|
type: String,
|
||||||
type: Function,
|
default: 'IranYekan-light'
|
||||||
default: () => {
|
},
|
||||||
}
|
titleColor: {
|
||||||
},
|
type: String,
|
||||||
onClick: {
|
default: 'white',
|
||||||
type: Function,
|
},
|
||||||
default: () => {
|
messageColor: {
|
||||||
}
|
type: String,
|
||||||
},
|
default: 'white',
|
||||||
queue: Boolean,
|
},
|
||||||
pauseOnHover: {
|
borderColor: {
|
||||||
type: Boolean,
|
type: String,
|
||||||
default: true
|
default: '#888888'
|
||||||
},
|
},
|
||||||
},
|
position: {
|
||||||
data() {
|
type: String,
|
||||||
return {
|
default: Positions.BOTTOM_RIGHT,
|
||||||
isActive: false,
|
validator(value) {
|
||||||
parentTop: null,
|
return Object.values(Positions).includes(value)
|
||||||
parentBottom: null,
|
}
|
||||||
isHovered: false,
|
},
|
||||||
}
|
duration: {
|
||||||
},
|
type: Number,
|
||||||
computed: {
|
default: 6000
|
||||||
correctParent() {
|
},
|
||||||
switch (this.position) {
|
direction: {
|
||||||
case Positions.TOP:
|
type: String,
|
||||||
case Positions.TOP_RIGHT:
|
default: 'rtl'
|
||||||
case Positions.TOP_LEFT:
|
},
|
||||||
return this.parentTop;
|
dismissible: {
|
||||||
|
type: Boolean,
|
||||||
case Positions.BOTTOM:
|
default: true
|
||||||
case Positions.BOTTOM_RIGHT:
|
},
|
||||||
case Positions.BOTTOM_LEFT:
|
onDismiss: {
|
||||||
return this.parentBottom;
|
type: Function,
|
||||||
}
|
default: () => {
|
||||||
},
|
}
|
||||||
transition() {
|
},
|
||||||
switch (this.position) {
|
onClick: {
|
||||||
case Positions.TOP:
|
type: Function,
|
||||||
case Positions.TOP_RIGHT:
|
default: () => {
|
||||||
case Positions.TOP_LEFT:
|
}
|
||||||
return {
|
},
|
||||||
enter: 'v-toast--fade-in-down',
|
queue: Boolean,
|
||||||
leave: 'v-toast--fade-out'
|
pauseOnHover: {
|
||||||
};
|
type: Boolean,
|
||||||
|
default: true
|
||||||
case Positions.BOTTOM:
|
},
|
||||||
case Positions.BOTTOM_RIGHT:
|
},
|
||||||
case Positions.BOTTOM_LEFT:
|
data() {
|
||||||
return {
|
return {
|
||||||
enter: 'v-toast--fade-in-up',
|
isActive: false,
|
||||||
leave: 'v-toast--fade-out'
|
parentTop: null,
|
||||||
}
|
parentBottom: null,
|
||||||
}
|
isHovered: false,
|
||||||
},
|
timer: null,
|
||||||
},
|
}
|
||||||
methods: {
|
},
|
||||||
setupContainer() {
|
// watch: {
|
||||||
this.parentTop = document.querySelector('.v-toast.v-toast--top');
|
// 'timer.delay': {
|
||||||
this.parentBottom = document.querySelector('.v-toast.v-toast--bottom');
|
// deep: true,
|
||||||
// No need to create them, they already exists
|
// handler(newVal) {
|
||||||
if (this.parentTop && this.parentBottom) return;
|
// console.log(newVal);
|
||||||
|
// if (!this.timer) return
|
||||||
if (!this.parentTop) {
|
// console.log(this.timer, (this.timer.delay / this.duration) * 100);
|
||||||
this.parentTop = document.createElement('div');
|
// this.getTimerWidth = 100 - ((this.timer.delay / this.duration) * 100);
|
||||||
this.parentTop.className = 'v-toast v-toast--top';
|
// },
|
||||||
}
|
// },
|
||||||
|
// },
|
||||||
if (!this.parentBottom) {
|
computed: {
|
||||||
this.parentBottom = document.createElement('div');
|
correctParent() {
|
||||||
this.parentBottom.className = 'v-toast v-toast--bottom'
|
switch (this.position) {
|
||||||
}
|
case Positions.TOP:
|
||||||
|
case Positions.TOP_RIGHT:
|
||||||
const container = document.body;
|
case Positions.TOP_LEFT:
|
||||||
container.appendChild(this.parentTop);
|
return this.parentTop;
|
||||||
container.appendChild(this.parentBottom);
|
|
||||||
},
|
case Positions.BOTTOM:
|
||||||
|
case Positions.BOTTOM_RIGHT:
|
||||||
shouldQueue() {
|
case Positions.BOTTOM_LEFT:
|
||||||
if (!this.queue) return false;
|
return this.parentBottom;
|
||||||
|
}
|
||||||
return (
|
},
|
||||||
this.parentTop.childElementCount > 0 ||
|
transition() {
|
||||||
this.parentBottom.childElementCount > 0
|
switch (this.position) {
|
||||||
)
|
case Positions.TOP:
|
||||||
},
|
case Positions.TOP_RIGHT:
|
||||||
|
case Positions.TOP_LEFT:
|
||||||
dismiss() {
|
return {
|
||||||
if (this.timer) this.timer.stop();
|
enter: 'me-toast--fade-in-down',
|
||||||
clearTimeout(this.queueTimer);
|
leave: 'me-toast--fade-out'
|
||||||
this.isActive = false;
|
};
|
||||||
|
|
||||||
// Timeout for the animation complete before destroying
|
case Positions.BOTTOM:
|
||||||
setTimeout(() => {
|
case Positions.BOTTOM_RIGHT:
|
||||||
this.onDismiss.apply(null, arguments);
|
case Positions.BOTTOM_LEFT:
|
||||||
|
return {
|
||||||
const wrapper = this.$refs.root;
|
enter: 'me-toast--fade-in-up',
|
||||||
// unmount the component
|
leave: 'me-toast--fade-out'
|
||||||
// removeElement(wrapper);
|
}
|
||||||
}, 150)
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
showNotice() {
|
methods: {
|
||||||
if (this.shouldQueue()) {
|
setupContainer() {
|
||||||
// Call recursively if it should queue
|
this.parentTop = document.querySelector('.me-toast.me-toast--top');
|
||||||
this.queueTimer = setTimeout(this.showNotice, 250);
|
this.parentBottom = document.querySelector('.me-toast.me-toast--bottom');
|
||||||
return
|
// No need to create them, they already exists
|
||||||
}
|
if (this.parentTop && this.parentBottom) return;
|
||||||
console.log(this.correctParent);
|
|
||||||
document.querySelector('.v-toast--bottom').insertAdjacentElement('afterbegin', this.$refs.root);
|
if (!this.parentTop) {
|
||||||
this.correctParent.appendChild(this.$refs.root);
|
this.parentTop = document.createElement('div');
|
||||||
console.log(this.$refs.root);
|
this.parentTop.className = 'me-toast me-toast--top';
|
||||||
document.querySelector('.v-toast--bottom').appendChild(this.$refs.root);
|
}
|
||||||
|
|
||||||
this.$options.elem = this.correctParent;
|
if (!this.parentBottom) {
|
||||||
|
this.parentBottom = document.createElement('div');
|
||||||
this.isActive = true;
|
this.parentBottom.className = 'me-toast me-toast--bottom'
|
||||||
|
}
|
||||||
if (this.duration) {
|
|
||||||
this.timer = new Timer(this.dismiss, this.duration);
|
const container = document.body;
|
||||||
}
|
container.appendChild(this.parentTop);
|
||||||
},
|
container.appendChild(this.parentBottom);
|
||||||
|
},
|
||||||
whenClicked() {
|
|
||||||
if (!this.dismissible) return;
|
shouldQueue() {
|
||||||
this.onClick.apply(null, arguments);
|
if (!this.queue) return false;
|
||||||
this.dismiss()
|
|
||||||
},
|
return (
|
||||||
|
this.parentTop.childElementCount > 0 ||
|
||||||
toggleTimer(newVal) {
|
this.parentBottom.childElementCount > 0
|
||||||
if (!this.pauseOnHover || !this.timer) return;
|
)
|
||||||
newVal ? this.timer.pause() : this.timer.resume();
|
},
|
||||||
}
|
|
||||||
},
|
dismiss() {
|
||||||
beforeUnmount() {
|
if (this.timer) this.timer.stop();
|
||||||
eventBus.off('toast-clear', this.dismiss)
|
clearTimeout(this.queueTimer);
|
||||||
},
|
this.isActive = false;
|
||||||
beforeMount() {
|
|
||||||
this.setupContainer()
|
// Timeout for the animation complete before destroying
|
||||||
},
|
setTimeout(() => {
|
||||||
mounted() {
|
this.onDismiss.apply(null, arguments);
|
||||||
this.showNotice();
|
|
||||||
eventBus.on('toast-clear', this.dismiss)
|
const wrapper = this.$refs.root;
|
||||||
},
|
// unmount the component
|
||||||
})
|
removeElement(wrapper);
|
||||||
</script>
|
}, 150)
|
||||||
<style lang="scss">
|
},
|
||||||
@import './theme/bootstrap';
|
|
||||||
</style>
|
showNotice() {
|
||||||
|
if (this.shouldQueue()) {
|
||||||
|
// Call recursively if it should queue
|
||||||
|
this.queueTimer = setTimeout(this.showNotice, 250);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
document.querySelector('.me-toast--bottom').insertAdjacentElement('afterbegin', this.$refs.root);
|
||||||
|
this.correctParent.appendChild(this.$refs.root);
|
||||||
|
document.querySelector('.me-toast--bottom').appendChild(this.$refs.root);
|
||||||
|
|
||||||
|
this.$options.elem = this.correctParent;
|
||||||
|
|
||||||
|
this.isActive = true;
|
||||||
|
|
||||||
|
if (this.duration) {
|
||||||
|
this.timer = new Timer(this.dismiss, this.duration);
|
||||||
|
this.timer.move(this.$refs.progress_bar);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
whenClicked() {
|
||||||
|
if (!this.dismissible) return;
|
||||||
|
this.onClick.apply(null, arguments);
|
||||||
|
this.dismiss()
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleTimer(newVal) {
|
||||||
|
if (!this.pauseOnHover || !this.timer) return;
|
||||||
|
if (newVal) {
|
||||||
|
this.timer.move(this.$refs.progress_bar, true);
|
||||||
|
this.timer.pause();
|
||||||
|
} else {
|
||||||
|
this.timer.move(this.$refs.progress_bar);
|
||||||
|
this.timer.resume();
|
||||||
|
}
|
||||||
|
// newVal ? this.timer.pause(); : this.timer.resume();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
eventBus.off('toast-clear', this.dismiss)
|
||||||
|
},
|
||||||
|
beforeMount() {
|
||||||
|
this.setupContainer()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.showNotice();
|
||||||
|
eventBus.on('toast-clear', this.dismiss)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
@ -1,51 +1,12 @@
|
|||||||
// Import vue component
|
import { useToast } from './api';
|
||||||
import Vue from 'vue';
|
|
||||||
import MeshkeeToast from './MeshkeeToast.vue';
|
// To allow use as module (npm/webpack/etc.) export component
|
||||||
import { useToast } from './api';
|
export default {
|
||||||
|
install(Vue, options) {
|
||||||
// Vue.prototype.$meshkeeToast = function () {
|
// Let's register our component globally
|
||||||
// console.log(324);
|
// https://vuejs.org/v2/guide/components-registration.html
|
||||||
// return 321;
|
Vue.prototype.$metoast = () => {
|
||||||
// }
|
return new useToast(options);
|
||||||
// // Declare install function executed by Vue.use()
|
}
|
||||||
// export function install(Vue) {
|
}
|
||||||
// console.log(43);
|
|
||||||
|
|
||||||
// if (install.installed) return;
|
|
||||||
// install.installed = true;
|
|
||||||
// Vue.prototype.$meshkeeToast = function () {
|
|
||||||
// console.log(324);
|
|
||||||
// return 321;
|
|
||||||
// }
|
|
||||||
// Vue.component('MeshkeeToast', MeshkeeToast);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Create module definition for Vue.use()
|
|
||||||
// const plugin = {
|
|
||||||
// install,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Auto-install when vue is found (eg. in browser via <script> tag)
|
|
||||||
// let GlobalVue = null;
|
|
||||||
// if (typeof window !== 'undefined') {
|
|
||||||
// GlobalVue = window.Vue;
|
|
||||||
// } else if (typeof global !== 'undefined') {
|
|
||||||
// GlobalVue = global.Vue;
|
|
||||||
// }
|
|
||||||
// console.log(global, GlobalVue);
|
|
||||||
// if (GlobalVue) {
|
|
||||||
// GlobalVue.use(plugin);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // To allow use as module (npm/webpack/etc.) export component
|
|
||||||
// export default MeshkeeToast;
|
|
||||||
export default {
|
|
||||||
install(Vue, options) {
|
|
||||||
// Let's register our component globally
|
|
||||||
// https://vuejs.org/v2/guide/components-registration.html
|
|
||||||
Vue.prototype.$meshkeeToast = function () {
|
|
||||||
const { open } = useToast(options);
|
|
||||||
open('Vue');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
@ -1,59 +1,135 @@
|
|||||||
@keyframes fadeOut {
|
@keyframes fadeOut {
|
||||||
from {
|
from {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-toast--fade-out {
|
.me-toast--fade-out {
|
||||||
animation-name: fadeOut;
|
animation-name: fadeOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeInDown {
|
@keyframes fadeInDown {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translate3d(0, -100%, 0);
|
transform: translate3d(0, -100%, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-toast--fade-in-down {
|
.me-toast--fade-in-down {
|
||||||
animation-name: fadeInDown;
|
animation-name: fadeInDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeInUp {
|
@keyframes fadeInUp {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translate3d(0, 100%, 0);
|
transform: translate3d(0, 100%, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-toast--fade-in-up {
|
.me-toast--fade-in-up {
|
||||||
animation-name: fadeInUp;
|
animation-name: fadeInUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vue Transitions
|
* Meshkeetoast Transitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.fade-enter-active,
|
.fade-enter-active,
|
||||||
.fade-leave-active {
|
.fade-leave-active {
|
||||||
transition: opacity 150ms ease-out;
|
transition: opacity 150ms ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-enter,
|
.fade-enter,
|
||||||
.fade-leave-to {
|
.fade-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// progress bar
|
||||||
|
// @-webkit-keyframes progress {
|
||||||
|
// 0% {
|
||||||
|
// width: 0%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 50% {
|
||||||
|
// width: 50%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 100% {
|
||||||
|
// width: 100%;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @-moz-keyframes progress {
|
||||||
|
// 0% {
|
||||||
|
// width: 0%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 50% {
|
||||||
|
// width: 50%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 100% {
|
||||||
|
// width: 100%;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @-o-keyframes progress {
|
||||||
|
// 0% {
|
||||||
|
// width: 0%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 50% {
|
||||||
|
// width: 50%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 100% {
|
||||||
|
// width: 100%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @keyframes progress {
|
||||||
|
// 0% {
|
||||||
|
// width: 0%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 50% {
|
||||||
|
// width: 50%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 100% {
|
||||||
|
// width: 100%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .me-toast__progress {
|
||||||
|
// -webkit-animation-name: progress;
|
||||||
|
// -moz-animation-name: progress;
|
||||||
|
// -o-animation-name: progress;
|
||||||
|
// animation-name: progress;
|
||||||
|
// -webkit-animation: progress 2s linear;
|
||||||
|
// -moz-animation: progress 2s linear;
|
||||||
|
// -o-animation: progress 2s linear;
|
||||||
|
// -ms-animation: progress 2s linear;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .me-toast__root:hover>.me-toast__bar {
|
||||||
|
// -webkit-animation-play-state: paused;
|
||||||
|
// animation-play-state: paused;
|
||||||
|
// }
|
@ -1 +0,0 @@
|
|||||||
$toast-icons-path: "./theme/sugar/icons" !default;
|
|
@ -1,5 +0,0 @@
|
|||||||
@import '../default/variables';
|
|
||||||
@import 'variables';
|
|
||||||
@import '../animations';
|
|
||||||
@import '../default/main';
|
|
||||||
@import '../sugar/icons';
|
|
@ -1,95 +1,148 @@
|
|||||||
.v-toast {
|
.me-toast {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: flex;
|
display: flex;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 1090;
|
z-index: 1090;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
&__item {
|
&__root {
|
||||||
display: inline-flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
animation-duration: 150ms;
|
// Individual toast position
|
||||||
margin: 0.5em 0;
|
&.me-toast__root--top,
|
||||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
|
&.me-toast__root--bottom {
|
||||||
border-radius: 0.25em;
|
align-self: center;
|
||||||
pointer-events: auto;
|
}
|
||||||
opacity: 0.92;
|
|
||||||
color: #fff;
|
&.me-toast__root--top-right,
|
||||||
min-height: 3em;
|
&.me-toast__root--bottom-right {
|
||||||
cursor: pointer;
|
align-self: flex-end;
|
||||||
|
}
|
||||||
// Directions
|
|
||||||
&__item--rtl {
|
&.me-toast__root--top-left,
|
||||||
direction: rtl;
|
&.me-toast__root--bottom-left {
|
||||||
}
|
align-self: flex-start;
|
||||||
|
}
|
||||||
&__item--ltr {
|
}
|
||||||
direction: ltr;
|
|
||||||
}
|
&__item {
|
||||||
|
display: inline-flex;
|
||||||
// Colors
|
align-items: center;
|
||||||
@each $color, $value in $toast-colors {
|
justify-content: space-between;
|
||||||
|
animation-duration: 150ms;
|
||||||
&--#{$color} {
|
margin: 0.3em 0;
|
||||||
background-color: $value !important;
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
|
||||||
}
|
border-radius: 0.25em;
|
||||||
|
pointer-events: auto;
|
||||||
& .v-toast__icon--#{$color} {
|
opacity: 0.92;
|
||||||
background-color: $value;
|
color: #fff;
|
||||||
}
|
min-height: 49px;
|
||||||
}
|
width: 490px;
|
||||||
|
cursor: pointer;
|
||||||
&--warning {
|
|
||||||
color: #000
|
& .me-toast__box {
|
||||||
}
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
// Individual toast position
|
height: 49px;
|
||||||
&.v-toast__item--top,
|
}
|
||||||
&.v-toast__item--bottom {
|
|
||||||
align-self: center;
|
// Directions
|
||||||
}
|
|
||||||
|
&--rtl {
|
||||||
&.v-toast__item--top-right,
|
direction: rtl;
|
||||||
&.v-toast__item--bottom-right {
|
|
||||||
align-self: flex-end;
|
.me-toast__icon {
|
||||||
}
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
&.v-toast__item--top-left,
|
}
|
||||||
&.v-toast__item--bottom-left {
|
|
||||||
align-self: flex-start;
|
}
|
||||||
}
|
|
||||||
}
|
&--ltr {
|
||||||
|
direction: ltr;
|
||||||
&__text {
|
|
||||||
margin: 0;
|
.me-toast__icon {
|
||||||
padding: 0.5em 1em;
|
border-top-right-radius: 4px;
|
||||||
word-break: break-word;
|
border-bottom-right-radius: 4px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&__icon {
|
|
||||||
display: none;
|
// Colors
|
||||||
}
|
@each $color, $value in $toast-colors {
|
||||||
|
|
||||||
// Notice container positions
|
&--#{$color} {
|
||||||
&.v-toast--top {
|
background-color: $value !important;
|
||||||
flex-direction: column;
|
}
|
||||||
}
|
|
||||||
|
& .me-toast__icon--#{$color} {
|
||||||
&.v-toast--bottom {
|
background-color: $value;
|
||||||
flex-direction: column-reverse;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.v-toast--custom-parent {
|
}
|
||||||
position: absolute;
|
|
||||||
}
|
&__title {
|
||||||
|
font-size: 12px;
|
||||||
@media screen and (max-width: 768px) {
|
padding: 0 16px;
|
||||||
padding: 0;
|
height: 65%;
|
||||||
position: fixed !important;
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__message {
|
||||||
|
font-size: 10px;
|
||||||
|
margin-right: 16px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colors
|
||||||
|
@each $color, $value in $toast-colors {
|
||||||
|
|
||||||
|
&__progress--#{$color} {
|
||||||
|
background: $value !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.me-toast__bar--#{$color} {
|
||||||
|
background-color: $value ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&__progress {
|
||||||
|
width: 490px;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
.me-toast__bar {
|
||||||
|
width: 1%;
|
||||||
|
height: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notice container positions
|
||||||
|
&.me-toast--top {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.me-toast--bottom {
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.me-toast--custom-parent {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
padding: 0;
|
||||||
|
position: fixed !important;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,14 +1,15 @@
|
|||||||
$toast-colors: (
|
$toast-colors: (
|
||||||
) !default;
|
) !default;
|
||||||
$toast-colors: map-merge(("success": #32CAD5,
|
$toast-colors: map-merge(("success": #32CAD5,
|
||||||
"success-light": #32CAD5CC,
|
"success-light": #32CAD5CC,
|
||||||
"info": #E8E8E8,
|
"info": #000000,
|
||||||
"info-light": #F7F7F7,
|
"info-light": #3E3E3E,
|
||||||
"warning": #febc22,
|
"warning": #febc22,
|
||||||
"warning-light": #febc22,
|
"warning-light": #febc22,
|
||||||
"error": #EE3552,
|
"error": #EE3552,
|
||||||
"error-light": #EE3552CC,
|
"error-light": #EE3552CC,
|
||||||
"default": #000,
|
"default": #E8E8E8,
|
||||||
"default-light": #3E3E3E),
|
"default-light": #F7F7F7),
|
||||||
$toast-colors
|
$toast-colors
|
||||||
);
|
);
|
||||||
|
$toast-icons-path: "../sugar/icons" !default;
|
@ -1,3 +1,4 @@
|
|||||||
@import 'variables';
|
@import 'variables';
|
||||||
@import '../animations';
|
@import '../animations';
|
||||||
@import 'main';
|
@import 'main';
|
||||||
|
@import '../sugar/icons';
|
After Width: | Height: | Size: 759 B |
After Width: | Height: | Size: 759 B |
Before Width: | Height: | Size: 466 B After Width: | Height: | Size: 616 B |
Before Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 211 B |
Before Width: | Height: | Size: 453 B After Width: | Height: | Size: 211 B |
Before Width: | Height: | Size: 308 B After Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 589 B |
@ -1,24 +0,0 @@
|
|||||||
export default class Timer {
|
|
||||||
constructor(callback, delay) {
|
|
||||||
this.startedAt = Date.now();
|
|
||||||
this.callback = callback;
|
|
||||||
this.delay = delay;
|
|
||||||
|
|
||||||
this.timer = setTimeout(callback, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
pause() {
|
|
||||||
this.stop();
|
|
||||||
this.delay -= Date.now() - this.startedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
resume() {
|
|
||||||
this.stop();
|
|
||||||
this.startedAt = Date.now();
|
|
||||||
this.timer = setTimeout(this.callback, this.delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
clearTimeout(this.timer);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,3 @@
|
|||||||
import mitt from 'mitt'
|
import mitt from 'mitt'
|
||||||
const eventBus = mitt();
|
const eventBus = mitt();
|
||||||
export default eventBus;
|
export default eventBus;
|
@ -1,48 +1,30 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
export const removeElement = (el) => {
|
export const removeElement = (el) => {
|
||||||
console.log(el);
|
if (typeof el.remove !== 'undefined') {
|
||||||
if (typeof el.remove !== 'undefined') {
|
el.remove()
|
||||||
el.remove()
|
} else {
|
||||||
} else {
|
if (el.parentNode) el.parentNode.removeChild(el)
|
||||||
if (el.parentNode) el.parentNode.removeChild(el)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
export const createComponent = (component, props, parentContainer, slots = {}) => {
|
||||||
export const createComponent = (component, props, parentContainer, slots = {}) => {
|
const toastTpl = Vue.extend({
|
||||||
// const vNode = h(component, props, slots)
|
data() {
|
||||||
// const container = document.createElement('div');
|
return {
|
||||||
// console.log(parentContainer, container);
|
}
|
||||||
// container.classList.add('v-toast--pending')
|
},
|
||||||
// parentContainer.appendChild(container);
|
render(h) {
|
||||||
// h(vNode, container);
|
return h(
|
||||||
|
component,
|
||||||
// return vNode.component
|
{
|
||||||
// return Vue.component('MeshkeeToast', {
|
style: this.extStyle,
|
||||||
// render: (createElement) => {
|
props
|
||||||
// return createElement(
|
}
|
||||||
// 'div',
|
)
|
||||||
// { class: { 'v-toast--pending': true } },
|
}
|
||||||
// MeshkeeToast
|
});
|
||||||
// )
|
let toastVM = new toastTpl();
|
||||||
// }
|
const tpl = toastVM.$mount().$el;
|
||||||
// });
|
parentContainer.appendChild(tpl);
|
||||||
const toastTpl = Vue.extend({
|
return toastVM.$children[0];
|
||||||
data() {
|
}
|
||||||
return {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render(h) {
|
|
||||||
return h(
|
|
||||||
component,
|
|
||||||
{
|
|
||||||
style: this.extStyle,
|
|
||||||
props
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let toastVM = new toastTpl();
|
|
||||||
const tpl = toastVM.$mount().$el;
|
|
||||||
parentContainer.appendChild(tpl);
|
|
||||||
return toastVM.$children[0];
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
export default Object.freeze({
|
export default Object.freeze({
|
||||||
TOP_RIGHT: 'top-right',
|
TOP_RIGHT: 'top-right',
|
||||||
TOP: 'top',
|
TOP: 'top',
|
||||||
TOP_LEFT: 'top-left',
|
TOP_LEFT: 'top-left',
|
||||||
BOTTOM_RIGHT: 'bottom-right',
|
BOTTOM_RIGHT: 'bottom-right',
|
||||||
BOTTOM: 'bottom',
|
BOTTOM: 'bottom',
|
||||||
BOTTOM_LEFT: 'bottom-left',
|
BOTTOM_LEFT: 'bottom-left',
|
||||||
})
|
})
|
@ -0,0 +1,47 @@
|
|||||||
|
export default class Timer {
|
||||||
|
constructor(callback, delay) {
|
||||||
|
this.startedAt = Date.now();
|
||||||
|
this.callback = callback;
|
||||||
|
this.delay = delay;
|
||||||
|
this.timer = setTimeout(callback, delay);
|
||||||
|
this.index = 0;
|
||||||
|
this.width = 0;
|
||||||
|
this.widthTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pause() {
|
||||||
|
this.stop();
|
||||||
|
this.delay -= Date.now() - this.startedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
resume() {
|
||||||
|
this.stop();
|
||||||
|
this.startedAt = Date.now();
|
||||||
|
this.timer = setTimeout(this.callback, this.delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
clearTimeout(this.timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
move(elem, stop) {
|
||||||
|
if (stop) {
|
||||||
|
this.index = 0;
|
||||||
|
return clearInterval(this.widthTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.index == 0) {
|
||||||
|
this.index = 1;
|
||||||
|
this.widthTimer = setInterval(() => {
|
||||||
|
if (this.width >= 100) {
|
||||||
|
clearInterval(this.widthTimer);
|
||||||
|
this.index = 0;
|
||||||
|
} else {
|
||||||
|
this.width++;
|
||||||
|
elem.style.width = this.width + "%";
|
||||||
|
}
|
||||||
|
}, (this.delay / 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|