React Integration
The @mandaitor/react package provides ready-to-use React components and hooks for building delegation flows into product UIs. This guide now shows live previews for the full public component set, with mocked documentation data wherever a component would normally talk to the Mandaitor backend. That keeps the page stable on docs.mandaitor.io while still rendering the real library components, not screenshots or simplified replicas.
Installation
npm install @mandaitor/react @mandaitor/sdk react react-dom
Setup: MandaitorProvider
Wrap your application, or the relevant subtree, with the MandaitorProvider. This makes the SDK client available to all child components via React Context.
import { MandaitorProvider } from "@mandaitor/react";
function App() {
return (
<MandaitorProvider
tenantId="tnt_your_tenant_id"
apiKey={process.env.REACT_APP_MANDAITOR_API_KEY}
theme={{
primaryColor: "#2dd4a8",
mode: "dark",
}}
>
<YourApp />
</MandaitorProvider>
);
}
In production, the provider should point to your real tenant, credentials, and runtime environment. In the documentation previews below, the provider is wrapped with a docs-only mock layer so data-dependent components render consistently without live credentials.
Components
MandateCreator
MandateCreator renders a form for creating mandates with action selection, scope defaults, and constraint inputs.
import { MandateCreator } from "@mandaitor/react";
<MandateCreator
availableActions={[
{ id: "construction.validation.approve", label: "Approve Validation" },
{ id: "construction.validation.flag", label: "Flag Issue" },
]}
defaultResources={["monco:project:proj_123/*"]}
onMandateCreated={(mandate) => console.log("Created:", mandate.mandate_id)}
/>;
MandateViewer
MandateViewer displays a single mandate, including scope, constraints, and optional event history.
import { MandateViewer } from "@mandaitor/react";
<MandateViewer mandateId="mdt_abc123" showAuditTrail showProof />;
MandateVerifier
MandateVerifier lets users check whether a specific action is currently authorized under a mandate.
import { MandateVerifier } from "@mandaitor/react";
<MandateVerifier
defaultMandateId="mdt_abc123"
defaultAction="construction.validation.approve"
defaultResource="monco:project:proj_123/*"
requestPoM
onResult={(result) => console.log(result.decision)}
/>;
MandateManager
MandateManager loads a paginated mandate list and exposes operational actions such as suspend, reactivate, and revoke.
import { MandateManager } from "@mandaitor/react";
<MandateManager onMandateSelect={(mandate) => navigate(`/mandates/${mandate.mandate_id}`)} />;
OverlayShell
OverlayShell provides a floating management widget with a summary view, mandate management, and mandate creation in one container.
import { OverlayShell } from "@mandaitor/react";
<OverlayShell
position="right"
width={420}
activeMandate={currentMandate}
availableActions={[
{ id: "construction.validation.approve", label: "Approve Validation" },
{ id: "construction.validation.flag", label: "Flag Issue" },
]}
defaultResources={["monco:project:proj_123/*"]}
onMandateCreated={(mandate) => console.log("Created:", mandate.mandate_id)}
onStatusChange={(mandate, status) => console.log("Status:", status)}
/>;
Key props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state |
defaultOpen | boolean | false | Default open state for the uncontrolled variant |
onOpenChange | (open: boolean) => void | — | Callback when the shell opens or closes |
position | "right" | "left" | "bottom-right" | "bottom-left" | "right" | Placement of the overlay panel |
width | number | 420 | Width of the panel in pixels |
activeMandate | Mandate | — | Currently active mandate shown in the summary view |
availableActions | ActionOption[] | [] | Action list passed through to the embedded mandate creator |
defaultResources | string[] | [] | Default resources passed through to the embedded mandate creator |
onMandateCreated | (mandate: Mandate) => void | — | Callback when the creator issues a new mandate |
onStatusChange | (mandate: Mandate, status: MandateStatus) => void | — | Callback when the manager changes a mandate status |
MandateWizard
MandateWizard provides a guided, multi-step creation flow with risk-aware action metadata and a final review step.
import { MandateWizard } from "@mandaitor/react";
<MandateWizard
availableActions={[
{
id: "construction.validation.approve",
label: "Approve Validation",
description: "Approve a construction validation step",
riskLevel: "MEDIUM",
},
{
id: "construction.documentation.sign",
label: "Sign Documentation",
description: "Digitally sign construction documents",
riskLevel: "HIGH",
requiresHumanApproval: true,
},
]}
templates={[
{
id: "read-only",
name: "Read-Only Access",
description: "Allow viewing but no modifications",
actions: ["data.read"],
},
]}
availableResources={["monco:project:proj_123/*"]}
defaultResources={["monco:project:proj_123/*"]}
onMandateCreated={(mandate) => console.log("Created:", mandate.mandate_id)}
/>;
Wizard steps
- Agent — Define who the delegate is.
- Permissions — Select actions, templates, and resources.
- Validity — Set time bounds and additional constraints.
- Preview & Activate — Review the final mandate before issuing it.
ApiKeyManager
ApiKeyManager provides a tenant-facing UI for listing, creating, and revoking API keys.
import { ApiKeyManager } from "@mandaitor/react";
<ApiKeyManager tenantId="tnt_your_tenant_id" />;
WidgetConfigDashboard
WidgetConfigDashboard exposes the configuration surface for identity providers, branding, templates, webhooks, and approval defaults.
import { WidgetConfigDashboard } from "@mandaitor/react";
<WidgetConfigDashboard />;
The component uses the MandaitorConfigClient from provider context, so in a real application it still requires a valid tenant and config-authenticated provider setup.
How the documentation previews work
The documentation previews render the real React components for the stable public examples, not screenshots or static HTML mocks. To make that safe and reliable on the docs site, the preview wrapper does two things:
| Preview concern | Documentation behavior |
|---|---|
| Provider context | Supplies a docs-only MandaitorProvider with demo tenant settings |
| Backend-dependent requests | Intercepts component fetches and returns representative mock responses |
| Viewer and manager state | Returns sample mandates and sample event history |
| Verification flows | Returns mocked allow decisions and a sample Proof-of-Mandate VC |
| Tenant dashboard flows | Served through a docs-only mocked tenant and config layer so admin-facing components can be explored safely |
This means readers can inspect the real rendered component surface across both evaluator-facing and admin-facing flows while the production docs environment stays free of live backend dependencies.
Demo wiring example
If you want the same pattern in Storybook, internal docs, or a local demo environment, the essential setup looks like this:
import { MandaitorProvider, MandateManager } from "@mandaitor/react";
function DemoApp() {
return (
<MandaitorProvider
tenantId="demo-tenant"
apiKey="pk_demo_only"
apiUrl="https://api.demo.mandaitor.io/v1"
theme={{
primaryColor: "#2dd4a8",
mode: "dark",
}}
>
<MandateManager onSelectMandate={(id) => console.log(id)} />
</MandaitorProvider>
);
}
In your own environment, either point the provider at a real sandbox backend or replace the network layer with your own mock adapter for local preview use.
Hooks
useMandate
Fetches a single mandate by ID and can optionally include audit events.
import { useMandate } from "@mandaitor/react";
const { mandate, events, isLoading, error } = useMandate("mdt_abc123", {
includeEvents: true,
});
useMandates
Fetches a paginated list of mandates with optional filtering and incremental loading.
import { useMandates } from "@mandaitor/react";
const { mandates, isLoading, hasMore, loadMore } = useMandates({
status: "ACTIVE",
limit: 20,
});
useMandaitorSDK
Provides direct access to the underlying SDK client for custom interactions.
import { useMandaitorSDK } from "@mandaitor/react";
const { sdk } = useMandaitorSDK();
const result = await sdk.getWidgetConfig();
Recommended next reads
| Document | Why it matters |
|---|---|
| Getting Started | Fastest evaluator path from first contact to first mandate and verification |
| Proof-of-Mandate | Explains the proof artifact that the verifier can return |
| /api-reference | Full API contract, schemas, and endpoint examples |
This page should now give you both the publicly useful live component surfaces and the copyable implementation patterns needed to embed Mandaitor into a React application.