# Guard components

Guards conditionally render children based on connection state, provider selection, and error conditions. Import from `@arlopass/react/guards`.

```tsx
import {
  ArlopassConnectionGate,
  ArlopassProviderGate,
  ArlopassChatReadyGate,
  ArlopassNotInstalled,
  ArlopassDisconnected,
  ArlopassConnected,
  ArlopassProviderNotReady,
  ArlopassHasError,
  ArlopassChatNotReady,
  ArlopassChatReady,
  ArlopassErrorBoundary,
} from "@arlopass/react/guards";
```

---

### Positive gates

Gates render their children when a condition is met and show a fallback otherwise.

#### ArlopassConnectionGate

Renders children when the client is connected. Shows fallbacks for loading, error, and not-installed states.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ` fallback` | ` ReactNode` | `null` | Rendered while connecting or when disconnected. |
| ` errorFallback` | ` (props: { error: ArlopassSDKError; retry: (() => Promise<void>) | null }) => ReactNode` | — | Rendered when connection fails. Receives the error and a retry function. |
| ` notInstalledFallback` | ` ReactNode` | — | Rendered when the Arlopass extension is not installed. |
| ` children`<br>required | ` ReactNode` | — | Rendered when connected (state is "connected" or "degraded"). |

```tsx
<ArlopassConnectionGate
  fallback={<p>Connecting…</p>}
  notInstalledFallback={<p>Please install the Arlopass extension.</p>}
  errorFallback={({ error, retry }) => (
    <div>
      <p>Error: {error.message}</p>
      {retry && <button onClick={retry}>Retry</button>}
    </div>
  )}
>
  <MyApp />
</ArlopassConnectionGate>
```

#### ArlopassProviderGate

Renders children when a provider/model pair is selected.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ` fallback` | ` ReactNode` | `null` | Rendered when no provider is selected. |
| ` loadingFallback` | ` ReactNode` | — | Rendered while providers are being listed. Falls back to fallback if not set. |
| ` children`<br>required | ` ReactNode` | — | Rendered when a provider is selected. |

```tsx
<ArlopassProviderGate fallback={<ProviderPicker />}>  
  <Chat />
</ArlopassProviderGate>
```

#### ArlopassChatReadyGate

All-in-one gate that checks connection, provider selection, and error state. Renders children only when everything is ready to chat.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ` connectingFallback` | ` ReactNode` | `null` | Rendered while connecting. |
| ` notInstalledFallback` | ` ReactNode` | — | Rendered when the extension is not installed. |
| ` providerFallback` | ` ReactNode` | `null` | Rendered when connected but no provider is selected. |
| ` errorFallback` | ` (props: { error: ArlopassSDKError; retry: (() => Promise<void>) | null }) => ReactNode` | — | Rendered on connection failure. |
| ` children`<br>required | ` ReactNode` | — | Rendered when connected and a provider is selected. |

```tsx
<ArlopassChatReadyGate
  connectingFallback={<Spinner />}
  providerFallback={<ProviderPicker />}
>
  <Chat />
</ArlopassChatReadyGate>
```

---

### Negative guards

Negative guards render children when a condition is **not** met. They accept `ReactNode` or a render function as children.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ` ArlopassNotInstalled` | ` Component` | — | Renders children only when the Arlopass extension is not detected. Children type: ReactNode \| (() => ReactNode) |
| ` ArlopassDisconnected` | ` Component` | — | Renders children when the client is not connected (any state except "connected" or "degraded"). Children type: ReactNode \| (() => ReactNode) |
| ` ArlopassConnected` | ` Component` | — | Renders children only when connected ("connected" or "degraded"). Children type: ReactNode \| (() => ReactNode) |
| ` ArlopassProviderNotReady` | ` Component` | — | Renders children when no provider is selected. Children type: ReactNode \| (() => ReactNode) |
| ` ArlopassHasError` | ` Component` | — | Renders children when a connection error is present. Children receive { error, retry } as a render prop. Children type: (props: { error: ArlopassSDKError; retry: (() => Promise<void>) | null }) => ReactNode |
| ` ArlopassChatNotReady` | ` Component` | — | Renders children when chat is not ready (not connected or no provider selected). Children type: ReactNode \| (() => ReactNode) |
| ` ArlopassChatReady` | ` Component` | — | Renders children only when chat is ready (connected and provider selected). Children type: ReactNode \| (() => ReactNode) |

```tsx
<ArlopassNotInstalled>
  <p>Install the Arlopass extension to use AI features.</p>
</ArlopassNotInstalled>

<ArlopassHasError>
  {({ error, retry }) => (
    <div>
      <p>{error.message}</p>
      {retry && <button onClick={retry}>Retry</button>}
    </div>
  )}
</ArlopassHasError>
```

---

### ArlopassErrorBoundary

A React error boundary that catches rendering errors in the child tree. Standard class-component boundary with a render-prop fallback.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ` fallback`<br>required | ` (props: { error: Error; resetErrorBoundary: () => void }) => ReactNode` | — | Render prop called when an error is caught. Receives the error and a reset function. |
| ` onError` | ` (error: Error, errorInfo: ErrorInfo) => void` | — | Optional callback for logging or telemetry. |
| ` children`<br>required | ` ReactNode` | — | Child tree to wrap with the error boundary. |

```tsx
<ArlopassErrorBoundary
  fallback={({ error, resetErrorBoundary }) => (
    <div>
      <p>Something went wrong: {error.message}</p>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  )}
  onError={(err, info) => console.error(err, info)}
>
  <Chat />
</ArlopassErrorBoundary>
```
