Sakuga Back to Sakuga
Theme
Sound
Jump to a component

AniCanonKit · Manga

PageWall

PageWall is Proof: every page of the issue at once, in spreads, each with its caption and how far it has come.

@anicanon/sakuga/anicanonkitv1.0Used onWebFrom AniCanon™

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Web only

PageWall is made for the web, and isn’t part of Sakuga for iOS yet.

Android

Web only

PageWall is made for the web, and isn’t part of Sakuga for Android yet.

Use it for
The Proof view: every page of the issue at once in spreads, each with its caption and how far it has come (Laid out, Drawn, Lettered, Proofed).
Not for

Guidelines

  • spreads as for IssueStrip; each page adds title, meta (its stage in words) and stage, the number of steps it has passed (Laid out, Drawn, Lettered, Proofed).
  • columns spreads to a row (3 on desktop); a page-turn rule sits between spreads in a row.
  • Choosing a page opens it beside the wall; the wall itself never edits.
PageWallExample.jsxReact
import { PageWall } from '@anicanon/sakuga/anicanonkit';

const spreads = [
  [
    {
      image: '/art/bad-memories-the-winter-p00.webp',
      label: 'Front cover',
      title: 'Cover',
      meta: 'Drawn',
      stage: 2,
    },
  ],
  [
    {
      image: '/art/bad-memories-the-winter-bruce.webp',
      label: 'Page 3',
      title: '3 · Bruce',
      meta: 'Lettered',
      stage: 3,
    },
    {
      image: '/art/bad-memories-the-winter-p04.webp',
      label: 'Page 4',
      title: '4 · First snow',
      meta: 'Proofed',
      stage: 4,
    },
  ],
  [
    {
      image: '/art/bad-memories-the-winter-alarm.webp',
      label: 'Page 5',
      title: '5 · Ten missed calls',
      meta: 'Lettered',
      stage: 3,
    },
    {
      frames: [
        { x: 4, y: 4, w: 92, h: 30 },
        { x: 4, y: 36, w: 44, h: 28, state: 'drawing' },
        { x: 52, y: 36, w: 44, h: 28 },
        { x: 4, y: 66, w: 92, h: 30 },
      ],
      label: 'Page 6, drawing',
      title: '6',
      meta: 'Drawing · 1 of 4',
      stage: 1,
    },
  ],
  [
    {
      frames: [
        { x: 4, y: 4, w: 56, h: 44 },
        { x: 62, y: 4, w: 34, h: 44 },
        { x: 4, y: 50, w: 92, h: 46 },
      ],
      label: 'Page 7, laid out',
      title: '7',
      meta: 'Laid out',
      stage: 1,
    },
    {
      frames: [
        { x: 4, y: 4, w: 92, h: 22 },
        { x: 4, y: 28, w: 44, h: 34 },
        { x: 52, y: 28, w: 44, h: 34 },
        { x: 4, y: 64, w: 30, h: 32 },
        { x: 36, y: 64, w: 60, h: 32 },
      ],
      label: 'Page 8, laid out',
      title: '8',
      meta: 'Laid out',
      stage: 1,
    },
  ],
  [
    {
      frames: [
        { x: 4, y: 4, w: 92, h: 58 },
        { x: 4, y: 64, w: 92, h: 32 },
      ],
      label: 'Page 9, laid out',
      title: '9',
      meta: 'Laid out',
      stage: 1,
    },
    {
      blank: true,
      label: 'Back cover, not made',
      title: 'Back',
      meta: 'Not made',
      stage: 0,
    },
  ],
];

export default function PageWallExample() {
  return <PageWall size={64} columns={3} spreads={spreads} />;
}

PropsPageWallProps

spreadsrequired
(MangaPageProps & { stage?: number; })[][]
size
number
columns
number
steps
string[]
Default: Laid out, Drawn, Lettered, Proofed.
label
string
className
string

Types

interface MangaPageProps {
    /** The area an edit redraws, in percent. Slot: slot="action" beside the caption. */
    mask?: Area;
    maskLabel?: string;
    width?: number;
    /** Height over width; defaults to the B5 trim. */
    ratio?: number;
    image?: string;
    frames?: MangaFrame[];
    numbers?: boolean;
    selected?: boolean;
    /** A page not made yet, e.g. the back cover. */
    blank?: boolean;
    /** One item selected on the page, with handles, in percent. */
    selection?: Area;
    selectionLabel?: string;
    label?: string;
    alt?: string;
    title?: string;
    meta?: string;
    /** The caption's alignment: the right page of a spread reads from its outer edge. */
    align?: 'end';
    children?: ReactNode;
    className?: string;
}
PageWallExample.swiftiOS · coming soon
PageWallExample.ktAndroid · coming soon

Each token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.

Colour

wall-stagePageWall: a stage not reached.
bg-fillshade-a12rgba(11,10,16,0.12)
bg-fillwhite-a14rgba(255,255,255,0.14)
wall-stage-onPageWall: a stage reached.
text-primaryneutral-925#0b0a10
text-primaryneutral-0#ffffff
wall-capPageWall: a page's caption title.
text-secondaryneutral-800#2e2d36
text-secondaryneutral-200#dcdcde
wall-cap-metaPageWall: a page's stage in words.
text-mutedneutral-600#5c5b67
text-mutedneutral-400#a3a3a7

Space and shape

wall-row-gap
gap-2xl
24px
wall-column-gap
gap-lg
12px
wall-cell-gap
gap-md
8px
wall-spread-gap
gap-2xs
2px
wall-page-gap
gap-sm
6px
wall-cap-gap
gap-2xs
2px
wall-stage-gap
gap-2xs
2px
wall-stage-margin-top
gap-xs
4px
wall-stage-i-height
its own value
4px
wall-stage-i-radius
radius-xs
4px
wall-istrip-turn-margin-top
gap-sm
6px
wall-istrip-turn-margin-bottom
gap-3xl
40px

Type

wall-cap-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
wall-cap-span-font-weight
weight-medium
500

Checked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.

Result
No issues found, in light or in dark.
By design
Not focusable; a list named by label (default "The whole issue") with a spread per item: each page is an image named by its label, alt or title, then its title, meta and stage (an image named by its step) read as text, with a "Page turn" separator between spreads.
Not tested
The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.