Back

Table

Tables display structured clinical data with inline sparklines, visual reference range bars, and status-coded values. Wrap in Card for grouped presentation.

Laboratory Results

Columns follow clinical reading order: identify the test, read the value, check if it's in range (via the range bar marker color), then assess the trend. Panel groups (like CBC) are collapsible; standalone results sit alongside them in the same table.

Lab Results
Test
Result
Reference RangeTrend
Date
Hemoglobin A1c6.8 %
45.6
8%
since 08/12/2025
01/25/2026
Complete Blood Count (CBC)(4 components)
White Blood Cells7.5 K/uL
4.511
10%
since 08/12/2025
01/25/2026
Hemoglobin15.2 g/dL
13.517.5
3%
since 08/12/2025
01/25/2026
Platelets425 K/uL
150400
12%
since 08/12/2025
01/25/2026
Potassium6.2 mEq/L
3.55
48%
since 08/12/2025
01/25/2026

Design Notes

Column Order — Clinical Reading Flow

Columns are ordered to match how clinicians scan lab results: Test → Result → Reference Range → Trend → Date. The eye identifies the test name, reads the numeric value, checks whether it falls within range (via the range bar), assesses the trend direction, then notes recency. This left-to-right flow mirrors the cognitive priority of clinical decision-making.

Range Bar — Interpretation Without Labels

The reference range bar replaces text-based status badges entirely. A horizontal track shows the normal zone as a shaded region, with a colored dot marker indicating where the current value sits. Marker color encodes HL7 interpretation: green for Normal (N), amber for High/Low (H/L), and red for Critically High/Low (HH/LL). This removes the need for separate badge components or a legend — the color is the interpretation, visible at a glance.

Result Value Color

Result numbers use a three-tier color system matching the range bar marker: default text for normal values, amber for abnormal (H/L), and red for critical (HH/LL). This reinforces the range bar without requiring the user to look across to the bar for every row.

Sparkline Trends

Each row includes a 72px inline sparkline showing the last 6 readings. The line color matches the current interpretation tier. A percentage-change annotation (e.g. “↑ 12%”) and “since” date are displayed alongside to give immediate context on trajectory and timeframe. Hovering over the sparkline reveals a tooltip with the exact value and date for each data point, positioned above the chart to avoid obscuring the line.

Panel Groups & Standalone Results

Lab results can appear as collapsible panel groups (e.g. CBC with 4 components) or standalone rows (e.g. HbA1c). Panel headers span the full table width with a chevron toggle on the right edge. Component rows within a panel are slightly indented and use a smaller font size to establish visual hierarchy. Standalone results render at the same level as panel headers. This structure mirrors how lab panels are ordered in clinical systems.

Compact Card Layout

The card uses zero internal padding (py-0 gap-0 overrides) with a slim title bar separated by a border. Column headers use reduced vertical padding. Data rows use py-2.5 for density without sacrificing readability. Critical rows receive a subtle red background tint to draw attention without overwhelming the table.

HL7 FHIR Interpretation Codes

Values follow the HL7 FHIR Observation Interpretation code system: N (Normal), H (High), L (Low), HH (Critically High), LL (Critically Low). Note that Synthea fixture data does not include interpretation or referenceRange fields on Observations — interpretation must be derived at display time using LOINC-based reference ranges.

Medications

Data mirrors FHIR MedicationRequest structure. The medication column contains the full RxNorm display string (drug + dose + form) from medicationCodeableConcept.text. Frequency is derived from dosageInstruction timing data. Reason comes from reasonReference.display. Separate dosage and route columns are unnecessary — both are embedded in the medication name.

Medications
Medication
Frequency
Reason
Status
Prescribed
Requester
Lisinopril 10 MG Oral Tablet1x dailyHypertensionActive01/15/2025Dr. Terri Gutmann
Metformin hydrochloride 500 MG Oral Tablet2x dailyDiabetes mellitus type 2Active03/20/2025Dr. Terri Gutmann
Atorvastatin 20 MG Oral Tablet1x dailyHyperlipidemiaActive06/10/2024Dr. Maia Williams
Ibuprofen 200 MG Oral TabletAs neededOsteoarthritis of kneeActive09/14/2025Dr. Maia Williams
Completed
Warfarin Sodium 5 MG Oral Tablet1x dailyAtrial fibrillationCompleted12/01/2024Dr. Terri Gutmann

Design Notes

Column Order — Clinical Reading Flow

Columns follow clinical scanning priority: Medication → Frequency → Reason → Status → Prescribed → Requester. The clinician identifies the drug and dose, checks the schedule, understands why it was prescribed, confirms whether it's still active, then notes when it started and who ordered it. This mirrors the natural question flow when reviewing a medication list.

FHIR Data Mapping

All columns map directly to FHIR MedicationRequest fields. The medication name uses the full RxNorm display string from medicationCodeableConcept.text which includes drug name, dose, and form (e.g. “Lisinopril 10 MG Oral Tablet”). This eliminates the need for separate dosage and route columns — both are embedded in the medication name. Frequency is derived from dosageInstruction[].timing.repeat or falls back to dosageInstruction[].text. About 20% of MedicationRequests in Synthea fixtures lack dosageInstruction entirely.

Reason for Prescribing

The reason column surfaces clinical intent from reasonReference[].display or reasonCode[].text. This connects the medication to the underlying condition (e.g. Lisinopril → Hypertension), giving context that a drug name alone cannot. In real workflows, this helps catch inappropriate prescriptions and supports medication reconciliation.

Status Values

FHIR MedicationRequest uses active and completed — not “discontinued” as commonly seen in EHR interfaces. The positive badge variant (green) marks active medications, and neutral (gray) marks completed ones. Status is placed mid-table as a key scanning signal — the clinician needs to quickly distinguish current from historical medications.

Dropped Columns

Dosage and Route are intentionally omitted. Synthea's RxNorm display strings embed both (e.g. “500 MG Oral Tablet”), making separate columns redundant. Route in particular has extremely low information density — nearly all outpatient medications are oral. Removing these columns reduces visual noise and lets the table focus on clinically actionable fields.

Requester vs Prescriber

The column is labeled “Requester” to match the FHIR field name (requester.display). In FHIR, the requester is the practitioner who authored the medication order, sourced via NPI reference. This is placed last as the least-scanned column — clinicians prioritize what the drug is and whether it's active over who prescribed it.

Immunizations

Data mirrors FHIR Immunization resources. The vaccine column uses the CVX display string from vaccineCode.text. All Synthea immunizations have status “completed” — there are no pending or refused records in the fixtures.

Immunizations
Vaccine
Date
Location
Influenza, seasonal, injectable, preservative free10/15/2025River's Edge Primary Care LLC
Influenza, seasonal, injectable, preservative free10/22/2024River's Edge Primary Care LLC
COVID-19, mRNA, LNP-S, PF, 100 mcg/0.5mL dose06/02/2024University of MA Med Ctr
COVID-19, mRNA, LNP-S, PF, 30 mcg/0.3 mL dose01/15/2024University of MA Med Ctr
Td (adult), 5 Lf tetanus toxoid, preservative free, adsorbed08/09/2023River's Edge Primary Care LLC
Zoster vaccine, live03/14/2023River's Edge Primary Care LLC
Hep B, adult11/20/2022University of MA Med Ctr

Design Notes

Column Order

Vaccine → Date → Location. The clinician identifies which vaccine was given, checks when it was administered, and notes where. Status is omitted as a column because all Synthea immunizations are “completed” — in a production system with pending/refused states, a status column would be added.

FHIR Data Mapping

The vaccine name comes from vaccineCode.text, which contains the CVX display string (e.g. “Influenza, seasonal, injectable, preservative free”). Date maps to occurrenceDateTime and location to location.display. The CVX code (vaccineCode.coding[0].code) is available in the FHIR data but omitted from display — the full vaccine name provides sufficient identification for clinical review.

Fixture Characteristics

Synthea generates 73 immunization records across 5 patient bundles with 7 distinct vaccine types. Influenza dominates (50 of 73), followed by COVID-19 variants (10), tetanus (5), zoster (4), hepatitis B (3), and meningococcal (1). All records include primarySource: true and a location reference. No optional FHIR fields (site, route, doseQuantity, performer) are present in the Synthea data.

Omitted Fields

Several FHIR Immunization fields are absent from Synthea fixtures and therefore not displayed: site (injection site), route (administration route), doseQuantity, performer (administering practitioner), and note. A production implementation would add columns for these if populated.

Basic Table

Simple key-value or props reference table using the shared compact card wrapper and consistent column header styling.

Props API
Name
Type
Default
variantstring"default"
sizestring"md"

Shared Table Styling

Card Wrapper

All tables use Card with py-0 gap-0 overrides to eliminate the default vertical padding and gap. A slim title bar sits at the top, separated from the table by a border. This keeps the card chrome minimal so the data is the focus.

Column Headers

All column headers share the same class: uppercase, text-xs, muted foreground color, with px-4 py-2 padding and a bg-muted/30 background. This creates a consistent, unobtrusive header row across all table variants.

Data Rows

Data cells use px-4 py-2 to py-2.5 padding depending on content density, with text-sm font sizing. Rows are separated by divide-y borders. The first column is typically font-medium to anchor the eye, while secondary columns like dates use text-muted-foreground.

Status Badges

Status indicators use the Badge component at sm size. The positive variant (green) is used for active states, and neutral (gray) for inactive or discontinued states. Badges are placed in the final column as a scannable status indicator.