Pixel Loader <mv-pixel-loader>

Indicateurs de réflexion en matrice de points sur une minuscule grille de pixels (3×3 à 9×9) en currentColor : serpent, orbite, ondulation concentrique, balayage, spirale, respiration, scintillement ou vague diagonale, avec un libellé facultatif traversé par une bande plus claire.

Fonctionnement

Indicateurs de réflexion en matrice de points sur une minuscule grille de pixels (3×3 à 9×9) en currentColor : serpent, orbite, ondulation concentrique, balayage, spirale, respiration, scintillement ou vague diagonale, avec un libellé facultatif traversé par une bande plus claire. Le script ne fait que construire la grille ; chaque mouvement est une keyframe CSS.

CatégorieFeedback
TypeWeb Component (<mv-pixel-loader>)
Statutstable
Keywordsloader, spinner, pixel, dot-matrix, grid, ai, thinking, status, shimmer, css

When to use

  • An AI feature needs a distinctive thinking indicator with a shimmering label like Thinking
  • A loading state should feel techy and branded, with pattern choices such as snake, ripple or scan
  • A lightweight CSS-only status indicator is needed inside a chat bubble or toolbar

Avoid when

  • A neutral, conventional loader fits the product better, such as in a button or form → use Spinner instead
  • A voice assistant needs a presence that reacts to audio and conversation states → use Thinking Orb instead
  • The loading content has a predictable layout that could be previewed → use Skeleton instead

Installation

node scripts/add.mjs pixel-loader --out ./src/marvelous

Agent IA avec le serveur MCP de Marvelous UI : install_components({ slugs: ["pixel-loader"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Fichiers copiés (dépendances comprises) : tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/i18n.js, components/pixel-loader/pixel-loader.js, components/pixel-loader/pixel-loader.css.

Utilisation

Balisage de référence : partez de celui-ci et personnalisez-le avec les attributs, data-* et les variables CSS :

<div id="mv-pxl-demo">
  <style>
    #mv-pxl-demo { display: grid; gap: 1.5rem; width: 100%; max-width: 44rem; }
    #mv-pxl-demo .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: .75rem; margin: 0; padding: 0; list-style: none; }
    #mv-pxl-demo .grid li { display: grid; justify-items: center; gap: .875rem; padding: 1.25rem .75rem 1rem; border: 1px solid var(--mv-border); border-radius: var(--mv-radius-lg); background: var(--mv-surface); }
    #mv-pxl-demo .grid code { font: 500 .75rem var(--mv-font-mono); color: var(--mv-fg-muted); }
    #mv-pxl-demo .chat { display: grid; gap: .875rem; padding: 1rem 1.125rem; border: 1px solid var(--mv-border); border-radius: var(--mv-radius-xl); background: var(--mv-bg-subtle); font-size: .875rem; }
    #mv-pxl-demo .ask { justify-self: end; max-width: 80%; padding: .625rem .875rem; border-radius: var(--mv-radius-lg) var(--mv-radius-lg) var(--mv-radius-xs) var(--mv-radius-lg); background: var(--mv-accent); color: var(--mv-fg-on-accent); }
    #mv-pxl-demo .steps { display: flex; flex-wrap: wrap; gap: 1.25rem 1.75rem; padding-top: .75rem; border-top: 1px solid var(--mv-border); }
  </style>

  <ul class="grid" aria-label="Pixel loader variants">
    <li><mv-pixel-loader variant="snake" size="7" data-size="lg"></mv-pixel-loader><code>snake</code></li>
    <li><mv-pixel-loader variant="orbit" size="7" data-size="lg"></mv-pixel-loader><code>orbit</code></li>
    <li><mv-pixel-loader variant="ripple" size="7" data-size="lg"></mv-pixel-loader><code>ripple</code></li>
    <li><mv-pixel-loader variant="scan" size="7" data-size="lg"></mv-pixel-loader><code>scan</code></li>
    <li><mv-pixel-loader variant="spiral" size="7" data-size="lg"></mv-pixel-loader><code>spiral</code></li>
    <li><mv-pixel-loader variant="breathing" size="7" data-size="lg"></mv-pixel-loader><code>breathing</code></li>
    <li><mv-pixel-loader variant="sparkle" size="7" data-size="lg"></mv-pixel-loader><code>sparkle</code></li>
    <li><mv-pixel-loader variant="wave" size="7" data-size="lg"></mv-pixel-loader><code>wave</code></li>
  </ul>

  <div class="chat">
    <div class="ask">Which flights from Toronto to Lisbon land before noon on October 12?</div>
    <mv-pixel-loader variant="orbit" label="Thinking…" style="--mv-pixel-loader-color: var(--mv-accent)"></mv-pixel-loader>
    <div class="steps">
      <mv-pixel-loader variant="scan" label="Comparing 42 fares"></mv-pixel-loader>
      <mv-pixel-loader variant="wave" label="Checking layovers"></mv-pixel-loader>
      <mv-pixel-loader variant="sparkle" data-size="sm" label="Drafting the answer"></mv-pixel-loader>
    </div>
  </div>
</div>

API

Attributes

NameTypePar défautDescription
variantsnake | orbit | ripple | scan | spiral | breathing | sparkle | wavesnakeAnimated pattern.
sizenumber5Grid side, from 3 to 9 cells.
labelstringVisible label crossed by a brighter band ("Thinking…"). Without a label, strings.loading ("Loading…") is still read by screen readers.
speednumber1Speed multiplier.
data-sizesm | lg | xlPixel size (3, 6 or 10 px; 4 px by default).

Properties

NameTypeDescription
stringsPartial<{ loading: string }>Overrides for the default text: loading ("Loading…"), read when no label is set. English defaults.

CSS classes

NameDescription
mv-pixel-loader-grid / -cell / -labelGenerated parts; each cell carries its moment in the cycle in --_t (idle cells have data-idle).

CSS variables

NamePar défautDescription
--mv-pixel-loader-colorvar(--mv-fg)Pixel color (otherwise currentColor via color).
--mv-pixel-loader-cell4pxSize of one pixel; the gap follows it unless set.
--mv-pixel-loader-gap0.375 × cellSpace between pixels.
--mv-pixel-loader-off0.14Opacity of an unlit pixel.
--mv-pixel-loader-radius1pxPixel corner radius (50% for round dots).
--mv-pixel-loader-label-color / -shineLabel color and the color of its moving band.

Accessibility

role="status" (polite live region) with a text label, visible or visually hidden; the grid is aria-hidden. Reduced motion (OS setting or data-motion="reduce"): the keyframes stop and the grid shows a still frame of its pattern, and the label band stops. Forced colors: pixels in CanvasText, plain label text.