# zidane-ui/approvals

Import: `import { … } from 'zidane-ui/approvals'`. Source: [ui/src/approvals/index.ts](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/index.ts).

## Components

### `ApprovalBar`

Component.

Renders the first pending approval of a session: the inline [`ApprovalCard`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalCard), or the
file-edit review for the tools that write files. While the inline card shows, esc denies (not
from inside the code editor, where it clears the selection), ⌘↵ allows once and ⌘⇧↵ always
allows. Renders nothing when the session has no pending approval.

```ts
function ApprovalBar(props: ApprovalBarProps): Element | null
```

**Parameters**

- `props` (`ApprovalBarProps`): The `sessionId`, an optional `onFileEdit`, `renderFrame`, `className` and `style`.

**Returns** `Element | null`

**Props**

- `className?` (`string`): Extra classes on the inline card's root.
- `onFileEdit?` (`(request: WireApprovalRequest) => void`): Opens the file-edit review for an `edit`, `multi_edit` or `write_file` approval on the
  app's modal layer (once per request; the bar then renders nothing). Absent: the bar renders
  [`FileEditApproval`](https://zidane.si/docs/reference/ui-approvals.md#FileEditApproval) in place.
- `renderFrame?` (`(props: ApprovalFrameProps) => ReactElement`): Draws the inline card's surface. See `ApprovalCardProps.renderFrame`.
- `sessionId` (`string | null`): The session whose first pending approval shows. `null`: nothing shows.
- `style?` (`CSSProperties`): Inline styles on the inline card's root.

Source: [ui/src/approvals/ApprovalBar.tsx:194](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalBar.tsx#L194)

### `ApprovalCard`

Component.

Renders the inline approval card: the tool, what worried the decision model, the command or
input (scrolling inside a capped body while the title and actions stay on screen), and the
decisions. Once per request, focus lands on the card itself, never on a button, unless the user
is typing somewhere.

```ts
function ApprovalCard(props: ApprovalCardProps): Element
```

**Parameters**

- `props` (`ApprovalCardProps`): The `request`, `onResolve`, an optional `renderFrame`, `className` and `style`.

**Returns** `Element`

**Props**

- `className?` (`string`): Extra classes on the root (the `alertdialog`).
- `onResolve?` (`(requestId: string, decision: ApprovalDecision) => void`): Called with the user's decision. Absent: the card shows the request without its buttons.
- `renderFrame?` (`(props: ApprovalFrameProps) => ReactElement`): Draws the card's surface (an app's own dock card). Default: a raised card tinted with the warn color.
- `request` (`WireApprovalRequest`): The pending approval to show.
- `style?` (`CSSProperties`): Inline styles on the root.

Source: [ui/src/approvals/ApprovalBar.tsx:86](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalBar.tsx#L86)

### `ApprovalConcern`

Component.

Renders what worried the decision model about a call it handed to the user.

```ts
function ApprovalConcern(props: ApprovalConcernProps): Element
```

**Parameters**

- `props` (`ApprovalConcernProps`): The `concern`, plus `className` and `style`.

**Returns** `Element`

**Props**

- `className?` (`string`): Extra classes on the line.
- `concern` (`ModelApproval`): The decision model's verdict, from the request's `concern`.
- `style?` (`CSSProperties`): Inline styles on the line.

Source: [ui/src/approvals/ApprovalConcern.tsx:25](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalConcern.tsx#L25)

### `ApprovalShell`

Component.

Renders a titled panel with a body and an optional footer, as a `dialog` named by its title.

```ts
function ApprovalShell(props: ApprovalShellProps): Element
```

**Parameters**

- `props` (`ApprovalShellProps`): The `title`, `description`, `onClose`, `footer`, `children`, `className` and `style`.

**Returns** `Element`

**Props**

- `children` (`ReactNode`): The body.
- `className?` (`string`): Extra classes on the panel.
- `description?` (`string`): A line under the heading.
- `footer?` (`ReactNode`): The actions row under the body.
- `onClose?` (`() => void`): Called by the close button (the file-edit review denies). Absent: no close button.
- `style?` (`CSSProperties`): Inline styles on the panel.
- `title` (`string`): The panel's heading.

Source: [ui/src/approvals/ApprovalShell.tsx:36](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalShell.tsx#L36)

### `ApprovalsProvider`

Component.

Provides an [`ApprovalsHost`](https://zidane.si/docs/reference/ui-approvals-headless.md#ApprovalsHost) and optional label overrides to the approval components below it.

```ts
function ApprovalsProvider(props: ApprovalsProviderProps): Element
```

**Parameters**

- `props` (`ApprovalsProviderProps`): Provider props: the `host`, optional `labels`, and the `children` to render.

**Returns** `Element`

**Props**

- `children` (`ReactNode`): The components that read from `host`.
- `host` (`ApprovalsHost`): The host the approval components read pending approvals from and send decisions to.
- `labels?` (`Partial<{ approvalAllow: string; approvalAllowForSession: string; approvalAllowNoneSelected: string; approvalAllowOnce: string; approvalAlwaysAllow: string; approvalApplySelected: (selected: number, total: number) => string; approvalClose: string; approvalConcern: (concern: ModelApproval) => string; approvalCwd: (cwd: string) => string; approvalDeny: string; approvalFileEditNoPath: string; approvalFileEditReview: string; approvalFileEditTitle: (tool: string, path: string | null) => string; approvalFromSubagent: (label: string) => string; approvalRunAfter: string; approvalRunBefore: string; approvalsError: (error: ApprovalsError) => string; approvalTimeout: (timeout: string) => string; hunkAdded: (count: number) => string; hunkAmbiguous: (matches: number) => string; hunkAmbiguousHint: (matches: number) => string; hunkFile: string; hunkInclude: (index: number, total: number) => string; hunkNewFile: string; hunkNotInFile: string; hunkNotInFileHint: string; hunkRemoved: (count: number) => string; hunkReplaceAll: string; hunksClear: string; hunksOf: string; hunksSelectAll: string; hunksSelected: string; hunksSomeMissing: string; hunkTitle: (index: number, total: number) => string; hunkVia: (via: string) => string; hunkViaHint: (via: string) => string; safelistCount: (count: number) => string; safelistDescription: string; safelistEmpty: string; safelistEmptyHint: string; safelistLoading: string; safelistProject: string; safelistRevoke: string; safelistRevoking: string; safelistTitle: string }>`): Overrides for the approval components' strings. Keys you leave out keep the default English label.

Source: [ui/src/approvals/ApprovalsProvider.tsx:50](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalsProvider.tsx#L50)

### `FileEditApproval`

Component.

Renders the file-edit review of a pending approval: the path, the subagent that asked, what
worried the decision model, the diff (or the per-hunk checklist), and the decisions with their
a / s / p / d keys. Esc and a click on the modal scrim deny. Focus starts on Allow.

```ts
function FileEditApproval(props: FileEditApprovalProps): Element
```

**Parameters**

- `props` (`FileEditApprovalProps`): The `request`, `onDone`, an optional `renderShell`, `className` and `style`.

**Returns** `Element`

**Props**

- `className?` (`string`): Extra classes on the default shell.
- `onDone?` (`() => void`): Called once the user decided, or when the request was answered elsewhere: close the modal that holds the review.
- `renderShell?` (`(props: ApprovalShellProps) => ReactNode`): Draws the panel around the review (an app's own modal shell). It receives the title,
  description, body, footer and `onClose` (which denies). Default: [`ApprovalShell`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalShell).
- `request` (`WireApprovalRequest`): The pending `edit`, `multi_edit` or `write_file` approval.
- `style?` (`CSSProperties`): Inline styles on the default shell.

Source: [ui/src/approvals/FileEditApproval.tsx:80](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/FileEditApproval.tsx#L80)

### `SafelistPanel`

Component.

Renders the safelist: each project's "Always allow" entries with a Revoke button (when the host
offers `safelist.remove`), the empty state, and read or revoke errors. Renders nothing when the
host has no safelist.

```ts
function SafelistPanel(props: SafelistPanelProps): Element | null
```

**Parameters**

- `props` (`SafelistPanelProps`): An optional `renderShell`, `className` and `style`.

**Returns** `Element | null`

**Props**

- `className?` (`string`): Extra classes on the default shell.
- `renderShell?` (`(props: ApprovalShellProps) => ReactNode`): Draws the panel around the list (an app's own modal shell). It receives the title, description and body. Default: [`ApprovalShell`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalShell).
- `style?` (`CSSProperties`): Inline styles on the default shell.

Source: [ui/src/approvals/SafelistPanel.tsx:33](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/SafelistPanel.tsx#L33)

## Functions

### `useApprovalsHost`

Function.

Returns the [`ApprovalsHost`](https://zidane.si/docs/reference/ui-approvals-headless.md#ApprovalsHost) from the nearest [`ApprovalsProvider`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalsProvider). Throws when called outside one.

```ts
function useApprovalsHost(): ApprovalsHost
```

**Returns** `ApprovalsHost`

Source: [ui/src/approvals/ApprovalsProvider.tsx:69](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalsProvider.tsx#L69)

### `useApprovalsLabels`

Function.

Returns the approval components' strings: the defaults merged with any overrides given to [`ApprovalsProvider`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalsProvider) or `LabelsProvider`.

```ts
function useApprovalsLabels(): { approvalAllow: string; approvalAllowForSession: string; approvalAllowNoneSelected: string; approvalAllowOnce: string; approvalAlwaysAllow: string; approvalApplySelected: (selected: number, total: number) => string; approvalClose: string; approvalConcern: (concern: ModelApproval) => string; approvalCwd: (cwd: string) => string; approvalDeny: string; approvalFileEditNoPath: string; approvalFileEditReview: string; approvalFileEditTitle: (tool: string, path: string | null) => string; approvalFromSubagent: (label: string) => string; approvalRunAfter: string; approvalRunBefore: string; approvalsError: (error: ApprovalsError) => string; approvalTimeout: (timeout: string) => string; hunkAdded: (count: number) => string; hunkAmbiguous: (matches: number) => string; hunkAmbiguousHint: (matches: number) => string; hunkFile: string; hunkInclude: (index: number, total: number) => string; hunkNewFile: string; hunkNotInFile: string; hunkNotInFileHint: string; hunkRemoved: (count: number) => string; hunkReplaceAll: string; hunksClear: string; hunksOf: string; hunksSelectAll: string; hunksSelected: string; hunksSomeMissing: string; hunkTitle: (index: number, total: number) => string; hunkVia: (via: string) => string; hunkViaHint: (via: string) => string; safelistCount: (count: number) => string; safelistDescription: string; safelistEmpty: string; safelistEmptyHint: string; safelistLoading: string; safelistProject: string; safelistRevoke: string; safelistRevoking: string; safelistTitle: string }
```

**Returns** `{ approvalAllow: string; approvalAllowForSession: string; approvalAllowNoneSelected: string; approvalAllowOnce: string; approvalAlwaysAllow: string; approvalApplySelected: (selected: number, total: number) => string; approvalClose: string; approvalConcern: (concern: ModelApproval) => string; approvalCwd: (cwd: string) => string; approvalDeny: string; approvalFileEditNoPath: string; approvalFileEditReview: string; approvalFileEditTitle: (tool: string, path: string | null) => string; approvalFromSubagent: (label: string) => string; approvalRunAfter: string; approvalRunBefore: string; approvalsError: (error: ApprovalsError) => string; approvalTimeout: (timeout: string) => string; hunkAdded: (count: number) => string; hunkAmbiguous: (matches: number) => string; hunkAmbiguousHint: (matches: number) => string; hunkFile: string; hunkInclude: (index: number, total: number) => string; hunkNewFile: string; hunkNotInFile: string; hunkNotInFileHint: string; hunkRemoved: (count: number) => string; hunkReplaceAll: string; hunksClear: string; hunksOf: string; hunksSelectAll: string; hunksSelected: string; hunksSomeMissing: string; hunkTitle: (index: number, total: number) => string; hunkVia: (via: string) => string; hunkViaHint: (via: string) => string; safelistCount: (count: number) => string; safelistDescription: string; safelistEmpty: string; safelistEmptyHint: string; safelistLoading: string; safelistProject: string; safelistRevoke: string; safelistRevoking: string; safelistTitle: string }`

Source: [ui/src/approvals/ApprovalsProvider.tsx:107](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalsProvider.tsx#L107)

### `usePendingApprovals`

Function.

Returns every pending approval, oldest first. Re-renders on every change to the queue.

```ts
function usePendingApprovals(): readonly WireApprovalRequest[]
```

**Returns** `readonly WireApprovalRequest[]`

Source: [ui/src/approvals/ApprovalsProvider.tsx:74](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalsProvider.tsx#L74)

### `useResolveApproval`

Function.

Returns `resolve`: answers a pending approval through the host, ignoring a failed send (the
request already left the queue). `undefined` when the host can't answer approvals.

```ts
function useResolveApproval(): ((requestId: string, decision: ApprovalDecision) => void) | undefined
```

**Returns** `((requestId: string, decision: ApprovalDecision) => void) | undefined`

Source: [ui/src/approvals/ApprovalsProvider.tsx:95](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalsProvider.tsx#L95)

### `useSessionApprovalHead`

Function.

Returns the first pending approval of `sessionId`, or `null`. Re-renders only when that
session's first approval changes, so rows of other sessions stay still.

```ts
function useSessionApprovalHead(sessionId: string | null): WireApprovalRequest | null
```

**Parameters**

- `sessionId` (`string | null`): The session, or `null` for none.

**Returns** `WireApprovalRequest | null`

Source: [ui/src/approvals/ApprovalsProvider.tsx:84](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalsProvider.tsx#L84)

## Interfaces

### `ApprovalBarProps`

Interface.

Props for [`ApprovalBar`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalBar).

```ts
interface ApprovalBarProps
```

**Properties**

- `className?` (`string`): Extra classes on the inline card's root.
- `onFileEdit?` (`(request: WireApprovalRequest) => void`): Opens the file-edit review for an `edit`, `multi_edit` or `write_file` approval on the
  app's modal layer (once per request; the bar then renders nothing). Absent: the bar renders
  [`FileEditApproval`](https://zidane.si/docs/reference/ui-approvals.md#FileEditApproval) in place.
- `renderFrame?` (`(props: ApprovalFrameProps) => ReactElement`): Draws the inline card's surface. See `ApprovalCardProps.renderFrame`.
- `sessionId` (`string | null`): The session whose first pending approval shows. `null`: nothing shows.
- `style?` (`CSSProperties`): Inline styles on the inline card's root.

Source: [ui/src/approvals/ApprovalBar.tsx:169](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalBar.tsx#L169)

### `ApprovalCardProps`

Interface.

Props for [`ApprovalCard`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalCard).

```ts
interface ApprovalCardProps
```

**Properties**

- `className?` (`string`): Extra classes on the root (the `alertdialog`).
- `onResolve?` (`(requestId: string, decision: ApprovalDecision) => void`): Called with the user's decision. Absent: the card shows the request without its buttons.
- `renderFrame?` (`(props: ApprovalFrameProps) => ReactElement`): Draws the card's surface (an app's own dock card). Default: a raised card tinted with the warn color.
- `request` (`WireApprovalRequest`): The pending approval to show.
- `style?` (`CSSProperties`): Inline styles on the root.

Source: [ui/src/approvals/ApprovalBar.tsx:65](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalBar.tsx#L65)

### `ApprovalConcernProps`

Interface.

Props for [`ApprovalConcern`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalConcern).

```ts
interface ApprovalConcernProps
```

**Properties**

- `className?` (`string`): Extra classes on the line.
- `concern` (`ModelApproval`): The decision model's verdict, from the request's `concern`.
- `style?` (`CSSProperties`): Inline styles on the line.

Source: [ui/src/approvals/ApprovalConcern.tsx:11](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalConcern.tsx#L11)

### `ApprovalFrameProps`

Interface.

What `ApprovalCardProps.renderFrame` receives: the card's layout classes and its content.

```ts
interface ApprovalFrameProps
```

**Properties**

- `children` (`ReactNode`): The card's content.
- `className` (`string`): The card's layout classes (a column, capped in height), to put on the frame.
- `tone` (`'attention'`): Always `attention`: the frame of something waiting for the user.

Source: [ui/src/approvals/ApprovalBar.tsx:33](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalBar.tsx#L33)

### `ApprovalShellProps`

Interface.

What a shell receives: the panel's title, description, content and footer, and how to close it.

```ts
interface ApprovalShellProps
```

**Properties**

- `children` (`ReactNode`): The body.
- `className?` (`string`): Extra classes on the panel.
- `description?` (`string`): A line under the heading.
- `footer?` (`ReactNode`): The actions row under the body.
- `onClose?` (`() => void`): Called by the close button (the file-edit review denies). Absent: no close button.
- `style?` (`CSSProperties`): Inline styles on the panel.
- `title` (`string`): The panel's heading.

Source: [ui/src/approvals/ApprovalShell.tsx:14](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalShell.tsx#L14)

### `ApprovalsProviderProps`

Interface.

Props for [`ApprovalsProvider`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalsProvider).

```ts
interface ApprovalsProviderProps
```

**Properties**

- `children` (`ReactNode`): The components that read from `host`.
- `host` (`ApprovalsHost`): The host the approval components read pending approvals from and send decisions to.
- `labels?` (`Partial<{ approvalAllow: string; approvalAllowForSession: string; approvalAllowNoneSelected: string; approvalAllowOnce: string; approvalAlwaysAllow: string; approvalApplySelected: (selected: number, total: number) => string; approvalClose: string; approvalConcern: (concern: ModelApproval) => string; approvalCwd: (cwd: string) => string; approvalDeny: string; approvalFileEditNoPath: string; approvalFileEditReview: string; approvalFileEditTitle: (tool: string, path: string | null) => string; approvalFromSubagent: (label: string) => string; approvalRunAfter: string; approvalRunBefore: string; approvalsError: (error: ApprovalsError) => string; approvalTimeout: (timeout: string) => string; hunkAdded: (count: number) => string; hunkAmbiguous: (matches: number) => string; hunkAmbiguousHint: (matches: number) => string; hunkFile: string; hunkInclude: (index: number, total: number) => string; hunkNewFile: string; hunkNotInFile: string; hunkNotInFileHint: string; hunkRemoved: (count: number) => string; hunkReplaceAll: string; hunksClear: string; hunksOf: string; hunksSelectAll: string; hunksSelected: string; hunksSomeMissing: string; hunkTitle: (index: number, total: number) => string; hunkVia: (via: string) => string; hunkViaHint: (via: string) => string; safelistCount: (count: number) => string; safelistDescription: string; safelistEmpty: string; safelistEmptyHint: string; safelistLoading: string; safelistProject: string; safelistRevoke: string; safelistRevoking: string; safelistTitle: string }>`): Overrides for the approval components' strings. Keys you leave out keep the default English label.

Source: [ui/src/approvals/ApprovalsProvider.tsx:36](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/ApprovalsProvider.tsx#L36)

### `FileEditApprovalProps`

Interface.

Props for [`FileEditApproval`](https://zidane.si/docs/reference/ui-approvals.md#FileEditApproval).

```ts
interface FileEditApprovalProps
```

**Properties**

- `className?` (`string`): Extra classes on the default shell.
- `onDone?` (`() => void`): Called once the user decided, or when the request was answered elsewhere: close the modal that holds the review.
- `renderShell?` (`(props: ApprovalShellProps) => ReactNode`): Draws the panel around the review (an app's own modal shell). It receives the title,
  description, body, footer and `onClose` (which denies). Default: [`ApprovalShell`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalShell).
- `request` (`WireApprovalRequest`): The pending `edit`, `multi_edit` or `write_file` approval.
- `style?` (`CSSProperties`): Inline styles on the default shell.

Source: [ui/src/approvals/FileEditApproval.tsx:57](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/FileEditApproval.tsx#L57)

### `SafelistPanelProps`

Interface.

Props for [`SafelistPanel`](https://zidane.si/docs/reference/ui-approvals.md#SafelistPanel).

```ts
interface SafelistPanelProps
```

**Properties**

- `className?` (`string`): Extra classes on the default shell.
- `renderShell?` (`(props: ApprovalShellProps) => ReactNode`): Draws the panel around the list (an app's own modal shell). It receives the title, description and body. Default: [`ApprovalShell`](https://zidane.si/docs/reference/ui-approvals.md#ApprovalShell).
- `style?` (`CSSProperties`): Inline styles on the default shell.

Source: [ui/src/approvals/SafelistPanel.tsx:17](https://github.com/Tahul/zidane/blob/main/ui/src/approvals/SafelistPanel.tsx#L17)
