Repository navigation
Conversation
Move the existing cropper, its provider, hook, types, helpers and story into `src/legacy/`, and mark each export as deprecated. The package's exports and their behavior are unchanged. Keeping everything the old cropper needs in one folder means it can be removed in one step later, once the media editor's cropper moves into this package and replaces it. The ESLint suppression for the story follows the file to its new path.
Move the cropper the media editor uses from `packages/media-editor/src/image-editor` into `@wordpress/image-cropper` and make it the package's default API: `Cropper`, `useCropperController`, `CropperProvider` / `useCropper`, the source-region helpers, `exportCroppedImage`, the default aspect-ratio presets, and the zoom and rotation limits for building controls. The media editor now imports all of these from the package. Also move `buildModifiers`, which turns a crop into the rotate, flip and crop instructions the WordPress media REST endpoint expects. Its test reads the cropper's camera maths, which the package does not export, so it moves in the same change. Other changes that come with the move: - The cropper's state type is renamed from `CropperState` to `CropGeometry`, because the deprecated `react-easy-crop` cropper already exports a `CropperState`. - CSS classes use the `wp-image-cropper` prefix instead of `wp-media-editor-image-editor`. - The styles build to `build-style/style.css`, which the media editor's stylesheet loads. - The docs, tests, story, test-policy exceptions and ESLint suppressions move with the files. The media editor's session notes move to `packages/media-editor/src/state/README.md`. A few reducer-level helpers are exported only because the media editor's state code still needs them. They are marked as such in `src/index.ts` and can be dropped when that state code moves into the package.
…kage Add `useCropSession` to `@wordpress/image-cropper`: a cropper controller with undo and redo, gesture boundaries (a drag or pinch is one undo entry), crop options, and aspect-ratio presets that reshape the crop in one step. It is the media editor's history code, moved without its media-specific parts. `resolveAspectRatio`, which turns a preset value into a width / height ratio, moves with it. A session can hold more state in the same undo history: pass a reducer that handles your own actions and hands the rest to `cropSessionReducer`, with an equality check and a function that builds the initial state. The media editor now does exactly that for its named edits (title, alt text and so on), so `useMediaEditorState` is a thin wrapper around `useCropSession`. The reducer-level helpers exported only for the media editor's state code are no longer exported. The media editor's state tests are split: the 21 that cover undo, redo, gestures, aspect ratios and loading a new image move to the package and run against `useCropSession`; the 10 that cover named edits and the saved-image check stay.
🤖 PR meta 🤖🏷️ LabelsThis pull request needs exactly one label indicating its type, and has 0.
Read more about Type labels in Gutenberg. If you cannot add labels yourself, a reviewer can do it for you. 📦 Bundle sizeSize Change: +181 B (0%) Total Size: 8.58 MB 📦 View Changed
⚡ PerformanceShow the resultsClient side metrics exclude the server response time. front-end-block-theme
front-end-classic-theme
media-processing
media-upload
post-editor
site-editor
🏁 Flaky testsSome 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. default to my most recently created menu in
|
The type holds the cropper's whole state: the source image, how the image sits under the crop (pan, zoom, rotation, flip), the crop rectangle, and internal fine-rotation bookkeeping. "Geometry" described only part of that. The new name says what it is, the state a CropperController holds, and does not clash with the deprecated API's CropperState or ImageCropperState.
Only the stories import @wordpress/components, so move it to the development dependencies and drop it from the build's TypeScript references. Exclude stories and tests from the published files, as the media editor does.
A browser test that uses only what the package exports, as an outside consumer would: it mounts Cropper with useCropSession, applies a square preset, rotates and flips, checks the server instructions, then undoes and redoes.
The locked aspect ratio now lives in the cropper's state (`state.aspectRatio`), and `controller.setAspectRatio( ratio )` sets it and reshapes the crop in one change, so one undo restores both. `Cropper` loses its `aspectRatio` prop: it reads the ratio from the state to lock its resize handles and to keep a fixed crop fitted when the viewport resizes, and it no longer reshapes the crop by itself. `useCropSession`'s `setAspectRatioValue` keeps the preset the dropdown shows and hands the reshape to the same state change. The plain `useCropperController` now keeps the rendered size it is given, which `setAspectRatio` needs. A ratio-only change is recorded in the undo history but does not make `cropper.isDirty` true, since it does not change the cropped image on its own. The media editor stops passing the prop and reads the ratio from the state.
Export only what a consumer imports. The new API is now Cropper,
useCropperController, createCropperState, areCropperStatesEqual,
buildModifiers, the default aspect-ratio presets with
resolveAspectRatio, and the zoom and rotation limits for building
controls, plus the types those need.
The cropper no longer keeps an undo history. History covers everything
an editor changes, not only the crop, so it belongs to the consumer.
To put the crop in your own history, keep the cropper state yourself:
useCropperController( { state, onChange } ) works out each change and
reports the next state, with isEdit: false for changes the person did
not make (an image loading, a refit after a window resize).
useCropSession and its reducer exports are gone, and so are
CropperProvider / useCropper, the stencil prop and its types, the
source-region and canvas export helpers, and the geometry types.
Nothing outside the package used them. The old API keeps all of its
exports, including Flip.
The media editor keeps its own history again, with the cropper state
as one slice next to the sidebar options and named edits. Its 31
session tests from before the move run against it unchanged, plus the
aspect-ratio checks.
Member
Author
|
Closed in favour of a new package. See: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Proof of concept for #86145: moves the media editor's cropper into
@wordpress/image-cropperas the package's default API. The existingreact-easy-cropcropper stays, deprecated, insrc/legacy/.Why?
So others can build their own image editor or cropper without depending on
@wordpress/media-editor.How?
media-editor/src/image-editorintoimage-cropper. The media editor imports it from the package.Cropper,useCropperController,createCropperState,areCropperStatesEqual,buildModifiers, the aspect-ratio presets and the zoom/rotation limits.useCropperController( { state, onChange } ); the media editor does this and keeps its own history.controller.setAspectRatio), soCropperno longer takes anaspectRatioprop.buildModifiers(the instructions for the media/editendpoint).CropperControllerStateand its CSS prefix towp-image-cropper.Not done yet: rebuilding the old API on the new cropper and removing
react-easy-crop.Testing Instructions