opsinjs
ComponentsPatternsTask patterns

Result disclosure

Showing someone a result they may not want to see, without ambush. The sequence from notification to number to next step.

When to use

Use this pattern whenever a value arrives that the reader did not create themselves and cannot immediately interpret: a lab result, a screening outcome, a derived risk score, a clinician's note attached to a number.

The defining property is asymmetry of preparation. The reader knows a result is coming but not what it says, and the moment they find out is chosen by your notification schedule rather than by them. That is the moment this pattern exists to design. Everything else follows from getting that moment right, including the layout of the card and the colour of the pill.

Signals that you are in this situation:

  • The value has a reference range attached that the reader did not set.
  • The value can be outside that range in a direction that matters.
  • Somebody may need to do something about it, and it is not obvious what.
  • The reader may be alone, at work, on a phone, at 07:40 in the morning.

When not to use

  • The reader entered the number themselves. Someone who has just typed their own weight is not being told anything. Use Daily logging, which optimises for speed of re-entry rather than for careful disclosure.
  • The value implies emergency action. If a reading crosses a threshold where the correct next step is to call emergency services, disclosure is the wrong frame. The design goal stops being comprehension and becomes speed. Use Emergency and escalation.
  • The result is a mental-health screening score with a self-harm item. That has its own duty of care and its own sequence. Use Crisis and self-harm.
  • You are showing change, not a value. A number that only means something against its own history belongs in Trend review.
  • There is nothing to disclose yet. A pending result is an Empty and first-use problem; do not render an empty ResultCard with dashes in it and hope.

How it works

The sequence has four moments, and the design work is in the gaps between them rather than in any one screen.

Diagram source (mermaid)
flowchart TD
A["Result becomes available"] --> B{"Does the reader get a push?"}
B -->|"yes"| C["Notification: says a result is ready, never the value"]
B -->|"no"| D["In-app entry point with an unread marker"]
C --> E["Landing surface: what this test is, before the number"]
D --> E
E --> F["The value, its units and its range together"]
F --> G{"Outside the expected range?"}
G -->|"no"| H["Plain statement plus what would change it"]
G -->|"yes"| I["Status, then meaning, then a concrete next step"]
I --> J["Named route to a human"]
H --> K["Exit: history, share, or done"]
J --> K

NOT IMPLEMENTED. This component does not exist in any released version of opsinjs. There is no package to install, no module to import and no props interface to generate code against. Everything on this page is a specification of intended behaviour and may change without notice. Do not write code against it.

This component is not built yet

There is nothing to render because there is nothing to install. What you can read on this page is the specification the implementation will have to satisfy.

PlannedRoadmapWhat “planned” means

Moment 1. The notification. A push notification is read on a lock screen, possibly by someone else. It says that a result is ready and what it is about. It never carries the value, the status word, or a colour that encodes one. This is the single most common breach of this pattern and the most consequential; see Notifications and off-screen alerts.

Moment 2. The landing surface. Before the number, one sentence saying what this test measures in plain English. A reader who does not know what ferritin is cannot be told anything by a ferritin value, and the sentence costs nothing to the reader who does know.

Moment 3. The value. The number, its unit and the range it is being judged against appear together, in one visual unit, on first paint. Never animate the number into place from zero; never reveal the status after the value with a transition. A CareCard's worth of interpretation may load afterwards, but the value and its range are a single atomic disclosure.

Moment 4. The next step. Every result ends with something the reader can do, including "nothing, and here is why nothing is the right answer". A result outside the expected range without a named route to a human is an anxiety generator.

The states this sequence has to survive

StateWhat the reader seesWhat must not happen
PendingThe test, the expected timeframe, no placeholder valueA dash or a zero styled as a value
PartialThe values that arrived, explicitly marked incompleteInterpretation drawn from a partial panel
ArrivedValue, unit, range, status, meaning, next stepStatus before the reader knows what the test is
SupersededThe current value, with the previous one reachableA silent replacement with no record
WithdrawnAn explicit statement that a result was retractedThe value quietly disappearing

Content

The copy order is fixed: what this is → what it says → what it means → what to do → who to ask. Readers who are worried stop reading early, so the sentence that matters most is the one nearest the top of its section.

Do

"Your ferritin result is ready." This notification tells the reader something has happened and lets them choose where they are when they learn what.

Don’t

"Your ferritin is 8 µg/L low." This is the value and the verdict on a lock screen, read in a queue, possibly by a colleague.

Do

"This is higher than the range used for this test. That is common and often has a simple explanation. Your clinic will contact you within three working days."

Don’t

"Abnormal result. Please contact your doctor." That is two words of clinical jargon, an instruction with no timeframe, and no indication of urgency in either direction.

Word rules that apply here and are owned elsewhere: "normal" is banned by Reference ranges; numeric formatting and rounding follow Numbers, units and precision; the status sentence patterns are in Writing status and alerts. Any clinical term appearing for the first time is wrapped in Term so its plain-English definition is one tap away.

Accessibility

  • Order over emphasis. The DOM order must be the reading order: test name, value, unit, range, status, meaning, action. A status pill positioned visually above the value but placed after it in the DOM tells a sighted reader and a screen-reader user two different stories about which came first.
  • The value is one accessible unit. "Ferritin, 8 micrograms per litre, below the expected range of 30 to 300" should be one announcement, not five fragments read as a table. Units are spoken, not symbols: µg/L is unintelligible to most speech synthesis.
  • Status never depends on colour. The status word is present as text. Run the screen through Colour independence in grayscale before shipping.
  • Arrival is announced, not animated. If the result loads after paint, it is announced via a status message (WCAG 2.2 SC 4.1.3). Motion must not be the signal. See Motion in health UI.
  • The next-step control is reachable first by keyboard. After the heading, the first focusable element should be the action, not a share button or a chart legend.
  • No timed disclosure. Nothing on this surface may auto-dismiss or advance. WCAG 2.2 SC 2.2.1 is the floor; the design rule is stricter. A result screen has no timers at all.

Research

Updates to this page

Last read through against the system on 2026-09-20. Due for review every 6 months; expiry is reported by pnpm run check:freshness.

On this page