Notepad
binding: "top" puts the spine along the top edge. It’s the same book turned a quarter, so everything you know still holds - the outer edge is where a page lifts, only now that edge is the bottom one and the page folds up over the one behind it. With layout: "single" you get a notepad. Leave the layout on auto and a top-bound book stacks two pages, which is how a wall calendar hangs. There’s a "bottom" too, the same thing upside down, for the odd flip chart.
One thing to know before you put one of these on a phone: a top-bound book turns on vertical drags, so it keeps them for itself and a finger on the pad won’t scroll the page. Scrolling from anywhere outside the pad still works, the same trade a carousel makes with horizontal swipes.
A notepad
Pull the bottom edge up
Bound along the top
Same book, turned a quarter: the spine runs along the top, so a page lifts from its bottom edge and folds up over the one behind it. On a mouse, hover near the bottom and the edge furls to show you where to grab.
Swipe up on a phone
A quick swipe up turns the page, and a swipe down turns it back. Scrolling past the pad still works from anywhere outside it.
One page or two
This pad shows one page at a time. Leave the layout on auto and a top-bound book stacks two, the way a wall calendar hangs.
The end
import "@openpageflip/core/styles.css";import { type Book, createBook } from "@openpageflip/core";
/** A notepad: bound along the top, one page, turned up from the bottom edge. */export function mount(container: HTMLElement): Book { return createBook(container, { width: 360, // the page's ratio, and with maxWidth below, its largest size height: 480, size: "stretch", // shrinks to fit a phone maxWidth: 360, // but never grows past one phone-sized page binding: "top", // the spine runs along the top edge, so pages turn up layout: "single", // one page; "auto" would stack two, like a wall calendar });}A book on a desk, a notepad in a hand
Section titled “A book on a desk, a notepad in a hand”The library doesn’t pick a breakpoint for you. Honestly it’s better that way - whether a book should turn into a notepad on a phone, and at what width, depends on the book, and the pieces are already there: a media query, and props that rebuild the book on the page it was showing when they change. This one becomes a notepad below 640px, so make the window narrower and watch it, or open this page on a phone.
Cover
One
A book: pull the outer edge across. Make the window narrower than 640px and it becomes a notepad.
Two
A book: pull the outer edge across. Make the window narrower than 640px and it becomes a notepad.
Three
A book: pull the outer edge across. Make the window narrower than 640px and it becomes a notepad.
Four
A book: pull the outer edge across. Make the window narrower than 640px and it becomes a notepad.
The end
import "@openpageflip/core/styles.css";import { FlipBook, Page } from "@openpageflip/react";import { useSyncExternalStore } from "react";
/** Whether a media query matches, kept current. False on the server, where there is no viewport. */function useMediaQuery(query: string): boolean { return useSyncExternalStore( (onChange) => { const media = matchMedia(query); media.addEventListener("change", onChange); return () => media.removeEventListener("change", onChange); }, () => matchMedia(query).matches, () => false, );}
const pages = ["Cover", "One", "Two", "Three", "Four", "The end"];
export default function Responsive() { // The breakpoint is yours: the book only knows which way it is bound. Below it, the spread // becomes a notepad. Changing a prop rebuilds the book on the page it was showing. const handheld = useMediaQuery("(max-width: 640px)"); return ( <FlipBook className="book" width={360} height={480} size="stretch" maxWidth={360} cover binding={handheld ? "top" : "left"} layout={handheld ? "single" : "auto"} > {pages.map((title, i) => { const isCover = i === 0 || i === pages.length - 1; return ( <Page key={title} density={isCover ? "hard" : "soft"} className={isCover ? "page page-cover" : "page"} > <h3>{title}</h3> {!isCover && ( <p> {handheld ? "A notepad: pull the bottom edge up." : "A book: pull the outer edge across. Make the window narrower than 640px and it becomes a notepad."} </p> )} </Page> ); })} </FlipBook> );}