import { createSignal, Show } from 'solid-js' import { createStore } from 'solid-js/store' import Cropper from 'cropperjs' import styles from './ImageCropper.module.scss' export const ImageCropper = (props) => { let cropImage const [state, setState] = createStore({ error: null, loading: false, file: {}, croppedImage: null, }), [dropZoneActive, setDropZoneActive] = createSignal(false), [uploading, setUploading] = createSignal(false), [preview, setPreview] = createSignal(null), [cropper, setCropper] = createSignal(null), noPropagate = (e) => { e.preventDefault() }, uploadFile = async (file) => { if (!file) return setUploading(true) setState('loading', true) setState('file', file) try { const reader = new FileReader() reader.onload = (e) => { setPreview(e.target.result) setCropper( new Cropper(cropImage, { aspectRatio: 1 / 1, viewMode: 1, rotatable: false, }), ) } reader.readAsDataURL(file) } catch (e) { console.error('upload failed', e) const message = e instanceof Error ? e.message : String(e) setState('error', message) } setState('loading', false) setUploading(false) }, handleFileDrop = async (e) => { e.preventDefault() setDropZoneActive(false) uploadFile(e.dataTransfer.files[0]) }, handleFileInput = async (e) => { e.preventDefault() uploadFile(e.currentTarget.files[0]) } return ( <> { setState('croppedImage', cropper().getCroppedCanvas().toDataURL(state.file.type)) props.saveImage(state) }} > Save (uploading() ? undefined : setDropZoneActive(true))} onDragLeave={() => setDropZoneActive(false)} onDragOver={noPropagate} onDrop={(event) => (uploading() ? noPropagate(event) : handleFileDrop(event))} > upload > ) }