Skip to Content

Body

<Clover.Body /><clover-body>34 kB added to a page with a Root, gzipped53 kB added to a page with a <clover-root>, styles included, gzipped

The active items of the relative manifest. Items may be a spread of images, audio, video or a 3D object. Wraps the Canvas, Timeline and Scene components.

<Clover.Root iiifContent={url}>
  <Clover.Body
    controls={}
    navigator={}
    style={{ height:  }}
  />
</Clover.Root>
<clover-root
  iiif-content="https://clover.iiif.library.northwestern.edu/mocks/page-transcript/manifest.json">
  <clover-body
    controls=""
    navigator=""
    style="height: px">
  </clover-body>
</clover-root>

API reference

Draws the Root’s current view with Canvas<clover-canvas>, or with a renderer of yours that claims it, in a box as tall as --clover-body-height, 60vh by default. It works only inside a Root<clover-root>. Its other props are Canvas’s, and go to the Canvas, but for what to draw, which comes from the Root; its label, annotations, chapters and language do too, unless you pass your own.

While the Root loads, it is aria-busy and shows Clover’s loading mark along its top edge; <Clover.Status loading={false} /><clover-status loading="false"></clover-status> announces it. The table of contents is Contents<clover-contents>.

PropTypeDefaultDescription
renderersBodyRenderer[]The Root’sComponents of yours that draw the views they claim.
styleReact.CSSProperties—On its box, merged over its inline height.
classNamestring—Added to clover-body.
childrenReactNode—Controls after Clover’s own, or the renderer’s children.

<clover-body>

The view of the clover-root it is in, drawn as Body draws it: images, video and sound, or a renderer of yours. It is the Body's box, its height from --clover-body-height (60vh by default) or its own style. A clover-panel-toggle, and a button of yours, in it are among its controls.

NameTypeDefaultDescription
controlsbooleantrue"false" leaves out the controls over the Body.
navigatorbooleanfalseA small map of the whole image, while zoomed in.
placeholderbooleantrue"false" opens a Canvas straight away, past its placeholderContainer.
animate-annotationsbooleanfalseGlide to a picked annotation, rather than frame it in one cut. A reader who asks for reduced motion gets the cut.
.handleCloverCanvasHandle | null—Read-only. The Canvas's handle once its view is laid out (clover-ready), as onReady hands it in React: the camera and its coordinates (handle.zoomBy(2), handle.home()). Null before.
.controlsboolean | { zoom?: boolean; fullPage?: boolean; rotation?: boolean; reset?: boolean; annotations?: boolean; information?: boolean; [option: string]: unknown } | null—As a property: Which of the Body's controls it shows, as Canvas's controls takes it: false for none, or some ({ rotation: false }), in place of the attribute.
.options{ request?: { credentials?: RequestCredentials; headers?: Record<string, string>; fetch?: typeof fetch }; [key: string]: unknown } | null—The Canvas's options: the request it loads with (credentials, headers, a fetch of your own), its gestures and more.
.controlButtonsCloverControlButtons | null—The Body's controls, each replaced by a button you make: a function given the control's name, label and Clover's icon, returning the button. Clover keeps it named, keyed and in its state, presses the control with it, and adds its popover.
.renderersCloverRenderer[] | null—Renderers of yours for this Body only, in place of the root's: each claims views (canvasId, format or match) and draws one into a box of its own (render).
clover-ready{ handle: CloverCanvasHandle }—An event. The view is laid out and fitted: its handle is here, and works from now on.
clover-annotation-active{ id: string | null }—An event. An annotation is hovered or focused; null when none is.
clover-caption-change{ caption: { id: string; language?: string } | null }—An event. The reader chose a caption file in the Captions menu, or Off (null).
clover-endedRecord<string, never>—An event. A recording played to its end.

Examples

Height

Set --clover-body-height on it, or on anything around it: 100% fills a parent with a height of its own.

<Clover.Body style={{ "--clover-body-height": "16rem" }} />
<clover-body style="--clover-body-height: 16rem"></clover-body>

Controls

Use controls to choose Clover’s controls: false for none, or an object that leaves some out.

<Clover.Body controls={{ rotation: false }} />
<clover-body></clover-body> <script type="module"> const body = document.querySelector("clover-body"); body.controls = { rotation: false }; </script>

Use navigator for an overview of the whole image, in the top left, to press or drag in.

<Clover.Body navigator />
<clover-body navigator></clover-body>

Controls of your own

Children join the Canvas’s controls, after Clover’s, and stay where Clover’s are left out: over a placeholder, or a lone recording. Name each one as Clover’s are named (Controls of your own).

<Clover.Body> <Clover.PanelToggle open={open} onOpenChange={setOpen} controls="panel" /> </Clover.Body>
<!-- The toggle shows the panel while the panel is not hidden: hide it to start it shut. --> <clover-body> <clover-panel-toggle controls="panel"></clover-panel-toggle> </clover-body>

Renderers of your own

Give renderers.renderers to Body<clover-body>, or to the Root<clover-root> for every Body<clover-body> in it, and a view that one claims, by Canvas id, painting format or a match test, is drawn by your component (Renderers of your own).

const renderers = [{ format: ["model/gltf-binary"], component: ModelViewer }]; <Clover.Body renderers={renderers} />;
<clover-body></clover-body> <script type="module"> document.querySelector("clover-body").renderers = [ { format: ["model/gltf-binary"], render(container, { bodies }) { const model = document.createElement("model-viewer"); model.setAttribute("src", bodies[0].id); container.append(model); }, }, ]; </script>

Previous versions

Clover 3.x › Viewer

  • options.canvasHeight is --clover-body-height.
  • customDisplays is renderers.renderers, on Body<clover-body> or the Root<clover-root>.