Skip to content

Notes: restore the sidebar the add-note flow displaced - #81547

Closed
adamsilverstein wants to merge 10 commits into
try/notes-in-canvas-marginfrom
add/75450-restore-sidebar-after-note
Closed

adamsilverstein wants to merge 10 commits into
try/notes-in-canvas-marginfrom
add/75450-restore-sidebar-after-note

Conversation

@adamsilverstein

@adamsilverstein adamsilverstein commented Aug 12, 2026 •

Copy link
Copy Markdown
Member

What?

Restores the sidebar that was open before a note was composed, when the note form is cancelled.

Stacked on #79864 - please merge that first. This PR only adds the follow-up on top of it.

Fixes #75450
Supersedes #75455 (closed)

Why?

From @talldan's report: open the block inspector, add a note, cancel the note form, and no sidebar is open at all. The inspector is gone and nothing brings it back, so the user loses their place.

Only one complementary area can be active at a time, so opening a notes surface necessarily closes the inspector, the document sidebar, or whatever plugin sidebar was there. @Mamaduka is right that this is ordinary complementary-area behavior - closing one sidebar has never reopened the previous one. What makes notes different is that the switch was programmatic and the thing it opened can be cancelled. An ordinary sidebar switch is something the user asked for; a cancelled note composer is a detour that ended with nothing to show for it.

#79864 already fixes the headline repro at large viewports: floating notes become part of the canvas and stop competing for the sidebar slot, so nothing is displaced and there is nothing to restore. That is what this issue was punted to 7.2 for. What is left after it is the small viewport (below the medium breakpoint, 782px), where "All notes" is the only notes surface and still has to take the slot.

How?

Two small pieces in packages/editor/src/components/collab-sidebar/:

Capture at the moment of the switch. focusNote already read the active area and threw it away. It now records it in a ref, right before enableComplementaryArea overwrites the slot, and only for the new-note path - that is the only one that can be cancelled. A capture is skipped when a notes sidebar is already active, which also keeps a second "Add note" during composition from clobbering the original target.

Restore keyed to the composer, not to the sidebar. A useEffect watches the 'new' -> undefined note-selection transition, which is what every dismissal produces: the Cancel button, Escape, clicking away, and switching blocks. resolveRestoreTarget in the new restore-sidebar.ts then decides what to do, and it is a pure function so the rules are readable and unit-testable:

Situation Result
The user switched or closed sidebars mid-composition do nothing, their choice wins
A notes sidebar was already open do nothing, nothing was displaced
Nothing was open before (null or undefined) close the sidebar
Anything else re-enable that exact identifier

Submitting clears the capture without restoring: on a small viewport the new note lives in the sidebar the user is now looking at, and yanking it away to re-show the inspector would hide their own note. That sidebar has a "Close Notes" button, unlike the old floating one the issue was written about.

The three reasons #75455 didn't land are each addressed by construction, and the table above is where each one lives: it restores the real identifier rather than a hardcoded document sidebar, "nothing was open" maps to closing rather than opening, and the restore no longer hangs off useEnableFloatingSidebar's enable flag, so it fires whether or not the post has other unresolved notes.

The state is a component ref rather than store state on purpose. It is transient memory for a single in-flight composer: it must not persist (the active area is backed by @wordpress/preferences, and a stale restore target firing in a later session would be a worse bug than the one being fixed), it must not sync to other users, and it is produced and consumed in one component. A store slice would only buy survival across a NotesSidebar remount, and every remount that matters also destroys the composer.

Testing Instructions

Test with WordPress Playground

Enable notes, then in the post editor at a narrow window (under 782px wide):

  1. Add a paragraph, open the Settings sidebar on the Block tab, then add a note (block options > "Add note", or ctrl+alt+m). "All notes" takes over. Cancel the form - the Block tab comes back, and focus is on the paragraph. Escape behaves the same.
  2. Same flow starting from the Post tab, and from a plugin sidebar - each one comes back.
  3. Close all sidebars, then add a note and cancel. No sidebar opens. This is the case Notes: Conditionally restore default sidebar #75455 got wrong.
  4. Add a note and submit it this time. "All notes" stays open showing the new note.
  5. With the composer open, open the Settings sidebar yourself. The composer dismisses and Settings stays - no restore fights you for it.
  6. Add a second note to a post that already has notes, then cancel. The inspector still comes back.

At a normal window width, open the Settings sidebar and add a note: the inspector never moves, because the floating notes don't take the slot.

Automated

  • npm run test:unit packages/editor/src/components/collab-sidebar/test/restore-sidebar.ts - 8 passing.
  • npm run test:e2e -- test/e2e/specs/editor/various/block-notes.spec.js -g "Sidebar restoration" - 7 passing. The four that assert a restore were confirmed to fail against this branch without the source change.

Notes for reviewers

A few open questions, none of them blocking:

  • Submit on small viewports keeps "All notes" open rather than restoring. The issue text ("no obvious way to return") was written when the floating sidebar had no close button, which no longer applies. Happy to flip this if reviewers read composition as a strictly modal detour.
  • Mid-composition manual switching is detected by comparing the active area at dismissal against the one the flow opened. Someone who switches away and back to "All notes" before cancelling still gets a restore. Catching that exactly would need a store subscription open for the life of the composer, which seems like a poor trade.
  • undefined becomes an explicit null when cancelling from a never-toggled state, which suppresses the document sidebar's isActiveByDefault auto-open later on. focusNote's own enableComplementaryArea has already set the visibility preference by that point, so that state is unrecoverable either way.
  • The resolved-note path (isApproved) also opens "All notes" over the inspector, but restoring on thread collapse is a different question from restoring after a cancelled composer, so it is left alone here.
  • The new beforeEach/afterEach in the e2e block reset preferences and close sidebars. The active area persists to user meta on a debounce, and without that cleanup the new tests both inherit and leak sidebar state - block-notes.spec.js has already been implicated in unrelated specs failing for this reason.

AI Use

Code and description both written with 🤖 Claude Code. I will review and test.

Adding a note takes the single complementary-area slot, and cancelling the
composer leaves the user with no sidebar at all. Pin the expected behaviour
before changing it, including the case the previous attempt (#75455) got
wrong: cancelling with nothing open must not open the document sidebar.
Capture the active complementary area at the moment the flow opens the notes
sidebar over it, and put it back when the composer is dismissed. Keying the
restore to the note selection rather than to the sidebar's own lifecycle makes
it fire on every dismissal and regardless of whether the post has other notes,
and capturing the real identifier restores the tab or plugin sidebar the user
actually had. Nothing open before means nothing open after. Submitting keeps
the notes sidebar, where the new note now lives.

Fixes #75450.
@github-actions github-actions Bot added the [Package] Editor /packages/editor label Aug 12, 2026
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

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

Co-authored-by: adamsilverstein <adamsilverstein@git.wordpress.org>

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

@github-actions

Copy link
Copy Markdown

Size Change: +200 B (0%)

Total Size: 7.72 MB

📦 View Changed
Filename Size Change
build/scripts/editor/index.min.js 531 kB +200 B (+0.04%)

compressed-size-action

@github-actions

Copy link
Copy Markdown

Flaky tests detected in bd9fdd3.
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.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/31652840459
📝 Reported tests:

Focus management when using the navigation link appender 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/pages
    - user-agent: Playwright/1.62.1 (x64; ubuntu 24.04) node/20.20 CI/1
    - accept: */*
    - accept-encoding: gzip,deflate,br
    - X-WP-Nonce: 8a11de29ff
    - content-type: application/json
    - content-length: 34
    - cookie: wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_23778236db82f19306f247e20a353a99=admin%7C1786752278%7CCAb79G2fWMsNjnyAm93ewARMp3AxuKrNjAdpevkVgJ5%7Caffd3e91d0bb22654c977bace5819addd11f5b47a19c6ba3c75531607d63317c; wp-settings-time-1=1786579644

    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.createPage (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/pages.ts:71:14)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/navigation.spec.js:300:33

adamsilverstein and others added 2 commits September 14, 2026 22:42
… add/75450-restore-sidebar-after-note

# Conflicts:
#	packages/editor/CHANGELOG.md
The trunk merge brought the Jest-to-Vitest migration, which runs with
`globals: false`. The test's bare `describe`/`it`/`expect` were
undefined, so the suite failed to load.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H22PasvCsxDt17L7sQfa5f
@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

📦 Bundle size

Size Change: +225 B (0%)

Total Size: 8.21 MB

📦 View Changed
Filename Size Change
build/scripts/editor/index.min.js 612 kB +225 B (+0.04%)

b3d7248 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric 61c46b7 try/notes-in-canvas-margin % Change
timeToFirstByte 43.5 ms +3.79% -1.03% 44.45 ms +2.7% -3.04% -2.14%
largestContentfulPaint 76 ms +5.26% -5.26% 76 ms +7.89% -5.26% 0%
lcpMinusTtfb 29.7 ms +24.58% -5.22% 31.4 ms +21.18% -8.92% -5.41%
wpBeforeTemplate 21.02 ms +6.76% -2.57% 21.2 ms +5.99% -2.69% -0.85%
wpTemplate 19.16 ms +3.18% -1.15% 19.18 ms +5.06% -3.75% -0.1%
wpTotal 40.25 ms +3.75% -1.59% 40.99 ms +3% -3.07% -1.81%
wpMemoryUsage 7.59 MB +0% -0% 7.58 MB +0% -0% 0.15%
wpDbQueries 17 +0% -0% 17 +0% -0% 0%

front-end-classic-theme

Metric 61c46b7 try/notes-in-canvas-margin % Change
timeToFirstByte 36.65 ms +6.68% -4.23% 37.05 ms +1.75% -4.05% -1.08%
largestContentfulPaint 80 ms +7.5% -2.5% 80 ms +5% -0% 0%
lcpMinusTtfb 44.3 ms +4.06% -5.08% 44.9 ms +3.67% -3.45% -1.34%
wpBeforeTemplate 18.8 ms +6.44% -2.29% 18.8 ms +2.71% -3.03% 0%
wpTemplate 14.43 ms +6.93% -4.78% 14.37 ms +6.82% -3.06% 0.42%
wpTotal 33.63 ms +7.37% -4.22% 33.74 ms +3.11% -3.35% -0.33%
wpMemoryUsage 6.21 MB +0% -0% 6.20 MB +0% -0% 0.12%
wpDbQueries 14 +0% -0% 14 +0% -0% 0%

media-processing

Metric 61c46b7 try/notes-in-canvas-margin % Change
mediaProcessingJpeg 320.88 ms +0.44% -0.6% 325.01 ms +1.32% -2.25% -1.27%
mediaProcessingAvif 4498.42 ms +1.55% -0.37% 4553.16 ms +0.65% -0.44% -1.2%
mediaProcessingJpegToAvif 3009.19 ms +3.06% -0.48% 3137.26 ms +0.64% -1.18% -4.08%

media-upload

Metric 61c46b7 try/notes-in-canvas-margin % Change
jpegUploadProcessing 1408.34 ms +0.72% -0.73% 1402.03 ms +0.6% -0.62% 0.45%
pngUploadProcessing 185.5 ms +9.56% -3.98% 195.53 ms +7.36% -6.21% -5.13%
largeJpegUploadProcessing 1403.42 ms +2.22% -0.31% 1415.15 ms +0.6% -0.63% -0.83%
multipleImageUploadProcessing 1470.08 ms +2.78% -0.38% 1506.78 ms +0.82% -1.34% -2.44%

post-editor

Metric 61c46b7 try/notes-in-canvas-margin % Change
serverResponse 418.23 ms +0.92% -1.75% 395.63 ms +7.35% -3.82% 5.71%
firstPaint 233.99 ms +16.16% -19.01% 230.12 ms +12.6% -28.56% 1.68%
domContentLoaded 945.9 ms +2.57% -1.97% 946.76 ms +1.08% -2.86% -0.09%
loaded 946.92 ms +2.56% -1.97% 947.84 ms +1.06% -2.86% -0.1%
firstContentfulPaint 401.9 ms +2.26% -7.14% 400.55 ms +2.02% -1.63% 0.34%
firstBlock 2706.3 ms +2.21% -1.07% 2705.98 ms +1.49% -0.73% 0.01%
type 18.92 ms +2.7% -4.39% 18.9 ms +5.4% -5.82% 0.11%
typeWithoutInspector 18.5 ms +1.24% -5.3% 18.63 ms +3.38% -4.24% -0.7%
typeWithTopToolbar 23.4 ms +7.48% -1.54% 22.7 ms +3.79% -2.78% 3.08%
typeContainer 8.5 ms +5.76% -6% 8.29 ms +11.7% -2.17% 2.53%
focus 69.24 ms +6.7% -3.89% 66.6 ms +11.07% -4.28% 3.96%
firstFocus 185.69 ms +0% -0% 186.99 ms +0% -0% -0.7%
selectAll 383.29 ms +3.74% -0.7% 382.83 ms +0.24% -7.04% 0.12%
listViewOpen 62.81 ms +5.75% -9% 63.63 ms +2.61% -5.56% -1.29%
inserterOpen 22.84 ms +14.32% -4.03% 22.15 ms +9.98% -8.22% 3.12%
inserterHover 3.07 ms +4.89% -13.03% 2.89 ms +9.34% -15.92% 6.23%
inserterSearch 7.93 ms +6.31% -8.83% 7.43 ms +16.42% -3.63% 6.73%
loadPatterns 615.99 ms +1.19% -2.94% 607.26 ms +4.97% -5.66% 1.44%
wpTotal 408.37 ms +0.87% -1.85% 385.88 ms +7.41% -4.04% 5.83%
wpMemoryUsage 13.13 MB +0% -0% 13.12 MB +0% -0% 0.09%
wpDbQueries 54 +0% -0% 54 +0% -0% 0%

site-editor

Metric 61c46b7 try/notes-in-canvas-margin % Change
serverResponse 489.56 ms +2.32% -5.53% 492.88 ms +4.69% -5.35% -0.67%
firstPaint 252.19 ms +11.36% -22.61% 257.57 ms +9.05% -6.95% -2.09%
domContentLoaded 1126.35 ms +0.49% -0.45% 1118.74 ms +1.36% -0.75% 0.68%
loaded 1127.55 ms +0.49% -0.45% 1119.93 ms +1.37% -0.75% 0.68%
firstContentfulPaint 442.35 ms +3.5% -1.76% 435.41 ms +1.35% -1.3% 1.59%
firstBlock 4111.64 ms +0.72% -0.98% 4110.47 ms +0.43% -1% 0.03%
type 20.36 ms +6.97% -4.52% 19.34 ms +5.38% -3% 5.27%
navigate 117.39 ms +11.93% -3.91% 104.46 ms +33.4% -4.84% 12.38%
loadPatterns 1356.31 ms +6.58% -8.34% 1484.09 ms +5.76% -12.34% -8.61%
loadPages 1052.08 ms +5.88% -1.1% 1069.65 ms +1.72% -2.27% -1.64%
wpTotal 479.79 ms +2.3% -5.64% 483.15 ms +4.82% -5.46% -0.7%
wpMemoryUsage 12.10 MB +0% -0% 12.09 MB +0% -0% 0.06%
wpDbQueries 43.5 +1.15% -1.15% 43 +2.33% -0% 1.16%

b3d7248 Run

🏁 Flaky tests

Show the failures

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.

Navigates the items list via UP/DOWN arrow keys in /test/e2e/specs/site-editor/dataviews-list-layout-keyboard.spec.js, passed after 1 failed attempt.
Error: expect(locator).toBeFocused() failed

Locator:  getByLabel('Page Two')
Expected: focused
Received: inactive
Timeout:  5000ms

Call log:
  - Expect "toBeFocused" getByLabel('Page Two') with timeout 5000ms
  - waiting for getByLabel('Page Two')
    14 × locator resolved to <button type="button" tabindex="-1" aria-pressed="false" id="view-list-0-358-item-wrapper" class="dataviews-view-list__item" aria-labelledby="view-list-0-358-label" aria-describedby="view-list-0-358-description"></button>
       - unexpected value "inactive"

    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/site-editor/dataviews-list-layout-keyboard.spec.js:146:49
refuses the drop and uploads nothing in /test/e2e/specs/editor/various/single-file-placeholder-drop.spec.js, passed after 1 failed attempt.
Error: expect(received).toHaveLength(expected)

Expected length: 0
Received length: 2
Received array:  [{"_links": {"about": [{"href": "http://localhost:8889/wp-json/wp/v2/types/attachment"}], "author": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/users/1"}], "collection": [{"href": "http://localhost:8889/wp-json/wp/v2/media"}], "replies": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/comments?post=196"}], "self": [{"href": "http://localhost:8889/wp-json/wp/v2/media/196", "targetHints": {"allow": ["GET", "POST", "PUT", "PATCH", "DELETE"]}}]}, "alt_text": "", "author": 1, "caption": {"rendered": ""}, "class_list": ["post-196", "attachment", "type-attachment", "status-inherit", "hentry", "entry"], "comment_status": "open", "date": "2026-09-23T01:28:15", "date_gmt": "2026-09-23T01:28:15", "description": {"rendered": "<p class=\"attachment\"><a href='http://localhost:8889/wp-content/uploads/2026/09/10x10_e2e_test_image_z9T8jK.png'><img loading=\"lazy\" decoding=\"async\" width=\"10\" height=\"10\" src=\"http://localhost:8889/wp-content/uploads/2026/09/10x10_e2e_test_image_z9T8jK.png\" class=\"attachment-medium size-medium\" alt=\"\" style=\"width:100%;height:100%;max-width:10px;\" /></a></p>
"}, "featured_media": 0, "filename": "10x10_e2e_test_image_z9T8jK.png", "filesize": 80, "guid": {"rendered": "http://localhost:8889/wp-content/uploads/2026/09/10x10_e2e_test_image_z9T8jK.png"}, "id": 196, "link": "http://localhost:8889/10x10_e2e_test_image_z9t8jk/", "media_details": {"file": "2026/09/10x10_e2e_test_image_z9T8jK.png", "filesize": 80, "height": 10, "image_meta": {"alt": "", "aperture": "0", "camera": "", "caption": "", "copyright": "", "created_timestamp": "0", "credit": "", "focal_length": "0", "iso": "0", "keywords": [], "orientation": "0", "shutter_speed": "0", "title": ""}, "sizes": {}, "width": 10}, "media_type": "image", "meta": [], "mime_type": "image/png", "modified": "2026-09-23T01:28:15", "modified_gmt": "2026-09-23T01:28:15", "ping_status": "closed", "post": null, "slug": "10x10_e2e_test_image_z9t8jk", "source_url": "http://localhost:8889/wp-content/uploads/2026/09/10x10_e2e_test_image_z9T8jK.png", "status": "inherit", "template": "", "title": {"rendered": "10x10_e2e_test_image_z9T8jK"}, "type": "attachment"}, {"_links": {"about": [{"href": "http://localhost:8889/wp-json/wp/v2/types/attachment"}], "author": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/users/1"}], "collection": [{"href": "http://localhost:8889/wp-json/wp/v2/media"}], "curies": [{"href": "https://api.w.org/{rel}", "name": "wp", "templated": true}], "replies": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/comments?post=194"}], "self": [{"href": "http://localhost:8889/wp-json/wp/v2/media/194", "targetHints": {"allow": ["GET", "POST", "PUT", "PATCH", "DELETE"]}}], "wp:attached-to": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/posts/193", "id": 193, "post_type": "post"}]}, "alt_text": "", "author": 1, "caption": {"rendered": ""}, "class_list": ["post-194", "attachment", "type-attachment", "status-inherit", "hentry", "entry"], "comment_status": "open", "date": "2026-09-23T01:28:13", "date_gmt": "2026-09-23T01:28:13", "description": {"rendered": "<p class=\"attachment\"><a href='http://localhost:8889/wp-content/uploads/2026/09/deb9a471-6149-401f-b1cd-d330bbfdcfc6.png'><img loading=\"lazy\" decoding=\"async\" width=\"10\" height=\"10\" src=\"http://localhost:8889/wp-content/uploads/2026/09/deb9a471-6149-401f-b1cd-d330bbfdcfc6.png\" class=\"attachment-medium size-medium\" alt=\"\" style=\"width:100%;height:100%;max-width:10px;\" /></a></p>
"}, "featured_media": 0, "filename": "deb9a471-6149-401f-b1cd-d330bbfdcfc6.png", "filesize": 80, "guid": {"rendered": "http://localhost:8889/wp-content/uploads/2026/09/deb9a471-6149-401f-b1cd-d330bbfdcfc6.png"}, "id": 194, "link": "http://localhost:8889/?attachment_id=194", "media_details": {"file": "2026/09/deb9a471-6149-401f-b1cd-d330bbfdcfc6.png", "filesize": 80, "height": 10, "image_meta": {"alt": "", "aperture": "0", "camera": "", "caption": "", "copyright": "", "created_timestamp": "0", "credit": "", "focal_length": "0", "iso": "0", "keywords": [], "orientation": "0", "shutter_speed": "0", "title": ""}, "sizes": {}, "width": 10}, "media_type": "image", "meta": [], "mime_type": "image/png", "modified": "2026-09-23T01:28:13", "modified_gmt": "2026-09-23T01:28:13", "ping_status": "closed", "post": 193, "slug": "deb9a471-6149-401f-b1cd-d330bbfdcfc6", "source_url": "http://localhost:8889/wp-content/uploads/2026/09/deb9a471-6149-401f-b1cd-d330bbfdcfc6.png", "status": "inherit", "template": "", "title": {"rendered": "deb9a471-6149-401f-b1cd-d330bbfdcfc6"}, "type": "attachment"}]
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/single-file-placeholder-drop.spec.js:71:45

b3d7248 Run

adamsilverstein and others added 5 commits September 15, 2026 09:54
… add/75450-restore-sidebar-after-note

# Conflicts:
#	packages/editor/CHANGELOG.md
Trunk's Prettier update collapses short union types onto one line, so
the RestoreTarget type failed lint after the trunk merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0171yvn6uH3beNJ6dsUrAyRt
@adamsilverstein

Copy link
Copy Markdown
Member Author

Claude wrote up the closing note:

Closing because its base, #79864, is closed in favor of #83786. #75450 is still open. The restore logic, its unit test, and the e2e tests will come back as a follow-up on top of #83786. That PR opens All notes in more cases (narrow canvas, device preview, zoom out), so the fix matters even more there.

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

Labels

[Package] Editor /packages/editor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant