2
2
import type CropType from 'react-image-crop'
3
3
4
4
import { useModal } from '@faceless-ui/modal'
5
- import React , { useRef , useState } from 'react'
5
+ import React , { forwardRef , useRef , useState } from 'react'
6
6
import ReactCrop from 'react-image-crop'
7
7
import 'react-image-crop/dist/ReactCrop.css'
8
8
@@ -14,16 +14,28 @@ import './index.scss'
14
14
15
15
const baseClass = 'edit-upload'
16
16
17
- const Input : React . FC < { name : string ; onChange : ( value : string ) => void ; value : string } > = ( {
18
- name,
19
- onChange,
20
- value,
21
- } ) => (
22
- < div className = { `${ baseClass } __input` } >
23
- { name }
24
- < input name = { name } onChange = { ( e ) => onChange ( e . target . value ) } type = "number" value = { value } />
25
- </ div >
26
- )
17
+ type Props = {
18
+ name : string
19
+ onChange : ( value : string ) => void
20
+ value : string
21
+ }
22
+
23
+ const Input = forwardRef < HTMLInputElement , Props > ( ( props , ref ) => {
24
+ const { name, onChange, value } = props
25
+
26
+ return (
27
+ < div className = { `${ baseClass } __input` } >
28
+ { name }
29
+ < input
30
+ name = { name }
31
+ onChange = { ( e ) => onChange ( e . target . value ) }
32
+ ref = { ref }
33
+ type = "number"
34
+ value = { value }
35
+ />
36
+ </ div >
37
+ )
38
+ } )
27
39
28
40
type FocalPosition = {
29
41
x : number
@@ -43,8 +55,10 @@ export type EditUploadProps = {
43
55
44
56
const defaultCrop : CropType = {
45
57
height : 100 ,
58
+ heightPixels : 0 ,
46
59
unit : '%' ,
47
60
width : 100 ,
61
+ widthPixels : 0 ,
48
62
x : 0 ,
49
63
y : 0 ,
50
64
}
@@ -84,6 +98,17 @@ export const EditUpload: React.FC<EditUploadProps> = ({
84
98
const imageRef = useRef < HTMLImageElement | undefined > ( undefined )
85
99
const cropRef = useRef < HTMLDivElement | undefined > ( undefined )
86
100
101
+ const heightRef = useRef < HTMLInputElement | null > ( null )
102
+ const widthRef = useRef < HTMLInputElement | null > ( null )
103
+
104
+ const [ imageLoaded , setImageLoaded ] = useState < boolean > ( false )
105
+
106
+ const onImageLoad = ( e ) => {
107
+ setOriginalHeight ( e . currentTarget . naturalHeight )
108
+ setOriginalWidth ( e . currentTarget . naturalWidth )
109
+ setImageLoaded ( true )
110
+ }
111
+
87
112
const fineTuneCrop = ( { dimension, value } : { dimension : 'height' | 'width' ; value : string } ) => {
88
113
const intValue = parseInt ( value )
89
114
if ( dimension === 'width' && intValue >= originalWidth ) return null
@@ -115,7 +140,13 @@ export const EditUpload: React.FC<EditUploadProps> = ({
115
140
const saveEdits = ( ) => {
116
141
if ( typeof onSave === 'function' )
117
142
onSave ( {
118
- crop,
143
+ crop : crop
144
+ ? {
145
+ ...crop ,
146
+ heightPixels : Number ( heightRef . current ?. value ?? crop . heightPixels ) ,
147
+ widthPixels : Number ( widthRef . current ?. value ?? crop . widthPixels ) ,
148
+ }
149
+ : undefined ,
119
150
focalPosition,
120
151
} )
121
152
closeModal ( editDrawerSlug )
@@ -159,6 +190,7 @@ export const EditUpload: React.FC<EditUploadProps> = ({
159
190
aria-label = { t ( 'general:applyChanges' ) }
160
191
buttonStyle = "primary"
161
192
className = { `${ baseClass } __save` }
193
+ disabled = { ! imageLoaded }
162
194
onClick = { saveEdits }
163
195
>
164
196
{ t ( 'general:applyChanges' ) }
@@ -186,21 +218,15 @@ export const EditUpload: React.FC<EditUploadProps> = ({
186
218
>
187
219
< img
188
220
alt = { t ( 'upload:setCropArea' ) }
189
- onLoad = { ( e ) => {
190
- setOriginalHeight ( e . currentTarget . naturalHeight )
191
- setOriginalWidth ( e . currentTarget . naturalWidth )
192
- } }
221
+ onLoad = { onImageLoad }
193
222
ref = { imageRef }
194
223
src = { fileSrcToUse }
195
224
/>
196
225
</ ReactCrop >
197
226
) : (
198
227
< img
199
228
alt = { t ( 'upload:setFocalPoint' ) }
200
- onLoad = { ( e ) => {
201
- setOriginalHeight ( e . currentTarget . naturalHeight )
202
- setOriginalWidth ( e . currentTarget . naturalWidth )
203
- } }
229
+ onLoad = { onImageLoad }
204
230
ref = { imageRef }
205
231
src = { fileSrcToUse }
206
232
/>
@@ -233,8 +259,10 @@ export const EditUpload: React.FC<EditUploadProps> = ({
233
259
onClick = { ( ) =>
234
260
setCrop ( {
235
261
height : 100 ,
262
+ heightPixels : originalHeight ,
236
263
unit : '%' ,
237
264
width : 100 ,
265
+ widthPixels : originalWidth ,
238
266
x : 0 ,
239
267
y : 0 ,
240
268
} )
@@ -251,11 +279,13 @@ export const EditUpload: React.FC<EditUploadProps> = ({
251
279
< Input
252
280
name = { `${ t ( 'upload:width' ) } (px)` }
253
281
onChange = { ( value ) => fineTuneCrop ( { dimension : 'width' , value } ) }
282
+ ref = { widthRef }
254
283
value = { ( ( crop . width / 100 ) * originalWidth ) . toFixed ( 0 ) }
255
284
/>
256
285
< Input
257
286
name = { `${ t ( 'upload:height' ) } (px)` }
258
287
onChange = { ( value ) => fineTuneCrop ( { dimension : 'height' , value } ) }
288
+ ref = { heightRef }
259
289
value = { ( ( crop . height / 100 ) * originalHeight ) . toFixed ( 0 ) }
260
290
/>
261
291
</ div >
0 commit comments