Skip to content

Components

Every component works in any slide without an import. This page covers the ones that do more than show content: elements you drag into place, a video that follows the clicks, and components that know where they are drawn. The component reference has every one, with its props and an example, and npx kadal-deck info components <Name>pnpm exec kadal-deck info components <Name>yarn kadal-deck info components <Name>bunx kadal-deck info components <Name> prints the same.

<Drag> puts a block at stage coordinates (the stage is 1920 × 1080) and lets you move it with the mouse while you write:

<Drag pos="1400,120,380,_">
![Our logo](/logo.png)
</Drag>

pos is x,y,width,height, with an optional rotation in degrees as a fifth number. _ for the height means as tall as it needs. Or name the position and keep it in the slide’s frontmatter:

---
dragPos:
logo: 1400,120,380,_
---
<Drag pos="logo">![Our logo](/logo.png)</Drag>

In kadal-deck dev, double-click a <Drag> on the slide you are showing. Then:

  • drag it to move it; drag a corner or an edge to resize it (Shift keeps the proportions);
  • drag the round handle above it to turn it (Shift snaps to 15°);
  • nudge it with the arrow keys (Shift: 10 px at a time);
  • Esc, Enter or a click elsewhere ends it.

Each change is saved into deck.mdx a moment later (the dragPos entry for a named one, the tag’s own pos otherwise) and nothing else in the file moves. A save is refused if that position changed in the file meanwhile. While you drag, every other open window of the deck (the presenter view, a second screen) follows without a reload. Everywhere else, in a built deck, the hosted player or print, it is simply placed.

<DragArrow> is an arrow whose ends you drag. Its pos is x,y,dx,dy: from (x, y), by (dx, dy).

<DragArrow pos="300,700,600,-280" color="var(--deck-accent)" width={4} />

Both take at, hide and effect too, so they can arrive on a click like <Click>. <DragArrow> takes twoWay for heads at both ends.

<Video src="/demo.mp4" at={1} pauseAt={3} steps={{ 2: "rewind", 4: 42 }} autoreset="slide" />
Prop Meaning
src a file in public/ or a URL; or <source> children
autoplay play when the slide arrives (or the <Click> round it reveals it); "once": only the first time
at the click at which it starts playing
pauseAt the click at which it pauses
steps what happens at further clicks: "pause", "play", "rewind", or a time in seconds to jump to
autoreset "slide": back to timestamp whenever the slide is left; "click": whenever the deck steps back before at
timestamp start here, in seconds
loop, muted (default true), controls as on any video
poster, printPoster, printTimestamp the picture for print, the overview and the next-slide box: a poster, or a frame ("last" or seconds)

Its at, pauseAt and steps are clicks of the slide like any other, so the slide counts them.

One thing in the light colour scheme, another in the dark. It follows the slide’s own scheme when its frontmatter forces one.

<LightOrDark>
<div slot="light">![Logo](/logo-black.svg)</div>
<div slot="dark">![Logo](/logo-white.svg)</div>
</LightOrDark>
<LightOrDark light={<span>Day</span>} dark={<span>Night</span>} />

Children can also be a function of the scheme: {({ scheme }) => …}.

The same slide is drawn in many places: the stage, the presenter’s current slide and next-slide box, the overview, printed pages, the audience’s phone. <RenderWhen> shows its children only in some of them.

<RenderWhen context="presenter">Only the speaker sees this.</RenderWhen>
<RenderWhen context={["print", "overview"]} fallback={<Iframe src="https://example.com" />}>
![A still of the page](/still.png)
</RenderWhen>
Context Where
main the deck and the presenter’s current slide (and the audience’s phone)
slide the deck itself: the stage, a mirror, the scroll view
presenter the presenter view’s current slide
previewNext the presenter’s next-slide box
overview an overview tile
print a printed or exported page (export is the same)
audience the audience page’s copy, on a phone
visible on screen right now; combined with others, must also hold

Several contexts — a list, or "presenter overview" — render in any of them. fallback renders everywhere else.

Slide <SlideCurrentNo /> of <SlidesTotal />
Next up: <TitleRenderer no={5} />
  • <SlideCurrentNo> is this slide’s number; in a layer it is the current slide’s. format: c (the default), c/t with the total, h.v or h/v with vertical slides.
  • <SlidesTotal> counts the slides, hidden ones left out.
  • <TitleRenderer> is another slide’s title, by no (1-based) or id; with neither, this slide’s. as picks the element (span, h1–h3, strong, div); fallback shows when there is no title.
<BlueSky uri="https://bsky.app/profile/bsky.app/post/3myi2ihquwk26" />

The post through Bluesky’s embed, in the slide’s colour scheme. uri is its bsky.app address or its AT-URI; scale sizes it. kadal-deck export captures a poster for each scheme, so it prints; poster sets your own.

Moving a deck that used another tool’s names for these? Migrate a Slidev deck maps each one.

Send feedback