Restyle HP display as compact rounded pill
Group current HP, temp HP, and max HP into a single bordered pill container with a subtle slash separator. Removes the scattered layout with separate elements and gaps. Temp HP +N only renders when present (no invisible spacer). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -172,7 +172,12 @@ function MaxHpDisplay({
|
||||
<button
|
||||
type="button"
|
||||
onClick={startEditing}
|
||||
className="inline-block h-7 min-w-[3ch] text-center text-muted-foreground text-sm tabular-nums leading-7 transition-colors hover:text-hover-neutral"
|
||||
className={cn(
|
||||
"inline-block h-7 min-w-[3ch] text-center leading-7 transition-colors hover:text-hover-neutral",
|
||||
maxHp === undefined
|
||||
? "text-muted-foreground text-sm"
|
||||
: "text-muted-foreground text-xs",
|
||||
)}
|
||||
>
|
||||
{maxHp ?? "Max"}
|
||||
</button>
|
||||
@@ -183,35 +188,20 @@ function ClickableHp({
|
||||
currentHp,
|
||||
maxHp,
|
||||
tempHp,
|
||||
hasTempHp,
|
||||
onAdjust,
|
||||
onSetTempHp,
|
||||
dimmed,
|
||||
}: Readonly<{
|
||||
currentHp: number | undefined;
|
||||
maxHp: number | undefined;
|
||||
tempHp: number | undefined;
|
||||
hasTempHp: boolean;
|
||||
onAdjust: (delta: number) => void;
|
||||
onSetTempHp: (value: number) => void;
|
||||
dimmed?: boolean;
|
||||
}>) {
|
||||
const [popoverOpen, setPopoverOpen] = useState(false);
|
||||
const status = deriveHpStatus(currentHp, maxHp);
|
||||
|
||||
if (maxHp === undefined) {
|
||||
return (
|
||||
<span
|
||||
className={cn(
|
||||
"inline-block h-7 w-[4ch] text-center text-muted-foreground text-sm tabular-nums leading-7",
|
||||
dimmed && "opacity-50",
|
||||
)}
|
||||
role="status"
|
||||
aria-label="No HP set"
|
||||
>
|
||||
--
|
||||
</span>
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -221,24 +211,17 @@ function ClickableHp({
|
||||
onClick={() => setPopoverOpen(true)}
|
||||
aria-label={`Current HP: ${currentHp}${tempHp ? ` (+${tempHp} temp)` : ""} (${status})`}
|
||||
className={cn(
|
||||
"inline-block h-7 min-w-[3ch] text-center font-medium text-sm tabular-nums leading-7 transition-colors hover:text-hover-neutral",
|
||||
"inline-block h-7 min-w-[3ch] text-center font-medium text-sm leading-7 transition-colors hover:text-hover-neutral",
|
||||
status === "bloodied" && "text-amber-400",
|
||||
status === "unconscious" && "text-red-400",
|
||||
status === "healthy" && "text-foreground",
|
||||
dimmed && "opacity-50",
|
||||
)}
|
||||
>
|
||||
{currentHp}
|
||||
</button>
|
||||
{!!hasTempHp && (
|
||||
<span
|
||||
className={cn(
|
||||
"inline-block min-w-[3ch] text-center text-sm tabular-nums leading-7",
|
||||
tempHp ? "font-medium text-cyan-400" : "invisible",
|
||||
dimmed && "opacity-50",
|
||||
)}
|
||||
>
|
||||
{tempHp ? `+${tempHp}` : ""}
|
||||
{!!tempHp && (
|
||||
<span className="font-medium text-cyan-400 text-sm leading-7">
|
||||
+{tempHp}
|
||||
</span>
|
||||
)}
|
||||
{!!popoverOpen && (
|
||||
@@ -463,7 +446,6 @@ export function CombatantRow({
|
||||
setHp,
|
||||
adjustHp,
|
||||
setTempHp,
|
||||
hasTempHp,
|
||||
setAc,
|
||||
toggleCondition,
|
||||
toggleConcentration,
|
||||
@@ -615,29 +597,26 @@ export function CombatantRow({
|
||||
</div>
|
||||
|
||||
{/* HP */}
|
||||
<div className="flex items-center gap-1">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center rounded-md tabular-nums",
|
||||
maxHp === undefined
|
||||
? ""
|
||||
: "gap-0.5 border border-border/50 bg-muted/30 px-1.5",
|
||||
dimmed && "opacity-50",
|
||||
)}
|
||||
>
|
||||
<ClickableHp
|
||||
currentHp={currentHp}
|
||||
maxHp={maxHp}
|
||||
tempHp={combatant.tempHp}
|
||||
hasTempHp={hasTempHp}
|
||||
onAdjust={(delta) => adjustHp(id, delta)}
|
||||
onSetTempHp={(value) => setTempHp(id, value)}
|
||||
dimmed={dimmed}
|
||||
/>
|
||||
{maxHp !== undefined && (
|
||||
<span
|
||||
className={cn(
|
||||
"text-muted-foreground text-sm tabular-nums",
|
||||
dimmed && "opacity-50",
|
||||
)}
|
||||
>
|
||||
/
|
||||
</span>
|
||||
<span className="text-muted-foreground/50 text-xs">/</span>
|
||||
)}
|
||||
<div className={cn(dimmed && "opacity-50")}>
|
||||
<MaxHpDisplay maxHp={maxHp} onCommit={(v) => setHp(id, v)} />
|
||||
</div>
|
||||
<MaxHpDisplay maxHp={maxHp} onCommit={(v) => setHp(id, v)} />
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
|
||||
Reference in New Issue
Block a user