{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "patient-results-editor",
  "title": "Patient Results Editor",
  "description": "BlockNote-powered editor with the patient results custom block family registered.",
  "dependencies": [
    "@blocknote/core",
    "@blocknote/shadcn"
  ],
  "registryDependencies": [
    "@blocks/diagnostic-interpretation-columns",
    "@blocks/diagnostic-metric-donut-card",
    "@blocks/diagnostic-metric-range-card",
    "@blocks/diagnostic-metric-split-card",
    "@blocks/diagnostic-metric-stat-card",
    "@blocks/segment-muscle-analysis",
    "@circle-ui/button",
    "@circle-ui/utils"
  ],
  "files": [
    {
      "path": "registry/berlin/blocks/patient-results/editor/patient-results-editor.tsx",
      "content": "// Generated from packages/ui/src/components/patient-results/editor/patient-results-editor.tsx\n\"use client\";\n\nimport * as React from \"react\";\n\nimport { BlockNoteSchema, PartialBlock } from \"@blocknote/core\";\nimport { filterSuggestionItems } from \"@blocknote/core\";\nimport {\n  DefaultReactSuggestionItem,\n  SuggestionMenuController,\n  createReactBlockSpec,\n  getDefaultReactSlashMenuItems,\n  useCreateBlockNote,\n} from \"@blocknote/react\";\nimport { BlockNoteView } from \"@blocknote/shadcn\";\n\nimport { Button } from \"@/registry/berlin/circle-ui/button\";\nimport { cn } from \"@/registry/berlin/lib/utils\";\nimport { DiagnosticInterpretationColumns } from \"@/registry/berlin/blocks/diagnostic-interpretation-columns\";\nimport { DiagnosticMetricDonutCard } from \"@/registry/berlin/blocks/diagnostic-metric-donut-card\";\nimport { DiagnosticMetricRangeCard } from \"@/registry/berlin/blocks/diagnostic-metric-range-card\";\nimport { DiagnosticMetricSplitCard } from \"@/registry/berlin/blocks/diagnostic-metric-split-card\";\nimport { DiagnosticMetricStatCard } from \"@/registry/berlin/blocks/diagnostic-metric-stat-card\";\nimport { SegmentMuscleAnalysis } from \"@/registry/berlin/blocks/segment-muscle-analysis\";\nimport {\n  getPatientResultsPreset,\n  patientResultsPresets,\n} from \"@/registry/berlin/blocks/patient-results-presets\";\nimport type {\n  DiagnosticInterpretationColumnsProps,\n  DiagnosticMetricDonutCardProps,\n  DiagnosticMetricRangeCardProps,\n  DiagnosticMetricSplitCardProps,\n  DiagnosticMetricStatCardProps,\n  DiagnosticStatusBadge,\n  PatientResultsBlock,\n  PatientResultsBlockType,\n  SegmentMuscleAnalysisProps,\n} from \"@/registry/berlin/blocks/patient-results-types\";\n\nimport \"@blocknote/core/fonts/inter.css\";\nimport \"@blocknote/shadcn/style.css\";\n\nconst toneValues = [\n  \"average\",\n  \"below-average\",\n  \"normal\",\n  \"supporting\",\n] as const;\n\nfunction readStatus(\n  label: string,\n  tone: string,\n): DiagnosticStatusBadge | undefined {\n  if (!label.trim()) return undefined;\n\n  return {\n    label,\n    tone: toneValues.includes(tone as DiagnosticStatusBadge[\"tone\"])\n      ? (tone as DiagnosticStatusBadge[\"tone\"])\n      : \"supporting\",\n  };\n}\n\nfunction parseCsvNumbers(value: string) {\n  return value\n    .split(\",\")\n    .map((item) => Number(item.trim()))\n    .filter((item) => Number.isFinite(item));\n}\n\nfunction parseJsonValue<T>(value: string, fallback: T): T {\n  try {\n    return JSON.parse(value) as T;\n  } catch {\n    return fallback;\n  }\n}\n\nfunction formatNumber(value: number) {\n  return Number.isFinite(value) ? value : 0;\n}\n\nfunction Field({\n  label,\n  value,\n  onChange,\n  type = \"text\",\n}: {\n  label: string;\n  value: string | number;\n  onChange: (value: string) => void;\n  type?: \"number\" | \"text\";\n}) {\n  return (\n    <label className=\"space-y-1\">\n      <span className=\"text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground\">\n        {label}\n      </span>\n      <input\n        type={type}\n        value={value}\n        onChange={(event) => onChange(event.target.value)}\n        className=\"w-full rounded-md border border-black/10 bg-white px-3 py-2 text-sm text-black\"\n      />\n    </label>\n  );\n}\n\nfunction TextAreaField({\n  label,\n  value,\n  onChange,\n}: {\n  label: string;\n  value: string;\n  onChange: (value: string) => void;\n}) {\n  return (\n    <label className=\"space-y-1\">\n      <span className=\"text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground\">\n        {label}\n      </span>\n      <textarea\n        value={value}\n        onChange={(event) => onChange(event.target.value)}\n        className=\"min-h-24 w-full rounded-md border border-black/10 bg-white px-3 py-2 text-sm text-black\"\n      />\n    </label>\n  );\n}\n\nfunction BlockEditorFrame({\n  title,\n  children,\n  fields,\n  editable,\n}: {\n  title: string;\n  children: React.ReactNode;\n  fields?: React.ReactNode;\n  editable: boolean;\n}) {\n  return (\n    <div className=\"rounded-[20px] border border-dashed border-black/10 bg-[#faf8f5] p-4\">\n      <div className=\"mb-3 text-xs font-medium uppercase tracking-[0.08em] text-muted-foreground\">\n        {title}\n      </div>\n      {children}\n      {editable && fields ? (\n        <div className=\"mt-4 grid gap-3 md:grid-cols-2\">{fields}</div>\n      ) : null}\n    </div>\n  );\n}\n\nconst diagnosticMetricRangeBlock = createReactBlockSpec(\n  {\n    type: \"diagnosticMetricRange\",\n    propSchema: {\n      title: { default: \"Metric\" },\n      value: { default: 0 },\n      unit: { default: \"\" },\n      statusLabel: { default: \"\" },\n      statusTone: { default: \"supporting\", values: toneValues },\n      ticksCsv: { default: \"0,25,50,75,100\" },\n      min: { default: 0 },\n      max: { default: 100 },\n      pointerValue: { default: 50 },\n      highlightStart: { default: 0 },\n      highlightEnd: { default: 100 },\n      summary: { default: \"\" },\n      layout: { default: \"compact\", values: [\"compact\", \"hero\"] as const },\n    },\n    content: \"none\" as const,\n  },\n  {\n    render: ({ block, editor }) => {\n      const props: DiagnosticMetricRangeCardProps = {\n        title: block.props.title,\n        value: formatNumber(block.props.value),\n        unit: block.props.unit || undefined,\n        status: readStatus(block.props.statusLabel, block.props.statusTone),\n        ticks: parseCsvNumbers(block.props.ticksCsv),\n        min: formatNumber(block.props.min),\n        max: formatNumber(block.props.max),\n        pointerValue: formatNumber(block.props.pointerValue),\n        highlightStart: formatNumber(block.props.highlightStart),\n        highlightEnd: formatNumber(block.props.highlightEnd),\n        summary: block.props.summary || undefined,\n        layout: block.props.layout,\n      };\n\n      return (\n        <BlockEditorFrame\n          title=\"Range Metric\"\n          editable={editor.isEditable}\n          fields={\n            <>\n              <Field\n                label=\"Title\"\n                value={block.props.title}\n                onChange={(title) =>\n                  editor.updateBlock(block, { props: { title } })\n                }\n              />\n              <Field\n                label=\"Value\"\n                value={block.props.value}\n                type=\"number\"\n                onChange={(value) =>\n                  editor.updateBlock(block, { props: { value: Number(value) } })\n                }\n              />\n              <Field\n                label=\"Unit\"\n                value={block.props.unit}\n                onChange={(unit) =>\n                  editor.updateBlock(block, { props: { unit } })\n                }\n              />\n              <Field\n                label=\"Ticks\"\n                value={block.props.ticksCsv}\n                onChange={(ticksCsv) =>\n                  editor.updateBlock(block, { props: { ticksCsv } })\n                }\n              />\n            </>\n          }\n        >\n          <DiagnosticMetricRangeCard {...props} />\n        </BlockEditorFrame>\n      );\n    },\n  },\n);\n\nconst diagnosticMetricDonutBlock = createReactBlockSpec(\n  {\n    type: \"diagnosticMetricDonut\",\n    propSchema: {\n      title: { default: \"Metric\" },\n      value: { default: 0 },\n      unit: { default: \"\" },\n      progress: { default: 0.5 },\n      summary: { default: \"\" },\n      size: { default: \"regular\", values: [\"compact\", \"regular\"] as const },\n    },\n    content: \"none\" as const,\n  },\n  {\n    render: ({ block, editor }) => {\n      const props: DiagnosticMetricDonutCardProps = {\n        title: block.props.title,\n        value: formatNumber(block.props.value),\n        unit: block.props.unit || undefined,\n        progress: formatNumber(block.props.progress),\n        summary: block.props.summary || undefined,\n        size: block.props.size,\n      };\n\n      return (\n        <BlockEditorFrame\n          title=\"Donut Metric\"\n          editable={editor.isEditable}\n          fields={\n            <>\n              <Field\n                label=\"Title\"\n                value={block.props.title}\n                onChange={(title) =>\n                  editor.updateBlock(block, { props: { title } })\n                }\n              />\n              <Field\n                label=\"Value\"\n                value={block.props.value}\n                type=\"number\"\n                onChange={(value) =>\n                  editor.updateBlock(block, { props: { value: Number(value) } })\n                }\n              />\n              <Field\n                label=\"Progress\"\n                value={block.props.progress}\n                type=\"number\"\n                onChange={(progress) =>\n                  editor.updateBlock(block, {\n                    props: { progress: Number(progress) },\n                  })\n                }\n              />\n              <Field\n                label=\"Summary\"\n                value={block.props.summary}\n                onChange={(summary) =>\n                  editor.updateBlock(block, { props: { summary } })\n                }\n              />\n            </>\n          }\n        >\n          <DiagnosticMetricDonutCard {...props} />\n        </BlockEditorFrame>\n      );\n    },\n  },\n);\n\nconst diagnosticMetricSplitBlock = createReactBlockSpec(\n  {\n    type: \"diagnosticMetricSplit\",\n    propSchema: {\n      title: { default: \"Metric\" },\n      summary: { default: \"\" },\n      leftLabel: { default: \"Left\" },\n      leftValue: { default: 0 },\n      leftFill: { default: 0.5 },\n      rightLabel: { default: \"Right\" },\n      rightValue: { default: 0 },\n      rightFill: { default: 0.5 },\n    },\n    content: \"none\" as const,\n  },\n  {\n    render: ({ block, editor }) => {\n      const props: DiagnosticMetricSplitCardProps = {\n        title: block.props.title,\n        summary: block.props.summary || undefined,\n        left: {\n          label: block.props.leftLabel,\n          value: formatNumber(block.props.leftValue),\n          fill: formatNumber(block.props.leftFill),\n        },\n        right: {\n          label: block.props.rightLabel,\n          value: formatNumber(block.props.rightValue),\n          fill: formatNumber(block.props.rightFill),\n        },\n      };\n\n      return (\n        <BlockEditorFrame\n          title=\"Split Metric\"\n          editable={editor.isEditable}\n          fields={\n            <>\n              <Field\n                label=\"Title\"\n                value={block.props.title}\n                onChange={(title) =>\n                  editor.updateBlock(block, { props: { title } })\n                }\n              />\n              <Field\n                label=\"Summary\"\n                value={block.props.summary}\n                onChange={(summary) =>\n                  editor.updateBlock(block, { props: { summary } })\n                }\n              />\n              <Field\n                label=\"Left label\"\n                value={block.props.leftLabel}\n                onChange={(leftLabel) =>\n                  editor.updateBlock(block, { props: { leftLabel } })\n                }\n              />\n              <Field\n                label=\"Right label\"\n                value={block.props.rightLabel}\n                onChange={(rightLabel) =>\n                  editor.updateBlock(block, { props: { rightLabel } })\n                }\n              />\n            </>\n          }\n        >\n          <DiagnosticMetricSplitCard {...props} />\n        </BlockEditorFrame>\n      );\n    },\n  },\n);\n\nconst diagnosticMetricStatBlock = createReactBlockSpec(\n  {\n    type: \"diagnosticMetricStat\",\n    propSchema: {\n      title: { default: \"Metric\" },\n      value: { default: 0 },\n      unit: { default: \"\" },\n      statusLabel: { default: \"\" },\n      statusTone: { default: \"supporting\", values: toneValues },\n    },\n    content: \"none\" as const,\n  },\n  {\n    render: ({ block, editor }) => {\n      const props: DiagnosticMetricStatCardProps = {\n        title: block.props.title,\n        value: formatNumber(block.props.value),\n        unit: block.props.unit || undefined,\n        status: readStatus(block.props.statusLabel, block.props.statusTone),\n      };\n\n      return (\n        <BlockEditorFrame\n          title=\"Stat Metric\"\n          editable={editor.isEditable}\n          fields={\n            <>\n              <Field\n                label=\"Title\"\n                value={block.props.title}\n                onChange={(title) =>\n                  editor.updateBlock(block, { props: { title } })\n                }\n              />\n              <Field\n                label=\"Value\"\n                value={block.props.value}\n                type=\"number\"\n                onChange={(value) =>\n                  editor.updateBlock(block, { props: { value: Number(value) } })\n                }\n              />\n              <Field\n                label=\"Unit\"\n                value={block.props.unit}\n                onChange={(unit) =>\n                  editor.updateBlock(block, { props: { unit } })\n                }\n              />\n              <Field\n                label=\"Status\"\n                value={block.props.statusLabel}\n                onChange={(statusLabel) =>\n                  editor.updateBlock(block, { props: { statusLabel } })\n                }\n              />\n            </>\n          }\n        >\n          <DiagnosticMetricStatCard {...props} />\n        </BlockEditorFrame>\n      );\n    },\n  },\n);\n\nconst diagnosticInterpretationBlock = createReactBlockSpec(\n  {\n    type: \"diagnosticInterpretation\",\n    propSchema: {\n      meaning: { default: \"\" },\n      improvement: { default: \"\" },\n    },\n    content: \"none\" as const,\n  },\n  {\n    render: ({ block, editor }) => (\n      <BlockEditorFrame\n        title=\"Interpretation\"\n        editable={editor.isEditable}\n        fields={\n          <>\n            <TextAreaField\n              label=\"Meaning\"\n              value={block.props.meaning}\n              onChange={(meaning) =>\n                editor.updateBlock(block, { props: { meaning } })\n              }\n            />\n            <TextAreaField\n              label=\"Improvement\"\n              value={block.props.improvement}\n              onChange={(improvement) =>\n                editor.updateBlock(block, { props: { improvement } })\n              }\n            />\n          </>\n        }\n      >\n        <DiagnosticInterpretationColumns\n          meaning={block.props.meaning}\n          improvement={block.props.improvement}\n        />\n      </BlockEditorFrame>\n    ),\n  },\n);\n\nconst segmentMuscleAnalysisBlock = createReactBlockSpec(\n  {\n    type: \"segmentMuscleAnalysis\",\n    propSchema: {\n      title: { default: \"Segment Muscular Analysis\" },\n      summary: {\n        default: \"Muscle distribution across different body segments\",\n      },\n      figureUrl: { default: \"\" },\n      figureAlt: { default: \"Segment analysis figure\" },\n      hotspotsJson: { default: \"[]\" },\n      leftMetricsJson: { default: \"[]\" },\n      rightMetricsJson: { default: \"[]\" },\n    },\n    content: \"none\" as const,\n  },\n  {\n    render: ({ block, editor }) => {\n      const props: SegmentMuscleAnalysisProps = {\n        title: block.props.title,\n        summary: block.props.summary,\n        figureUrl: block.props.figureUrl,\n        figureAlt: block.props.figureAlt,\n        hotspots: parseJsonValue(block.props.hotspotsJson, []),\n        leftMetrics: parseJsonValue(block.props.leftMetricsJson, []),\n        rightMetrics: parseJsonValue(block.props.rightMetricsJson, []),\n      };\n\n      return (\n        <BlockEditorFrame\n          title=\"Segment Analysis\"\n          editable={editor.isEditable}\n          fields={\n            <>\n              <Field\n                label=\"Title\"\n                value={block.props.title}\n                onChange={(title) =>\n                  editor.updateBlock(block, { props: { title } })\n                }\n              />\n              <Field\n                label=\"Figure URL\"\n                value={block.props.figureUrl}\n                onChange={(figureUrl) =>\n                  editor.updateBlock(block, { props: { figureUrl } })\n                }\n              />\n              <TextAreaField\n                label=\"Left metrics JSON\"\n                value={block.props.leftMetricsJson}\n                onChange={(leftMetricsJson) =>\n                  editor.updateBlock(block, { props: { leftMetricsJson } })\n                }\n              />\n              <TextAreaField\n                label=\"Right metrics JSON\"\n                value={block.props.rightMetricsJson}\n                onChange={(rightMetricsJson) =>\n                  editor.updateBlock(block, { props: { rightMetricsJson } })\n                }\n              />\n            </>\n          }\n        >\n          <SegmentMuscleAnalysis {...props} />\n        </BlockEditorFrame>\n      );\n    },\n  },\n);\n\nexport const patientResultsBlockSpecs = {\n  diagnosticInterpretation: diagnosticInterpretationBlock(),\n  diagnosticMetricDonut: diagnosticMetricDonutBlock(),\n  diagnosticMetricRange: diagnosticMetricRangeBlock(),\n  diagnosticMetricSplit: diagnosticMetricSplitBlock(),\n  diagnosticMetricStat: diagnosticMetricStatBlock(),\n  segmentMuscleAnalysis: segmentMuscleAnalysisBlock(),\n};\n\nexport const patientResultsBlockSchema = BlockNoteSchema.create({\n  blockSpecs: {\n    ...patientResultsBlockSpecs,\n  },\n});\n\nexport type PatientResultsEditorBlock = PartialBlock<\n  (typeof patientResultsBlockSchema)[\"blockSchema\"]\n>;\n\nconst blockTypeTitles: Record<PatientResultsBlockType, string> = {\n  diagnosticInterpretation: \"Interpretation columns\",\n  diagnosticMetricDonut: \"Donut metric\",\n  diagnosticMetricRange: \"Range metric\",\n  diagnosticMetricSplit: \"Split metric\",\n  diagnosticMetricStat: \"Stat metric\",\n  segmentMuscleAnalysis: \"Segment analysis\",\n};\n\nfunction blockTypeToSuggestionItem(\n  editor: any,\n  blockType: PatientResultsBlockType,\n  presetId?: keyof typeof patientResultsPresets,\n): DefaultReactSuggestionItem {\n  return {\n    title: blockTypeTitles[blockType],\n    group: \"Patient Results\",\n    aliases: [blockType],\n    onItemClick: () => {\n      insertPatientResultsBlock(editor, blockType, presetId);\n    },\n  };\n}\n\nexport function insertPatientResultsBlock(\n  editor: any,\n  blockType: PatientResultsBlockType,\n  presetId?: keyof typeof patientResultsPresets,\n) {\n  const currentBlock = editor.getTextCursorPosition().block;\n  const block = createPatientResultsInsertionBlock(blockType, presetId);\n  editor.insertBlocks([block], currentBlock, \"after\");\n}\n\nexport function createPatientResultsInsertionBlock(\n  blockType: PatientResultsBlockType,\n  presetId: keyof typeof patientResultsPresets = \"vo2-max-report\",\n): PatientResultsEditorBlock {\n  const preset = getPatientResultsPreset(presetId);\n  const match = preset.pages\n    .flatMap((page) => page.blocks)\n    .find((block) => block.type === blockType);\n\n  if (match) {\n    return convertPresetBlockToEditorBlock(match);\n  }\n\n  return { type: blockType };\n}\n\nexport function convertPresetBlockToEditorBlock(block: {\n  type: PatientResultsBlockType;\n  props: PatientResultsBlock[\"props\"];\n}): PatientResultsEditorBlock {\n  if (block.type === \"diagnosticMetricRange\") {\n    const props = block.props as unknown as DiagnosticMetricRangeCardProps;\n    return {\n      type: block.type,\n      props: {\n        title: props.title,\n        value: props.value,\n        unit: props.unit ?? \"\",\n        statusLabel: props.status?.label ?? \"\",\n        statusTone: props.status?.tone ?? \"supporting\",\n        ticksCsv: props.ticks.join(\",\"),\n        min: props.min,\n        max: props.max,\n        pointerValue: props.pointerValue,\n        highlightStart: props.highlightStart ?? props.min,\n        highlightEnd: props.highlightEnd ?? props.max,\n        summary: props.summary ?? \"\",\n        layout: props.layout ?? \"compact\",\n      },\n    };\n  }\n\n  if (block.type === \"diagnosticMetricDonut\") {\n    const props = block.props as unknown as DiagnosticMetricDonutCardProps;\n    return {\n      type: block.type,\n      props: {\n        title: props.title,\n        value: props.value,\n        unit: props.unit ?? \"\",\n        progress: props.progress,\n        summary: props.summary ?? \"\",\n        size: props.size ?? \"regular\",\n      },\n    };\n  }\n\n  if (block.type === \"diagnosticMetricSplit\") {\n    const props = block.props as unknown as DiagnosticMetricSplitCardProps;\n    return {\n      type: block.type,\n      props: {\n        title: props.title,\n        summary: props.summary ?? \"\",\n        leftLabel: props.left.label,\n        leftValue: props.left.value,\n        leftFill: props.left.fill,\n        rightLabel: props.right.label,\n        rightValue: props.right.value,\n        rightFill: props.right.fill,\n      },\n    };\n  }\n\n  if (block.type === \"diagnosticMetricStat\") {\n    const props = block.props as unknown as DiagnosticMetricStatCardProps;\n    return {\n      type: block.type,\n      props: {\n        title: props.title,\n        value: props.value,\n        unit: props.unit ?? \"\",\n        statusLabel: props.status?.label ?? \"\",\n        statusTone: props.status?.tone ?? \"supporting\",\n      },\n    };\n  }\n\n  if (block.type === \"diagnosticInterpretation\") {\n    const props = block.props as DiagnosticInterpretationColumnsProps;\n    return {\n      type: block.type,\n      props: {\n        meaning: String(props.meaning ?? \"\"),\n        improvement: String(props.improvement ?? \"\"),\n      },\n    };\n  }\n\n  const props = block.props as unknown as SegmentMuscleAnalysisProps;\n  return {\n    type: \"segmentMuscleAnalysis\",\n    props: {\n      title: props.title ?? \"Segment Muscular Analysis\",\n      summary:\n        props.summary ?? \"Muscle distribution across different body segments\",\n      figureUrl: props.figureUrl,\n      figureAlt: props.figureAlt,\n      hotspotsJson: JSON.stringify(props.hotspots),\n      leftMetricsJson: JSON.stringify(props.leftMetrics),\n      rightMetricsJson: JSON.stringify(props.rightMetrics),\n    },\n  };\n}\n\nexport function inferPatientResultsPresetId(\n  blocks: Array<Pick<PatientResultsBlock, \"type\"> | { type?: string }>,\n): keyof typeof patientResultsPresets {\n  if (blocks.some((block) => block.type === \"segmentMuscleAnalysis\")) {\n    return \"body-composition-report\";\n  }\n\n  if (blocks.some((block) => block.type === \"diagnosticMetricSplit\")) {\n    return \"vns-report\";\n  }\n\n  if (blocks.some((block) => block.type === \"diagnosticMetricStat\")) {\n    return \"body-composition-report\";\n  }\n\n  return \"vo2-max-report\";\n}\n\nexport function createPatientResultsInitialContent(\n  presetId: keyof typeof patientResultsPresets,\n) {\n  const preset = getPatientResultsPreset(presetId);\n  return preset.pages.flatMap((page) =>\n    page.blocks.map((block) => convertPresetBlockToEditorBlock(block)),\n  );\n}\n\nexport interface PatientResultsEditorProps {\n  presetId?: keyof typeof patientResultsPresets;\n  editable?: boolean;\n  className?: string;\n  initialContent?: PatientResultsEditorBlock[];\n  onChange?: (document: PatientResultsEditorBlock[]) => void;\n}\n\nexport function PatientResultsEditor({\n  presetId = \"vo2-max-report\",\n  editable = true,\n  className,\n  initialContent,\n  onChange,\n}: PatientResultsEditorProps) {\n  const preset = getPatientResultsPreset(presetId);\n  const editor = useCreateBlockNote(\n    {\n      schema: patientResultsBlockSchema,\n      initialContent:\n        initialContent ?? createPatientResultsInitialContent(presetId),\n    },\n    [initialContent, presetId],\n  );\n\n  const allowedTypes = new Set(preset.allowedBlockTypes);\n  const customSuggestionItems = React.useMemo<DefaultReactSuggestionItem[]>(\n    () =>\n      preset.allowedBlockTypes.map((blockType) =>\n        blockTypeToSuggestionItem(editor, blockType, presetId),\n      ),\n    [editor, preset.allowedBlockTypes, presetId],\n  );\n\n  React.useEffect(() => {\n    editor.isEditable = editable;\n  }, [editable, editor]);\n\n  return (\n    <div className={cn(\"space-y-4\", className)}>\n      <div className=\"flex flex-wrap gap-2 rounded-[16px] border border-black/10 bg-white p-3\">\n        {preset.allowedBlockTypes.map((blockType) => (\n          <Button\n            key={blockType}\n            size=\"small\"\n            variant=\"secondary\"\n            onClick={() =>\n              insertPatientResultsBlock(editor, blockType, presetId)\n            }\n          >\n            {blockType.replace(/([A-Z])/g, \" $1\").trim()}\n          </Button>\n        ))}\n      </div>\n\n      <BlockNoteView\n        editor={editor}\n        editable={editable}\n        formattingToolbar\n        linkToolbar\n        filePanel={false}\n        sideMenu\n        tableHandles={false}\n        slashMenu={false}\n        className=\"rounded-[24px] border border-black/10 bg-white p-4\"\n        onChange={() => {\n          onChange?.(editor.document as PatientResultsEditorBlock[]);\n        }}\n      >\n        <SuggestionMenuController\n          triggerCharacter=\"/\"\n          getItems={async (query) =>\n            filterSuggestionItems(\n              [\n                ...getDefaultReactSlashMenuItems(editor),\n                ...customSuggestionItems,\n              ],\n              query,\n            )\n          }\n        />\n      </BlockNoteView>\n\n      <div className=\"text-sm leading-6 text-muted-foreground\">\n        Active preset:{\" \"}\n        <span className=\"font-medium text-black\">{preset.title}</span>\n        {\" · \"}\n        allowed blocks:{\" \"}\n        {Array.from(allowedTypes)\n          .map((type) => type.replace(/([A-Z])/g, \" $1\").trim())\n          .join(\", \")}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "src/components/ui/patient-results/editor/patient-results-editor.tsx"
    }
  ],
  "type": "registry:ui"
}