PCN React components and claims context for rendering verified/pending claims.
npm install @pcn-js/uiReact components and claims context for rendering PCN verified/pending claims in the UI.
``bash`
pnpm add @pcn-js/core @pcn-js/ui react
For Data360 get_data (claim_id, OBS_VALUE, REF_AREA, TIME_PERIOD), use the preset: @pcn/data360. It provides Data360ClaimsProvider and DATA360_GET_DATA_TOOL.
Create a ClaimsManager, register extractors for tools that return claim_id, and wrap your app (or chat) in ClaimsProvider so components can look up claims.
`tsx
import { ClaimsManager, createDataPointExtractor } from "@pcn-js/core";
import { ClaimsProvider, ClaimMark, useClaimsManager } from "@pcn-js/ui";
const manager = new ClaimsManager();
// When get_data returns { data: [{ claim_id, OBS_VALUE, REF_AREA, TIME_PERIOD, ... }] }
manager.registerExtractor(
"get_data",
createDataPointExtractor({
dataKey: "data",
claimIdKey: "claim_id",
valueKey: "OBS_VALUE",
countryKey: "REF_AREA",
dateKey: "TIME_PERIOD",
})
);
function App() {
return (
);
}
`
When a tool result arrives, either use the IngestToolOutput component (works with any provider, including Data360’s Data360ClaimsProvider):
`tsx`
Or call manager.ingest(toolName, result) yourself:
`tsx
function Chat() {
const manager = useClaimsManager();
useEffect(() => {
if (toolName === "get_data") manager?.ingest("get_data", toolResult);
}, [toolName, toolResult, manager]);
return (/ ... /);
}
`
Use ClaimMark where you render claim content (e.g. as a custom component for in your markdown renderer). It looks up the claim by id, runs the policy comparison, and renders the content plus ✓ or ⚠. Hovering (or focusing) the mark shows a tooltip with claim details (country, date, source value, display rule).
`tsx
import { ClaimMark } from "@pcn-js/ui";
// In your markdown components or stream renderer:
42
`
Tooltip behavior: By default the tooltip stays open briefly (150 ms) after the pointer leaves the mark, so you can move the cursor onto the tooltip to read or copy. Set tooltipHideDelayMs={0} for immediate hide (original behavior), or a custom value (e.g. 300) for a longer delay.
If you use Streamdown or react-markdown with rehype-raw, pass the built-in claim component so raw HTML tags are rendered as ClaimMark and tables/layout stay intact:
`tsx
import { Streamdown } from "streamdown";
import { streamdownClaimComponents } from "@pcn-js/ui";
{markdownContent}
`
Or use the component directly: components={{ claim: ClaimMarkStreamdown }}. The model can emit markdown with inside table cells or paragraphs.
If you have a fixed map of claims (e.g. from server props), pass initialClaims and omit manager:
`tsx`
- IngestToolOutput – ingests a tool result into the manager when mounted; toolName, output, childrenmanager?: ClaimsManager
- ClaimsProvider – , initialClaims?: Record, childrenRecord
- useClaims() – returns ClaimsManager | null
- useClaimsManager() – returns Claim | undefined
- useClaim(id) – returns id
- ClaimMark – , policy, children (the displayed text to verify), optional tooltipHideDelayMs?: number (ms before hiding tooltip on leave; default 150; use 0 for immediate hide)components.claim
- ClaimMarkStreamdown – component for react-markdown/Streamdown (props: id, policy, decimals, tolerance, children from raw HTML){ claim: ClaimMarkStreamdown }
- streamdownClaimComponents – for
Optional styles: import "@pcn-js/ui/styles.css" for .pcn-claim, .verified-mark, .verify-pending`.