Files
corrosion-admin-panel/frontend/src/components/ds/feedback/Alert.vue
Vantz Stockwell f91ef84832
All checks were successful
Test Asgard Runner / test (push) Successful in 4s
feat(redesign): design-system tokens, 23 Vue components, game-aware shell + Fleet/Solo dashboard
Tokens ported 1:1 from the Claude Design bundle (colors/game-themes/type/spacing/elevation/motion/fonts) with the data-theme/data-game theming contract via useThemeGame (+ cc-skin-swap repaint guard). 23 design-system components reimplemented as Vue SFCs (core/forms/data/navigation/feedback/brand). DashboardLayout rebuilt as the game-aware shell (GameSwitcher, grouped nav with permission gating preserved, agent-health footer, topbar). DashboardView: Fleet + Solo with per-game GAME_FIELDS rows and the themed ECharts PlayersChart; Solo wired to the real server store, Fleet on representative data pending the multi-instance backend. All four game skins (Rust/Dune/Conan/Soulmask). vue-tsc + vite build green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 02:12:35 -04:00

87 lines
3.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
/**
* Alert — contextual inline alert strip.
* Tones: info | warn | danger | online | accent | neutral.
* Pass `title` for a bold heading, default slot for body text, `actions` slot
* for inline action buttons. Set `dismissible` to show an × ghost button that
* emits `dismiss`.
*/
import Icon from '@/components/ds/core/Icon.vue'
type Tone = 'info' | 'warn' | 'danger' | 'online' | 'accent' | 'neutral'
const ICONS: Record<Tone, string> = {
info: 'info',
warn: 'triangle-alert',
danger: 'octagon-alert',
online: 'circle-check',
accent: 'sparkles',
neutral: 'info',
}
const props = withDefaults(
defineProps<{
tone?: Tone
title?: string
dismissible?: boolean
icon?: string
}>(),
{ tone: 'info', dismissible: false },
)
defineEmits<{ dismiss: [] }>()
</script>
<template>
<div
:class="['cc-alert', 'cc-alert--' + tone]"
role="status"
>
<span class="cc-alert__icon">
<Icon :name="icon ?? ICONS[tone]" :size="17" :stroke-width="2" />
</span>
<div class="cc-alert__main">
<div v-if="title" class="cc-alert__title">{{ title }}</div>
<div v-if="$slots.default" class="cc-alert__body"><slot /></div>
<div v-if="$slots.actions" class="cc-alert__actions"><slot name="actions" /></div>
</div>
<button
v-if="dismissible"
class="cc-alert__dismiss"
type="button"
aria-label="Dismiss"
@click="$emit('dismiss')"
>
<Icon name="x" :size="15" :stroke-width="2.25" />
</button>
</div>
</template>
<style>
.cc-alert { display:flex; gap:11px; padding:12px 13px; border-radius:var(--radius-md); background:var(--surface-raised); box-shadow:var(--ring-default); }
.cc-alert__icon { flex:none; margin-top:1px; }
.cc-alert__main { flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; }
.cc-alert__title { font-size:var(--text-sm); font-weight:600; color:var(--text-primary); }
.cc-alert__body { font-size:var(--text-xs); color:var(--text-secondary); line-height:1.5; }
.cc-alert__actions { display:flex; gap:8px; margin-top:8px; }
.cc-alert--info { background:var(--status-info-soft); box-shadow: inset 0 0 0 1px var(--status-info-border); }
.cc-alert--info .cc-alert__icon { color:var(--status-info); }
.cc-alert--warn { background:var(--status-warn-soft); box-shadow: inset 0 0 0 1px var(--status-warn-border); }
.cc-alert--warn .cc-alert__icon { color:var(--status-warn); }
.cc-alert--danger { background:var(--status-offline-soft); box-shadow: inset 0 0 0 1px var(--status-offline-border); }
.cc-alert--danger .cc-alert__icon { color:var(--status-offline); }
.cc-alert--online { background:var(--status-online-soft); box-shadow: inset 0 0 0 1px var(--status-online-border); }
.cc-alert--online .cc-alert__icon { color:var(--status-online); }
.cc-alert--accent { background:var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-border); }
.cc-alert--accent .cc-alert__icon { color:var(--accent-text); }
.cc-alert__dismiss {
flex: none; display:inline-flex; align-items:center; justify-content:center;
width:26px; height:26px; border-radius:var(--radius-sm); border:none; cursor:pointer;
background:transparent; color:var(--text-secondary);
transition: var(--transition-colors);
margin-top:-3px; margin-right:-3px;
}
.cc-alert__dismiss:hover { background:var(--surface-hover); color:var(--text-primary); }
.cc-alert__dismiss:focus-visible { outline:none; box-shadow:var(--focus-ring); }
</style>