Media editor: Make the cropper available through the private API by ramonjd · Pull Request #86149 · WordPress/gutenberg · GitHub
Skip to content

Media editor: Make the cropper available through the private API - #86149

Closed
ramonjd wants to merge 3 commits into
refactor/media-editor-instruction-helper-inputfrom
add/media-editor-private-cropper-export
Closed

ramonjd wants to merge 3 commits into
refactor/media-editor-instruction-helper-inputfrom
add/media-editor-private-cropper-export

Conversation

@ramonjd

@ramonjd ramonjd commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

What?

See #86145. Stacked on #86147: until that PR merges, this PR is based on its branch so the diff shows only this change.

Makes the image editor's cropper available to other packages through the media editor's private API: the Cropper component, useCropperController, getSourceRegion, getSourceRegionPercent and buildModifiers.

Why?

This is the second small step of #86145: export the cropper privately first, so real use can shape the API before it becomes a public promise. Today the private API object only carries the store, the editor and its modal, so a package that wants only the cropper, such as the media library or the site icon screen, cannot use it.

How?

The five items are added to the object that private-apis.ts already locks. Nothing is added to the public exports, and a small test pins them. The image editor README now says the module is private and shows how a package that is allowed to use private APIs can unlock the new items. The README and the comment at the top of the image editor's main file no longer describe the module as internal or public.

There is no changelog entry, since this only touches the private API and does not change the public interface. Say if reviewers want one.

Testing Instructions

  1. Run npm run test:unit -- packages/media-editor. It should pass, including the new check on the public exports.
  2. There is no visible change: nothing uses the new items yet, and a follow-up is planned to add a Storybook demonstration that does.

Checked with the unit tests, lint, the docs lint and the typecheck. Not yet tried in a browser, and the README example was written against the code but not run.

Packages that are allowed to use private APIs could not use the cropper, its state hook or the crop helpers, because the private API object only carried the store, the editor and its modal.

This adds the cropper component, `useCropperController`, `getSourceRegion`, `getSourceRegionPercent` and `buildModifiers` to that object. The public exports do not change, and a small test pins them.

The image editor README and the comment at the top of its barrel file still called the module internal or a public contract, so both now describe the private API.
The comment listed three of the four things the private API takes from the image editor and left out how `buildModifiers` reaches it. It now says only that a small part of the module is available outside the package, and points at `private-apis.ts` for the list.
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

Preview in WordPress Playground

🏷️ Labels

This pull request needs exactly one label indicating its type, and has 0.

  • Required: any label starting with [Type].
  • Found: none.

Read more about Type labels in Gutenberg. If you cannot add labels yourself, a reviewer can do it for you.

📦 Bundle size

Size Change: +355 B (0%)

Total Size: 8.58 MB

📦 View Changed
Filename Size Change
build/scripts/editor/index.min.js 559 kB +355 B (+0.06%)

f914610 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric b6516cc refactor/media-editor-instruction-helper-input % Change
timeToFirstByte 56.3 ms +5.15% -3.11% 61.6 ms +13.31% -3.57% -8.6%
largestContentfulPaint 96 ms +4.17% -4.17% 102 ms +5.88% -5.88% -5.88%
lcpMinusTtfb 35.8 ms +23.32% -3.35% 36.2 ms +13.54% -4.7% -1.1%
wpBeforeTemplate 29.21 ms +10% -1.68% 31.37 ms +14.19% -3.44% -6.89%
wpTemplate 22.28 ms +5.12% -2.74% 25.38 ms +3.55% -4.49% -12.21%
wpTotal 52.48 ms +4.5% -3.03% 57.71 ms +9.41% -4.18% -9.06%
wpMemoryUsage 7.70 MB +0% -0% 7.71 MB +0% -0% -0.07%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric b6516cc refactor/media-editor-instruction-helper-input % Change
timeToFirstByte 47.65 ms +5.67% -2.62% 51.5 ms +3.98% -5.83% -7.48%
largestContentfulPaint 102 ms +1.96% -1.96% 108 ms +0% -3.7% -5.56%
lcpMinusTtfb 54.15 ms +2.86% -2.03% 55.65 ms +1.26% -2.43% -2.7%
wpBeforeTemplate 26.79 ms +13.77% -0.67% 28.2 ms +6.28% -1.45% -5%
wpTemplate 17.12 ms +2.16% -4.67% 19.02 ms +2.94% -8.25% -9.99%
wpTotal 44.46 ms +6.07% -2.59% 48.04 ms +4.37% -5.64% -7.45%
wpMemoryUsage 6.39 MB +0% -0% 6.40 MB +0% -0% -0.09%
wpDbQueries 13 +0% -0% 13 +0% -0% 0%

media-processing

Metric b6516cc refactor/media-editor-instruction-helper-input % Change
mediaProcessingJpeg 404.16 ms +1.56% -0.16% 409.23 ms +0.22% -0.49% -1.24%
mediaProcessingAvif 6159.87 ms +0.77% -0.07% 6177.45 ms +0.36% -0.23% -0.28%
mediaProcessingJpegToAvif 4254.67 ms +0.27% -0.32% 4269.8 ms +0.28% -0.19% -0.35%

media-upload

Metric b6516cc refactor/media-editor-instruction-helper-input % Change
jpegUploadProcessing 1980.4 ms +0.63% -1.62% 1951.87 ms +0.99% -0.23% 1.46%
pngUploadProcessing 259.84 ms +10.04% -28.01% 260.75 ms +13.89% -3.62% -0.35%
largeJpegUploadProcessing 1957.98 ms +0.33% -0.44% 1964.75 ms +0.62% -0.4% -0.34%
multipleImageUploadProcessing 2035.25 ms +1.85% -0.22% 2059.28 ms +1% -0.87% -1.17%

post-editor

Metric b6516cc refactor/media-editor-instruction-helper-input % Change
serverResponse 277.18 ms +14.85% -4.17% 288.81 ms +4.18% -9.34% -4.03%
firstPaint 369.54 ms +8.59% -32.59% 232.72 ms +60.12% -9.31% 58.79%
domContentLoaded 652.88 ms +2.45% -1.97% 599.43 ms +3.04% -2.93% 8.92%
loaded 653.79 ms +2.46% -1.96% 600.26 ms +3.03% -2.92% 8.92%
firstContentfulPaint 389.21 ms +3.1% -3.78% 354.36 ms +5.16% -3.93% 9.83%
firstBlock 1672.65 ms +0.8% -2.31% 1516.41 ms +1.52% -2.3% 10.3%
type 16.92 ms +4.55% -15.01% 14.25 ms +4.91% -11.44% 18.74%
typeWithoutInspector 15.68 ms +8.55% -10.08% 12.91 ms +3.8% -12.94% 21.46%
typeWithTopToolbar 19.85 ms +14.36% -8.66% 17.44 ms +10.09% -7.97% 13.82%
typeContainer 7.39 ms +12.86% -1.22% 6.3 ms +1.27% -8.89% 17.3%
focus 84.18 ms +3.72% -5.17% 70.5 ms +8.09% -6.81% 19.4%
firstFocus 206.15 ms +0% -0% 146.62 ms +0% -0% 40.6%
selectAll 271.94 ms +0.14% -3.75% 242.82 ms +0.25% -3.01% 11.99%
undo 25.05 ms +4.55% -5.07% 20.64 ms +6.59% -5.14% 21.37%
listViewOpen 52.07 ms +4.61% -3.55% 51.31 ms +6.33% -4.99% 1.48%
inserterOpen 30.98 ms +4.36% -6.49% 29.34 ms +4.7% -9.48% 5.59%
inserterHover 9.59 ms +5.74% -7.19% 8.55 ms +3.16% -8.3% 12.16%
inserterSearch 7.83 ms +8.94% -5.11% 7.07 ms +12.73% -4.38% 10.75%
loadPatterns 470.04 ms +9.44% -2.23% 426.1 ms +10.67% -3.68% 10.31%
wpTotal 269.86 ms +14.82% -4.16% 281.53 ms +3.41% -9.57% -4.15%
wpMemoryUsage 14.73 MB +0% -0% 14.76 MB +0% -0% -0.17%
wpDbQueries 55 +0% -0% 55 +0% -0% 0%

site-editor

Metric b6516cc refactor/media-editor-instruction-helper-input % Change
serverResponse 285.68 ms +1.32% -2.25% 286.24 ms +5.5% -8.86% -0.2%
firstPaint 269.78 ms +15.08% -19.42% 269.03 ms +5.54% -3.51% 0.28%
domContentLoaded 654.09 ms +1.48% -1.96% 637.07 ms +3.24% -1.97% 2.67%
loaded 655 ms +1.48% -1.95% 637.98 ms +3.24% -1.97% 2.67%
firstContentfulPaint 385.96 ms +2.03% -4.95% 373.95 ms +1.26% -2.43% 3.21%
firstBlock 1911.73 ms +0.57% -1.48% 1860.3 ms +1.47% -0.67% 2.76%
type 16.63 ms +2.59% -9.26% 14.23 ms +6.32% -5.34% 16.87%
navigate 102.57 ms +5.38% -2.45% 85.26 ms +7.1% -2.72% 20.3%
loadPatterns 959.02 ms +5.53% -11.78% 984.34 ms +5.85% -20.21% -2.57%
loadPages 946.82 ms +2.22% -1.12% 957.74 ms +1.5% -0.55% -1.14%
wpTotal 278.94 ms +1.29% -2.26% 279.43 ms +4.94% -9.1% -0.18%
wpMemoryUsage 12.77 MB +0% -0% 12.77 MB +0% -0% -0.03%
wpDbQueries 45 +0% -0% 45 +0% -0% 0%

f914610 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.

Undo restores the post selection when another synced entity is loaded (RTC WebSocket) in /test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 2
+ Received  + 2

  Object {
    "attributeKey": "content",
    "blockIndex": 0,
    "content": "abcdef",
-   "endOffset": 3,
-   "offset": 3,
+   "endOffset": 6,
+   "offset": 6,
  }

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts:363:5
Undo restores the post selection when another synced entity is loaded in /test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 2
+ Received  + 2

  Object {
    "attributeKey": "content",
    "blockIndex": 0,
    "content": "abcdef",
-   "endOffset": 3,
-   "offset": 3,
+   "endOffset": 6,
+   "offset": 6,
  }

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts:363:5
uploads multiple images via gallery in /test/e2e/specs/editor/various/client-side-media-processing.spec.js, passed after 1 failed attempt.
Error: apiRequestContext.fetch: socket hang up
Call log:
  - → GET http://localhost:8891/wp-json/wp/v2/media?per_page=100
    - user-agent: Playwright/1.63.0 (x64; ubuntu 24.04) node/24.20 CI/1
    - accept: */*
    - accept-encoding: gzip,deflate,br
    - X-WP-Nonce: 602c622536
    - cookie: wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_da433b7faafd8180ebeb1624ceeeab7e=admin%7C1793763317%7CslyNl6vQD5SyTsbzL9Cm5kJN3ZnnS2BQX49aloQEmkw%7C8c8e85c51db8059f05ca562e717b58312b6109ad7685b62d6e0227e70e9a214f; wp-settings-time-1=1793590688

    at RequestUtils.rest (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/rest.ts:111:39)
    at RequestUtils.listMedia (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/media.ts:24:30)
    at RequestUtils.deleteAllMedia (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/request-utils/media.ts:85:27)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/client-side-media-processing.spec.js:227:22

f914610 Run

The README and the comment at the top of the image editor's main file used "barrel", a word many readers will not know. Both now say what the file is. Only wording changes.
@ramonjd
ramonjd requested a review from andrewserong November 2, 2026 03:33
@ramonjd ramonjd self-assigned this Nov 2, 2026
@ramonjd

ramonjd commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

Closing this. I don't think it's a good idea to expose a private API from media-editor only to change the package source later with it's public.

For the record we want a separate package as media-editor comes with a lot of baggage, e.g., dataviews etc

@ramonjd ramonjd closed this Nov 2, 2026
@ramonjd
ramonjd deleted the add/media-editor-private-cropper-export branch November 2, 2026 04:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant