Skip to content
This repository has been archived by the owner on Aug 31, 2022. It is now read-only.

Commit

Permalink
Merge pull request #109 from Synthetixio/feat/uploader
Browse files Browse the repository at this point in the history
feat: add Uploader component with drop-zone
  • Loading branch information
Rickk137 authored Jul 20, 2022
2 parents d204240 + c89141e commit 7dbcbd5
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 1 deletion.
17 changes: 17 additions & 0 deletions src/components/Upload/Upload.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ComponentMeta, ComponentStory } from '@storybook/react';

import { Upload } from './Upload';

export default {
title: 'Upload',
component: Upload,
decorators: [(Story) => <Story />]
} as ComponentMeta<typeof Upload>;

const Template: ComponentStory<typeof Upload> = (args) => <Upload {...args} />;

export const Primary = Template.bind({});

Primary.args = {
upload: (file) => console.log('file to upload:', file)
};
102 changes: 102 additions & 0 deletions src/components/Upload/Upload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import clsx from 'clsx';
import React, { useState } from 'react';

export interface UploadProps {
className?: string;
upload: (file: string) => Promise<string>;
}

export const Upload: React.FC<UploadProps> = ({ className, upload }) => {
const [preview, setPreview] = useState({
data: '',
name: ''
});
const stopDefault = (e: any) => {
e.preventDefault();
e.stopPropagation();
};

const handleUpload = (e: any) => {
stopDefault(e);

const [file] = e.target.files || e.dataTransfer.files;

if (!file) return;
uploadFile(file);
};

function uploadFile(file: any) {
const reader = new FileReader();
reader.readAsBinaryString(file);

reader.onload = () => {
const fileRes = btoa(reader.result as string);
const data = `data:image/jpg;base64,${fileRes}`;
setPreview({
data,
name: file.name
});
upload(data);
};

reader.onerror = () => {
setPreview({
data: '',
name: ''
});
};
}
return (
<div
className={clsx('ui-relative ui-flex ui-justify-center ui-items-center ui-w-full', className)}
onDragEnter={stopDefault}
onDragLeave={stopDefault}
onDragOver={stopDefault}
onDrop={(e) => handleUpload(e)}
>
<label
className='ui-flex ui-flex-col ui-justify-center ui-items-center ui-w-full ui-h-64 ui-bg-gray-50 ui-rounded-lg ui-border-2 ui-border-gray-300 ui-border-dashed ui-cursor-pointer dark:hover:ui-bg-bray-800 dark:ui-bg-gray-700 ui-hover:ui-bg-gray-100 dark:ui-border-gray-600 dark:hover:ui-border-gray-500 dark:hover:ui-bg-gray-600'
htmlFor='dropzone'
>
<div className='ui-flex ui-flex-col ui-justify-center ui-items-center ui-pt-5 ui-pb-6'>
<svg
aria-hidden='true'
className='ui-mb-3 ui-w-10 ui-h-10 ui-text-gray-400'
fill='none'
stroke='currentColor'
viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
/>
</svg>
<p className='ui-mb-2 ui-text-sm ui-text-gray-500 dark:ui-text-gray-400'>
<span className='font-semibold'>Click to upload</span> or drag and drop
</p>
<p className='ui-text-xs ui-text-gray-500 dark:ui-text-gray-400'>SVG, PNG, JPG or GIF</p>
</div>
<input
accept='image/*'
className='ui-hidden'
id='dropzone'
type='file'
onChange={(e) => handleUpload(e)}
/>
{preview.data && (
<div className='ui-absolute ui-pr-8 ui-w-full ui-bottom-4 ui-left-4 ui-overflow-hidden ui-flex ui-items-center'>
<img
alt='preview'
className='ui-w-12 ui-h-12 ui-object-cover ui-rounded-full ui-mr-2'
src={preview.data}
/>
<span className='ui-flex-1 ui-truncate ui-text-white'>{preview.name}</span>
</div>
)}
</label>
</div>
);
};
5 changes: 4 additions & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Tab, TabProps } from './Tab/Tab';
import { Table, TableProps } from './Table/Table';
import { Tabs, TabsProps } from './Tabs/Tabs';
import { TextField, TextFieldProps } from './TextField/TextField';
import { Upload, UploadProps } from './Upload/Upload';

export {
Accordion,
Expand All @@ -51,6 +52,7 @@ export {
Tabs,
TextField,
TransactionDialogContextProvider,
Upload,
useTransactionModalContext
};
export type {
Expand All @@ -75,5 +77,6 @@ export type {
TabProps,
TabsProps,
TextFieldProps,
TxState
TxState,
UploadProps
};

0 comments on commit 7dbcbd5

Please sign in to comment.