Skip to content

Commit

Permalink
Merge pull request react-cropper#502 from react-cropper/feat/cropperj…
Browse files Browse the repository at this point in the history
…s-v1.5.10

feat: update cropperjs to v.1.5.10 and slight refactor
  • Loading branch information
shekhar-shubhendu authored Feb 12, 2021
2 parents 7102f94 + d811275 commit 90b1c59
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 30 deletions.
4 changes: 2 additions & 2 deletions example/src/Demo.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, {useState, useRef} from 'react';
import 'cropperjs/dist/cropper.css';
import {Cropper} from '../../src';
import {Cropper, ReactCropperElement} from '../../src';

const defaultSrc = 'example/img/child.jpg';

export const Demo: React.FC = () => {
const [image, setImage] = useState(defaultSrc);
const [cropData, setCropData] = useState('#');
const imageRef = useRef<HTMLImageElement>(null);
const imageRef = useRef<ReactCropperElement>(null);
const [cropper, setCropper] = useState<Cropper>();
const onChange = (e: any) => {
e.preventDefault();
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"url": "https://github.com/react-cropper/react-cropper.git"
},
"dependencies": {
"cropperjs": "^1.5.9"
"cropperjs": "^1.5.10"
},
"peerDependencies": {
"react": ">=16.0.0"
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export {ReactCropper as Cropper} from './react-cropper';
export {ReactCropper as default} from './react-cropper';
export {ReactCropperProps} from './react-cropper';
export type {ReactCropperProps, ReactCropperElement} from './react-cropper';
33 changes: 17 additions & 16 deletions src/react-cropper.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React, {useState, useEffect, useRef} from 'react';
import React, {useEffect, useRef} from 'react';
import Cropper from 'cropperjs';

interface ReactCropperElement extends HTMLImageElement {
cropper: Cropper;
}

type ReactCropperRef =
| ((instance: HTMLImageElement | null) => void)
| React.MutableRefObject<HTMLImageElement | null>
| ((instance: HTMLImageElement | ReactCropperElement | null) => void)
| React.MutableRefObject<HTMLImageElement | ReactCropperElement | null>
| null;

interface ReactCropperDefaultOptions {
Expand All @@ -16,7 +20,7 @@ interface ReactCropperDefaultOptions {

interface ReactCropperProps
extends ReactCropperDefaultOptions,
Cropper.Options,
Cropper.Options<HTMLImageElement>,
Omit<React.HTMLProps<HTMLImageElement>, 'data' | 'ref' | 'crossOrigin'> {
crossOrigin?: '' | 'anonymous' | 'use-credentials' | undefined;
on?: (eventName: string, callback: () => void | Promise<void>) => void | Promise<void>;
Expand All @@ -35,8 +39,8 @@ const applyDefaultOptions = (cropper: Cropper, options: ReactCropperDefaultOptio
/**
* sourced from: https://itnext.io/reusing-the-ref-from-forwardref-with-react-hooks-4ce9df693dd
*/
const useCombinedRefs = (...refs: ReactCropperRef[]): React.RefObject<HTMLImageElement> => {
const targetRef = useRef<HTMLImageElement>(null);
const useCombinedRefs = (...refs: ReactCropperRef[]): React.RefObject<ReactCropperElement> => {
const targetRef = useRef<ReactCropperElement>(null);

React.useEffect(() => {
refs.forEach((ref) => {
Expand All @@ -53,7 +57,7 @@ const useCombinedRefs = (...refs: ReactCropperRef[]): React.RefObject<HTMLImageE
return targetRef;
};

const ReactCropper = React.forwardRef<HTMLImageElement, ReactCropperProps>(({...props}, ref) => {
const ReactCropper = React.forwardRef<ReactCropperElement | HTMLImageElement, ReactCropperProps>(({...props}, ref) => {
const {
dragMode = 'crop',
src,
Expand All @@ -70,7 +74,6 @@ const ReactCropper = React.forwardRef<HTMLImageElement, ReactCropperProps>(({...
onInitialized,
...rest
} = props;
const [cropper, setCropper] = useState<Cropper | undefined>(undefined);
const defaultOptions: ReactCropperDefaultOptions = {scaleY, scaleX, enable, zoomTo, rotateTo};
const innerRef = useRef<HTMLImageElement>(null);
const combinedRef = useCombinedRefs(ref, innerRef);
Expand All @@ -80,31 +83,29 @@ const ReactCropper = React.forwardRef<HTMLImageElement, ReactCropperProps>(({...
dragMode,
...rest,
ready: (e) => {
if (e.target !== null) {
const target = e.target as any;
applyDefaultOptions(target.cropper, defaultOptions);
if (e.currentTarget !== null) {
applyDefaultOptions(e.currentTarget.cropper, defaultOptions);
}
ready && ready(e);
},
});
onInitialized && onInitialized(cropper);
setCropper(cropper);
}

/**
* destroy cropper on un-mount
*/
return () => {
cropper?.destroy();
combinedRef.current?.cropper?.destroy();
};
}, [combinedRef]);

/**
* re-render when src changes
*/
useEffect(() => {
if (typeof cropper !== 'undefined' && typeof src !== 'undefined') {
cropper.reset().clear().replace(src);
if (combinedRef.current?.cropper && typeof src !== 'undefined') {
combinedRef.current.cropper.reset().clear().replace(src);
}
}, [src]);

Expand All @@ -121,4 +122,4 @@ const ReactCropper = React.forwardRef<HTMLImageElement, ReactCropperProps>(({...
);
});

export {ReactCropper, ReactCropperProps, applyDefaultOptions};
export {ReactCropper, ReactCropperProps, ReactCropperElement, applyDefaultOptions};
23 changes: 16 additions & 7 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import React from 'react';
import Cropper from 'cropperjs';
interface ReactCropperProps
extends Cropper.Options,
Omit<React.HTMLProps<HTMLImageElement>, 'data' | 'ref' | 'crossOrigin'> {
crossOrigin?: '' | 'anonymous' | 'use-credentials' | undefined;
on?: (eventName: string, callback: () => void | Promise<void>) => void | Promise<void>;
interface ReactCropperElement extends HTMLImageElement {
cropper: Cropper;
}
interface ReactCropperDefaultOptions {
scaleX?: number;
scaleY?: number;
enable?: boolean;
zoomTo?: number;
rotateTo?: number;
}
interface ReactCropperProps
extends ReactCropperDefaultOptions,
Cropper.Options<HTMLImageElement>,
Omit<React.HTMLProps<HTMLImageElement>, 'data' | 'ref' | 'crossOrigin'> {
crossOrigin?: '' | 'anonymous' | 'use-credentials' | undefined;
on?: (eventName: string, callback: () => void | Promise<void>) => void | Promise<void>;
onInitialized?: (instance: Cropper) => void | Promise<void>;
}
declare const ReactCropper: React.ForwardRefExoticComponent<ReactCropperProps & React.RefAttributes<HTMLImageElement>>;
declare const applyDefaultOptions: (cropper: Cropper, options?: ReactCropperDefaultOptions) => void;
declare const ReactCropper: React.ForwardRefExoticComponent<
ReactCropperProps & React.RefAttributes<HTMLImageElement | ReactCropperElement>
>;
export {ReactCropper as Cropper};
export {ReactCropper as default};
export {ReactCropperProps};
export {ReactCropperProps, ReactCropperElement};

0 comments on commit 90b1c59

Please sign in to comment.