Stickers Documentation has not yet been reviewed by a human.
Square illustrated stickers in two flavors per name — a lightweight
static SVG and a Lottie-driven animated version. Stickers ship in their
own package, @antadesign/stickers (a companion to @antadesign/anta,
kept separate so apps that don’t use stickers never install
lottie-web). Each one is its own named export, so the consumer’s
bundler ships only the stickers actually used. The static variant is
the default; reach for the animated one explicitly when you want
motion.
npm install @antadesign/stickers # pulls @antadesign/anta + lottie-webBoth flavors are JSX wrappers over two custom elements,
<a-sticker>and<a-sticker-animated>, registered by@antadesign/stickers/elements. Plain HTML/JS consumers can drive the elements directly viasetAttributeinstead of using the JSX wrappers — see Non-React consumers below.
The full set is also published as a Telegram sticker pack.
Props
Both flavors share the same base props; the animated flavor adds playback props.
Sticker{Name} (static)
| Prop | Type | Description |
|---|---|---|
size? |
number |
Edge length in pixels. Stickers are always square. Defaults to 256. |
label? |
string |
Accessible name. When set, the sticker is exposed as role="img" + aria-label. Omitted ⇒ aria-hidden="true" (decorative). |
Inherited props (className, style).
Sticker{Name}Animated (Lottie)
Same as the static base, plus:
| Prop | Type | Description |
|---|---|---|
paused? |
boolean | number |
true freezes at the current frame; a number freezes at that time in seconds. Omit (or pass false) to play. |
delay? |
number |
Seconds to wait at the first frame before playing. |
playOnce? |
boolean |
Plays once and holds the final frame instead of looping. |
replayOnClick? |
boolean |
With playOnce, lets people click or press Enter/Space to replay the animation. The sticker becomes a labeled button. |
Web Component
Use the web component directly when you are not using React or Preact and a native control does not fit.
Pass the generated SVG payload to <a-sticker> and set a size through
--sticker-size. The animated element takes its generated Lottie JSON through
animation instead.
<a-sticker role="img" aria-label="Purple circle" svg='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><circle cx="8" cy="8" r="7" fill="currentColor"/></svg>' style="--sticker-size: 96px; color: var(--text-1-brand)"></a-sticker>Sizing
Pass size (a number, in pixels) to control width and height together.
Default is 256. Stickers are always square.
<StickerVacation /> // 256×256<StickerVacation size={128} /> // 128×128<StickerVacationAnimated size={64} /> // 64×64size sets the --sticker-size CSS custom property inline on the rendered
<a-sticker> or <a-sticker-animated>. External CSS reads it to size the host
and the square ::part(container) artwork box. You can also set the property
on the host through your own stylesheet:
.sticker-grid :is(a-sticker, a-sticker-animated) { --sticker-size: 96px; }Both element entries load external CSS. Preserve those imports in your bundler and load the resulting stylesheet before displaying stickers. Without that stylesheet, static SVGs use their intrinsic dimensions.
Animation control
paused, delay, playOnce, and replayOnClick only apply to
Sticker{Name}Animated.
They map to observed element attributes. Playback settings apply after the
player is ready, including asynchronous Lottie worker initialization. A numeric
paused={0} seeks to the first frame; boolean paused holds the current frame.
<StickerCodingAnimated /> // autoplay, looping<StickerCodingAnimated paused /> // freeze at the current frame<StickerCodingAnimated paused={1.5} /> // freeze at 1.5 seconds<StickerCodingAnimated paused={false} /> // explicitly play (same as omitted)<StickerCodingAnimated delay={0.5} /> // wait half a second, then play<StickerCodingAnimated playOnce /> // play once, then hold the final frame<StickerCodingAnimated playOnce replayOnClick label="Replay coding sticker" />Adding your own stickers
@antadesign/stickers ships a generator script at
@antadesign/stickers/generate-stickers.mjs. Drop your sources in a
folder structured the same way as the built-in set — one subfolder per
sticker, with a <name>.json (Lottie) and/or <name>.svg (static
pose):
my-stickers/ happy/ happy.json happy.svg sad/ sad.jsonThen point the generator at it:
node ./node_modules/@antadesign/stickers/dist/generate-stickers.mjs \ --input ./my-stickers \ --output ./src/my-generated-stickersThe emitted modules import their Sticker / StickerAnimated runtime
wrappers from @antadesign/stickers by default; pass --package <name>
to point them at a different specifier (e.g. your own re-export).
Out comes one <name>.ts per static sticker and one <name>-animated.ts
per animated sticker, plus an index.ts barrel. Import and use:
import { StickerHappy, StickerSadAnimated } from './my-generated-stickers'
<StickerHappy size={96} /><StickerSadAnimated paused={1.5} />Source conventions
- Animated stickers are
<name>.jsonLottie payloads. - Either file is optional — supply just the SVG for a static-only sticker, just the JSON for an animated-only one, or both.
Conflicting names
If a generated sticker has the same name as one of the pack’s built-ins
(e.g. vacation), the generator prints a warning. The built-in sticker
imported from @antadesign/stickers is unaffected — your generated
barrel exposes yours under your own import path.
Non-React consumers
The custom elements <a-sticker> and <a-sticker-animated> are
framework-agnostic. Each generated module exports the raw payload
(svg string for static, animationJson string for animated)
alongside the JSX component, so non-React consumers can pull just the
data and drive the elements directly:
import { svg } from '@antadesign/stickers/vacation'import { animationJson } from '@antadesign/stickers/vacation-animated'
const still = document.createElement('a-sticker')still.setAttribute('svg', svg)still.style.setProperty('--sticker-size', '128px')document.body.appendChild(still)
const movie = document.createElement('a-sticker-animated')movie.setAttribute('animation', animationJson)document.body.appendChild(movie)The static element renders the SVG into its own shadow DOM; the
animated element drives a shadow-DOM <svg> via lottie-web. Both
consume their payload through the svg / animation HTML attribute —
the JSX wrapper passes the same data, just through React/Preact’s
prop layer.
SSR
@antadesign/stickers/elements references browser APIs (HTMLElement,
customElements, lottie-web). In SSR contexts (Astro, Next.js) gate
the import behind a client boundary — same rule as anta’s own elements.
The sticker components themselves render fine on the server (just JSX);
only the underlying custom-element classes need the browser.
Strict Content Security Policy
The element entries load external CSS and inject no shadow stylesheets. With
style-src 'self'; style-src-attr 'none', omit size and set --sticker-size
on each host through a same-origin stylesheet:
<StickerCoding className="coding-sticker" label="Writing code" />.coding-sticker { --sticker-size: 128px; }The size prop still emits an inline style. The browser blocks that style in
server-rendered HTML under this policy, leaving the default size. Client-side
CSSOM updates may work, but hydration does not reliably repair blocked server
styles. External CSS gives consistent sizing before and after hydration.
Bundled static artwork uses SVG presentation attributes without inline styles.
Lottie 5.13.0 writes SVG styles through CSSOM and updates presentation attributes;
these writes work under the tested policy, including playback and seeking.
The resulting SVG can contain style attributes even though CSP permits the
CSSOM writes. If you enable Lottie’s web worker, allow its blob worker through
worker-src blob:; style directives can stay strict. Review custom SVGs and
Lottie data separately, including fonts, images, and expressions.
Styling
Set --sticker-size on the host to size the square artwork. Each host declares
its own default, so an ancestor’s value does not replace it. Host width and
height change the surrounding box while the artwork keeps its configured
size and stays centered.
Both elements expose container for the artwork box and artwork for the root
SVG. The SVG’s internal paths remain isolated from document selectors. Apply
rotation and other whole-sticker transforms to container so Lottie can retain ownership
of the animated root SVG’s dimensions and transform.
.coding-sticker { --sticker-size: 96px; width: 160px; height: 120px;}
.coding-sticker::part(container) { transform: rotate(-5deg);}The className is application-owned. Import an element entry to load its CSS,
or import @antadesign/stickers/elements/a-sticker.css and
@antadesign/stickers/elements/a-sticker-animated.css separately when your
application manages linked stylesheets.