You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.2 KiB
139 lines
4.2 KiB
<tiny-notification>
|
|
<div class="toast-wrapper { state.wrapperClass }" if={ state.items.length > 0 }>
|
|
<div
|
|
id={ item.id } class={ item.classes.join(' ') }
|
|
each={ item in state.items }
|
|
onclick={ (event) => { handleClick(event, item) } }>
|
|
|
|
<div class="toast__body">
|
|
{ item.message }
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
|
|
import { v4 as uuidv4 } from 'uuid'
|
|
import notificationStore from './notificationStore.js'
|
|
|
|
/**
|
|
* notification
|
|
*
|
|
*
|
|
* @author Björn Hase
|
|
* @license http://opensource.org/licenses/MIT The MIT License
|
|
* @link https://gitea.node001.net/tiny-components/notification
|
|
*
|
|
*/
|
|
|
|
export default {
|
|
|
|
state: {
|
|
items: [],
|
|
timeout: 5000,
|
|
prefixId: 'tiny-notification-',
|
|
wrapperClass: ''
|
|
},
|
|
|
|
/**
|
|
* on mounted
|
|
*
|
|
* @param {Object} props
|
|
* @param {Object} state
|
|
*
|
|
*/
|
|
onMounted(props, state) {
|
|
|
|
// change timeout by props
|
|
if (props.timeout) {
|
|
state.timeout = props.timeout
|
|
}
|
|
|
|
// change timeout by props
|
|
if (props.wrapperClass) {
|
|
state.wrapperClass = props.wrapperClass
|
|
}
|
|
|
|
// adding service for notifications and listen to "update"
|
|
notificationStore.on('append', (item) => {
|
|
|
|
// adding attributes
|
|
item.id = this.state.prefixId + 'toast-' + uuidv4()
|
|
|
|
// create timeout to remove notification
|
|
item.timeout = setTimeout(() => {
|
|
this.removeItem(item)
|
|
}, this.state.timeout)
|
|
|
|
item.classes = [
|
|
'toast',
|
|
'toast--' + item.type
|
|
]
|
|
|
|
this.state.items.push(item)
|
|
this.update()
|
|
|
|
setTimeout(() => {
|
|
for (let i = 0; i < this.state.items.length; i++) {
|
|
if (this.state.items[i].id === item.id) {
|
|
this.state.items[i].classes.push('toast--animation')
|
|
this.update()
|
|
}
|
|
}
|
|
}, 10)
|
|
})
|
|
},
|
|
|
|
/**
|
|
* remove single item
|
|
*
|
|
*
|
|
* @param {Object} item
|
|
*
|
|
*/
|
|
removeItem(item) {
|
|
|
|
// set event transitionend only to item that has to removed
|
|
// after animation is complete search for cleartimeout and remove it
|
|
// form items
|
|
this.$('#' + item.id).addEventListener('transitionend', () => {
|
|
|
|
const items = []
|
|
|
|
for (let i = 0; i < this.state.items.length; i++) {
|
|
if (this.state.items[i].id === item.id) {
|
|
clearTimeout(this.state.items[i].timeout)
|
|
} else {
|
|
items.push(this.state.items[i])
|
|
}
|
|
}
|
|
|
|
this.state.items = items
|
|
this.update()
|
|
})
|
|
|
|
// remove class animation and update
|
|
requestAnimationFrame(() => {
|
|
for (let i = 0; i < this.state.items.length; i++) {
|
|
if (this.state.items[i].id === item.id) {
|
|
this.state.items[i].classes.pop('toast--animation')
|
|
this.update()
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
/**
|
|
* remove item by clicked on it
|
|
*
|
|
* @param {Object} event
|
|
* @param {Object} item
|
|
*
|
|
*/
|
|
handleClick(event, item) {
|
|
this.removeItem(item)
|
|
}
|
|
}
|
|
|
|
</script>
|
|
</tiny-notification> |