Components / Clinical
Vital signs
Heart rate, blood pressure, SpO₂ and temperature at a glance, each checked against a normal range you can configure. Every status is written out with its own icon, so it never depends on colour.
Original example readings and common adult ranges. Not patient data or clinical guidance.
Installation
In a project set up as in Installation, run:
bunx shadcn@4.22.1 add https://organui.com/r/vital-signs.json
Or by name: bunx shadcn@4.22.1 add @organui/vital-signs.
The source installs into your configured UI directory, along with shadcn's card if you do not have it yet. It has no client state, so it renders in Server Components too, and its icons are inline so it adds no icon library.
Usage
import { VitalSigns } from "@/components/ui/vital-signs"
export function Vitals() {
return (
<VitalSigns
readings={{ heartRate: 72, systolic: 118, diastolic: 76,
spo2: 98, temperature: 36.8 }}
description="Measured at 09:30"
/>
)
}Pass the latest readings as numbers. A missing, null or non-finite value shows a dash and the status No reading. Blood pressure needs both systolic and diastolic.
Ranges and status
// Merged over adultVitalRanges, one vital at a time.
<VitalSigns
readings={readings}
ranges={{ spo2: { low: 88, high: 92 } }}
vitals={["heartRate", "bloodPressure", "spo2", "respiratoryRate"]}
/>
// Temperature readings and ranges in °F.
<VitalSigns readings={{ temperature: 100.4 }} temperatureUnit="fahrenheit"
vitals={["temperature"]} />Defaults are common resting adult ranges, exported as adultVitalRanges: heart rate 60–100 bpm, blood pressure 90–120 / 60–80 mmHg, SpO₂ 95–100%, temperature 36.1–37.2 °C (97–99 °F) and respiratory rate 12–20 per minute. Bounds are inclusive. Override any of them with ranges for children, a patient's own targets, or your institution's protocol.
A reading below its range is Low with a down arrow, above it High with an up arrow, and inside it Normal with a check. Out-of-range cards also get bold status text and your theme's destructive colour on the border and icon. Blood pressure is high when either part is high, and the text names the part out of range, such as High systolic. Each card carries data-vital and data-status attributes for your own styling.
The same logic is exported for use elsewhere: vitalStatus, bloodPressureStatus, resolveVitalRanges and assessVital.
Customize
Set title for the heading and the region's accessible name, description for a line under it, vitals to choose and order the cards, locale for number formatting (default en-US, so server and client render the same) and className for the outer card. Cards wrap to fit their container.
A display component, not a medical device. It does not compute early warning scores, trend readings, or raise alarms, and it is not a live region: announce changes yourself if readings stream in. The default ranges are not clinically validated for any population.