Skip to content

Alert

Stable

Display important messages to the user, such as warnings, errors, success messages, or informational notices.

vue
<script setup lang="ts">
import { HAlert } from '@holistics/design-system'
</script>

<template>
  <HAlert
    type="danger"
    title="Internal Server Error"
    class="w-[36rem]"
  >
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
  </HAlert>
</template>

Examples

Types

vue
<script setup lang="ts">
import { ALERT_TYPES, HAlert } from '@holistics/design-system'
</script>

<template>
  <div class="flex flex-wrap items-center justify-center gap-4">
    <HAlert
      v-for="type in ALERT_TYPES"
      :key="type"
      :type="type"
      :title="type.toUpperCase()"
      class="w-[28rem]"
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </HAlert>
  </div>
</template>

With Button

vue
<script setup lang="ts">
import { ALERT_TYPES, HAlert } from '@holistics/design-system'
</script>

<template>
  <div class="flex flex-wrap items-center justify-center gap-4">
    <HAlert
      v-for="type in ALERT_TYPES"
      :key="type"
      :type="type"
      :title="type.toUpperCase()"
      button="Clear"
      class="w-[28rem]"
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </HAlert>
  </div>
</template>

Dismissible

vue
<script setup lang="ts">
import {
  ALERT_TYPES, type AlertType, HAlert, HButton, type ButtonType,
} from '@holistics/design-system'
import { ref } from 'vue'

let id = 0

const baseAlerts = ALERT_TYPES.map((type) => ({
  id: id++,
  type,
  title: type.toUpperCase(),
}))

const alerts = ref(baseAlerts.slice())

function getButtonType (type: AlertType): ButtonType {
  switch (type) {
    case 'info': return 'outline-highlight'
    case 'neutral': return 'secondary-default'
    default: return `outline-${type}`
  }
}
function addAlert (type: AlertType) {
  alerts.value.push({
    ...baseAlerts.find(((al) => al.type === type))!,
    id: id++,
  })
}

function onDismiss (i: number) {
  alerts.value.splice(i, 1)
}
</script>

<template>
  <div class="grid grid-cols-5 gap-x-4 gap-y-2">
    <HButton
      v-for="type in ALERT_TYPES"
      :key="type"
      :type="getButtonType(type)"
      icon="add"
      @click="addAlert(type)"
    >
      {{ type.toUpperCase() }}
    </HButton>
  </div>

  <div
    v-if="alerts.length"
    class="mt-8 space-y-2"
  >
    <HAlert
      v-for="(al, i) in alerts"
      :key="al.id"
      :type="al.type"
      :title="al.title"
      dismissible
      class="w-[32rem]"
      @dismiss="onDismiss(i)"
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </HAlert>
  </div>
</template>

🗑️ Destroy component after dismiss!

Even though the component destroys its DOMs, its internal states still persist in VDOM. Therefore, you should manually unmount the component on @dismiss event.

Why? This is because a component cannot control its life-cycle, otherwise race conditions and memory leaks could happen!

Dimiss after a duration

vue
<script setup lang="ts">
import {
  ALERT_TYPES, type AlertType, HAlert, HButton, type ButtonType,
} from '@holistics/design-system'
import { ref } from 'vue'

let id = 0

const baseAlerts = ALERT_TYPES.map((type) => ({
  id: id++,
  type,
  title: type.toUpperCase(),
  duration: 2000,
}))

const alerts = ref<typeof baseAlerts>([])

function getButtonType (type: AlertType): ButtonType {
  switch (type) {
    case 'info': return 'outline-highlight'
    case 'neutral': return 'secondary-default'
    default: return `outline-${type}`
  }
}
function addAlert (type: AlertType) {
  alerts.value.push({
    ...baseAlerts.find(((al) => al.type === type))!,
    id: id++,
  })
}

function onDismiss (i: number) {
  alerts.value.splice(i, 1)
}
</script>

<template>
  <div class="grid grid-cols-5 gap-x-4 gap-y-2">
    <HButton
      v-for="type in ALERT_TYPES"
      :key="type"
      :type="getButtonType(type)"
      icon="add"
      @click="addAlert(type)"
    >
      {{ type.toUpperCase() }}
    </HButton>
  </div>

  <div
    v-if="alerts.length"
    class="mt-8 space-y-2"
  >
    <HAlert
      v-for="(al, i) in alerts"
      :key="al.id"
      :type="al.type"
      :title="al.title"
      dismissible
      :duration="al.duration"
      class="w-[32rem]"
      @dismiss="onDismiss(i)"
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    </HAlert>
  </div>
</template>

🗑️ Destroy component after dismiss!

Even though the component destroys its DOMs, its internal states still persist in VDOM. Therefore, you should manually unmount the component on @dismiss event.

Why? This is because a component cannot control its life-cycle, otherwise race conditions and memory leaks could happen!

API

Pass-through: <div>

What does this mean?

All props, events, and attrs that are not specified in the tables below will be passed to the element/component described above.

Props

NameTypeDescription
type *
"info" | "success" | "warning" | "danger" | "neutral"
title 
string
description 
string
hideIcon 
boolean
dismissible 
boolean
dismissable 
boolean
duration 
number | "short" | "long"
= 0
button 
string | ButtonPropsPreTyped

Events

NameParametersDescription
@buttonClick
[e: MouseEvent]
@dismiss
[]

Slots

NameScopedDescription
#header
any
#default
any