Files
ltbxd-actorle/assets/react/controllers/ActorPopover.jsx
thibaud-leclere ded3d063c6 fix: render hint popover via FloatingPortal to prevent overflow clipping
The popover was invisible because it rendered inside the table's
overflow-x:auto scroll container. FloatingPortal moves it to document.body.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 21:49:46 +02:00

63 lines
1.9 KiB
JavaScript

import React, { useState } from 'react';
import { useFloating, useClick, useDismiss, useInteractions, offset, shift, size, FloatingPortal } from '@floating-ui/react';
const HINT_ICONS = {
film: 'fa-solid fa-film',
character: 'fa-solid fa-masks-theater',
award: 'fa-solid fa-trophy',
};
export default function ActorPopover({ hintType, hintText }) {
const [isOpen, setIsOpen] = useState(false);
const { refs, floatingStyles, context } = useFloating({
open: isOpen,
onOpenChange: setIsOpen,
middleware: [
offset(8),
size({
apply({ availableWidth, elements }) {
Object.assign(elements.floating.style, {
maxWidth: `${availableWidth - 16}px`,
});
},
}),
shift({ padding: 8 }),
],
placement: 'left',
});
const click = useClick(context);
const dismiss = useDismiss(context);
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss]);
if (!hintText) return null;
const iconClass = HINT_ICONS[hintType] || 'fa-solid fa-circle-question';
return (
<>
<button
ref={refs.setReference}
{...getReferenceProps()}
className="popover-trigger"
type="button"
>
<i className={iconClass}></i>
</button>
{isOpen && (
<FloatingPortal>
<div
ref={refs.setFloating}
style={floatingStyles}
{...getFloatingProps()}
className="actor-popover"
>
{hintText}
</div>
</FloatingPortal>
)}
</>
);
}