Overlay Components
Surfaces that float over the page: modals, tooltips, flash toasts, and the login / account menu.
SparkModal
Animated modal with backdrop blur, card slide-up, escape-to-close, focus trapping, and outside-click dismiss. Supports ARIA attributes for screen readers.
<template>
<button @click="open = true">Open Modal</button>
<SparkModal v-model="open" title="Confirm">
<p>Are you sure?</p>
<div class="flex gap-3 justify-end mt-4">
<button class="kf-btn-ghost" @click="open = false">Cancel</button>
<button class="kf-btn" @click="open = false">Confirm</button>
</div>
</SparkModal>
</template>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | — | Controls visibility via v-model |
title | string | — | Heading text (sets aria-labelledby) |
label | string | — | Accessible label when no title |
size | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Max width of the card |
showClose | boolean | true | Show the close button |
closeOnOutside | boolean | true | Close on backdrop click |
cardClass | string | 'kf-card' | CSS class for the card container |
palette | SparkPalette | — | Scopes a palette's CSS variables to this modal. Omit to inherit the host app's palette. |
Slots
| Slot | Description |
|---|---|
default | Modal body content |
header | Replaces the default title rendering |
SparkTooltip
Hover/focus tooltip that teleports to <body> so it isn't clipped by overflow: hidden ancestors. The trigger renders the default slot. Tooltip content can come from the text prop or the content slot.
<!-- Plain string tooltip -->
<SparkTooltip text="Used by the leaderboard service to break ties.">
<span class="info-icon" tabindex="0">?</span>
</SparkTooltip>
<!-- Rich content via slot -->
<SparkTooltip placement="bottom">
<SparkButton>Hover me</SparkButton>
<template #content>
<strong>Pro tip:</strong> press <kbd>?</kbd> for shortcuts.
</template>
</SparkTooltip>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | — | Tooltip text. Fall back to the content slot if you need markup |
placement | 'top' | 'bottom' | 'top' | Preferred side; auto-flips when there's not enough room |
openDelay | number | 80 | ms to wait before showing on hover. 0 for instant |
disabled | boolean | false | Suppresses the tooltip without unmounting |
Slots
| Slot | Description |
|---|---|
| (default) | The trigger element. Hovering or focusing it shows the tooltip |
content | Tooltip body. Overrides text |
Form-field integration
SparkInput, SparkSelect, SparkCombobox, and SparkTextarea all read a help prop. When set, a small (?) glyph appears next to the field's label and the help text shows in a SparkTooltip on hover/focus. No setup required:
<SparkInput
v-model="username"
label="Username"
help="3–20 characters, letters/numbers/dashes only."
validation="required|alpha_dash"
/>
SparkFlash
Toast notification system. Place SparkFlashContainer once at the app root, then fire messages from anywhere with useFlash ().
<template>
<SparkFlashContainer />
<router-view />
</template>
import { useFlash } from '@katforge/spark';
const flash = useFlash ();
flash.success ('Changes saved');
flash.error ('Something went wrong');
flash.warning ('Rate limit approaching');
flash.info ('Tip: try keyboard shortcuts');
// With options
flash.success ('Saved', { title: 'Settings', duration: 3000 });
// Manual control
const id = flash.success ('Processing...');
flash.dismiss (id);
flash.dismissAll ();
Errors default to 10 seconds; all other types default to 5 seconds. Set duration: 0 for persistent messages that require manual dismissal.
SparkLogin
Drop-in login/register/guest modal. Wired to the @katforge/api's auth module. Handles email/password, OAuth buttons, guest sessions, forgot password, and guest-to-registered upgrade. Composes SparkModal internally.
<template>
<button @click="show = true">Sign In</button>
<SparkLogin
v-model="show"
:providers="[ 'discord', 'google', 'steam' ]"
@success="onLogin"
/>
</template>
<script setup>
import { ref } from 'vue';
const show = ref (false);
function onLogin (player) {
show.value = false;
console.log ('Logged in as', player.name);
}
</script>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | — | Controls visibility via v-model |
guest | boolean | true | Show "Play as Guest" option |
providers | OAuthProvider[] | [] | OAuth buttons to display |
manage | string | 'https://katforge.com' | Account management base URL |
callbackUrl | string | '' | OAuth redirect URL |
Events
| Event | Payload | Description |
|---|---|---|
success | Player | Fired after successful authentication. Reached via the Login, Register, Forgot (after reset), or Profile internal views. |
error | string | Fired with the raw error message. |
For most apps, prefer SparkUserMenu — it embeds SparkLogin, the avatar dropdown, and the wallet display behind one component.
SparkUserMenu
The canonical auth surface. Replaces the bespoke "sign in button + login modal + avatar dropdown" pattern that every game used to ship its own copy of. Logged out, it renders a pill-shaped Sign In button that opens an internally-owned SparkLogin. Logged in, it shows the avatar + name + chevron and reveals a dropdown with the user's currency snapshot, four built-in dashboard links (Dashboard, Account Details, My Games, Currency), Sign Out, and any extra items consumers slot in.
<!-- On katforge.com itself: omit `manage` so links stay same-origin -->
<SparkUserMenu mode="hover" :providers="[ 'discord', 'google' ]" />
<!-- On a game site: pass the dashboard origin so links open katforge.com in a new tab -->
<SparkUserMenu
mode="hover"
:providers="[ 'discord', 'google' ]"
:manage="dashboardUrl"
>
<template #items="{ close }">
<NuxtLink to="/leaderboards" @click="close">Leaderboards</NuxtLink>
</template>
</SparkUserMenu>
| Prop | Type | Default | Description |
|---|---|---|---|
palette | SparkPalette | palettes.stone | Palette applied to the embedded login modal. |
label | string | 'Sign In' | Sign In button text. |
providers | OAuthProvider[] | [] | OAuth providers surfaced in the modal. |
guest | boolean | false | Forwarded to SparkLogin — show the "Play as Guest" affordance. |
manage | string | '' | Base URL for dashboard links. Empty → in-site relative links (suitable for katforge.com). A full URL like https://katforge.com renders external links that open in a new tab. |
callbackUrl | string | '' | OAuth callback URL passthrough. |
mode | 'click' | 'hover' | 'click' | Dropdown trigger. Hover suits desktop nav; click suits mobile. |
The Sign In button and the avatar trigger render as the standard KATforge navbar pill — fully rounded, transparent at rest, rgba(255, 255, 255, 0.2) on hover. The dropdown panel uses SparkAvatar, SparkWallet, and built-in icon tiles. The #items slot lands between the four default dashboard links and Sign Out, and receives a close function so consumers can dismiss the menu after navigation.