fix: tooltip size
This commit is contained in:
@@ -583,6 +583,7 @@ function MorePopover({
|
|||||||
onBookmark,
|
onBookmark,
|
||||||
onSaveToCollection,
|
onSaveToCollection,
|
||||||
onMention,
|
onMention,
|
||||||
|
isMobile,
|
||||||
}: {
|
}: {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
position: Position;
|
position: Position;
|
||||||
@@ -590,18 +591,18 @@ function MorePopover({
|
|||||||
onBookmark: () => void;
|
onBookmark: () => void;
|
||||||
onSaveToCollection: () => void;
|
onSaveToCollection: () => void;
|
||||||
onMention: () => void;
|
onMention: () => void;
|
||||||
|
isMobile: boolean;
|
||||||
}) {
|
}) {
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const { copied, copy } = useCopyFeedback();
|
const { copied, copy } = useCopyFeedback();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) return;
|
if (!open || isMobile) return;
|
||||||
function handleClick(e: MouseEvent) {
|
function handleClick(e: MouseEvent) {
|
||||||
if (ref.current && !ref.current.contains(e.target as Node)) {
|
if (ref.current && !ref.current.contains(e.target as Node)) {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Delay to avoid the same click that opened it from immediately closing
|
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
document.addEventListener("mousedown", handleClick);
|
document.addEventListener("mousedown", handleClick);
|
||||||
}, 10);
|
}, 10);
|
||||||
@@ -609,7 +610,7 @@ function MorePopover({
|
|||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
document.removeEventListener("mousedown", handleClick);
|
document.removeEventListener("mousedown", handleClick);
|
||||||
};
|
};
|
||||||
}, [open, onClose]);
|
}, [open, onClose, isMobile]);
|
||||||
|
|
||||||
if (!open) return null;
|
if (!open) return null;
|
||||||
|
|
||||||
@@ -617,54 +618,99 @@ function MorePopover({
|
|||||||
{
|
{
|
||||||
key: "bookmark",
|
key: "bookmark",
|
||||||
label: "Add Bookmark",
|
label: "Add Bookmark",
|
||||||
icon: <Bookmark className="size-4" />,
|
description: "Save your place",
|
||||||
|
icon: <Bookmark className="size-5" />,
|
||||||
onClick: onBookmark,
|
onClick: onBookmark,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "collection",
|
key: "collection",
|
||||||
label: "Save to Collection",
|
label: "Save to Collection",
|
||||||
icon: <FolderPlus className="size-4" />,
|
description: "Organize into a collection",
|
||||||
|
icon: <FolderPlus className="size-5" />,
|
||||||
onClick: onSaveToCollection,
|
onClick: onSaveToCollection,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "copy-link",
|
key: "copy-link",
|
||||||
label: copied ? "Link Copied!" : "Copy Link",
|
label: copied ? "Link Copied!" : "Copy Link",
|
||||||
|
description: "Copy a link to this page",
|
||||||
icon: copied ? (
|
icon: copied ? (
|
||||||
<Check className="size-4" />
|
<Check className="size-5" />
|
||||||
) : (
|
) : (
|
||||||
<Link2 className="size-4" />
|
<Link2 className="size-5" />
|
||||||
),
|
),
|
||||||
onClick: () => copy(window.location.href),
|
onClick: () => copy(window.location.href),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "mention",
|
key: "mention",
|
||||||
label: "Mention",
|
label: "Mention",
|
||||||
icon: <AtSign className="size-4" />,
|
description: "Tag someone with this quote",
|
||||||
|
icon: <AtSign className="size-5" />,
|
||||||
onClick: onMention,
|
onClick: onMention,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Position the popover — clamp to all 4 viewport edges
|
// Mobile: bottom drawer
|
||||||
const popoverW = 192; // w-48 = 12rem = 192px
|
if (isMobile) {
|
||||||
const popoverH = actions.length * 36 + 8; // approximate height
|
return (
|
||||||
|
<Drawer open={open} onOpenChange={(o) => !o && onClose()}>
|
||||||
|
<DrawerContent className="bg-black dark:bg-[#1a1a1a] border-white/10">
|
||||||
|
<DrawerHeader className="text-left border-b border-white/10 pb-4">
|
||||||
|
<DrawerTitle className="text-white">More Options</DrawerTitle>
|
||||||
|
</DrawerHeader>
|
||||||
|
<div className="p-4 space-y-1">
|
||||||
|
{actions.map((action) => (
|
||||||
|
<button
|
||||||
|
key={action.key}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
action.onClick();
|
||||||
|
if (action.key !== "copy-link") {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="flex items-center gap-3 w-full px-3 py-3 rounded-lg text-left hover:bg-white/10 transition-colors"
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-center size-10 rounded-lg bg-white/10 text-white/60">
|
||||||
|
{action.icon}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-medium text-white/90">
|
||||||
|
{action.label}
|
||||||
|
</p>
|
||||||
|
<p className="text-xs text-white/50">{action.description}</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="p-4 pt-0">
|
||||||
|
<DrawerClose asChild>
|
||||||
|
<button className="w-full py-2.5 rounded-lg border border-white/15 text-sm font-medium text-white/60 hover:bg-white/10 transition-colors">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</DrawerClose>
|
||||||
|
</div>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Desktop: floating popover
|
||||||
|
const popoverW = 220;
|
||||||
|
const popoverH = actions.length * 44 + 8;
|
||||||
const pad = 8;
|
const pad = 8;
|
||||||
|
|
||||||
let popLeft = position.x;
|
let popLeft = position.x;
|
||||||
let popTop = position.y + 8;
|
let popTop = position.y + 8;
|
||||||
|
|
||||||
// Right edge
|
|
||||||
if (popLeft + popoverW > window.innerWidth - pad) {
|
if (popLeft + popoverW > window.innerWidth - pad) {
|
||||||
popLeft = window.innerWidth - popoverW - pad;
|
popLeft = window.innerWidth - popoverW - pad;
|
||||||
}
|
}
|
||||||
// Left edge
|
|
||||||
if (popLeft < pad) {
|
if (popLeft < pad) {
|
||||||
popLeft = pad;
|
popLeft = pad;
|
||||||
}
|
}
|
||||||
// Bottom edge — if it overflows, place above the trigger instead
|
|
||||||
if (popTop + popoverH > window.innerHeight - pad) {
|
if (popTop + popoverH > window.innerHeight - pad) {
|
||||||
popTop = position.y - popoverH - 8;
|
popTop = position.y - popoverH - 8;
|
||||||
}
|
}
|
||||||
// Top edge
|
|
||||||
if (popTop < pad) {
|
if (popTop < pad) {
|
||||||
popTop = pad;
|
popTop = pad;
|
||||||
}
|
}
|
||||||
@@ -680,7 +726,7 @@ function MorePopover({
|
|||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
style={style}
|
style={style}
|
||||||
className="w-48 rounded-lg border border-white/10 bg-black shadow-2xl py-1 animate-in fade-in-0 zoom-in-95 dark:bg-[#1a1a1a] dark:border-white/15"
|
className="w-55 rounded-lg border border-white/10 bg-black shadow-2xl py-1.5 animate-in fade-in-0 zoom-in-95 dark:bg-[#1a1a1a] dark:border-white/15"
|
||||||
>
|
>
|
||||||
{actions.map((action) => (
|
{actions.map((action) => (
|
||||||
<button
|
<button
|
||||||
@@ -692,7 +738,7 @@ function MorePopover({
|
|||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="flex items-center gap-2.5 w-full px-3 py-2 text-sm text-white/90 hover:bg-white/10 transition-colors text-left"
|
className="flex items-center gap-3 w-full px-4 py-2.5 text-sm text-white/90 hover:bg-white/10 transition-colors text-left"
|
||||||
>
|
>
|
||||||
<span className="text-white/50">{action.icon}</span>
|
<span className="text-white/50">{action.icon}</span>
|
||||||
{action.label}
|
{action.label}
|
||||||
@@ -1053,6 +1099,7 @@ export function TextSelectionToolbar() {
|
|||||||
<MorePopover
|
<MorePopover
|
||||||
open={showMore}
|
open={showMore}
|
||||||
position={morePos}
|
position={morePos}
|
||||||
|
isMobile={isMobile}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setShowMore(false);
|
setShowMore(false);
|
||||||
interactingRef.current = false;
|
interactingRef.current = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user