Files
SpaceWanderer/components/ui/alert.tsx
T
kamilkrzywda e688e9a0f0 app: shell + scificn-ui frontend (SCI-FI theme, brightened --text-muted)
scificn-ui v0.1.0 integrated copy-paste per its docs: Button/Panel/Badge/Card/Alert
in components/ui/, cn() helper in lib/utils.ts, theme tokens in app/globals.css.
Deliberate deviation from upstream: --text-muted #4A4A40 -> #6B6B5C (+12pt lightness)
for readability on the near-black background (default SCI-FI theme only). Landing page
proves the integration; no game UI yet.
2026-09-28 15:56:24 +00:00

120 lines
3.3 KiB
TypeScript
Raw Permalink 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.
import * as React from 'react'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
const alertVariants = cva(
[
'relative w-full',
'border border-solid border-l-[3px]',
'p-4',
'font-mono',
'rounded-none',
],
{
variants: {
variant: {
STATUS: [
'border-[var(--border)]',
'border-l-[var(--color-green)]',
'bg-[var(--surface)]',
],
WARNING: [
'border-[var(--border)]',
'border-l-[var(--color-amber)]',
'bg-[var(--surface)]',
],
CRITICAL: [
'border-[var(--border)]',
'border-l-[var(--color-red)]',
'bg-[var(--surface)]',
],
INFO: [
'border-[var(--border)]',
'border-l-[var(--color-blue)]',
'bg-[var(--surface)]',
],
},
},
defaultVariants: { variant: 'STATUS' },
}
)
const prefixMap = {
STATUS: { symbol: '◈', color: 'var(--color-green)', glow: 'var(--text-glow-green)' },
WARNING: { symbol: '⚠', color: 'var(--color-amber)', glow: 'var(--text-glow-amber)' },
CRITICAL: { symbol: '✕', color: 'var(--color-red)', glow: 'var(--text-glow-red)' },
INFO: { symbol: 'ℹ', color: 'var(--color-blue)', glow: 'var(--text-glow-blue)' },
}
export interface AlertProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof alertVariants> {}
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
({ className, variant = 'STATUS', children, ...props }, ref) => {
const v = variant ?? 'STATUS'
const prefix = prefixMap[v]
return (
<div ref={ref} className={cn(alertVariants({ variant }), className)} role="alert" {...props}>
<div style={{ display: 'flex', gap: '0.5rem', alignItems: 'flex-start' }}>
<span
style={{
color: prefix.color,
textShadow: prefix.glow,
fontSize: '0.85rem',
lineHeight: 1.5,
flexShrink: 0,
}}
>
{prefix.symbol}
</span>
<div style={{ flex: 1 }}>{children}</div>
</div>
</div>
)
}
)
Alert.displayName = 'Alert'
/* ── AlertTitle ── */
const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
({ className, style, ...props }, ref) => (
<h5
ref={ref}
className={cn(className)}
style={{
fontSize: '0.75rem',
fontWeight: 600,
color: 'var(--text-secondary)',
letterSpacing: '0.08em',
textTransform: 'uppercase',
marginBottom: '0.25rem',
...style,
}}
{...props}
/>
)
)
AlertTitle.displayName = 'AlertTitle'
/* ── AlertDescription ── */
const AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
({ className, style, ...props }, ref) => (
<p
ref={ref}
className={cn(className)}
style={{
fontSize: '0.8rem',
color: 'var(--text-muted)',
lineHeight: 1.6,
...style,
}}
{...props}
/>
)
)
AlertDescription.displayName = 'AlertDescription'
export { Alert, AlertTitle, AlertDescription, alertVariants }