PixelAlert

Inline status banner with title, message, tone, optional icon, and action — announces itself to screen readers via role="alert".

  • Seven tones (neutral, green, cyan, gold, red, purple, pink) with soft tint + matching border.
  • Surface-aware: pixel adds a left HP-bar accent stripe and chamfered border; linear stays rounded.
  • Smart aria-live default — red/gold use "assertive", everything else "polite". Overridable via live prop.
  • Optional icon and action slots for quick triage (e.g. Retry, Dismiss).
  • SSR-safe, no client state.
Status
stable
Category
feedback
Since
v1.0.0

API

import { PixelAlert } from '@pxlkit/ui-kit';
PropTypeDefaultDescription
labelstring—Short label shown in tone color (canonical name for the title).
titlestring—Deprecated. Use label instead. Retained as alias for one minor.
message (required)string—Body message under the label.
tone'green' | 'cyan' | 'gold' | 'red' | 'purple' | 'pink' | 'neutral''red'Tone determines border, fill, text colors. Defaults to 'red'.
iconReact.ReactNode—Optional leading icon (rendered in tone color).
actionReact.ReactNode—Optional action node rendered under the message.
surface'pixel' | 'linear'—Surface override; falls back to nearest provider.
live'polite' | 'assertive' | 'off'—Optional aria-live override. Status banners ("info") should usually use "polite".

ref points to <div>.

Accessibility

WCAG target: 2.1 AA

  • alert

Root carries role="alert" and a calculated aria-live (assertive for red/gold, polite otherwise). Icon slot is wrapped purely for layout — meaning must come from the title/message text, not the glyph. For non-urgent status (e.g. "saved"), pass live="polite" to prevent screen-reader interruption. Action buttons are exposed as siblings of the message and receive their own focus order.

Usage

import { PixelAlert } from '@pxlkit/ui-kit';

export function Default() {
  return (
    <PixelAlert
      title="Something went wrong"
      message="Your session expired. Please sign in again to continue."
    />
  );
}

Examples

Default

import { PixelAlert } from '@pxlkit/ui-kit';

export function Default() {
  return (
    <PixelAlert
      title="Something went wrong"
      message="Your session expired. Please sign in again to continue."
    />
  );
}

Tones

import { PixelAlert } from '@pxlkit/ui-kit';

export function Tones() {
  return (
    <div className="flex flex-col gap-3">
      <PixelAlert tone="neutral" title="Heads up" message="Neutral informational banner." />
      <PixelAlert tone="green" title="Saved" message="Your changes have been persisted." />
      <PixelAlert tone="cyan" title="New feature" message="Try the redesigned inbox." />
      <PixelAlert tone="gold" title="Warning" message="Storage is almost full." />
      <PixelAlert tone="red" title="Error" message="Failed to upload the file." />
      <PixelAlert tone="purple" title="Tip" message="Use ⌘K to jump anywhere." />
      <PixelAlert tone="pink" title="Highlight" message="You unlocked a new badge." />
    </div>
  );
}

Surfaces

import { PixelAlert } from '@pxlkit/ui-kit';

export function Surfaces() {
  return (
    <div className="flex flex-col gap-3">
      <PixelAlert
        surface="linear"
        tone="cyan"
        title="Linear surface"
        message="Soft border with rounded corners."
      />
      <PixelAlert
        surface="pixel"
        tone="cyan"
        title="Pixel surface"
        message="Chamfered border with a left accent stripe."
      />
    </div>
  );
}

With Icon

import { PixelAlert } from '@pxlkit/ui-kit';

const InfoIcon = () => (
  <span
    aria-hidden
    style={{
      width: 14,
      height: 14,
      borderRadius: 9999,
      background: 'currentColor',
      display: 'inline-block',
    }}
  />
);

export function WithIcon() {
  return (
    <PixelAlert
      tone="cyan"
      title="Pro tip"
      message="You can drag-and-drop files anywhere on the page."
      icon={<InfoIcon />}
    />
  );
}

With Action

import { PixelAlert, PixelButton } from '@pxlkit/ui-kit';

const InfoIcon = () => (
  <span
    aria-hidden
    style={{
      width: 14,
      height: 14,
      borderRadius: 9999,
      background: 'currentColor',
      display: 'inline-block',
    }}
  />
);

export function WithAction() {
  return (
    <PixelAlert
      tone="red"
      title="Connection lost"
      message="We couldn't reach the server. Check your network and retry."
      icon={<InfoIcon />}
      action={
        <PixelButton size="sm" tone="red" variant="outline">
          Retry
        </PixelButton>
      }
    />
  );
}

Polite Live Region

import { PixelAlert } from '@pxlkit/ui-kit';

export function PoliteLive() {
  return (
    <PixelAlert
      tone="green"
      live="polite"
      title="Auto-saved"
      message="Drafts are saved every few seconds."
    />
  );
}

Related