-
-
Notifications
You must be signed in to change notification settings - Fork 723
refactor: portal floating UI elements to document.body to prevent overflow clipping BLO-1115 #2591
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
50ebffb
11bdffd
1358d89
5756910
303eab2
eaae887
0d114d6
6550e46
670dffc
c6fbfec
73d3e51
3e13fa9
c93b468
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| .bn-container[data-changing-font-demo] .bn-editor * { | ||
| .bn-root[data-changing-font-demo] .bn-editor * { | ||
| font-family: "Comic Sans MS", sans-serif; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,10 @@ | ||
| /* Adds border and shadow to editor */ | ||
| .bn-container[data-theming-css-demo] .bn-editor * { | ||
| .bn-root[data-theming-css-demo] .bn-editor * { | ||
| color: blue; | ||
| } | ||
|
|
||
| /* Makes slash menu hovered items blue */ | ||
| .bn-container[data-theming-css-demo] | ||
| .bn-suggestion-menu-item[aria-selected="true"], | ||
| .bn-container[data-theming-css-demo] .bn-suggestion-menu-item:hover { | ||
| .bn-root[data-theming-css-demo] .bn-suggestion-menu-item[aria-selected="true"], | ||
| .bn-root[data-theming-css-demo] .bn-suggestion-menu-item:hover { | ||
| background-color: blue; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,7 +58,7 @@ export const Comment = forwardRef< | |
| actions, | ||
| children, | ||
| edited, | ||
| emojiPickerOpen, // Unused | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fyi, this was not implemented in ariakit / shadcn, so decided to fix |
||
| emojiPickerOpen, | ||
| ...rest | ||
| } = props; | ||
|
|
||
|
|
@@ -72,7 +72,8 @@ export const Comment = forwardRef< | |
| (showActions === true || | ||
| showActions === undefined || | ||
| (showActions === "hover" && hovered) || | ||
| focused); | ||
| focused || | ||
| emojiPickerOpen); | ||
|
|
||
| return ( | ||
| <AriakitGroup | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -714,6 +714,25 @@ export class BlockNoteEditor< | |
| return this.prosemirrorView?.dom as HTMLDivElement | undefined; | ||
| } | ||
|
|
||
| /** | ||
| * The portal container element at `document.body` used by floating UI | ||
| * elements (menus, toolbars) to escape overflow:hidden ancestors. | ||
| * Set by BlockNoteView; undefined in headless mode. | ||
| */ | ||
| public portalElement: HTMLElement | undefined; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nperez0111 not sure about setting this on the editor. We need it for the UniqueID and SideMenu extensions though. wdyt?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, I would not put this on the editor, much less public. Need to find a workaround here |
||
|
|
||
| /** | ||
| * Checks whether a DOM element belongs to this editor — either inside the | ||
| * editor's DOM tree or inside its portal container (used for floating UI | ||
| * elements like menus and toolbars). | ||
| */ | ||
| public isWithinEditor = (element: Element): boolean => { | ||
| return !!( | ||
| this.domElement?.parentElement?.contains(element) || | ||
| this.portalElement?.contains(element) | ||
| ); | ||
| }; | ||
|
YousefED marked this conversation as resolved.
|
||
|
|
||
| public isFocused() { | ||
| if (this.headless) { | ||
| return false; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,26 +20,6 @@ | |
| padding: 0; | ||
| } | ||
|
|
||
| /* | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this was unused, lingering code that I removed in this PR |
||
| bn-root should be applied to all top-level elements | ||
|
|
||
| This includes the Prosemirror editor, but also <div> element such as | ||
| Tippy popups that are appended to document.body directly | ||
| */ | ||
| .bn-root { | ||
| -webkit-box-sizing: border-box; | ||
| -moz-box-sizing: border-box; | ||
| box-sizing: border-box; | ||
| } | ||
|
|
||
| .bn-root *, | ||
| .bn-root *::before, | ||
| .bn-root *::after { | ||
| -webkit-box-sizing: inherit; | ||
| -moz-box-sizing: inherit; | ||
| box-sizing: inherit; | ||
| } | ||
|
|
||
| /* reset styles, they will be set on blockContent */ | ||
| .bn-default-styles p, | ||
| .bn-default-styles h1, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -11,18 +11,19 @@ import { forwardRef } from "react"; | |||||
| export const Popover = ( | ||||||
| props: ComponentProps["Generic"]["Popover"]["Root"], | ||||||
| ) => { | ||||||
| const { open, onOpenChange, position, children, ...rest } = props; | ||||||
| const { open, onOpenChange, position, portalRoot, children, ...rest } = props; | ||||||
|
|
||||||
| assertEmpty(rest); | ||||||
|
|
||||||
| return ( | ||||||
| <MantinePopover | ||||||
| middlewares={{ size: { padding: 20 } }} | ||||||
| withinPortal={false} | ||||||
| withinPortal={!!portalRoot} | ||||||
| portalProps={portalRoot ? { target: portalRoot } : undefined} | ||||||
| opened={open} | ||||||
| onChange={onOpenChange} | ||||||
| position={position} | ||||||
| zIndex={10000} | ||||||
| zIndex={portalRoot ? undefined : 10000} | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify z-index handling for Mantine popovers and bn root variable wiring.
# 1) Confirm changed Mantine popover behavior in this file.
rg -nP -C3 'withinPortal=|portalProps=|zIndex=' packages/mantine/src/popover/Popover.tsx
# 2) Check whether bn-ui-base-z-index is consumed anywhere in styling/code.
rg -nP -C2 'bn-ui-base-z-index|--bn-ui-base-z-index|z-index' packages/react packages/mantine
# 3) Inspect portal root creation context for explicit stacking styles.
rg -nP -C8 'createPortal\\(|className=|data-color-scheme|bn-root' packages/react/src/editor/BlockNoteView.tsxRepository: TypeCellOS/BlockNote Length of output: 2993 🏁 Script executed: # Find the portal root creation and its styling context
rg -nA15 -B5 'createPortal|portalRoot.*=' packages/react/src/editor/BlockNoteView.tsx | head -100Repository: TypeCellOS/BlockNote Length of output: 2391 🏁 Script executed: # Check if there's z-index styling on the portal root or bn-root specifically
rg -nP 'bn-root|portal.*root' packages/react/src/editor/styles.css packages/react/src/editor/BlockNoteView.tsx -A3 -B3Repository: TypeCellOS/BlockNote Length of output: 4550 🏁 Script executed: # Check Mantine Popover implementation or types to see how zIndex behaves
fd -t f -e tsx -e ts packages/mantine | xargs grep -l "zIndex" | head -5Repository: TypeCellOS/BlockNote Length of output: 433 🏁 Script executed: # Find Mantine Popover files
fd -t f --full-path 'packages/mantine' -e tsx -e ts | head -20Repository: TypeCellOS/BlockNote Length of output: 856 🏁 Script executed: # Check if there's any handling of zIndex prop for Popover in Mantine code
rg -n 'zIndex|z-index' packages/mantine/src/popover/ -B3 -A3Repository: TypeCellOS/BlockNote Length of output: 538 🏁 Script executed: # Verify what Mantine's default z-index behavior is for portaled popovers
rg -n 'const.*Popover|export.*Popover' packages/mantine/src/popover/ -A20 | head -80Repository: TypeCellOS/BlockNote Length of output: 3408 Portaled popovers lose stacking control with Mantine's default z-index. At line 26, The fix aligns with the established pattern used in Proposed fix- zIndex={portalRoot ? undefined : 10000}
+ zIndex={portalRoot ? "var(--bn-ui-base-z-index, 10000)" : 10000}This ensures portaled popovers respect the base z-index system while maintaining fallback to 10000 when the variable is not defined. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| > | ||||||
| {children} | ||||||
| </MantinePopover> | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.