Skip to content

feat(VAlert): add timeout prop to auto-dismiss alerts#22947

Open
eldardada wants to merge 5 commits into
vuetifyjs:masterfrom
eldardada:feat/valert-duration
Open

feat(VAlert): add timeout prop to auto-dismiss alerts#22947
eldardada wants to merge 5 commits into
vuetifyjs:masterfrom
eldardada:feat/valert-duration

Conversation

@eldardada

@eldardada eldardada commented Jun 26, 2026

Copy link
Copy Markdown

Description

Adds a timeout prop to VAlert that automatically dismisses the alert after a given time in milliseconds, matching VSnackbar's timeout. Currently developers have to wire up their own setTimeout to hide an alert after a delay.

  • timeout accepts a number (or numeric string) of milliseconds.
  • -1 (the default) keeps the alert visible indefinitely, so existing alerts are unaffected. 0 dismisses immediately and > 0 dismisses after the given delay, matching VSnackbar's semantics.
  • The timer pauses while the alert is hovered or focused, so it doesn't vanish while someone is reading it or reaching for the close button / a link in a slot. It restarts when the alert becomes visible again or when timeout changes, and is cleared on manual close and on unmount.

The auto-dismiss timeout and pause-on-hover/focus handling is shared with VSnackbar through a new useAutoDismiss composable, so the two components stay consistent and the hover/focus pause logic that used to live only in VSnackbar is no longer duplicated. Pausing while hovered or focused also satisfies WCAG 2.2.1 (Timing Adjustable). VSnackbar keeps driving its visual countdown timer through the composable's onStart/onClear hooks, so its behavior is unchanged.

Unit tests cover auto-dismiss, the pause-on-hover case, and the persistent default. The API description and a docs example have been added.

resolves #20409

#22952 addresses the same issue. This PR was opened first and also covers the requested shared composable, the hover/focus pause, and tests for both VSnackbar and VAlert. Happy to consolidate into whichever the team prefers.

Markup:

<template>
  <v-btn @click="visible = true">Show alert</v-btn>
  <v-alert
    v-model="visible"
    :timeout="3000"
    closable
    type="success"
    text="I will dismiss myself after 3 seconds"
  />
</template>

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

  const visible = shallowRef(true)
</script>

Add a `duration` prop that automatically dismisses the alert after the
given time in milliseconds. A value of `0` (default) preserves the
current behavior and never auto-dismisses. The timer restarts when the
alert becomes visible or the duration changes, pauses while the alert is
hovered or focused, and is cleared on manual close and on unmount —
mirroring VSnackbar's timeout handling.

resolves vuetifyjs#20409
@eldardada eldardada force-pushed the feat/valert-duration branch from 7226b80 to ddfea8d Compare June 26, 2026 20:44
@eldardada

eldardada commented Jun 26, 2026

Copy link
Copy Markdown
Author

On the prop name: I used duration as asked in #20409, though VSnackbar already calls the same thing timeout. The "off" value differs too: 0 (the default) means "never dismiss" here so existing alerts keep working, whereas VSnackbar defaults to 5000 and uses -1 for never. Happy to rename to timeout and match that convention if you'd rather the two line up.

@eldardada

Copy link
Copy Markdown
Author

On pausing: I copied the hover/focus handling from VSnackbar (pointerenter/leave + focusin/out), so an alert with a close button or links in a slot doesn't vanish while someone's reading it or reaching to click. Covers WCAG 2.2.1 as a side effect.

@eldardada

Copy link
Copy Markdown
Author

On reuse: I kept the timer inline rather than extracting a shared helper. VSnackbar's useCountdown is local and not exported, so sharing it would mean touching VSnackbar and pushing this past a good first issue. Can split that out separately if you want the two unified.

@eldardada

Copy link
Copy Markdown
Author

On edge values: Infinity and values past the 32-bit setTimeout limit dismiss right away, same as VSnackbar today. Left it for parity, can add a guard if you'd prefer.

@J-Sek

J-Sek commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Can split that out separately if you want the two unified.

I think it would make sense. Including prop rename to timeout so we don't cause cognitive load by inconsistency when both props deliver basically the same behavior.

eldardada added a commit to eldardada/vuetify that referenced this pull request Jun 28, 2026
Addresses review feedback on vuetifyjs#22947:

- Rename the `VAlert` `duration` prop to `timeout` so it matches
  `VSnackbar` and avoids the cognitive load of two differently-named
  props with the same behavior.
- Extract the auto-dismiss timeout and pause-on-hover/focus handling
  that was duplicated between `VSnackbar` and `VAlert` into a shared
  `useAutoDismiss` composable. `VSnackbar` keeps driving its visual
  countdown timer through the composable's `onStart`/`onClear` hooks.

A `timeout` of `0` or less keeps the alert visible (default), so the
behavior remains backwards compatible.
@eldardada eldardada changed the title feat(VAlert): add duration prop to auto-dismiss alerts feat(VAlert): add timeout prop to auto-dismiss alerts Jun 28, 2026
eldardada added a commit to eldardada/vuetify that referenced this pull request Jun 28, 2026
Addresses review feedback on vuetifyjs#22947:

- Rename the `VAlert` `duration` prop to `timeout` so it matches
  `VSnackbar` and avoids the cognitive load of two differently-named
  props with the same behavior.
- Extract the auto-dismiss timeout and pause-on-hover/focus handling
  that was duplicated between `VSnackbar` and `VAlert` into a shared
  `useAutoDismiss` composable. `VSnackbar` keeps driving its visual
  countdown timer through the composable's `onStart`/`onClear` hooks.

A `timeout` of `0` or less keeps the alert visible (default), so the
behavior remains backwards compatible.
@eldardada eldardada force-pushed the feat/valert-duration branch from 712c742 to b8a8f38 Compare June 28, 2026 21:44
eldardada added a commit to eldardada/vuetify that referenced this pull request Jun 28, 2026
Addresses review feedback on vuetifyjs#22947:

- Rename the `VAlert` `duration` prop to `timeout` so it matches
  `VSnackbar` and avoids the cognitive load of two differently-named
  props with the same behavior.
- Extract the auto-dismiss timeout and pause-on-hover/focus handling
  that was duplicated between `VSnackbar` and `VAlert` into a shared
  `useAutoDismiss` composable. `VSnackbar` keeps driving its visual
  countdown timer through the composable's `onStart`/`onClear` hooks.

The composable only treats a negative timeout as "never dismiss", so
`VSnackbar` is unchanged (`-1` stays persistent, `0` still dismisses
immediately). `VAlert` normalizes its `0` default to off, keeping it
persistent by default and fully backwards compatible.
@eldardada eldardada force-pushed the feat/valert-duration branch from 1e08331 to 2143c0e Compare June 28, 2026 21:54
Addresses review feedback on vuetifyjs#22947:

- Rename the `VAlert` `duration` prop to `timeout` so it matches
  `VSnackbar` and avoids the cognitive load of two differently-named
  props with the same behavior.
- Extract the auto-dismiss timeout and pause-on-hover/focus handling
  that was duplicated between `VSnackbar` and `VAlert` into a shared
  `useAutoDismiss` composable. `VSnackbar` keeps driving its visual
  countdown timer through the composable's `onStart`/`onClear` hooks.

Both components now share the same `timeout` semantics: `-1` keeps the
component visible indefinitely and `0` dismisses immediately. `VAlert`
defaults to `-1`, so it stays persistent unless a timeout is set and
remains backwards compatible. `VSnackbar` behavior is unchanged.
Document the new `timeout` prop on the alerts page with a runnable
example, mirroring the existing `VSnackbar` timeout example.
@eldardada eldardada force-pushed the feat/valert-duration branch from 2143c0e to 69b014d Compare June 28, 2026 21:59
@eldardada

Copy link
Copy Markdown
Author

@J-Sek updated. Renamed the prop to timeout and moved the shared auto-dismiss + hover/focus pause into a useAutoDismiss composable used by both VSnackbar and VAlert. Ready for another look when you have a moment, thanks!

VSnackbar previously had no test coverage. Add browser tests for the
timeout behavior now shared through `useAutoDismiss`: auto-dismiss
after the timeout, pause while hovered, and stay open when the timeout
is -1.
In headless CI the pointer rests at the top-left, over the full-width
VAlert, which fires pointerenter and pauses its auto-dismiss timer, so
the alert never closed (VSnackbar is unaffected since it renders away
from the corner). Render the auto-dismiss alerts offset from the corner
so their timer runs, and give the dismiss assertions a larger poll
budget for slower CI.
@eldardada eldardada force-pushed the feat/valert-duration branch from 28013e8 to c603d04 Compare June 28, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Add duration Prop to Automatically Dismiss v-alert

2 participants