feat(Gallery): add built-in image rotation support#378
Conversation
Add rotate-left/rotate-right actions for Gallery images with 90° increments via CSS transform. - Add GalleryImageRotationContext to share rotation state between header actions and image view - Add useImageRotation hook with useMemo-based styles, container dimension tracking, and max-width/max-height swap for 90/270 rotations to prevent cropping - Use unbounded rotation values (no modulo) so CSS transitions animate the correct direction - Merge zoom and rotation transforms in ImageView; reset zoom when rotation changes - Add getGalleryItemRotateLeftAction and getGalleryItemRotateRightAction utilities using __renderT for context-aware rendering - Add rotate-left/rotate-right i18n keys (en + ru) - Export new hook, context, and action utilities from package index
There was a problem hiding this comment.
GalleryContext already exists. Why not add GalleryImageRotationContext.tsx functionality to GalleryContext? There are reasons to create a separate context for image rotation?
There was a problem hiding this comment.
Yeah, moved GalleryContext before modal comp. Now should be fine
| ...(rotation ? {transform: `rotate(${rotation}deg)`} : {}), | ||
| ...(isHorizontalRotation && containerDims.width > 0 | ||
| ? {maxWidth: containerDims.height, maxHeight: containerDims.width} | ||
| : {}), | ||
| }), |
There was a problem hiding this comment.
Should rotation occur if the image dimensions haven't been set yet? I don't think so. The useImageZoom* hooks also check for the dimensions before zooming the image.
| const [rotation, setRotation] = React.useState(0); | ||
| const rotateLeft = React.useCallback(() => setRotation((r) => r - ROTATION_STEP), []); | ||
| const rotateRight = React.useCallback(() => setRotation((r) => r + ROTATION_STEP), []); |
There was a problem hiding this comment.
This can be moved to a separate hook – useRotationState(), to which you can pass the initial value and custom rotation step as arguments.
There was a problem hiding this comment.
Yes, but i think for now it enough to keep this hook in Gallery/Image scope without args
…yles Merge image rotation state into GalleryContext so a single provider serves both gallery actions and views. Extract rotation state ownership into a dedicated useImageRotationState hook. Gate the rotation style output on measured container dimensions to avoid emitting a rotate transform before max-width/max-height swaps can apply.
Add unit tests for the new state hook and the consumer hook, including the dimension guard, the 90°/270° max-width/max-height swap, negative and >360° angle normalization, and rotation action passthrough.
d3m1d0v
left a comment
There was a problem hiding this comment.
Plz update README for Gallery component and add new one for added hooks
| * @returns Rotation state, actions, computed styles, and a setter for container dimensions. | ||
| */ | ||
| export function useImageRotation(): UseImageRotationReturn { | ||
| const {rotation, rotateLeft, rotateRight} = useGalleryContext(); |
There was a problem hiding this comment.
<ImageView> already uses useGalleryContext and passes the onTap handler to useImageZoom. I suggest doing something similar in useImageRotation.
rotateLeft and rotateRight seem redundant here.
Summary
Implements image rotation for Gallery via context and action utilities.
GalleryImageRotationContextto share rotation state between header actions and image viewuseImageRotationhook — owns rotation styles, container dimension tracking, andmaxWidth/maxHeightswap at 90°/270° to prevent cropping
ImageView; reset zoom on rotation changegetGalleryItemRotateLeftAction/getGalleryItemRotateRightAction— context-aware via__renderTrotate-left/rotate-righti18n keys (en + ru)Closes #377
Test plan
RotationGallerystory in Storybook