PXD

Message

Display global messages as feedback in response to user operations.

Default

useMessage needs to ensure that the Message component has been mounted before being invoked. If you need to register multiple times or want to show it in different locations, you can set the group property to isolate it.

<script setup>
import { shallowRef } from 'vue'
import { useMessage } from 'pxd'

const position = shallowRef('top')

const options = [
  { label: 'Top Start', value: 'top-start' },
  { label: 'Top', value: 'top' },
  { label: 'Top End', value: 'top-end' },
  { label: 'Bottom Start', value: 'bottom-start' },
  { label: 'Bottom', value: 'bottom' },
  { label: 'Bottom End', value: 'bottom-end' },
]

const loremText =
  'Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque minima, excepturi distinctio quis asperiores magnam voluptate nostrum quibusdam!'

function addMessage(type) {
  const text = loremText.slice(0, Math.ceil(Math.random() * 100))
  useMessage(text, { type })
}
</script>

<template>
  <PMessage :position="position" />

  <PStack direction="vertical">
    <PRadioGroup v-model="position" :options="options" />

    <PStack gap="2">
      <PButton @click="addMessage()">Add normal</PButton>
      <PButton @click="addMessage('info')">Add info</PButton>
      <PButton @click="addMessage('error')">Add error</PButton>
      <PButton @click="addMessage('loading')">Add loading</PButton>
      <PButton @click="addMessage('warning')">Add warning</PButton>
      <PButton @click="addMessage('success')">Add success</PButton>
    </PStack>
  </PStack>
</template>

Promise

Sometimes it is necessary to rely on certain states to complete.

<script setup>
import { useMessage } from 'pxd'

const promise = () =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { id: Math.random().toString(16).slice(2) }
      if (Math.random() > 0.5) {
        resolve(data)
      } else {
        reject(data)
      }
    }, 1000)
  })

function addMessage() {
  useMessage('Loading...', {
    type: 'loading',
    promise: promise(),
    group: 'promise',
    success: (data) => {
      return `Success: ${data.id} is latest.`
    },
    error: 'Error',
    // If set, the value of success/error will be overwritten.
    // finally: 'Operation finished.',
  })
}
</script>

<template>
  <PMessage group="promise" />

  <PButton @click="addMessage()">Add</PButton>
</template>

Max

Max prop limits how many message can be displayed at the same time. (default: 3)

<script setup>
import { useMessage } from 'pxd'

function addMessage() {
  useMessage("Now it's:" + Date.now(), {
    class: 'bg-blue-100 border border-dashed border-blue-600 font-mono',
    closeable: true,
    durations: 5000,
    group: 'max',
  })
}
</script>

<template>
  <PMessage group="max" :max="5" width="240" position="bottom" />

  <PButton @click="addMessage()">Add</PButton>
</template>

Expand

Set expand prop to true to expand the message content.

<script setup>
import { useMessage } from 'pxd'

function addMessage() {
  useMessage("Now it's:" + Date.now(), { group: 'expand' })
}
</script>

<template>
  <PMessage group="expand" expand width="200" position="bottom" />

  <PButton @click="addMessage()">Add</PButton>
</template>

Action

Set the display content of the close button, and choose between it and the close button.

<script setup>
import { useMessage } from 'pxd'

function addMessage() {
  useMessage('Event has been created', {
    action: {
      // Optional values are consistent with the button component.
      variant: 'primary',
      label: 'Undo',
      onClick: () => {
        console.log('Undo')
      },
    },
    group: 'action',
  })
}
</script>

<template>
  <PMessage group="action" position="bottom-end" />

  <PButton @click="addMessage()">Add</PButton>
</template>

Manual Clear

<script setup>
import { shallowRef } from 'vue'
import { useMessage, closeMessage, clearMessage } from 'pxd'

let lastKey = 0
const messageRef = shallowRef()

function addMessage() {
  useMessage("Now it's:" + Date.now(), {
    id: ++lastKey,
    group: 'clear',
  })
}

function closeLast() {
  closeMessage('clear', lastKey--)
  // Or use the instance method (no need to set group)
  // messageRef.value.close(lastKey--)
}

function clearAll() {
  clearMessage('clear')
  // Or use the instance method (no need to set group)
  // messageRef.value.clear()
}
</script>

<template>
  <PMessage ref="messageRef" group="clear" position="bottom" />

  <PStack>
    <PButton @click="addMessage">Add</PButton>
    <PButton @click="closeLast">Close last</PButton>
    <PButton @click="clearAll">Clear all</PButton>
  </PStack>
</template>

Props

NameTypeDefaultDescription
maxnumber3How many messages stay visible, the rest stack behind
widthstring | number-Width of the message container, defaults to 356px
groupstringdefaultGroup name, only messages created with the same group are handled
expandboolean-Expand the stack so every message is fully shown
positionComponentPosition<'top' | 'bottom'>topWhere the stack is anchored, top or bottom with -start or -end

Events

NameTypeDescription
close(id: MessageItemConfig['id']) => voidEmitted when a message leaves the stack, whether its timer expired, its action button was used, or it was removed through the message API.

MessageItem Props

NameTypeDefaultDescription
maxnumber-Visible item limit, items beyond it are hidden
indexnumber-Position in the stack, driving the scale offset and z-index
item-dataMessageItemConfig-Message configuration created by useMessage

MessageItem Events

NameTypeDescription
close(key: MessageItemConfig['id']) => voidEmitted when the close or action button of the item is clicked.

Methods

NameTypeDescription
messagesMessageItemConfig[]The messages currently held in the group, newest first.
get(id: MessageItemConfig['id']) => { index: number, message: MessageItemConfig | null }Look up a message by id and get back its index in the group together with its configuration.
pause(id: MessageItemConfig['id']) => voidPause the auto-close timer of the message with the given id, keeping the time that is left.
resume(id: MessageItemConfig['id']) => voidRestart the auto-close timer of the message with the given id, closing it right away when 100 ms or less is left.
close(id: MessageItemConfig['id']) => voidClose the message with the given id, clearing its timer and emitting close.
clear() => voidClear every pending timer and drop all messages without emitting close.

Source

Source