BpDismissable is a renderless vue component for dismissable content such as alerts and banners. It exposes a single method to its slot, dismiss
, that hides the content. It requires a single parameter, storage-key
, which is used to uniquely identify the instance. It also has optional parameters for when content changes or whether the dismissal should only last for a fixed amount of time.
<bp-dismissable storage-key="example-alert" v-slot="{ dismiss }">
<div class="banner">
<div class="banner__container container">
<div class="banner__messsage">
Sit quisquam error ipsum atque odit ex At eum eius autem perspiciatis sit! Sint ab!
</div>
<button class="banner__dismiss" @click="dismiss">
<svg xmlns="http://www.w3.org/2000/svg" class="banner__dismissIcon" viewBox="0 0 24 24" stroke-width="1.5" stroke="#2c3e50" fill="none" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</button>
</div>
</div>
</bp-dismissable>
<script>
/**
* Renderless component for dismissable content.
*
* @param storageKey (required) - used to identify a specific instance of this
* component to tell if it's already dismissed or not.
* @param hash - optional second component for telling if content has changed
* and the component should be re-displayed even if it was already
* dismissed.
* @param expiration - optional duration for how long to hide the content
* before displaying it again. Defaults to a week. If set to 0, stays
* dimissed permanently.
*/
export default {
props: {
storageKey: {
type: String,
required: true,
},
hash: {
type: String,
default: '',
},
expiration: {
type: Number,
default: 604800000,
},
},
data: () => ({
isDismissed: true,
}),
mounted () {
const now = (new Date()).getTime()
if (this.storageKey in localStorage) {
const { hash, expiration } = JSON.parse(localStorage[this.storageKey])
if (hash === this.hash && (expiration === 0 || expiration > now)) {
return
}
}
this.isDismissed = false
},
methods: {
dismiss () {
const now = (new Date()).getTime()
this.isDismissed = true
localStorage[this.storageKey] = JSON.stringify({
expiration: this.expiration === 0 ? 0 : now + this.expiration,
hash: this.hash,
})
},
},
render () {
return this.isDismissed
? ''
: this.$scopedSlots.default({
dismiss: this.dismiss,
isDismissed: this.isDismissed,
})
},
}
</script>