# React API

> Presentation, Slide, SlideContent, Notes, and the navigation hooks

The structural components live in `@getnarro/core`. Full prop tables for every
component are in the [component reference](/docs/components), which is generated
from the types; this page covers the shape of the API and how the pieces fit.

## Presentation

The root container. Owns navigation, routing, keyboard and pointer handling, and
viewport scaling.

```tsx
import { Presentation } from "@getnarro/core";

<Presentation
  aspectRatio="16:9"
  keyboard
  mouse
  touch
  routing
  onSlideChange={(index) => console.log(index)}
>
  {/* slides */}
</Presentation>;
```

<!-- generated:props:Presentation -->
| Prop | Type | Default |
| --- | --- | --- |
| `children` | `ReactNode` | — |
| `aspectRatio` | `AspectRatio` | `"16:9"` |
| `autoPlay` | `number \| boolean \| number[]` | `false` |
| `autoPlayLoop` | `boolean` | `false` |
| `baseHeight` | `number` | `1080` |
| `baseWidth` | `number` | `1920` |
| `className` | `string` | — |
| `embedded` | `boolean` | `false` |
| `enableViewportScaling` | `boolean` | `true` |
| `favicon` | `string \| null` | — |
| `initialSlide` | `number` | `0` |
| `keepAwake` | `boolean` | `false` |
| `keyboard` | `boolean` | `true` |
| `maxDuration` | `number` | — |
| `mouse` | `boolean` | `true` |
| `onAutoPlayComplete` | `(() => void)` | — |
| `onSlideChange` | `((index: number) => void)` | — |
| `onSlidesData` | `((slides: SlideData[]) => void)` | — |
| `preserveAspectRatio` | `boolean` | `true` |
| `routing` | `boolean` | `true` |
| `showAutoPlayIndicator` | `boolean` | `false` |
| `sync` | `PresentationSync` | `false` |
| `theme` | `PresentationTheme` | — |
| `touch` | `boolean` | `true` |
| `transform` | `TransformConfig` | — |
<!-- /generated:props:Presentation -->

## Slide

One slide. Give it an `id` if you want it linkable and stable across edits.

```tsx
<Slide id="intro" layout="title" className="bg-slate-900" transition="fade">
  {/* content */}
</Slide>
```

`layout` is <!-- generated:union:LayoutType -->"default" | "center" | "two-column" | "image" | "title"<!-- /generated:union:LayoutType -->.
`transition` is <!-- generated:union:TransitionEffect -->"none" | "fade" | "slide" | "zoom"<!-- /generated:union:TransitionEffect -->.

## SlideContent

Handles padding and vertical alignment inside a slide.

```tsx
<SlideContent layout="centered">{/* content */}</SlideContent>
```

`layout` here is <!-- generated:type:SlideContent.layout -->"default" | "centered" | "top" | "bottom" | "fill" | "between"<!-- /generated:type:SlideContent.layout --> — a **different**
set from `Slide`'s `layout`. The two are easy to confuse; `Slide` positions the
slide, `SlideContent` positions the content within it.

## Notes

Speaker notes. Renders nothing on the slide.

```tsx
<Slide id="intro">
  <SlideContent>…</SlideContent>
  <Notes>Open with the customer story, then the numbers.</Notes>
</Slide>
```

## Hooks

All hooks must be called inside a `<Presentation>`.

```tsx
import { useNavigation } from "@getnarro/core";

function ProgressBar() {
  const { currentSlide, totalSlides, next, previous, goToSlideById } = useNavigation();

  return <div style={{ width: `${((currentSlide + 1) / totalSlides) * 100}%` }} />;
}
```

`useNavigation()` returns the navigation state and its actions together:

**State** — `currentSlide`, `totalSlides`, `currentFragment`, `totalFragments`,
`currentSubSlide`, `totalSubSlides`, `isFirst`, `isLast`, `isOverviewMode`,
`isFullscreen`.

**Actions** — `next()`, `previous()`, `goToSlide(index)`,
`goToSlideById(id)`, `toggleFullscreen()`, `toggleOverviewMode()`,
`toggleAspectRatio()`.

Other exported hooks:

| Hook | For |
| --- | --- |
| `usePresentationContext()` | The raw `{ state, actions }` pair |
| `useSlideContext()` | The current slide's index and metadata |
| `useSlideActive()` | Whether the calling slide is on screen — use this to gate animation. Also exported by `@getnarro/shared-ui`; both read the context `Slide` provides |
| `useSlideIndex()` | The calling slide's index |
| `useFullscreen()` | Fullscreen state and toggle, outside a presentation |
| `useViewportScale()` | The current scale factor |
| `useWakeLock()` | Keep the screen awake while presenting |

`Fragment` is also exported as **`Reveal`**, and new decks should use that name:
`import { Fragment } from "@getnarro/shared-ui"` sits beside `React.Fragment`
and `<>` in a file that is mostly JSX, nothing warns about the collision, and an
author who writes `<Fragment>` meaning React's gets a progressive reveal. Both
names are the same component, so nothing has to change.

There is no `usePresentation`, `useSlide`, or `useFragment` hook — those names
appeared in older documentation and were never exported.