{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ai-note",
  "title": "AI note",
  "description": "An AI-drafted clinical note whose claims cite the records they rely on, with unsupported claims marked for review.",
  "dependencies": [
    "cn@^0.5.0"
  ],
  "registryDependencies": [
    "@organui/clinical-citation",
    "@organui/clinical-sources"
  ],
  "files": [
    {
      "path": "registry/base-nova/ai-note/ai-note.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\nimport {\n  ClinicalCitation,\n  type ClinicalSource,\n} from \"@/components/ui/clinical-citation\"\nimport { ClinicalSources } from \"@/components/ui/clinical-sources\"\n\n/**\n * Text joining claims, or a claim with the ids of the sources it relies on.\n * A claim with no sources is marked as unsupported.\n */\nexport type AiNoteSegment =\n  string | { text: string; sources?: readonly string[] }\n\nexport type AiNoteSection = {\n  id: string\n  /** The section's name, such as \"Assessment\". */\n  title: string\n  /** The section's text, claim by claim. */\n  content: readonly AiNoteSegment[]\n}\n\nexport type AiNoteProps = React.ComponentProps<\"article\"> & {\n  /**\n   * The note's sections, in order: `{ id, title, content }`, where content\n   * mixes plain strings, which join claims, with claims: `{ text, sources }`.\n   */\n  sections: readonly AiNoteSection[]\n  /** The records the note may cite; the list under it shows those it does. */\n  sources?: readonly ClinicalSource[]\n  /** Underlines claims without a source and says so to screen readers. */\n  markUnsupported?: boolean\n  /** Names the note for assistive technology. */\n  label?: string\n}\n\n// A dotted underline marks a claim without a source, here and in the key.\nconst unsupportedMark =\n  \"underline decoration-muted-foreground decoration-dotted decoration-2 underline-offset-4\"\n\n/**\n * An AI-drafted clinical note: each claim cites the records it relies on,\n * and claims without one are marked, so a reviewer can see what to\n * check. Pair it with AiDisclaimer and ClinicianReview.\n */\nexport function AiNote({\n  sections,\n  sources = [],\n  markUnsupported = true,\n  label = \"AI-drafted note\",\n  className,\n  ...props\n}: AiNoteProps) {\n  const unsupported = sections.some((section) =>\n    section.content.some(\n      (segment) => typeof segment !== \"string\" && !segment.sources?.length\n    )\n  )\n  // The records the note cites, in the order it first cites them.\n  const citedIds = new Set(\n    sections.flatMap((section) =>\n      section.content.flatMap((segment) =>\n        typeof segment === \"string\" ? [] : (segment.sources ?? [])\n      )\n    )\n  )\n  const cited = [...citedIds].flatMap(\n    (id) => sources.find((source) => source.id === id) ?? []\n  )\n  return (\n    <article\n      data-slot=\"ai-note\"\n      aria-label={label}\n      className={cn(\"flex flex-col gap-4 text-sm\", className)}\n      {...props}\n    >\n      {sections.map((section) => (\n        // Named sections rather than headings, so the note fits under any\n        // heading level on the page that shows it.\n        <section\n          key={section.id}\n          aria-label={section.title}\n          className=\"flex flex-col gap-1\"\n        >\n          <p className=\"font-medium\">{section.title}</p>\n          <p className=\"leading-relaxed\">\n            {section.content.map((segment, index) => {\n              if (typeof segment === \"string\")\n                return <React.Fragment key={index}>{segment}</React.Fragment>\n              const cited = (segment.sources ?? []).flatMap((id) => {\n                const source = sources.find((entry) => entry.id === id)\n                return source ? [source] : []\n              })\n              if (cited.length === 0 && markUnsupported)\n                return (\n                  <span key={index} className={unsupportedMark}>\n                    {segment.text}\n                    <span className=\"sr-only\"> (no source)</span>\n                  </span>\n                )\n              return (\n                <React.Fragment key={index}>\n                  {segment.text}\n                  {cited.map((source) => (\n                    <ClinicalCitation key={source.id} source={source} />\n                  ))}\n                </React.Fragment>\n              )\n            })}\n          </p>\n        </section>\n      ))}\n      {markUnsupported && unsupported && (\n        <p className=\"text-xs text-muted-foreground\">\n          <span className={unsupportedMark}>Dotted text</span> has no source.\n          Check it against the record.\n        </p>\n      )}\n      <ClinicalSources sources={cited} />\n    </article>\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "docs": "AI note docs: https://organui.com/docs/ai-elements/ai-note",
  "categories": [
    "ai"
  ],
  "type": "registry:ui"
}