# Export

The record button. Wrap any machine and it can be saved as an animated WebP, an animated GIF or a still — encoded in the page, with nothing uploaded.

> For the complete index, see [llms.txt](https://robocn.dev/llms.txt). A Markdown version of any page is available by appending `.md` to its URL or by sending an `Accept: text/markdown` header.

## Install

```bash
bunx --bun shadcn@latest add https://robocn.dev/r/robot-export.json
```

Registry item: `robot-export` · [`https://robocn.dev/r/robot-export.json`](https://robocn.dev/r/robot-export.json)

## Notes

- Every number is typed, not picked. The chips are shortcuts to values the field beside them would take anyway: 7.5 seconds at 24 fps scaled 1.75× is as available as the two-second default, and arrow keys step a field.
- Seconds, rate and frames are three views of one recording. Asking for 90 frames at 30 fps is asking for three seconds, and the field you did not touch follows.
- The button carries `data-robocn-hide`, and the snapshotter drops those from the clone — otherwise every recording would have a record button in the corner of it.
- Settings are per menu, not global: the scale, rate and ground of one panel do not follow you to the next. `onSettingsChange` is there for a page that wants them to.
- Everything runs in the page — `robot-capture` does the work and the file is an anchor click. Notes: `docs/export.md`.

## Usage

```tsx
import { RobotExport, ExportMenu } from "@/components/ui/robot-export"

// Wrap a machine: the button appears over its corner on hover.
<RobotExport name="robot-arm">
  <RobotArm behavior="sweep" />
</RobotExport>

// Or put the menu in a toolbar that already knows its target.
<ExportMenu target={stageRef} name="robot-arm" label="Export" />

// Open on your own numbers, and widen what the fields will accept.
<RobotExport
  name="robot-arm"
  defaults={{ format: "gif", seconds: 7.5, fps: 24, scale: 1.5, ground: "custom", groundColor: "#101014" }}
  limits={{ fps: [1, 120], frames: 2000 }}
  presets={{ seconds: [0, 3, 7.5], fps: [24, 60], scale: [] }}
>
  <RobotArm behavior="sweep" />
</RobotExport>
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `name` | `string` | `"robocn"` | File stem. The extension comes from the format. |
| `target` | `RefObject<Element> | (() => Element | null)` | — | Record something other than the wrapper — the machine itself, or a whole stage. |
| `formats` | `("webp" | "gif" | "png")[]` | `["webp", "gif", "png"]` | Which formats the menu offers, in order. WebP is dropped on a browser whose canvas cannot write it. |
| `defaults` | `Partial<ExportSettings>` | — | Opening settings: `format`, `seconds` (0 is a still), `fps`, `scale`, `quality`, `loop`, `ground` and `groundColor`. |
| `limits` | `Partial<ExportLimits>` | `0–120 s, 1–60 fps, 0.1–8×, 900 frames` | What the fields will accept. The ceiling stops a typo asking for a hundred thousand frames; raise it and the field takes the higher number. |
| `presets` | `{ seconds?: number[]; fps?: number[]; scale?: number[] }` | — | The chips beside each field — shortcuts, not the range. An empty array leaves a field bare. |
| `onSettingsChange` | `(settings: ExportSettings) => void` | — | On `ExportMenu`: every setting as it changes, for a page that wants to remember them. |
| `destinations` | `ExportDestination[]` | — | Where the file may go. One is used silently; more than one becomes a row in the menu. Defaults to the browser's download. |
| `alwaysVisible` | `boolean` | `false` | Keep the button on screen instead of revealing it on hover or focus. |
| `corner` | `"start" | "end"` | `"end"` | Which top corner the button sits in. |
| `open / onOpenChange` | `boolean / (open: boolean) => void` | — | On `ExportMenu`: drive the menu from outside, which is how the workbench binds it to a key. |
| `destinations` | `ExportDestination[]` | `[{ id: "download", label: "Download" }]` | Where the finished file may go. One is used silently; more than one becomes a row in the menu. A destination with a `write(blob, filename)` callback replaces the browser's download — that is how the workbench writes a recording into a folder it is holding. |

## Source

- `src/components/ui/robot-export.tsx`
