# Shutter Button

Camera shutter for photo, video and hold-to-record. It turns red while recording, shows a stop square when a tap will end it, and fills a ring toward the time limit.

> Composed · Pro · Mobile-Native — React Native, Expo Go compatible.

## Install

```bash
npx @lumioui/cli add pro/shutter-button
```

## Import

```tsx
import { formatRecordingTime, ShutterButton } from "@/components/ui/shutter-button/shutter-button";
```

## Variants

- `camera` — Camera deck: `npx @lumioui/cli add pro/shutter-button-camera`
- `quicktake` — Hold to record: `npx @lumioui/cli add pro/shutter-button-quicktake`
- `scanner` — Document scanner: `npx @lumioui/cli add pro/shutter-button-scanner`

## Props

### ShutterButton

| Prop | Type | Notes |
| --- | --- | --- |
| `mode?` | `"photo" | "video"` | `photo` (white disc, tap captures) or `video` (red disc, tap toggles recording). Default `photo`. |
| `recording?` | `boolean` | Controlled recording state (video mode and hold-to-record). |
| `onRecordingChange?` | `(recording: boolean) => void` | Fires with the next recording state — start/stop your recorder here. |
| `onCapture?` | `() => void` | Photo tap — take the picture here. |
| `holdToRecord?` | `boolean` | Photo mode: press and hold to record video, release to stop; slide right to lock (QuickTake). |
| `onLock?` | `() => void` | Fires when a held recording is locked by sliding right. |
| `maxDuration?` | `number` | Seconds — draws a progress ring while recording and auto-stops at the limit. |
| `size?` | `keyof typeof SIZES` | Outer diameter preset: `md` 66 or `lg` 78. Default `lg`. |
| `disabled?` | `boolean` | — |
| `accessibilityLabel?` | `string` | Screen-reader name. Defaults by mode: "Take photo" / "Record video". |
| `className?` | `string` | — |

### ShutterCapture

| Prop | Type | Notes |
| --- | --- | --- |
| `run` | `number` | Bump (e.g. increment) to fire one capture. 0 never fires. |
| `origin?` | `{ x: number` | Where the light floods from — the shutter centre, in this overlay's  coordinates (it may sit below the viewfinder). Default bottom centre. |
| `y` | `number }` | — |
| `target?` | `ShutterCaptureRect` | The thumbnail slot the ghost lands in, in this overlay's coordinates.  Omit and the ghost dims in place. |
| `targetRadius?` | `number` | Corner radius of the slot the ghost lands in. Default 8. |
| `strength?` | `number` | Peak brightness of the light pool. Default 0.7. |
| `onLanded?` | `() => void` | Fires as the ghost lands — spark the thumbnail here. |
| `children?` | `React.ReactNode` | The captured frame, drawn inside the travelling ghost. |

### ShutterModes

| Prop | Type | Notes |
| --- | --- | --- |
| `modes` | `(string | ShutterModeOption)[]` | Modes left to right — strings or `{ value, label }`. |
| `value?` | `string` | Controlled selected mode value. |
| `defaultValue?` | `string` | Uncontrolled initial mode. Default: the first mode. |
| `onValueChange?` | `(value: string) => void` | — |
| `disabled?` | `boolean` | Lock the carousel (e.g. while recording). |
| `className?` | `string` | — |

### ShutterTimer

| Prop | Type | Notes |
| --- | --- | --- |
| `recording` | `boolean` | Counts up while true; resets to 00:00 when recording starts again. |
| `seconds?` | `number` | Override the displayed seconds (e.g. from your recorder's status). |
| `className?` | `string` | — |

Source: https://lumioui.com/components/shutter-button