Bladeren bron

Create Image Uploader component

Tatiana Inama 6 jaren geleden
bovenliggende
commit
9e440e4562

+ 68 - 0
recipes/src/components/ImageUploader/index.tsx

@@ -0,0 +1,68 @@
+import React, { useState, useRef } from 'react';
+
+import Button from 'components/Button';
+
+import './styles.scss';
+import sample_image from 'sample.png';
+
+type ImageUploaderProps = {
+  onChange?: (file: File) => void;
+};
+
+export const ImageUploader: React.FunctionComponent<ImageUploaderProps> = ({ onChange = () => {} }) => {
+  const [ file, setFile ] = useState({
+    name: '',
+    url: ''
+  });
+  const fileInput: React.RefObject<HTMLInputElement> = useRef(null);
+
+  const onChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
+    if (e.target.files && e.target.files[0]) {
+      setFile({
+        url: URL.createObjectURL(e.target.files[0]),
+        name: e.target.files[0].name
+      });
+      onChange(e.target.files[0])
+    }
+  }
+
+  return (
+    <div className='cbk-img-uploader'>
+      <input type='file' onChange={onChangeFile} ref={fileInput} accept="image/*"/>
+      {
+        file.url ? (
+          <div className='cbk-img-uploader__preview'
+            style={{
+              backgroundImage: `url(${file.url})`
+            }}
+          >
+            <Button
+            
+              type='button'
+              icon='clear'
+              onClick={() => setFile({
+                name: '',
+                url: ''
+              }) }
+            />
+            <label>{file.name}</label>
+          </div>
+        ) : (
+          <div className='cbk-img-uploader__upload'
+            style={{
+              backgroundImage: `url(${sample_image})`
+            }}
+          >
+            <Button
+              type='button'
+              icon='add'
+              onClick={() => { fileInput.current && fileInput.current.click() }}
+            ></Button>
+          </div>
+        )
+      }
+    </div>
+  )
+};
+
+export default ImageUploader;

+ 43 - 0
recipes/src/components/ImageUploader/styles.scss

@@ -0,0 +1,43 @@
+@import 'styles/_variables';
+
+.cbk-img-uploader {
+  position: relative;
+  @include solidBoxShadow();
+  
+
+  input {
+    display: none;
+  }
+
+  &__preview,
+  &__upload {
+    width: 100%;
+    min-height: 8rem;
+    background-repeat: no-repeat;
+    background-size: cover;
+    background-position: center;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    button {
+      opacity: .5;
+      i.material-icons {
+        text-shadow: 0px 0px 1px white;
+      }
+      &:hover {
+        opacity: 1;
+      }
+    }
+
+    label {
+      @include display();
+      position: absolute;
+      bottom: 0em;
+      width: 100%;
+      background-color: rgba(255, 255, 255, 0.5);
+      text-align: center;
+    }
+    
+  }
+}

+ 2 - 1
recipes/src/components/RecipeForm/index.tsx

@@ -6,6 +6,7 @@ import { Field, FieldArray, Formik, useField, Form, FieldArrayRenderProps } from
 import { MeasuresTypes } from 'services/measurements';
 import { Input, Textarea, ControlledInput } from 'components/Input';
 
+import ImageUploader from 'components/ImageUploader';
 import Button from 'components/Button';
 import Dialog from 'components/DialogConverter';
 import TagInput from 'components/TagInput';
@@ -112,7 +113,7 @@ const RecipeForm = <T extends Recipe|DBRecipe>({ initialValues, onSubmit }: Reci
             <Form className='cbk-recipe-form'>
             <Row>
               <Cell columns={2}>
-                <img src={sample_image} style={{ width: '100%' }}/>
+                <ImageUploader/>
               </Cell>
               <Cell columns={10}>
                 <FormikInput name='name' label='name' />