Implement the 024-fix-hp-popover-overflow feature that switches the HP adjustment popover from absolute to fixed positioning with viewport-aware clamping so it stays fully visible and causes no horizontal scrollbar, even when the HP display is near the right edge of the viewport
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
import { Heart, Sword } from "lucide-react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { Button } from "./ui/button";
|
||||
import { Input } from "./ui/input";
|
||||
|
||||
@@ -10,9 +16,28 @@ interface HpAdjustPopoverProps {
|
||||
|
||||
export function HpAdjustPopover({ onAdjust, onClose }: HpAdjustPopoverProps) {
|
||||
const [inputValue, setInputValue] = useState("");
|
||||
const [pos, setPos] = useState<{ top: number; left: number } | null>(null);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
const parent = el.parentElement;
|
||||
if (!parent) return;
|
||||
const trigger = parent.getBoundingClientRect();
|
||||
const popover = el.getBoundingClientRect();
|
||||
const vw = document.documentElement.clientWidth;
|
||||
let left = trigger.left;
|
||||
if (left + popover.width > vw) {
|
||||
left = vw - popover.width - 8;
|
||||
}
|
||||
if (left < 8) {
|
||||
left = 8;
|
||||
}
|
||||
setPos({ top: trigger.bottom + 4, left });
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
requestAnimationFrame(() => inputRef.current?.focus());
|
||||
}, []);
|
||||
@@ -61,7 +86,12 @@ export function HpAdjustPopover({ onAdjust, onClose }: HpAdjustPopoverProps) {
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className="absolute z-10 mt-1 rounded-md border border-border bg-background p-2 shadow-lg"
|
||||
className="fixed z-10 rounded-md border border-border bg-background p-2 shadow-lg"
|
||||
style={
|
||||
pos
|
||||
? { top: pos.top, left: pos.left }
|
||||
: { visibility: "hidden" as const }
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-1">
|
||||
<Input
|
||||
|
||||
Reference in New Issue
Block a user