Skip to content

Notes: Move floating notes into a canvas margin - #83786

Open
Mamaduka wants to merge 7 commits into
trunkfrom
add/notes-canvas-margin
Open

Mamaduka wants to merge 7 commits into
trunkfrom
add/notes-canvas-margin

Conversation

@Mamaduka

@Mamaduka Mamaduka commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

What?

Closes #79970. Closes #73417.
Alternative to #79864. Stacked on #83768.

Floating notes move from a complementary area into a canvas margin owned by VisualEditor, and gain a Minimize mode. Notes stay open beside the Settings sidebar, and notices and the canvas scrollbar span the full editor width. As the canvas narrows, notes collapse to avatar pills (82px, below 880px), then yield to All notes (below 482px); device preview, a resized canvas and zoom out also yield.

Why?

Only one complementary area can be active in the core scope, so floating notes and Settings were mutually exclusive, and the notes column narrowed the editor content.

#79864 fixed the layout from the notes side, finding the canvas by class name, adding ResizeObservers and measuring canvas width in React to pick a tier. VisualEditor already owns the canvas width, resizing, and zoom state, so the reservation belongs there, and CSS can pick the tier without measuring.

How?

NotesSidebar renders CanvasMargin.Fill only when it has notes to show; VisualEditor reads useSlotFills and notesDisplayMode, and adds the tiered reservation CSS (getCanvasMarginCSS) as in-iframe media queries, while a container query on the ResizableEditor box shows the slot in the same frame.

Pills are CSS only: one mixin applied by the .is-minimized class or by a container query below 880px, so React never needs the canvas width. A resizable canvas (enableResizing) or zoom out hides the slot, focusNote routes to All notes through the slot's checkVisibility(), and the board store's existing ResizeObserver measures the scrollbar width.

Testing Instructions

  1. Open a post, add a paragraph, and choose Options > Add note in the block toolbar. The note form opens in the canvas margin, and no content renders under it.
  2. Open the Settings sidebar. The notes stay visible.
  3. Narrow the window to about 1100px. The threads collapse to avatar pills; hovering over a pill shows the author, and clicking it expands the thread.
  4. Also open List View (window about 900px wide). The pills hide, and Add note opens All notes.
  5. Widen the window and choose Options > Notes > Minimize notes. The threads show as pills at any width. Expand notes brings back full threads.
  6. Choose Hide notes. The margin goes away. Add a note and the notes come back.
  7. Switch to View > Tablet, or drag a canvas resize handle. The notes hide, and Add note opens All notes. Switch back to Desktop and they return.
  8. With Twenty Twenty-Five, show the template and use Zoom Out. The notes hide, and Add note opens All notes.

Screenshots or screencast

CleanShot.2026-09-29.at.18.38.52.mp4

Use of AI Tools

Assisted by Claude.

@Mamaduka Mamaduka self-assigned this Sep 29, 2026
@Mamaduka Mamaduka added [Type] Enhancement A suggestion for improvement. [Feature] Notes Phase 3 of the Gutenberg roadmap around block commenting labels Sep 29, 2026
@github-actions github-actions Bot added the [Package] Editor /packages/editor label Sep 29, 2026
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @justinemshields.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: justinemshields.

Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: adamsilverstein <adamsilverstein@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: annezazu <annezazu@git.wordpress.org>
Co-authored-by: jeffpaul <jeffpaul@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

📦 Bundle size

Size Change: +2.21 kB (+0.03%)

Total Size: 8.25 MB

📦 View Changed
Filename Size Change
build/scripts/editor/index.min.js 617 kB +856 B (+0.14%)
build/styles/editor/style-rtl.css 32.3 kB +365 B (+1.14%)
build/styles/editor/style-rtl.min.css 27.6 kB +309 B (+1.13%)
build/styles/editor/style.css 32.4 kB +366 B (+1.14%)
build/styles/editor/style.min.css 27.5 kB +309 B (+1.13%)

38d67ee Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric 4d698b7 trunk % Change
timeToFirstByte 56.55 ms +7.25% -3.71% 55.5 ms +9.37% -1.89% 1.89%
largestContentfulPaint 92 ms +4.35% -4.35% 90 ms +11.11% -2.22% 2.22%
lcpMinusTtfb 34.4 ms +7.41% -2.33% 34.2 ms +20.32% -4.24% 0.58%
wpBeforeTemplate 27.66 ms +10.67% -1.37% 27.44 ms +15.09% -0.91% 0.8%
wpTemplate 24.39 ms +2.75% -3.44% 23.7 ms +5.11% -2.57% 2.91%
wpTotal 52.53 ms +8.32% -3.35% 52.01 ms +9.13% -2.02% 1%
wpMemoryUsage 7.62 MB +0% -0% 7.59 MB +0% -0% 0.46%
wpDbQueries 17 +0% -0% 17 +0% -0% 0%

front-end-classic-theme

Metric 4d698b7 trunk % Change
timeToFirstByte 46.35 ms +10.57% -1.08% 46.15 ms +4.98% -1.41% 0.43%
largestContentfulPaint 104 ms +1.92% -3.85% 100 ms +0% -4% 4%
lcpMinusTtfb 54.3 ms +3.41% -1.75% 52.2 ms +3.45% -2.97% 4.02%
wpBeforeTemplate 25.76 ms +7.88% -2.29% 25.71 ms +2.92% -2.37% 0.19%
wpTemplate 17.67 ms +2.38% -1.3% 17.56 ms +3.93% -1.03% 0.63%
wpTotal 43.47 ms +10.54% -1.56% 43.19 ms +5.37% -1.39% 0.65%
wpMemoryUsage 6.25 MB +0% -0% 6.20 MB +0% -0% 0.71%
wpDbQueries 14 +0% -0% 14 +0% -0% 0%

media-processing

Metric 4d698b7 trunk % Change
mediaProcessingJpeg 401.05 ms +0.37% -0.28% 400.76 ms +0.41% -2.05% 0.07%
mediaProcessingAvif 5975.03 ms +0.18% -0.18% 6023.3 ms +0.21% -0.08% -0.8%
mediaProcessingJpegToAvif 4124.38 ms +0.17% -0.04% 4147.26 ms +0.25% -0.04% -0.55%

media-upload

Metric 4d698b7 trunk % Change
jpegUploadProcessing 1434.7 ms +36.19% -1.33% 1405.73 ms +0.3% -0.61% 2.06%
pngUploadProcessing 175.87 ms +23.65% -3.41% 199.56 ms +5.31% -12.8% -11.87%
largeJpegUploadProcessing 1409.89 ms +0.24% -0.74% 1407.6 ms +0.51% -0.4% 0.16%
multipleImageUploadProcessing 1556.3 ms +0.56% -1.73% 1553.36 ms +0.22% -1.22% 0.19%

post-editor

Metric 4d698b7 trunk % Change
serverResponse 539.32 ms +2.77% -7.72% 501.16 ms +1.58% -2.53% 7.61%
firstPaint 237.65 ms +9.8% -13.7% 213.26 ms +18.38% -5.83% 11.44%
domContentLoaded 1144.09 ms +1.65% -2.38% 1087.44 ms +2.47% -0.42% 5.21%
loaded 1145.51 ms +1.65% -2.36% 1088.86 ms +2.49% -0.42% 5.2%
firstContentfulPaint 467.89 ms +5.23% -5.02% 447.73 ms +2.03% -1.75% 4.5%
firstBlock 3404.81 ms +0.5% -0.79% 3297.76 ms +1.62% -0.85% 3.25%
type 20.13 ms +4.42% -3.38% 18.45 ms +5.09% -3.96% 9.11%
typeWithoutInspector 19.18 ms +6.93% -4.59% 19.21 ms +2.5% -4.01% -0.16%
typeWithTopToolbar 25.29 ms +2.45% -4.39% 26.91 ms +4.61% -6.8% -6.02%
typeContainer 8.98 ms +11.36% -7.68% 9.16 ms +6.77% -2.84% -1.97%
focus 73.42 ms +13.95% -6.63% 85.46 ms +7.69% -7.03% -14.09%
firstFocus 194.63 ms +0% -0% 213 ms +0% -0% -8.62%
selectAll 534.25 ms +8.44% -2.65% 577.21 ms +2.71% -3.06% -7.44%
listViewOpen 66.55 ms +9.35% -11.87% 70.28 ms +15.47% -5.48% -5.31%
inserterOpen 23.38 ms +15.7% -6.84% 25.33 ms +13.19% -9.51% -7.7%
inserterHover 2.3 ms +5.22% -6.96% 2.43 ms +15.23% -13.99% -5.35%
inserterSearch 8.14 ms +8.72% -6.76% 8.49 ms +7.89% -12.13% -4.12%
loadPatterns 669.47 ms +3.61% -6.79% 639.69 ms +1.54% -5.49% 4.66%
wpTotal 528.79 ms +2.87% -7.8% 490.94 ms +1.57% -2.53% 7.71%
wpMemoryUsage 13.17 MB +0% -0% 13.13 MB +0% -0% 0.28%
wpDbQueries 54 +0% -1.85% 54 +0% -1.85% 0%

site-editor

Metric 4d698b7 trunk % Change
serverResponse 397.91 ms +3.03% -5.47% 402.64 ms +2.81% -5.39% -1.17%
firstPaint 189.04 ms +59.92% -17.39% 210.21 ms +4.03% -7.78% -10.07%
domContentLoaded 987.73 ms +2.13% -0.96% 1003.03 ms +0.89% -1.22% -1.53%
loaded 988.81 ms +2.1% -0.98% 1003.93 ms +0.9% -1.22% -1.51%
firstContentfulPaint 403.12 ms +2.82% -3.74% 405.14 ms +1.51% -2.7% -0.5%
firstBlock 3501.96 ms +1.89% -0.67% 3512.54 ms +0.35% -0.95% -0.3%
type 17.08 ms +1.81% -5.62% 16.12 ms +8.25% -1.49% 5.96%
navigate 104.81 ms +1.57% -12.77% 99.98 ms +2.88% -4.91% 4.83%
loadPatterns 1259.03 ms +8.86% -5.65% 1201.76 ms +2.11% -5.17% 4.77%
loadPages 1063.68 ms +1.25% -0.89% 1054.24 ms +1.4% -1.02% 0.9%
wpTotal 388.05 ms +3.16% -5.46% 393.17 ms +2.87% -5.74% -1.3%
wpMemoryUsage 12.14 MB +0% -0% 12.09 MB +0% -0% 0.41%
wpDbQueries 43.5 +1.15% -1.15% 43.5 +1.15% -1.15% 0%

38d67ee Run

🏁 Flaky tests

Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

submenu converts to link automatically in /test/e2e/specs/editor/blocks/navigation.spec.js, passed after 1 failed attempt.
Error: apiRequestContext.fetch: socket hang up
Call log:
  - → POST http://localhost:8889/wp-json/wp/v2/navigation
    - user-agent: Playwright/1.63.0 (x64; ubuntu 24.04) node/24.18 CI/1
    - accept: */*
    - accept-encoding: gzip,deflate,br
    - X-WP-Nonce: fedfc0698e
    - content-type: application/json
    - content-length: 356
    - cookie: wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_23778236db82f19306f247e20a353a99=admin%7C1791034755%7CeMfi93pbkD464BRGfdnEOb6V05P05KPxmcXLPPua4dV%7C7421b14702e87286089a6998a453e675415163d2a74b19498f4c24d40fc27e7c; wp-settings-time-1=1790862015

    at RequestUtils.rest (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/rest.ts:112:39)
    at RequestUtils.createRecord (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/records.ts:20:14)
    at RequestUtils.createNavigationMenu (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/menus.ts:63:14)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/navigation.spec.js:226:23

38d67ee Run

@Mamaduka

Copy link
Copy Markdown
Member Author

A couple of things to decide:

  • Are we shipping "Expanded notes" or "Minimized notes" as the new default?
  • Should the Options > Notes sub-menu reflect the screen size-based minimized state? See step 3 in testing instructions.

Screencast

CleanShot.2026-09-29.at.19.27.21.mp4

@adamsilverstein

Copy link
Copy Markdown
Member

Are we shipping "Expanded notes" or "Minimized notes" as the new default?

I would leave expanded by default (given a big enough screen).

Should the Options > Notes sub-menu reflect the screen size-based minimized state? See step 3 in testing instructions.

My feeling is yes - the menu should reflect the state, but only if we can do it in a temporary way so making the container larger again switches the selection back to expanded mode. Its a nit though and fine without this, so fine to leave it off for now to keep the PR simpler.

I'll give it a test in playground:
Test in WordPress Playground

@adamsilverstein

Copy link
Copy Markdown
Member

This tested well! Everything I tested checked out and I like the overall code restructure, moving the logic into the VisualEditor is smart, eliminating the observer from my PR entirely.

I'm going to close my PR in favor of this one and propose a few tests from that PR here in a follow up.

Comment thread packages/editor/src/components/collab-sidebar/style.scss
Comment thread packages/editor/src/components/visual-editor/canvas-margin.js
@annezazu

Copy link
Copy Markdown
Contributor

Took this for a spin. I dig it! This is much better than what I attempted previously. Overall, it feels quite smooth and the placement of the options makes sense to me. I agree with Adam's feedback around: "when i flip back and forth between the All Notes sidebar and floating notes in testing, the effect is slightly jarring." It's not horrible but it could be smoothed out a bit more.

Screen.Recording.2026-09-29.at.12.54.15.PM.mov

Base automatically changed from add/notes-display-mode to trunk September 30, 2026 04:01
@Mamaduka
Mamaduka force-pushed the add/notes-canvas-margin branch from 7100385 to 749b4f2 Compare September 30, 2026 04:03
@Mamaduka

Copy link
Copy Markdown
Member Author

Here's a screencast for the following behavior polish.

The Notes submenu now reflects the available room, as you suggested. "Expand notes" is disabled with "Not enough space." on a narrow canvas, shows Minimize as checked, and updates live while the menu is open. The preference doesn't change, so a wider canvas restores it. I'll push it shortly.

Screencast

CleanShot.2026-09-30.at.09.14.44.mp4

@jasmussen

Copy link
Copy Markdown
Contributor

Also took this for a spin, it's really getting there:

canvas notes

There's something fairly obvious about surfaces now, that makes a lot of sense for me. I think it will especially make sense come suggestion mode, where any change you would make in the inspector, say a font size change to a paragraph, would immediately make a suggestion note appear. Without this in-canvas feature, you would have to bounce between notes and inspector panels.

Minimised notes, and the option to toggle between them, looks good to me.

The main thing that tripped me was in a constrained context where the notes are minimised and cover your content when expanded: in this situation simply selecting the paragraph would expand the note in addition to highlighting it, meaning you can't select a paragraph just to read it. Perhaps this is a use case I hadn't thought of in previous mockups, and I wonder would it be possible to only highlight the attached note, not also expand it?

@Mamaduka

Copy link
Copy Markdown
Member Author

Thanks, @jasmussen!

I wonder would it be possible to only highlight the attached note, not also expand it?

I think that should be doable. I can change what selecting a block signals based on display mode.

@jasmussen

Copy link
Copy Markdown
Contributor

I think it might be worth a shot, at least on the narrow/mobile breakpoints.

@Mamaduka

Copy link
Copy Markdown
Member Author

@jasmussen, pushed the fix in the latest commit.

@Mamaduka

Mamaduka commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

Added a small animation, which hopefully makes the "All Notes" sidebar toggle less jarring.

It's a bit hard to coordinate more complex animations when owners are different packages (the sidebar is handled by the interface package).

Screencast

CleanShot.2026-10-01.at.09.37.25.mp4

@annezazu

annezazu commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

The updated animation looks solid to me!

@Mamaduka

Mamaduka commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

I think we can close #75450 after this is merged. The "All notes" is just another sidebar, and it works like one. Closing the current sidebar doesn't restore the sidebar you had open before. cc @talldan

@jasmussen jasmussen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General thumbs up for the direction.

Mamaduka and others added 7 commits October 1, 2026 17:33
Floating notes are no longer a complementary area. The visual editor owns a
canvas margin slot and reserves 280px inside the canvas while notes fill it,
so notes sit beside the Settings sidebar and notices span the editor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds "Minimize notes", which collapses unselected threads to avatar
pills in an 82px canvas margin. Full mode also shows pills when the
canvas is between 482px and 880px. Pills are CSS only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A resized canvas or device preview gets no canvas margin, like zoom out;
Add note opens All notes. Rename "Show notes" to "Expand notes" and trim
the floating notes tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Match the other Options menu items, which stay open. Also check that
notices keep the full canvas width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Expand and Minimize disable when the canvas has no room for them, with a
short reason. A narrow canvas shows Minimize as checked; the preference
stays. The menu follows canvas resizes while open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selecting a block highlights its minimized note without expanding it, so
the note doesn't cover content the user only wants to read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hides the double notes while "All notes" closes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Mamaduka
Mamaduka force-pushed the add/notes-canvas-margin branch from f0b8e5e to 38d67ee Compare October 1, 2026 13:33
@adamsilverstein

Copy link
Copy Markdown
Member

@Mamaduka Nice one, the animation is a nice touch and improves the transition.

);
const floatingRef = useRef( null );
const isKeyboardTabbingRef = useRef( false );
// Minimized threads expand only while focused, not on block selection.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@adamsilverstein

Copy link
Copy Markdown
Member

I'm doing some more manual testing on this one @Mamaduka and I found a bug state where the notes are not in the correct location. Currently trying to verify reproduction steps and that its a regression here.

@adamsilverstein

Copy link
Copy Markdown
Member

I'm doing some more manual testing on this one @Mamaduka and I found a bug state where the notes are not in the correct location. Currently trying to verify reproduction steps and that its a regression here.

I was able to reproduce the bug I saw, but I don't think its related to the PR but rather a slight variation on an existing bug - splitting an inline note has very unexpected results, the note jumps to an unrelated location. This is very similar to the issue raised in #71544 with block duplication, but the inline notes make it even more obvious.

I'm opening a follow up for this, its easy to reproduce though:

  1. Add an inline note on a text selection.
  2. Hit enter somewhere in the middle of the selection

Expected result: note stays aligned with top part of selection
Actual Result: note jumps down below either selection

Also related:

@Mamaduka

Mamaduka commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

Thanks, @adamsilverstein!

Yes, it's an existing bug and similar to what we've flagged regarding block duplication in #83485. Our board doesn't know how to handle it when a note is shared by multiple anchors - blocks or inline markers.

It's worth researching how other apps handled this, so we don't reinvent the wheel, but here's what I have in mind:

When multiple anchors share a note, by default it's positioned for the first anchor and not rendered for the rest. Selecting another anchor should move it relative to that anchor. What do you think?

P.S. Based on feedback, this looks good to merge. Let's target early next week, which I think will let us ship a Gutenberg release ahead of the first beta.

@adamsilverstein

Copy link
Copy Markdown
Member

P.S. Based on feedback, this looks good to merge. Let's target early next week, which I think will let us ship a Gutenberg release ahead of the first beta.

Lets do it!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Notes Phase 3 of the Gutenberg roadmap around block commenting [Package] Editor /packages/editor [Type] Enhancement A suggestion for improvement.

Projects

None yet

4 participants