Logo Spinner
The animated Plane mark, shown while a whole screen is waiting on app boot or a page transition.
Show codeHide code
Installation
import { LogoSpinner } from "@makeplane/propel/components/logo-spinner";Usage
The animated Plane mark, for the moments a whole screen is waiting — app boot, a splash screen, a
full-page route transition. For pending state inside a control or a section, use CircularProgress
(or a control’s own loading state) instead: this is brand furniture, not a status glyph.
Both themes’ artwork is rendered and CSS shows the one matching the active data-theme, so a theme
flip costs no JS and no second request (both files load with the page — 88KB together). Under
prefers-reduced-motion: reduce the same CSS paints a still of the fully drawn mark instead of the
animation, since a GIF cannot be paused. alt is required — name what the app is waiting on; only
the visible image is in the accessibility tree, so it is announced once.
import { LogoSpinner } from "@makeplane/propel/components/logo-spinner";
export default function BasicDemo() {
return <LogoSpinner size="md" alt="Loading Plane" />;
}Examples
Sizes
Mark height: sm 24px inline, md 44px full page. The width follows the artwork’s aspect ratio.
Show codeHide code
Responsive
size="fluid" is the third step and the one a splash screen wants: 24px on a phone, 44px from the
640px breakpoint up. It is the same recipe the apps’ own splash CSS used. Above that breakpoint it
is by definition indistinguishable from md — narrow the window past 640px to see it step down.
Show codeHide code
Assets
This is the only propel component that ships binary assets: the mark is designed frame-by-frame artwork (65 frames per theme), not something tokens and CSS can express. The GIFs ship inside the package next to the component, each with a PNG still of the fully drawn mark for reduced motion, and all four are pulled in as static asset imports, so your bundler turns them into URLs at build time — Vite, webpack 5+, Parcel, or Rollup with an asset plugin.
If you render on the server (SSR, or a prerendered SPA shell), tell your bundler not to externalize
propel, or the asset import reaches Node — which cannot load a .gif — and the render fails:
// vite.config.ts
export default defineConfig({
ssr: { noExternal: ["@makeplane/propel"] },
});The files are also exported raw
(@makeplane/propel/components/logo-spinner/logo-spinner-light.gif,
…/logo-spinner-light-still.png), so an app’s own pre-hydration splash CSS can point at the same
artwork instead of keeping a copy.
They are exported at 158×88 / 159×88, twice the largest size they are ever displayed at (44px tall), so they stay crisp on 2x screens while weighing 39KB and 48KB; the stills are under 1KB each.
API Reference
LogoSpinner
The animated Plane mark, for the moments a whole screen is waiting — app boot, a splash screen, a
full-page route transition. For pending state inside a control or a section, use
CircularProgress (or a control's own loading state) instead: this is brand furniture, not a
status glyph.
Both themes' artwork is rendered and CSS shows the one matching the active data-theme, so a
theme flip costs no JS and no second request. Under prefers-reduced-motion: reduce the same CSS
paints a still of the fully drawn mark instead of the animation. Only the visible image is in the
accessibility tree (the other three are display: none), so alt is announced once.



