import React, { forwardRef } from 'react'; import { Tone, Surface, cn, toneMap, surfaceClasses, useEffectiveSurface, } from '../common'; /* ───────────────────────────────────────────────────────────────────────── PixelAlert — banner with tone + icon + action. Pixel surface adds a left accent stripe (RPG status-bar pattern). ───────────────────────────────────────────────────────────────────────── */ /** Public prop bag for {@link PixelAlert}. */ export interface PixelAlertProps { /** Short label shown in tone color (canonical name for the title). */ label?: string; /** * @deprecated Use `label` instead. Retained as alias for one minor. */ title?: string; /** Body message under the label. */ message: string; /** Tone determines border, fill, text colors. Defaults to `'red'`. */ tone?: Tone; /** Optional leading icon (rendered in tone color). */ icon?: React.ReactNode; /** Optional action node rendered under the message. */ action?: React.ReactNode; /** Surface override; falls back to nearest provider. */ surface?: Surface; /** Optional `aria-live` override. Status banners ("info") should usually use `"polite"`. */ live?: 'polite' | 'assertive' | 'off'; } export const PixelAlert = forwardRef(function PixelAlert( { label, title, message, tone = 'red', icon, action, surface: surfaceProp, live }, ref, ) { const resolvedLabel = label ?? title ?? ''; const surface = useEffectiveSurface(surfaceProp); const s = surfaceClasses(surface); // Critical tones get assertive announcements by default; neutral tones go polite. const ariaLive = live ?? (tone === 'red' || tone === 'gold' ? 'assertive' : 'polite'); return (
{surface === 'pixel' && ( )}
{icon && {icon}}

{resolvedLabel}

{message}

{action &&
{action}
}
); }); PixelAlert.displayName = 'PixelAlert';