@open-press/core

Frame

A fixed page surface or a nested region inside a page. Root Frames become output pages; nested Frames become selectable object boundaries inside the current page.

Component Impl

# <Frame>

Renders a <section> with data-openpress-* attributes the engine reads. A root Frame is the page address used for allocation, comments, editing, and export. A nested Frame is a region object scoped under the current page.

import { Frame } from "@open-press/core";
<Frame
  frameKey="cover"
  role?="document.cover"
  chrome?={true}
  className?="reader-page--cover"
  ...sectionProps
>
  {/* page or region contents */}
</Frame>

Props

Name Type Default Description
frameKey required string Stable identifier. On a root Frame, this is the page allocation key, page address, and data-openpress-frame-key. On a nested Frame, this is a region key scoped under the parent Frame and written to data-openpress-region-frame-key. Must be non-empty and must not contain :extended:.
children required ReactNode The page contents. Typically one or more <MdxArea> slots wrapped in a layout (.page-frame / .page-body) plus any header/footer chrome.
role string Semantic label. The core runtime does not branch on this value. It writes the value to data-frame-role; root Frames also derive data-page-kind from the last dot segment, such as cover from document.cover. Themes, inspectors, and agents can use it as a stable hint.
chrome boolean true Root Frame only. When false, writes data-frame-chrome="false" and data-page-footer="false". Theme helpers use these flags to hide page chrome such as footer/header bands. Nested Frames inherit the page and do not emit chrome flags.
className string Appended to the rendered section. Root Frames automatically include reader-page; nested Frames do not, so they can be used as neutral region boundaries.
...rest HTMLAttributes All other props pass through to the underlying <section>. data-* attributes are commonly used for layout flags read by CSS or the inspector.
A4 content page (manuscript role)
<Frame frameKey="ch-2" role="document.content" className="reader-page--content">
  <div className="page-frame">
    <header className="page-header" aria-hidden="true" />
    <main className="page-body">
      <MdxArea chainId="story" />
    </main>
    <footer className="page-footer">
      <span className="footer-left">{title}</span>
      <span className="footer-right">{pageIndex + 1}/{totalPages}</span>
    </footer>
  </div>
</Frame>
Canvas-style slide (no chrome)
<Frame
  frameKey="slide-1"
  role="canvas.slide"
  chrome={false}
  className="reader-page--slide"
>
  <div className="page-frame">
    <main className="page-body">
      <MdxArea chainId="slides" overflow="truncate" />
    </main>
  </div>
</Frame>

Page geometry

The <Frame> contract does not include a page prop. Paper or canvas size is set on each <Press page> JSX prop. One Press → one fixed geometry; mixed-geometry projects use a multi-Press <Workspace> with one geometry per Press.

Context Impl

# FrameContext

Low-level context for custom helpers. MdxArea calls consumeArea to claim its slot in the engine's allocation table. Normal documents usually do not need to read this context directly.

import { FrameContext } from "@open-press/core";
const frame = useContext(FrameContext);
// -> { frameKey, objectId, pageId, consumeArea(chainId) } | null

consumeArea(chainId) increments the per-chain counter on each call so multiple <MdxArea> with the same chainId in one frame map to distinct allocation slots in source order.

Symbol Impl

# FRAME_MARKER

Symbol identifier the renderer uses to detect Frame instances during tree walking. Custom frame wrappers can re-export Frame and attach this marker.

import { FRAME_MARKER } from "@open-press/core";

Data attributes the renderer writes

The rendered <section> carries these attributes — theme selectors and inspector behavior depend on them:

Name Type Default Description
data-openpress-frame-key string Root Frames only. Mirrors the page frameKey.
data-openpress-region-frame-key string Nested Frames only. Mirrors the region frameKey inside the current page.
data-openpress-object-id string Object id used by the inspector, editing layer, and comment-marker system.
data-frame-role string Mirrors the role prop.
data-page-kind string Root Frames only. Last dot segment of role, for example cover from document.cover.
data-frame-chrome "true" | "false" Root Frames only. Reflects the chrome prop.
data-page-footer "true" | "false" Root Frames only. Matches data-frame-chrome by default.

Role naming convention

role is a free string, but the framework documents a two-segment convention so themes and docs stay consistent:

  • document.* — long-form pages that flow MDX content through the allocator: document.cover, document.toc, document.content, document.back-cover.
  • canvas.* — fixed-format pages with one designed surface and overflow="truncate" MDX areas: canvas.slide, canvas.post, canvas.card.
  • manuscript.* — used by the bundled manuscript helpers (manuscript.content from DefaultSectionPage).