🩺

【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