GkSnackbar
A non-blocking message surface teleported to body: no scrim, Escape closes, auto-dismiss via timeout, pause while hovered or focused (timer and countdown reset on resume, matching common snackbar behavior). location controls edge and alignment (e.g. bottom center, top start). timer adds a thin linear countdown strip.
For imperative messages from arbitrary code, add GkSnackbarHost once (e.g. in App.vue) and call pushGkSnackbar({ text, ... }) from useGkSnackbar / pushGkSnackbar.
When to use
Use for transient, non-blocking status updates after user actions (save complete, retry warning, background sync status).
Live Examples
Declarative
v-model, timer strip, placement, and action slot. Mount one GkSnackbarHost at app root if you also use pushGkSnackbar.
<script setup lang="ts">
import { ref } from 'vue'
import { GkButton, GkSnackbar } from 'god-kit/vue'
const open = ref(false)
</script>
<template>
<div class="gk-doc-row">
<GkButton type="button" @click="open = true">
Open snackbar
</GkButton>
<GkSnackbar
v-model="open"
title="GkSnackbar"
text="Declarative mode with v-model, timeout, timer strip, and Escape to dismiss."
:timeout="6000"
timer="bottom"
location="top end"
variant="info"
>
<template #actions>
<GkButton type="button" variant="ghost" size="sm" @click="open = false">
Dismiss
</GkButton>
</template>
</GkSnackbar>
</div>
</template>
<style scoped>
.gk-doc-row {
display: flex;
flex-wrap: wrap;
gap: var(--gk-space-2);
align-items: center;
}
</style>Programmatic queue
GkSnackbarHost plus pushGkSnackbar for toasts from non-template code.
<script setup lang="ts">
import { GkButton, GkSnackbarHost, pushGkSnackbar } from 'god-kit/vue'
</script>
<template>
<div class="gk-doc-stack">
<GkSnackbarHost />
<GkButton
type="button"
variant="secondary"
@click="pushGkSnackbar({ text: 'Queued from pushGkSnackbar()', variant: 'success', timeout: 5000 })"
>
Push programmatic snackbar
</GkButton>
</div>
</template>
<style scoped>
.gk-doc-stack {
display: flex;
flex-direction: column;
gap: var(--gk-space-2);
align-items: flex-start;
}
</style>Best practice: Keep a single host near the app root so stacking and z-index stay consistent.
Manual dismiss
timeout -1 with actions; use isActive from the actions slot props to close.
<script setup lang="ts">
import { ref } from 'vue'
import { GkButton, GkSnackbar } from 'god-kit/vue'
const open = ref(false)
</script>
<template>
<div class="gk-doc-stack">
<GkButton type="button" variant="secondary" @click="open = true">
Open persistent snackbar
</GkButton>
<GkSnackbar
v-model="open"
:timeout="-1"
variant="danger"
title="Action required"
text="Dismiss manually when finished."
>
<template #actions>
<GkButton
type="button"
size="sm"
variant="ghost"
@click="open = false"
>
Dismiss
</GkButton>
</template>
</GkSnackbar>
</div>
</template>
<style scoped>
.gk-doc-stack {
display: flex;
flex-direction: column;
gap: var(--gk-space-2);
align-items: flex-start;
}
</style>API — GkSnackbar
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | false | Open state; v-model |
title / text | string | — | Text content (also #title / #text slots) |
timeout | number | string | 5000 | Auto-close ms; -1 = no auto-close |
timer | boolean | 'top' | 'bottom' | false | Countdown strip position |
timerColor | string | — | Strip color (CSS) |
reverseTimer | boolean | false | Strip fills from the opposite side |
variant | 'neutral' | 'info' | ... | 'neutral' | Surface tone (aligned with GkAlert) |
location | string | 'bottom center' | Edge + alignment, e.g. bottom start, left center |
rounded | boolean | true | Rounded corners |
elevation | 0–5 | — | Shadow preset |
loading | boolean | false | Shows GkSpinner in prepend when no #prepend |
prependAvatar / prependIcon | string | — | Image URL or short glyph |
vertical | boolean | false | Stack content vertically |
collapsed | { width, height } | — | Fixed dimensions (CSS variables) |
queueIndex / queueGap | number | 0 / 8 | Stacking offset for GkSnackbarHost |
zIndex | number | string | token | Layering |
to | string | HTMLElement | 'body' | Teleport target |
transitionName | string | 'gk-snackbar' | Vue <Transition> name |
Slots
| Slot | Slot props | Description |
|---|---|---|
default | — | Main body |
header | — | Above the row |
prepend | — | Replaces default prepend media |
title / text | — | Overrides title / text props |
actions | isActive | Action buttons (GkButton recommended); isActive is the v-model ref |
Events
| Event | Description |
|---|---|
update:modelValue | Open state |
afterEnter / afterLeave | Transition hooks |
Programmatic API
- Mount
GkSnackbarHostonce in your app root. - Call
pushGkSnackbar({ text: '…', variant: 'success', timeout: 4000 })from anywhere (oruseGkSnackbar().push). - Returns
{ id, dismiss }—dismiss()closes that item after its leave transition.
clearGkSnackbars() removes all queued items immediately (no leave animation).
Tokens
| Token | Purpose |
|---|---|
--gk-snackbar-z-index | Stacking |
--gk-snackbar-inset | Edge padding |
--gk-snackbar-max-width | Panel width cap |
--gk-snackbar-stack-unit | Approximate height for stacked offsets |
Examples
Each scenario under Live Examples includes a copyable Vue snippet (source is imported from the same SFC as the preview).
Accessibility notes
- Keep snackbar text concise and action-oriented; avoid long instructional content.
- Provide explicit action labels in
#actionsslots. - Use indefinite timeout (
-1) only when users must manually acknowledge the message.
