PixelHeroMedia

Aspect-ratio-preserving figure slot for hero media with optional frame, tone border, and caption.

  • Four ratio presets (1/1, 4/5, 16/10, 16/9) reserve layout to prevent CLS
  • Optional framed border driven by surface + tone tokens
  • Renders as semantic figure/figcaption when caption is provided
  • Surface-aware (pixel / linear) frame and corners
Status
stable
Category
hero
Since
v1.7.0

API

import { PixelHeroMedia } from '@pxlkit/ui-kit';
PropTypeDefaultDescription
ratio'1/1' | '4/5' | '16/10' | '16/9''16/10'Aspect ratio of the figure.
anchor'center' | 'baseline-headline''center'Centred across its row, or on the row's end beside a headline.
framedbooleanfalseDraw the surface border and radius in the tone's border colour.
tone'neutral' | 'green' | 'cyan' | 'gold' | 'red' | 'purple' | 'pink''neutral'Tone of the frame.
captionstring—Caption under the media, in a <figcaption>.
captionClassNamestring—Optional className applied to the inner caption (figcaption).
surface'pixel' | 'linear'—Surface override; defaults to the nearest provider.
children (required)React.ReactNode—The media.

Also takes the native attributes and event handlers of its element (HTMLAttributes<HTMLElement>).

ref points to its element (HTMLElement).

Accessibility

WCAG target: 2.1 AA

  • figure/figcaption when caption present
  • aspect-ratio reserves layout to avoid CLS

Caption is rendered inside a <figcaption> when provided; otherwise the media stands alone inside <figure>.

Usage

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

const Placeholder = ({ label }: { label: string }) => (
  <div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-cyan-500/20 to-purple-500/20 text-xs font-mono text-retro-muted">
    {label}
  </div>
);

export function Default() {
  return (
    <PixelHeroMedia ratio="16/10">
      <Placeholder label="16:10 media" />
    </PixelHeroMedia>
  );
}

Examples

Default

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

const Placeholder = ({ label }: { label: string }) => (
  <div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-cyan-500/20 to-purple-500/20 text-xs font-mono text-retro-muted">
    {label}
  </div>
);

export function Default() {
  return (
    <PixelHeroMedia ratio="16/10">
      <Placeholder label="16:10 media" />
    </PixelHeroMedia>
  );
}

Framed with caption

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

const Placeholder = ({ label }: { label: string }) => (
  <div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-cyan-500/20 to-purple-500/20 text-xs font-mono text-retro-muted">
    {label}
  </div>
);

export function Framed() {
  return (
    <PixelHeroMedia ratio="16/9" framed tone="cyan" caption="Framed hero with caption">
      <Placeholder label="16:9 framed" />
    </PixelHeroMedia>
  );
}

Square (1:1)

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

const Placeholder = ({ label }: { label: string }) => (
  <div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-cyan-500/20 to-purple-500/20 text-xs font-mono text-retro-muted">
    {label}
  </div>
);

export function Square() {
  return (
    <PixelHeroMedia ratio="1/1" framed tone="purple">
      <Placeholder label="1:1 square" />
    </PixelHeroMedia>
  );
}