Symptom diary

A chronological record of supplied symptoms and intensity descriptions, with notes and 44px native detail disclosures.

  1. Headache

    Mild, self-reported

    Recorded after the afternoon walk.
    Details
    Lasted around twenty minutes.

The past two days

Personal journal / Self-reported

  1. Headache

    Mild

    Recorded after breakfast
    Details
    Slept later than usual. Added this note before leaving for work.
  2. Fatigue

    Noticeable

    Recorded at the end of the workday

Use it for

  • Read patient-entered symptom history without converting their descriptions into a diagnosis.
  • Supply intensity in words or with a named scale; the component does not create severity categories.
  • Use actions for application-owned edit or review controls with accessible names and 44px targets.

Not for

  • Triage, diagnosis or urgency inferred from diary text.
  • Assuming a missing diary entry means that no symptom occurred.
  • Passing ambiguous timestamps; use ISO timestamps with an explicit offset and timeLabel for display.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { SymptomDiary } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/symptom-diary.

2. Vendor the source

npx @noorddev/vlak-cli add symptom-diary

The StyleX leaf lands in components/vlak/, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/symptom-diary.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { SymptomDiary } from "@noorddev/vlak-react";

<SymptomDiary aria-label="Recent symptom entries" order="newest" entries={[
  { id: "morning", symptom: "Headache", dateTime: "2026-09-06T09:00:00+02:00", timeLabel: "6 Sep, 09:00 CEST", intensity: "Mild, self-reported", notes: "Recorded after breakfast", details: "No additional context recorded" },
  { id: "evening", symptom: "Fatigue", dateTime: "2026-09-05T18:30:00+02:00", timeLabel: "5 Sep, 18:30 CEST", intensity: "Noticeable, self-reported", notes: "Recorded at the end of the workday" },
]} />

SymptomDiary

A time-ordered record of supplied symptoms, descriptions and native detail disclosures.

PropTypeDefaultDescription
entriesrequiredreadonly SymptomEntry[]
emptyLabelstring"No symptoms recorded"
order"newest" | "oldest""newest"Sorts a copy of entries. Equal timestamps retain their supplied order.

Also accepts HTMLAttributes<HTMLOListElement>.

KeysDoes
TabFocuses each detail summary and any supplied actions
Enter, SpaceOpens or closes a focused native detail disclosure
<ol class="rs-symptom-diary" aria-label="Recent symptom entries"><li class="rs-symptom-diary-item">
  <time class="rs-symptom-diary-time" datetime="2026-09-06T09:00:00+02:00">6 Sep, 09:00 CEST</time>
  <div class="rs-symptom-diary-content"><div class="rs-symptom-diary-head"><p class="rs-symptom-diary-symptom">Headache</p><p class="rs-symptom-diary-intensity">Mild, self-reported</p></div><p class="rs-symptom-diary-body">Recorded after breakfast</p><details><summary class="rs-symptom-diary-summary" aria-label="Details for Headache, 6 Sep at 09:00 CEST">Details</summary><p class="rs-symptom-diary-body">No additional context recorded</p></details></div>
</li></ol>
.rs-symptom-diary.rs-symptom-diary-item.rs-symptom-diary-time.rs-symptom-diary-content.rs-symptom-diary-head.rs-symptom-diary-symptom.rs-symptom-diary-intensity.rs-symptom-diary-body.rs-symptom-diary-summary.rs-symptom-diary-actions