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 an optional parameter for expiration.
It uses the composable function useStorage
.
<bp-dismissable storage-key="example-alert" v-slot="{ dismiss }">
<div class="banner" v-cloak>
<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>
<template>
<slot
v-if="!isDismissed"
:dismiss="dismiss"
/>
</template>
<script setup>
import { ref } from 'vue'
import useStorage from '@resources/js/components/UseStorage.js'
const props = defineProps({
storageKey: {
type: String,
required: true,
},
expiration: {
type: Number,
default: 604800000,
},
})
const isDismissed = ref(false)
const expiresAt = ref(undefined)
useStorage(isDismissed, props.storageKey)
useStorage(expiresAt, `${props.storageKey}__expiresAt`)
if (isDismissed.value && (!expiresAt.value || expiresAt.value < (new Date()).getTime())) {
isDismissed.value = false
expiresAt.value = undefined
}
const dismiss = () => {
expiresAt.value = (new Date()).getTime() + props.expiration
isDismissed.value = true
}
</script>