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.
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
- The issue's pages as the reader turns themIssueStrip
- Every page with its stage at oncePageWall
- An issue on a shelfMediaCard
Guidelines
- Pass
imagefor a drawn page,frames(in percent of the page) for one only laid out. A framedrawingorwaitingsays so inside it;numbersprints each frame's number (4.2). selectedrings the page;selectionputs one item (a panel, a balloon) under handles, in percent. Only the editor's canvas shows a selection.titleandmetacaption it under the page; on a spread the right page's caption takesalign="end".blankis 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 (ratioto its shape);maskLabelnames it.- In
slot="action"a caption takes its menu button (Rename, Move, Delete).
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
maskAreaThe area an edit redraws, in percent. Slot: slot="action" beside the caption.
maskLabelstringwidthnumberrationumberHeight over width; defaults to the B5 trim.
imagestringframesMangaFrame[]numbersbooleanselectedbooleanblankbooleanA page not made yet, e.g. the back cover.
selectionAreaOne item selected on the page, with handles, in percent.
selectionLabelstringlabelstringaltstringtitlestringmetastringalign'end'The caption's alignment: the right page of a spread reads from its outer edge.
childrenReactNodeclassNamestringTypes
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; }
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#ffffffbg-surfaceneutral-900#111117mpage-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#2e2d36text-secondaryneutral-200#dcdcdempage-selectedMangaPage: the selected page, spread or region.accentcamellia-600#c2335faccentcamellia-400#f4779fmpage-handleMangaPage: a selection handle.text-on-medianeutral-0#fffffftext-on-medianeutral-0#ffffffmpage-dimMangaPage: the page outside the selected region.bg-medianeutral-950#07070abg-medianeutral-950#07070ampage-capMangaPage: the caption's title.text-secondaryneutral-800#2e2d36text-secondaryneutral-200#dcdcdempage-cap-metaMangaPage: the caption's quiet line.text-mutedneutral-600#5c5b67text-mutedneutral-400#a3a3a7mpage-maskMangaPage: the area an edit redraws.accentcamellia-600#c2335faccentcamellia-400#f4779fSpace and shape
mpage-inset-ring-widthline-hairline1px
mpage-selected-ring-widthline-strong2px
mpage-frame-border-widthline-hairline1px
mpage-frame-radiusradius-xs4px
mpage-frame-b-leftinset-xs4px
mpage-frame-b-topinset-2xs2px
mpage-frame-small-margin-topits own value
calc(2px + 16px)
mpage-sel-outline-widthline-strong2px
mpage-h-sizeits own value
8px
mpage-h-radiusradius-xs4px
mpage-h-ring-widthline-strong2px
mpage-fig-gapgap-md8px
mpage-cap-gapgap-sm6px
mpage-captext-gapgap-2xs2px
Aa
mpage-mask-ring-widthline-strong2px
mpage-forced-selected-widthline-strong2px
mpage-forced-edge-widthline-hairline1px
mpage-forced-mask-widthline-strong2px
Type
mpage-frame-b-fonttext-micro700 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
mpage-frame-small-fonttext-small-strong600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
mpage-frame-b-line-heighttext-micro-line-height16px
mpage-cap-fonttext-small-strong600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
mpage-captext-span-font-weightweight-medium500
Motion
mpage-img-develop-animationmotion-developsk-develop 560ms cubic-bezier(0, 0, 0, 1)
mpage-sel-sel-in-animationmotion-selectsk-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,altortitle(else "Page"), followed by "selected", how many frames are drawing or waiting, the area to redraw (maskLabel) and the item selected (selectionLabel), and withtitleormetait sits in a figure captioned by them, where theactionslot 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.