message.html
<p-dismissable class="message error" v-slot="{ close }">
  <svg class="message__icon icon -square" viewBox="0 0 32 32"><use href="/main-icons-sprite.svg#error" /></svg>
  <div class="message__content">
    Message content neque tincidunt, rhoncus sapien ac, volutpat enim.
  </div>
  <button class="message__close" @click="close">
        <svg viewBox="0 0 18 18"><use href="/main-icons-sprite.svg#close" /></svg>
  </button>
</p-dismissable>

<p-dismissable class="message warning" v-slot="{ close }">
  <svg class="message__icon icon -square" viewBox="0 0 32 32"><use href="/main-icons-sprite.svg#error" /></svg>
  <div class="message__content">
    Elit molestiae natus deleniti ipsam modi mollitia iusto quos, quaerat Itaque quasi quae maiores quidem est. Exercitationem optio voluptatem fuga provident dolores Sint dolor facilis dolor mollitia quos? Enim porro.
  </div>
  <button class="message__close" @click="close">
        <svg viewBox="0 0 18 18"><use href="/main-icons-sprite.svg#close" /></svg>
  </button>
</p-dismissable>

<p-dismissable class="message success" v-slot="{ close }">
  <svg class="message__icon icon -square" viewBox="0 0 32 32"><use href="/main-icons-sprite.svg#check" /></svg>
  <div class="message__content">
    Message content neque tincidunt, rhoncus sapien ac, volutpat enim.
  </div>
  <button class="message__close" @click="close">
        <svg viewBox="0 0 18 18"><use href="/main-icons-sprite.svg#close" /></svg>
  </button>
</p-dismissable>

<p-dismissable class="message info" v-slot="{ close }">
  <svg class="message__icon icon -square" viewBox="0 0 32 32"><use href="/main-icons-sprite.svg#info" /></svg>
  <div class="message__content">
    Message content neque tincidunt, rhoncus sapien ac, volutpat enim.
  </div>
  <button class="message__close" @click="close">
        <svg viewBox="0 0 18 18"><use href="/main-icons-sprite.svg#close" /></svg>
  </button>
</p-dismissable>
index.scss
.message {
  position: static;
  display: grid;
  grid: auto / 2rem 1fr 3rem;
  align-items: start;
  gap: 1em;
  padding: 1em;
  background: var(--accent-color-50);
  border-radius: .5rem;
  margin-bottom: 2rem;
  box-shadow: 0 1px 1px 0 rgba(from var(--accent-color-900) r g b / .2),
    0 .5rem 1.5rem 0 rgba(from var(--accent-color) r g b / .1);

  &__icon {
    --icon-stroke-color: #fff;
    --icon-fill-color: var(--accent-color);
  }

  &__content {
    padding: .25em 0;
  }

  &__close {
    appearance: none;
    border: 0;
    background: #0000;
    color: inherit;
    height: 2rem;
    border-left: 1px solid rgba(from var(--accent-color) r g b / .5);
    display: grid;
    place-content: center;
    --icon-stroke-width: 1;
    grid: 1rem / 1rem;
  }

  &:is(dialog:not(:open)) {
    display: none;
  }

  &.-dark {
    background: var(--accent-color-900);
    color: #fff;
  }
}
PDismissable.vue
<script setup>
import { ref } from 'vue'

const { name } = defineProps({ name: { type: String } })

const open = ref(name ? sessionStorage[name] !== 'dismissed' : true)

const close = () => {
  open.value = false
  if (name) {
    sessionStorage[name] = 'dismissed'
  }
}
</script>

<template>
  <div v-if="open" @close="close">
    <slot :close="close" />
  </div>
</template>