From 786e357dbd12a33bf10923f2199e893a919c7539 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 9 Oct 2025 18:26:44 +0200 Subject: [PATCH 1/4] Emoji picker fixes --- .../06-comments-with-sidebar/src/style.css | 6 +--- packages/ariakit/src/style.css | 4 +++ packages/mantine/src/blocknoteStyles.css | 4 ++- packages/mantine/src/popover/Popover.tsx | 8 ++++- .../src/components/Comments/EmojiPicker.tsx | 32 ++++++++++++------- packages/react/src/editor/styles.css | 9 ++++++ packages/shadcn/src/popover/popover.tsx | 2 +- 7 files changed, 46 insertions(+), 19 deletions(-) diff --git a/examples/07-collaboration/06-comments-with-sidebar/src/style.css b/examples/07-collaboration/06-comments-with-sidebar/src/style.css index 8ec1d5103e..f903d52e1b 100644 --- a/examples/07-collaboration/06-comments-with-sidebar/src/style.css +++ b/examples/07-collaboration/06-comments-with-sidebar/src/style.css @@ -23,6 +23,7 @@ flex-direction: column; gap: 10px; max-height: 100%; + min-width: 350px; width: 0; } @@ -47,11 +48,6 @@ max-width: 700px; } -.sidebar-comments-main-container .threads-sidebar-section, -.sidebar-comments-main-container .bn-threads-sidebar .bn-thread { - min-width: 0; -} - .sidebar-comments-main-container .settings { display: flex; flex-wrap: wrap; diff --git a/packages/ariakit/src/style.css b/packages/ariakit/src/style.css index 46917be46b..1fde174b11 100644 --- a/packages/ariakit/src/style.css +++ b/packages/ariakit/src/style.css @@ -38,6 +38,10 @@ inset 0 1px 1px 1px var(--shadow); } +.bn-ak-popover { + z-index: 10000; +} + .bn-toolbar .bn-ak-popover { gap: 0.5rem; } diff --git a/packages/mantine/src/blocknoteStyles.css b/packages/mantine/src/blocknoteStyles.css index 4d1933979c..7f0e3b74cd 100644 --- a/packages/mantine/src/blocknoteStyles.css +++ b/packages/mantine/src/blocknoteStyles.css @@ -74,11 +74,13 @@ } /* Mantine Popover component base styles */ -.bn-mantine .mantine-Popover-dropdown:not(.bn-menu-dropdown) { +.bn-mantine .bn-panel-popover, +.bn-mantine .bn-emoji-picker-popover { background-color: transparent; border: none; border-radius: 0; box-shadow: none; + display: flex; padding: 0; } diff --git a/packages/mantine/src/popover/Popover.tsx b/packages/mantine/src/popover/Popover.tsx index d6c1f96c68..69768e8b12 100644 --- a/packages/mantine/src/popover/Popover.tsx +++ b/packages/mantine/src/popover/Popover.tsx @@ -16,7 +16,13 @@ export const Popover = ( assertEmpty(rest); return ( - + {children} ); diff --git a/packages/react/src/components/Comments/EmojiPicker.tsx b/packages/react/src/components/Comments/EmojiPicker.tsx index def1693ec7..d60075a4d7 100644 --- a/packages/react/src/components/Comments/EmojiPicker.tsx +++ b/packages/react/src/components/Comments/EmojiPicker.tsx @@ -3,6 +3,8 @@ import { ReactNode, useState } from "react"; import { useComponentsContext } from "../../editor/ComponentsContext.js"; import { useBlockNoteContext } from "../../editor/BlockNoteContext.js"; import Picker from "./EmojiMartPicker.js"; +import { createPortal } from "react-dom"; +import { useBlockNoteEditor } from "../../hooks/useBlockNoteEditor.js"; export const EmojiPicker = (props: { onEmojiSelect: (emoji: { native: string }) => void; @@ -11,6 +13,7 @@ export const EmojiPicker = (props: { const [open, setOpen] = useState(false); const Components = useComponentsContext()!; + const editor = useBlockNoteEditor(); const blockNoteContext = useBlockNoteContext(); return ( @@ -34,17 +37,24 @@ export const EmojiPicker = (props: { {props.children} - - setOpen(false)} - onEmojiSelect={(emoji: { native: string }) => { - props.onEmojiSelect(emoji); - setOpen(false); - }} - theme={blockNoteContext?.colorSchemePreference} - /> - + {createPortal( + + setOpen(false)} + onEmojiSelect={(emoji: { native: string }) => { + props.onEmojiSelect(emoji); + setOpen(false); + }} + theme={blockNoteContext?.colorSchemePreference} + /> + , + editor.domElement!.parentElement!, + )} ); }; diff --git a/packages/react/src/editor/styles.css b/packages/react/src/editor/styles.css index eb61a59fa2..90c8b62b74 100644 --- a/packages/react/src/editor/styles.css +++ b/packages/react/src/editor/styles.css @@ -286,3 +286,12 @@ background-color: #20242a; border: 2px solid #23405b; } + +/* Emoji Picker styling */ +em-emoji-picker { + max-height: 100%; +} + +.bn-emoji-picker-popover { + z-index: 6000; +} diff --git a/packages/shadcn/src/popover/popover.tsx b/packages/shadcn/src/popover/popover.tsx index ac14b34f13..3a6f91369f 100644 --- a/packages/shadcn/src/popover/popover.tsx +++ b/packages/shadcn/src/popover/popover.tsx @@ -57,7 +57,7 @@ export const PopoverContent = forwardRef< sideOffset={8} className={cn( className, - "flex flex-col gap-2", + "z-[10000] flex flex-col gap-2", variant === "panel-popover" ? "w-fit max-w-none border-none p-0 shadow-none" : "", From a71f278bd1d1779de183f2647f775045284d48c9 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Fri, 10 Oct 2025 11:02:13 +0200 Subject: [PATCH 2/4] Fixed Mantine focus handling --- examples/07-collaboration/05-comments/src/App.tsx | 4 ++-- examples/07-collaboration/05-comments/src/style.css | 5 +++++ packages/ariakit/src/comments/Comment.tsx | 1 + packages/mantine/src/comments/Comment.tsx | 7 +++---- packages/react/src/components/Comments/Comment.tsx | 4 ++++ packages/react/src/components/Comments/EmojiPicker.tsx | 9 +++++++-- packages/react/src/editor/ComponentsContext.tsx | 1 + packages/react/src/editor/styles.css | 5 +---- packages/shadcn/src/comments/Comment.tsx | 1 + 9 files changed, 25 insertions(+), 12 deletions(-) diff --git a/examples/07-collaboration/05-comments/src/App.tsx b/examples/07-collaboration/05-comments/src/App.tsx index bd11b2539e..81d5ae0931 100644 --- a/examples/07-collaboration/05-comments/src/App.tsx +++ b/examples/07-collaboration/05-comments/src/App.tsx @@ -4,8 +4,8 @@ import { DefaultThreadStoreAuth, YjsThreadStore, } from "@blocknote/core/comments"; -import { BlockNoteView } from "@blocknote/mantine"; -import "@blocknote/mantine/style.css"; +import { BlockNoteView } from "@blocknote/shadcn"; +import "@blocknote/shadcn/style.css"; import { useCreateBlockNote } from "@blocknote/react"; import { YDocProvider, useYDoc, useYjsProvider } from "@y-sweet/react"; import { useMemo, useState } from "react"; diff --git a/examples/07-collaboration/05-comments/src/style.css b/examples/07-collaboration/05-comments/src/style.css index 1172740d3d..eaf9d337e9 100644 --- a/examples/07-collaboration/05-comments/src/style.css +++ b/examples/07-collaboration/05-comments/src/style.css @@ -40,3 +40,8 @@ line-height: 12px; padding-left: 14px; } + +.bn-thread { + max-height: 200px; + overflow: auto !important; +} diff --git a/packages/ariakit/src/comments/Comment.tsx b/packages/ariakit/src/comments/Comment.tsx index 452cf49073..efc1746f20 100644 --- a/packages/ariakit/src/comments/Comment.tsx +++ b/packages/ariakit/src/comments/Comment.tsx @@ -58,6 +58,7 @@ export const Comment = forwardRef< actions, children, edited, + emojiPickerOpen, // Unused ...rest } = props; diff --git a/packages/mantine/src/comments/Comment.tsx b/packages/mantine/src/comments/Comment.tsx index a09626f867..e555d9df99 100644 --- a/packages/mantine/src/comments/Comment.tsx +++ b/packages/mantine/src/comments/Comment.tsx @@ -1,7 +1,7 @@ import { assertEmpty } from "@blocknote/core"; import { ComponentProps, mergeRefs, useDictionary } from "@blocknote/react"; import { Avatar, Group, Skeleton, Text } from "@mantine/core"; -import { useFocusWithin, useHover } from "@mantine/hooks"; +import { useHover } from "@mantine/hooks"; import { forwardRef } from "react"; const AuthorInfo = forwardRef< @@ -59,12 +59,12 @@ export const Comment = forwardRef< timeString, edited, actions, + emojiPickerOpen, children, ...rest } = props; const { hovered, ref: hoverRef } = useHover(); - const { focused, ref: focusRef } = useFocusWithin(); const mergedRef = mergeRefs([ref, hoverRef]); assertEmpty(rest, false); @@ -73,13 +73,12 @@ export const Comment = forwardRef< (showActions === true || showActions === undefined || (showActions === "hover" && hovered) || - focused); + emojiPickerOpen); return ( {doShowActions ? ( onReactionSelect(emoji.native) } + onOpenChange={(open) => setEmojiPickerOpen(open)} > onReactionSelect(emoji.native) } + onOpenChange={(open) => setEmojiPickerOpen(open)} > void; + onOpenChange?: (open: boolean) => void; children: ReactNode; }) => { const [open, setOpen] = useState(false); @@ -27,6 +28,7 @@ export const EmojiPicker = (props: { event.preventDefault(); event.stopPropagation(); setOpen(!open); + props.onOpenChange?.(!open); }} style={{ display: "flex", @@ -43,12 +45,15 @@ export const EmojiPicker = (props: { variant={"panel-popover"} > setOpen(false)} + onClickOutside={() => { + setOpen(false); + props.onOpenChange?.(false); + }} onEmojiSelect={(emoji: { native: string }) => { props.onEmojiSelect(emoji); setOpen(false); + props.onOpenChange?.(false); }} theme={blockNoteContext?.colorSchemePreference} /> diff --git a/packages/react/src/editor/ComponentsContext.tsx b/packages/react/src/editor/ComponentsContext.tsx index 2eb161d828..c57e2a5eb1 100644 --- a/packages/react/src/editor/ComponentsContext.tsx +++ b/packages/react/src/editor/ComponentsContext.tsx @@ -233,6 +233,7 @@ export type ComponentProps = { edited: boolean; actions?: ReactNode; showActions?: boolean | "hover"; + emojiPickerOpen: boolean; }; }; // TODO: We should try to make everything as generic as we can diff --git a/packages/react/src/editor/styles.css b/packages/react/src/editor/styles.css index 90c8b62b74..1cd909599f 100644 --- a/packages/react/src/editor/styles.css +++ b/packages/react/src/editor/styles.css @@ -290,8 +290,5 @@ /* Emoji Picker styling */ em-emoji-picker { max-height: 100%; -} - -.bn-emoji-picker-popover { - z-index: 6000; + z-index: 11000; } diff --git a/packages/shadcn/src/comments/Comment.tsx b/packages/shadcn/src/comments/Comment.tsx index 75caab87bb..68dd782b56 100644 --- a/packages/shadcn/src/comments/Comment.tsx +++ b/packages/shadcn/src/comments/Comment.tsx @@ -70,6 +70,7 @@ export const Comment = forwardRef< timeString, actions, edited, + emojiPickerOpen, // Unused children, ...rest } = props; From 81db812042ea5ee273bc747ffdf3451c14c73887 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Fri, 10 Oct 2025 12:06:53 +0200 Subject: [PATCH 3/4] Fixed build --- packages/react/src/editor/ComponentsContext.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/editor/ComponentsContext.tsx b/packages/react/src/editor/ComponentsContext.tsx index c57e2a5eb1..5bd29c3686 100644 --- a/packages/react/src/editor/ComponentsContext.tsx +++ b/packages/react/src/editor/ComponentsContext.tsx @@ -233,7 +233,7 @@ export type ComponentProps = { edited: boolean; actions?: ReactNode; showActions?: boolean | "hover"; - emojiPickerOpen: boolean; + emojiPickerOpen?: boolean; }; }; // TODO: We should try to make everything as generic as we can From d7fa0c7095a29f4a3471d756f1782ec1739690d6 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Fri, 10 Oct 2025 14:09:00 +0200 Subject: [PATCH 4/4] Implemented PR feedback --- examples/07-collaboration/05-comments/src/App.tsx | 4 ++-- packages/react/src/components/Comments/Comment.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/07-collaboration/05-comments/src/App.tsx b/examples/07-collaboration/05-comments/src/App.tsx index 81d5ae0931..bd11b2539e 100644 --- a/examples/07-collaboration/05-comments/src/App.tsx +++ b/examples/07-collaboration/05-comments/src/App.tsx @@ -4,8 +4,8 @@ import { DefaultThreadStoreAuth, YjsThreadStore, } from "@blocknote/core/comments"; -import { BlockNoteView } from "@blocknote/shadcn"; -import "@blocknote/shadcn/style.css"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; import { useCreateBlockNote } from "@blocknote/react"; import { YDocProvider, useYDoc, useYjsProvider } from "@y-sweet/react"; import { useMemo, useState } from "react"; diff --git a/packages/react/src/components/Comments/Comment.tsx b/packages/react/src/components/Comments/Comment.tsx index 18e8cb0ff4..26f940892e 100644 --- a/packages/react/src/components/Comments/Comment.tsx +++ b/packages/react/src/components/Comments/Comment.tsx @@ -167,7 +167,7 @@ export const Comment = ({ onEmojiSelect={(emoji: { native: string }) => onReactionSelect(emoji.native) } - onOpenChange={(open) => setEmojiPickerOpen(open)} + onOpenChange={setEmojiPickerOpen} > onReactionSelect(emoji.native) } - onOpenChange={(open) => setEmojiPickerOpen(open)} + onOpenChange={setEmojiPickerOpen} >