【React × TypeScript】医療系アプリで学ぶ基準値UI設計:①基準値より高い・低いを矢印で表示する方法
📘 はじめに
Next.js + TypeScript + Tailwind CSSを学習しながら、
看護現場で役に立ちそうな「看護師向け計算ツールアプリ」の開発を進めております。
今回、基準値より高い・低いを矢印で可視化する機能を実装しました。
たとえば、血清Na値やK値、BMIなどが
「基準より高い」「基準より低い」とひと目で分かるように👇
🔺 高値(赤) 🔻 低値(青)
医療現場では数値だけでなく“傾向”を瞬時に把握できることが重要です。
この記事では、React + TypeScript + Tailwind CSSで実装した
この矢印表示機能の仕組みを解説します。
💡 背景
医療アプリのUIでは、以下の3点が非常に重要です:
- 数値の異常を一目で判断できる
- 色覚多様性に配慮した配色
- コード上でも安全に扱える設計
単なる表示ではなく、「安全性」「視認性」「再利用性」を意識することで、
シンプルなUIでも安心して使える医療ツールになります。
⚙️ 実装ステップ
🧩 1. 基準値データをまとめる:normalRanges.ts
まず、各指標の正常範囲 (基準値)を一元管理します。
この設定は、後から新しい項目を追加する際にも再利用しやすくなります。
// config/normalRanges.ts
export const normalRanges = {
sodium: { min: 135, max: 145 }, // Na(mEq/L)
potassium: { min: 3.5, max: 5.0 }, // K(mEq/L)
bmi: { min: 18.5, max: 24.9 }, // BMI
};
💬 この「基準値を一元管理する設計」は、
シリーズ第2回「normalRanges.tsで基準値を一元管理する設計パターン」で詳しく解説します。
🧮 2. 判定ロジック:getStatusIcon() 関数
次に、基準値より高い or 低い場合に矢印を返す関数を作成します。
import { ArrowUp, ArrowDown } from "lucide-react";
interface Range {
min: number;
max: number;
}
const getStatusIcon = (value: number, range?: Range) => {
if (!range) return null;
if (value > range.max)
return <ArrowUp className="w-4 h-4 text-red-500 ml-1 inline-block" />;
if (value < range.min)
return <ArrowDown className="w-4 h-4 text-blue-500 ml-1 inline-block" />;
return null;
};
💡ポイント
- lucide-reactで軽量アイコンを利用
- Range型で型安全に比較を実装
- JSXではnullを返すと「非表示」扱いになるため、正常値は何も描画されません
📊 3. ResultBoxに組み込む
結果を表示するResultBox内で、上記関数を呼び出します。
<li key={i} className="flex items-baseline gap-2">
<span className="text-base">{item.label}:</span>
<strong className="text-2xl flex items-center">
{item.value}
{getStatusIcon(Number(item.value), item.range)}
</strong>
<span className="text-sm">{item.unit}</span>
</li>
さらに、各計算結果から基準値を渡します。
<ResultBox
color="orange"
results={[
{
label: "BMI",
value: result,
unit: "",
range: { min: 18.5, max: 24.9 }, // 基準値を渡す
},
]}
note="※ BMIは目安です。臨床判断と併用してください。"
typeId="bmi"
/>
📜 4. 履歴ページでも再利用
履歴一覧(HistoryList.tsx)でも同じロジックを使いましょう。
Summaryテキスト(例:Na: 147)から数値を抽出して判定します。
const valueMatch = item.resultSummary
? item.resultSummary.match(/([\d.]+)/)
: null;
const value = valueMatch ? parseFloat(valueMatch[1]) : undefined;
{value !== undefined && range && getStatusIcon(value, range)}
同じgetStatusIcon()関数を利用することで、
UIとロジックの一貫性を保てます。
🎨 UI改善ポイント
配色ルール
| 状態 | 色 | Tailwindクラス |
|---|---|---|
| 高値 | 赤 | text-red-500 |
| 低値 | 青 | text-blue-500 |
| 正常 | 表示なし | — |
小さなアイコン(w-4 h-4)を数値横に配置することで、
視線を邪魔せずに情報を補足できます。
🧠 学びまとめ
| 項目 | 内容 |
|---|---|
| 🧩基準値管理 | normalRanges.tsでmin/maxを定義 |
| ⚙️判定関数 | getStatusIcon()で数値を比較して矢印を返す |
| 🎨UI | 赤↑・青↓を数値横に表示 |
| 🔁再利用 | ResultBox/HistoryListで共通利用 |
| 💡医療的工夫 | 視認性・安全性・一貫性を意識 |
🔗 シリーズ案内
🩺 【React × TypeScript】医療系アプリで学ぶ基準値UI設計シリーズ
1.基準値より高い・低いを矢印で表示する方法 ←(この記事)
2.normalRanges.tsで基準値を一元管理する設計パターン
3.型安全に基準値を扱う!TypeScriptで安全な比較ロジックを設計する
4.見やすさ重視のUI設計!Tailwindで基準値判定をわかりやすく表示する
Discussion