Sakuga Back to Sakuga
Theme
Sound
Jump to a component

AniCanonKit · Manga

MangaPage

MangaPage draws one page of an issue at its trim (1448 × 2048): its art once drawn, or its layout's frames before.

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

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Web only

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

Android

Web only

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

Use it for
One page of an issue at its trim: its art once drawn, its layout's frames before, or blank when it is not made yet, with a selection only on the editor's canvas.
Not for

Guidelines

  • Pass image for a drawn page, frames (in percent of the page) for one only laid out. A frame drawing or waiting says so inside it; numbers prints each frame's number (4.2).
  • selected rings the page; selection puts one item (a panel, a balloon) under handles, in percent. Only the editor's canvas shows a selection.
  • title and meta caption it under the page; on a spread the right page's caption takes align="end".
  • blank is a page not made yet, such as the back cover. Never fake art for a page that is not drawn.
  • mask (percent) marks the area an edit redraws, on a page or a single panel's picture (ratio to its shape); maskLabel names it.
  • In slot="action" a caption takes its menu button (Rename, Move, Delete).
MangaPageExample.jsxReact
import { MangaPage } from '@anicanon/sakuga/anicanonkit';

export default function MangaPageExample() {
  return (
    <>
      <MangaPage
        {...Object.assign(
          { width: 120, title: '3 · Bruce', meta: 'Lettered', selected: true },
          { image: '/art/bad-memories-the-winter-bruce.webp', label: 'Page 3' },
        )}
      />
      <MangaPage
        {...Object.assign(
          {
            width: 120,
            title: '4 · First snow',
            meta: 'Drawn',
            selection: { x: 4, y: 36, w: 44, h: 28 },
            selectionLabel: 'Panel 4.2 selected',
          },
          { image: '/art/bad-memories-the-winter-p04.webp', label: 'Page 4' },
        )}
      />
      <MangaPage
        width={120}
        title="6"
        meta="Drawing · 1 of 4"
        numbers
        frames={[
          { x: 4, y: 4, w: 92, h: 30, number: '6.1' },
          { x: 4, y: 36, w: 44, h: 28, number: '6.2', state: 'drawing' },
          { x: 52, y: 36, w: 44, h: 28, number: '6.3' },
          { x: 4, y: 66, w: 92, h: 30, number: '6.4' },
        ]}
        label="Page 6, drawing"
      />
    </>
  );
}

PropsMangaPageProps

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

Types

type Area = {
    x: number;
    y: number;
    w: number;
    h: number;
};
interface MangaFrame extends Area {
    /** "4.2"; shown with `numbers`. */
    number?: string;
    state?: 'laid-out' | 'drawing' | 'waiting';
    /** Replaces "Drawing…" or "Waiting". */
    label?: string;
}
MangaPageExample.swiftiOS · coming soon
MangaPageExample.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

mpage-paperMangaPage: a page before it is drawn.
bg-surfaceneutral-0#ffffff
bg-surfaceneutral-900#111117
mpage-blankMangaPage: a page not made yet, such as the back cover.
bg-fill-subtleshade-a06rgba(11,10,16,0.06)
bg-fill-subtlewhite-a08rgba(255,255,255,0.08)
mpage-edgeMangaPage: the page's edge.
border-hairlineshade-a08rgba(11,10,16,0.08)
border-hairlinewhite-a06rgba(255,255,255,0.06)
mpage-frameMangaPage: a frame of the layout.
border-controlshade-a52rgba(11,10,16,0.52)
border-controlwhite-a45rgba(255,255,255,0.45)
mpage-busyMangaPage: a frame being drawn or waiting.
bg-fill-subtleshade-a06rgba(11,10,16,0.06)
bg-fill-subtlewhite-a08rgba(255,255,255,0.08)
mpage-textMangaPage: a frame's number and state.
text-secondaryneutral-800#2e2d36
text-secondaryneutral-200#dcdcde
mpage-selectedMangaPage: the selected page, spread or region.
accentcamellia-600#c2335f
accentcamellia-400#f4779f
mpage-handleMangaPage: a selection handle.
text-on-medianeutral-0#ffffff
text-on-medianeutral-0#ffffff
mpage-dimMangaPage: the page outside the selected region.
bg-medianeutral-950#07070a
bg-medianeutral-950#07070a
mpage-capMangaPage: the caption's title.
text-secondaryneutral-800#2e2d36
text-secondaryneutral-200#dcdcde
mpage-cap-metaMangaPage: the caption's quiet line.
text-mutedneutral-600#5c5b67
text-mutedneutral-400#a3a3a7
mpage-maskMangaPage: the area an edit redraws.
accentcamellia-600#c2335f
accentcamellia-400#f4779f

Space and shape

mpage-inset-ring-width
line-hairline
1px
mpage-selected-ring-width
line-strong
2px
mpage-frame-border-width
line-hairline
1px
mpage-frame-radius
radius-xs
4px
mpage-frame-b-left
inset-xs
4px
mpage-frame-b-top
inset-2xs
2px
mpage-frame-small-margin-top
its own value
calc(2px + 16px)
mpage-sel-outline-width
line-strong
2px
mpage-h-size
its own value
8px
mpage-h-radius
radius-xs
4px
mpage-h-ring-width
line-strong
2px
mpage-fig-gap
gap-md
8px
mpage-cap-gap
gap-sm
6px
mpage-captext-gap
gap-2xs
2px
Aa
mpage-mask-ring-width
line-strong
2px
mpage-forced-selected-width
line-strong
2px
mpage-forced-edge-width
line-hairline
1px
mpage-forced-mask-width
line-strong
2px

Type

mpage-frame-b-font
text-micro
700 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
mpage-frame-small-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
mpage-frame-b-line-height
text-micro-line-height
16px
mpage-cap-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
mpage-captext-span-font-weight
weight-medium
500

Motion

mpage-img-develop-animation
motion-develop
sk-develop 560ms cubic-bezier(0, 0, 0, 1)
mpage-sel-sel-in-animation
motion-select
sk-sel-in 100ms cubic-bezier(0, 0, 0, 1)

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; read as one image named by label, alt or title (else "Page"), followed by "selected", how many frames are drawing or waiting, the area to redraw (maskLabel) and the item selected (selectionLabel), and with title or meta it sits in a figure captioned by them, where the action slot takes focus.
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.