rcgit

/ karakeep

Commit 523a251b

SHA 523a251b6f330f72adb13119a2577a4220d5a078
Author Mark :) <Mxrk at users dot noreply dot github dot com>
Author Date 2025-05-18 10:36 +0200
Committer GitHub <noreply at github dot com>
Commit Date 2025-05-18 09:36 +0100
Parent(s) dbd0fd197323 (diff)
Tree a2b010894ef7

patch snapshot

feat: position highlight menu based on device type (#1348)
* feat: position highlight menu based on device type

* fix: re-run prettier
File + - Graph
M apps/web/components/dashboard/preview/BookmarkHtmlHighlighter.tsx +17 -6
1 file(s) changed, 17 insertions(+), 6 deletions(-)

apps/web/components/dashboard/preview/BookmarkHtmlHighlighter.tsx

diff --git a/apps/web/components/dashboard/preview/BookmarkHtmlHighlighter.tsx b/apps/web/components/dashboard/preview/BookmarkHtmlHighlighter.tsx
index a3b34f9a..dc446112 100644
--- a/apps/web/components/dashboard/preview/BookmarkHtmlHighlighter.tsx
+++ b/apps/web/components/dashboard/preview/BookmarkHtmlHighlighter.tsx
@@ -19,6 +19,7 @@ interface ColorPickerMenuProps {
   onDelete?: () => void;
   selectedHighlight: Highlight | null;
   onClose: () => void;
+  isMobile: boolean;
 }
 
 const ColorPickerMenu: React.FC<ColorPickerMenuProps> = ({
@@ -27,6 +28,7 @@ const ColorPickerMenu: React.FC<ColorPickerMenuProps> = ({
   onDelete,
   selectedHighlight,
   onClose,
+  isMobile,
 }) => {
   return (
     <Popover
@@ -44,7 +46,10 @@ const ColorPickerMenu: React.FC<ColorPickerMenuProps> = ({
           top: position?.y,
         }}
       />
-      <PopoverContent side="top" className="flex w-fit items-center gap-1 p-2">
+      <PopoverContent
+        side={isMobile ? "bottom" : "top"}
+        className="flex w-fit items-center gap-1 p-2"
+      >
         {SUPPORTED_HIGHLIGHT_COLORS.map((color) => (
           <Button
             size="none"
@@ -113,6 +118,11 @@ function BookmarkHTMLHighlighter({
   const [selectedHighlight, setSelectedHighlight] = useState<Highlight | null>(
     null,
   );
+  const isMobile = useState(
+    () =>
+      typeof window !== "undefined" &&
+      window.matchMedia("(pointer: coarse)").matches,
+  )[0];
 
   // Apply existing highlights when component mounts or highlights change
   useEffect(() => {
@@ -160,7 +170,7 @@ function BookmarkHTMLHighlighter({
     window.getSelection()?.addRange(newRange);
   }, [pendingHighlight, contentRef]);
 
-  const handleMouseUp = (e: React.MouseEvent) => {
+  const handlePointerUp = (e: React.PointerEvent) => {
     const selection = window.getSelection();
 
     // Check if we clicked on an existing highlight
@@ -192,11 +202,11 @@ function BookmarkHTMLHighlighter({
       return;
     }
 
-    // Position the menu above the selection
+    // Position the menu based on device type
     const rect = range.getBoundingClientRect();
     setMenuPosition({
-      x: rect.left + rect.width / 2, // Center the menu
-      y: rect.top,
+      x: rect.left + rect.width / 2, // Center the menu horizontally
+      y: isMobile ? rect.bottom : rect.top, // Position below on mobile, above otherwise
     });
 
     // Store the highlight for later use
@@ -333,7 +343,7 @@ function BookmarkHTMLHighlighter({
         role="presentation"
         ref={contentRef}
         dangerouslySetInnerHTML={{ __html: htmlContent }}
-        onMouseUp={handleMouseUp}
+        onPointerUp={handlePointerUp}
         className={className}
       />
       <ColorPickerMenu
@@ -342,6 +352,7 @@ function BookmarkHTMLHighlighter({
         onDelete={handleDelete}
         selectedHighlight={selectedHighlight}
         onClose={closeColorPicker}
+        isMobile={isMobile}
       />
     </div>
   );