Graphics gallery
GraphicsGallery is the section under the video where a viewer collects their pictures. Each graphic is a tile on the palette's own background with a download button. A graphic the scan has not found yet is a locked tile, so there is always one more to get.
4 graphics to keep.
Post them, pin them, put them in your README. 2 more unlock as the scan finds them.
Share card
The year on one card, sized for a post.
Long Haul
Contributions per week. The lit stretch is your streak: not one day missed.
Second Wind
This year against last. The ring is where last year ended, the dot is where this one did.
Clean Sheet
June, every day of it. Not one of them empty.
Still hidden
Scan your year to unlock it.
Still hidden
Scan your year to unlock it.
The share card, three insight cards and two that are still locked.
Installation
pnpm add @react-wrapped/graphics @react-wrapped/core gsapimport "@react-wrapped/core/styles.css";
import "@react-wrapped/graphics/styles.css";Usage
Describe each graphic as a WrappedGraphic and pass the list with the palette. A graphic can be an image that already has an address, or a function that draws it. Memoize the list: a tile draws its image again whenever its image function changes.
import { useMemo } from "react";
import { resolvePalette, type WrappedConfig } from "@react-wrapped/core";
import {
GraphicsGallery,
type InsightCardSpec,
renderInsightCard,
renderShareCard,
type ShareCardSpec,
type WrappedGraphic,
} from "@react-wrapped/graphics";
/** An insight card with a name for its file, and whether the scan still has to find it. */
type Insight = InsightCardSpec & { id: string; locked?: boolean };
export function ThingsToKeep({
card,
insights,
config,
}: {
card: ShareCardSpec;
insights: readonly Insight[];
config: WrappedConfig;
}) {
const { palette: id, accent, mode } = config;
const palette = useMemo(() => resolvePalette({ palette: id, accent, mode }), [id, accent, mode]);
// Each graphic says how to draw itself. Nothing is drawn until its tile is about to scroll into view.
const graphics = useMemo(
(): WrappedGraphic[] => [
{
id: "share-card",
title: "Share card",
line: "The year on one card, sized for a post.",
image: () => renderShareCard(card, palette),
fileName: `${card.handle}-wrapped`,
wide: true,
},
...insights.map((insight) => ({
id: insight.id,
title: insight.name,
line: insight.insight,
image: () => renderInsightCard(insight, palette),
fileName: `${card.handle}-${insight.id}`,
wide: true,
locked: insight.locked,
})),
],
[card, insights, palette],
);
return <GraphicsGallery graphics={graphics} palette={palette} />;
}Props
| Prop | Type | What it does |
|---|---|---|
graphics | readonly WrappedGraphic[] | The tiles. Unlocked ones are shown first, whatever order you pass. |
palette | WrappedPalette | The video's palette: resolvePalette(config). Each tile sits on its background. |
className? | string | A class for the gallery's root. |
classNames? | SlotClassNames<GraphicsGallerySlot> | A class per part, by slot name: "gallery-tile", "gallery-download". See styling. |
A graphic
| Key | Type | What it is |
|---|---|---|
id | string | Stable and unique in the gallery. |
title | string | The tile's heading. |
line | string | One line under it. |
image | string | (() => Promise<Blob>) | Where the picture comes from: the address of an image, or a function that draws it when the tile is about to be seen. |
fileName | string | The name of the saved file, without an extension. The gallery saves a PNG. |
markdown? | string | A snippet that embeds the image. With one, the tile gets a second button that copies it. |
locked? | boolean | Not found yet. The tile is shown closed, with nothing to download. |
wide? | boolean | Wide artwork, such as a card. The tile takes two columns. |
Locked tiles
Set locked on a graphic that belongs to a drop the scan has not found. The tile shows a lock and "Still hidden", the heading counts only what can be taken, and the line under it says how many more are waiting. When the scan finds the drop, pass the graphic again without locked and its tile draws itself.
Drawing and downloading
- A tile draws its image when it is about to scroll into view, not when the page loads. A gallery of ten cards three screens down costs nothing until someone gets there.
- Download saves a PNG named
fileName. An image given by address is fetched and redrawn at twice its size first, so an SVG badge becomes a PNG people can post. - With
markdownset, a second button copies that snippet. Use it for images you host, such as a badge for a README that should stay live. - A graphic with
widetakes two columns. The grid is one column on a phone, two on a tablet and four on a wide screen.
