安全バナーSafetyBannerExperimental
重要な警告や安全確認を強調し、必要に応じて明示的な確認状態を管理します。
プレビュー
アレルギー警告:ペニシリン
処方薬「アモキシシリン」は患者のアレルギーに該当します。投与は禁忌です。
状態とバリエーション
確認必須
確認前は関連操作を無効にし、理由をツールチップで示します。
アレルギー警告:ペニシリン
処方薬「アモキシシリン」は患者のアレルギーに該当します。投与は禁忌です。
確認済み
確認済み状態では後続操作を有効にし、押下後は完了状態とトーストを表示します。
アレルギー警告:ペニシリン
処方薬「アモキシシリン」は患者のアレルギーに該当します。投与は禁忌です。
確認済み
注意
確認は求めず、注意喚起に関連する記録操作をその場で完了できます。
投与量を再確認
前回投与からの間隔が短いため、投与量と時間を確認してください。
情報
補足情報はpoliteなstatusとして通知し、関連情報を開く操作を添えます。
情報共有:検査結果待ち
最終判断前に検査結果の更新を確認してください。
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| title | ReactNode | - | 警告や確認事項の見出しです。 |
| tone | "destructive" | "warning" | "info" | "destructive" | 重要度です。destructiveはrole=alert、warning/infoはrole=statusです。 |
| requireAck | boolean | false | 明示的な確認ボタンを表示します。 |
| acknowledged / defaultAcknowledged | boolean | - | controlled / uncontrolled の確認状態です。 |
| onAcknowledge | () => void | - | 確認ボタン押下時に呼ばれます。 |
| ackLabel / acknowledgedLabel | ReactNode | - | 確認前後のラベルです。 |
| actions | ReactNode | - | 右側に置く関連操作です。 |
使い方
import * as React from "react";
import { Button, SafetyBanner, Toast, Tooltip, TooltipContent, TooltipTrigger } from "@gunjo/ui";
export function PrescriptionGate() {
const rootRef = React.useRef<HTMLDivElement | null>(null);
const [portalContainer, setPortalContainer] = React.useState<HTMLElement | null>(null);
const [acked, setAcked] = React.useState(false);
const [signed, setSigned] = React.useState(false);
const [toastMessage, setToastMessage] = React.useState<string | null>(null);
React.useEffect(() => {
setPortalContainer(rootRef.current?.closest<HTMLElement>("[data-doc-component-preview-surface]") ?? rootRef.current);
}, []);
return (
<div ref={rootRef} className="relative flex w-full max-w-2xl flex-col gap-3 rounded-lg border bg-card p-4">
{toastMessage ? (
<div className="pointer-events-none absolute right-3 top-3 z-[100] w-[min(340px,calc(100%-1.5rem))]">
<Toast
message={toastMessage}
type="success"
isVisible
placement="inline"
closeLabel="閉じる"
onClose={() => setToastMessage(null)}
tooltipPortalContainer={portalContainer}
/>
</div>
) : null}
<SafetyBanner tone="destructive" title="アレルギー警告:ペニシリン" requireAck acknowledged={acked} onAcknowledge={() => setAcked(true)}>
処方薬「アモキシシリン」は患者のアレルギーに該当します。投与は禁忌です。
</SafetyBanner>
{!acked ? (
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex w-fit" tabIndex={0} aria-label="安全確認にチェックすると署名できます。">
<Button disabled variant="secondary">処方を署名</Button>
</span>
</TooltipTrigger>
<TooltipContent>安全確認にチェックすると署名できます。</TooltipContent>
</Tooltip>
) : signed ? (
<span className="inline-flex min-h-9 w-fit items-center rounded-md border border-success-border bg-success-subtle px-3 text-sm font-medium text-success-subtle-foreground">
署名済み
</span>
) : (
<Button onClick={() => {
setSigned(true);
setToastMessage("処方を署名しました。");
}}>
処方を署名
</Button>
)}
</div>
);
}使用コンポーネント
関連コンポーネント
設計の判断(UIXHERO)
「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。