# Data controls

Control over the account's data: facts about how it's used (from the service), an export, deleting thread history, and deleting the account. Destructive steps say exactly what goes and ask you to type the account's name; the account delete is owner-only and says so to everyone else. Deleting history and exporting can be locked with a reason the same way.

- Registry name: `data-controls` (`@candor/data-controls`)
- Tier: Pro. Installing it needs a Pro, Premium or Team licence key: the person runs `npx candor-ui key <key>` themselves; never ask for the key in chat or write it to a file.
- Docs: https://candor.themethodic.com/docs/data-controls

## Install

```bash
npx candor-ui add data-controls
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/data-controls`.
It brings in: button, locale, locked, relative-time, type-to-confirm, utils.
npm packages: lucide-react@^1.67.0.

## Example

```tsx
"use client"

import * as React from "react"
import { DataControls, type ExportState } from "@/components/data-controls"

export default function Example() {
  const [exportState, setExportState] = React.useState<ExportState>({ kind: "idle" })
  return (
    <DataControls
      className="max-w-xl"
      account="Acme"
      statements={["Never used to train models", "Encrypted at rest and in transit", "Only your members can open your threads"]}
      exportState={exportState}
      onExport={() => setExportState({ kind: "preparing", startedAt: new Date().toISOString() })}
      exportIncludes="Every thread, run log and approval, as JSON in a zip."
      onDeleteHistory={() => {}}
      historyNote="Removes every thread and its messages. Run logs and the audit log stay."
      onDeleteAccount={() => {}}
      deleteAccountLocked="Only the account owner can delete the account."
      whatDeleteRemoves={["Every thread, run and approval", "Connections to your repositories", "All members’ access"]}
    />
  )
}
```

## <DataControls>

Props:

- `account: string`: The account's name; destructive steps ask for it typed exactly.
- `statements: string[]`: How data is used, one sentence each, e.g. "Never used to train models".
- `exportState: ExportState`: Where the export is: idle, preparing, ready to download, or failed.
- `onExport: () => void`: Start an export.
- `onDeleteHistory?: (() => void) | undefined`: Delete all thread history. Without it, the row isn't shown.
- `onDeleteAccount?: (() => void) | undefined`: Delete the account. Without it, the row isn't shown.
- `deleteAccountLocked?: string | undefined`: Why the viewer can't delete the account (non-owners).
- `deleteHistoryLocked?: string | undefined`: Why the viewer can't delete thread history, e.g. "Only owners can delete data." The row shows, locked.
- `exportLocked?: string | undefined`: Why the viewer can't export, e.g. "Only admins can export."
- `whatDeleteRemoves: string[]`: What deleting the account removes, from the service.
- `exportIncludes: string`: What the export contains, from the service.
- `historyNote: string`: What deleting history removes and keeps, from the service.
- `className?: string | undefined`

## Strings (`dataControls`)

The fixed words, English by default. Override any of them under `dataControls` in `<LocaleProvider strings={{ dataControls: { … } }}>`; the table is exported as `dataControlsStrings`.

- `label`: Data controls
- `typeToConfirm`: Type {account} to confirm.
- `typeExactly`: Type the account name exactly.
- `cancel`: Cancel
- `deleteAllThreads`: Delete all threads
- `deleteTheAccount`: Delete the account
- `exportEverything`: Export everything
- `preparing`: Preparing since {since}. You can leave this page.
- `ready`: Ready. The link expires {expires}.
- `exportFailed`: Export failed: {reason}
- `download`: Download
- `export`: Export
- `tryAgain`: Try again
- `deleteThreadHistory`: Delete thread history
- `deleteHistory`: Delete history
- `deleteAccount`: Delete account

## Types

### ExportState

```ts
{ kind: "idle" } | { kind: "preparing"; startedAt: string } | { kind: "ready"; href: string; expiresAt: string } | { kind: "failed"; reason: string }
```

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider` (fixed strings) and `TermsProvider` (nouns); entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
