Demos

A result inside its range.

Usage

Use a reference range card to show one lab result: the value, its flag, the range printed on the report, and where the value falls. For a full report, put several in a grid.

Import it from @workspace/ui/tools/reference-range.

Anatomy

  • Header — The test name, an optional longer name, and a flag badge.
  • Value — The result and its unit, in the status colour.
  • Range — The reference range as printed on a report, such as Ref 70–99 mg/dL.
  • Bar — Coloured zones with a marker at the value: normal inside the range, mild outside it, and extreme past a critical limit. Only shown for numbers with a low or high limit. The harmless side of a directional range is grey.
  • Footer — The Z-score and the direction, when there are any.

Flags

FlagWhen
normalBetween low and high, inclusive.
low, highOutside low or high.
critical-low, critical-highBelow criticalLow or above criticalHigh. Checked first.
abnormalOnly when you pass flag="abnormal", such as a text result that doesn't match.
unflaggedA text value, or no low or high.

Z-score and direction

With both limits, the range is read as the middle 95% of healthy values. The mean is (low + high) / 2, the SD is (high − low) / 4, and Z is (value − mean) / SD. A value inside the range has a |Z| of 2 or less.

range.direction says which way is bad:

DirectionLabelMeaning
high↑ BadA raised value is a concern, such as CRP. A low one is not.
low↓ BadA lowered value is a concern, such as HDL or vitamin D.
bothNormal bestEither side is a concern. The default.
contextContextEither side may matter, depending on the person.

rangeDirectionLabels maps each direction to its label.

Colours

The colour uses the five-step severity scale from globals.css, in the same order as the Bio Clock. Change --status-* in your theme to recolour it.

ResultColour
In range--status-normal
Out of range, |Z| under 3 (or no Z-score)--status-mild
|Z| 3 to under 4--status-moderate
|Z| 4 to under 5, or abnormal--status-severe
|Z| 5 or more, or a critical flag--status-extreme
Out of range on the harmless side, or unflaggedMuted

Notes

  • Limits are inclusive. A glucose of 99 with a high of 99 is normal.
  • A range with only high prints as ≤ 200, and its bar starts at zero. A range with only low prints as ≥ 30.
  • range.text replaces the printed range, for results such as Negative. Text values are never flagged on their own, so pass flag yourself.
  • decimals sets the decimal places for the value and the range.
  • The card sets data-flag and data-tone, for styling or tests.

Reference range helpers

The flagging logic is in @workspace/ui/lib/reference-range, so you can use it without the UI.

rangeTone(flag, z, direction) from the component file returns the status colour the card uses, as a RangeTone: normal, mild, moderate, severe, extreme, or none.

Examples

Flags

Low, high, critical, a lower limit only, a text result, and a result with no range.

Interactive

Change the value to see the flag and the marker move. Potassium has critical limits at 2.8 and 6.2 mmol/L.

Biomarker panel

Forty example biomarkers, each with a direction. Most are out of range, so the colours step up with |Z|. CRP at 4.2 is inside its range, so it stays green even with a Z of +1.42.

Props

Unlisted props pass through to the Card that wraps the result.

ReferenceRange

PropTypeDefaultDescription
namestring—The test name, such as Glucose or hs-CRP.
descriptionstring—A longer name under the title.
valuenumber or string—The result.
unitstring—Unit shown after the value and the range.
rangeReferenceRange—The limits to flag against.
decimalsnumber—Decimal places for the value and the range.
flagRangeFlagcomputedOverrides the flag.
classNamestring—Classes merged onto the card.

ReferenceRange (type)

FieldTypeDescription
lownumberLowest normal value, inclusive.
highnumberHighest normal value, inclusive.
criticalLownumberValues below this are critical low.
criticalHighnumberValues above this are critical high.
textstringShown instead of the generated range, such as Negative.
direction"high", "low", "both", or "context"Which way is bad. Defaults to both.