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

<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>