Skip to content
organui
GitHub repository, 242 stars

Condition viewer

The view every OrganUI condition is built on. Describe a condition as findings on any organ model, as this example does for hypertrophic cardiomyopathy; it shows what is affected and spared at each stage and scale, with the course as a timeline under the model and a panel of findings and investigations.

Installation

Most apps want a ready-made condition: abdominal aortic aneurysm, acl rupture, acute angle-closure glaucoma, acute appendicitis, acute otitis media, addison's disease, autoimmune hepatitis, benign prostatic hyperplasia, breast cancer, crohn's disease, ectopic pregnancy, gallstone disease, graves' disease, hodgkin lymphoma, ischaemic stroke, kidney stones, laryngeal cancer, lobar pneumonia, lumbar disc herniation, melanoma, myasthenia gravis, myocardial infarction, oesophageal cancer, pancreatic cancer, peptic ulcer disease, pituitary adenoma, primary hyperparathyroidism, rheumatoid arthritis. To describe your own, install the viewer alone.

bunx shadcn@4.22.1 add @organui/condition-viewer

This adds condition-viewer.tsx and condition-model.ts, the condition types and the conditionModel function, which has no client code so server components can use it too. It installs the organ viewer and shadcn's badge and button.

View registry item JSON

Usage

import type { Condition } from "@/components/condition-model"
import { kidneysModel } from "@/components/kidneys"

export const kidneyStones: Condition = {
  name: "Kidney stones",
  code: "N20.0",
  summary: "Crystals form in the urine and can block the ureter.",
  scales: [
    {
      id: "kidneys",
      label: "Kidneys",
      model: kidneysModel,
      // Structures without a finding are spared.
      findings: {
        "left-ureter": {
          affected: true,
          description: "A stone lodges and the kidney above it swells.",
        },
      },
    },
  ],
  stages: [
    {
      id: "colic",
      label: "Renal colic",
      time: "Hours",
      summary: "Sudden loin-to-groin pain.",
    },
    {
      id: "passed",
      label: "Passed",
      time: "Days to weeks",
      summary: "Most small stones pass on their own.",
    },
  ],
  events: [
    {
      stage: "colic",
      label: "CT",
      description: "A low-dose CT shows the stone's size and position.",
    },
  ],
  investigations: [
    { name: "Urine dipstick", result: "Blood", flag: "abnormal" },
  ],
}

A condition is drawn on the models of organ components, one per scale: a whole organ, and a tissue such as the liver lobule for what happens under the microscope. Findings name structures of that model; a structure without one is spared and keeps its anatomical description. A stage replaces the findings and investigations it lists, so it describes only what changes. A scale's translucentIds draws structures see-through, such as the fat around a breast's lobes, so the condition inside them shows.

Affected structures share one amber, so a condition of a whole organ still shows, and spared ones a muted tone. Red is kept for critical results. An abnormal investigation is bold with an arrow for high or low, as in the lab results table.

Behaviour

Scale, stage and selection are each controlled or uncontrolled: pass stage with onStageChange to drive the stage from your own timeline, or defaultStage to only choose where it starts. Selecting a structure in 3D shows its finding in the panel, and selecting a finding highlights it in 3D. Spared structures the condition says nothing about fold behind a button, so a whole-body model lists only what matters; selecting one in 3D unfolds them. Changing the scale clears the selection, because each model has its own structures.

A condition with more than one stage shows its course as a timeline under the model: each stage at its time in a typical course, and its events, such as a treatment or a test, beneath it. Select a stage or an event to show it, or play the course to step through it while the model fades from one stage to the next. The stages are one tab stop: the arrow keys, Home and End move along the course. A stage marked alternative is another path from the one before it, such as an untreated course beside a treated one, and joins the track with a dashed line. Pass timeline={false} to hide it.

conditionModel(condition, scale, stage) returns the organ model for one scale at one stage, for the anatomy tree or your own list. Pass panel={false} to show only the model.

Just the model

conditionModel returns a plain organ model, so the organ viewer shows a condition on its own, with no panel or timeline: one scale at one stage, coloured affected or spared.

import { conditionModel } from "@/components/condition-model"
import { gravesDisease } from "@/components/graves-disease"
import { OrganViewer } from "@/components/organ-viewer"

export function Thyroid() {
  return (
    <OrganViewer
      model={conditionModel(gravesDisease, "thyroid", "thyrotoxic")}
      label="Thyroid in Graves' disease"
    />
  )
}

API Reference

Import ConditionViewerProps from the same file as ConditionViewer.

ConditionViewer props
PropTypeDefault
conditionCondition

The condition: its scales, stages, findings and investigations.

Required
scalestring

The scale shown, by ID.

—
defaultScalestring

The scale shown first when `scale` is not set. Defaults to the first.

condition.scales[0]!.id
onScaleChange(scale: string) => void

Called with the scale a reader chooses.

—
stagestring

The stage shown, by ID.

—
defaultStagestring

The stage shown first when `stage` is not set. Defaults to the first.

condition.stages?.[0]?.id ?? ""
onStageChange(stage: string) => void

Called with the stage a reader chooses.

—
selectedIdstring | null

The selected structure ID, or null.

—
onSelectionChange(id: string | null) => void

Called with the structure a reader selects, or null when they clear it.

—
panelboolean

Shows the panel with the scales, findings and investigations. Defaults to true.

true
timelineboolean

Shows the course under the model as a timeline, with its events and a play button. Defaults to true; a condition with one stage has none.

true