Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: file upload #1749

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions src/examples/src/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,17 @@ import InitialStateTree from './widgets/tree/InitialState';
import PopupConfirmation from './widgets/popup-confirmation/Basic';
import PopupConfirmationUnderlay from './widgets/popup-confirmation/Underlay';
import ClickableCard from './widgets/card/ClickableCard';
import BasicFileUploadInput from './widgets/file-upload-input/Basic';
import DisabledFileUploadInput from './widgets/file-upload-input/Disabled';
import LabelledFileUploadInput from './widgets/file-upload-input/Labelled';
import MultipleFileUploadInput from './widgets/file-upload-input/Multiple';
import NoDropFileUploadInput from './widgets/file-upload-input/NoDrop';
import BasicFileUploader from './widgets/file-uploader/Basic';
import ControlledFileUploader from './widgets/file-uploader/Controlled';
import CustomValidatorFileUploader from './widgets/file-uploader/CustomValidator';
import DisabledFileUploader from './widgets/file-uploader/Disabled';
import MultipleFileUploader from './widgets/file-uploader/Multiple';
import ValidatedFileUploader from './widgets/file-uploader/Validated';

import * as dojoDarkVariant from '@dojo/widgets/theme/dojo/variants/dark.m.css';
import * as materialDarkVariant from '@dojo/widgets/theme/material/variants/dark.m.css';
Expand Down Expand Up @@ -810,6 +821,76 @@ export const config = {
}
}
},
'file-upload-input': {
filename: 'index',
overview: {
example: {
title: 'Basic FileUploadInput',
filename: 'Basic',
module: BasicFileUploadInput
}
},
examples: [
{
title: 'Disabled FileUploadInput',
filename: 'Disabled',
module: DisabledFileUploadInput
},
{
title: 'Multiple FileUploadInput',
filename: 'Multiple',
module: MultipleFileUploadInput,
description:
'Demonstrates using child `content` property to render information about the uploaded files that is available to the `onValue` callback.'
},
{
title: 'FileUploadInput with label',
filename: 'Labelled',
module: LabelledFileUploadInput
},
{
title: 'FileUploadInput with no DnD',
filename: 'NoDrop',
module: NoDropFileUploadInput
}
]
},
'file-uploader': {
filename: 'index',
overview: {
example: {
filename: 'Basic',
module: BasicFileUploader
}
},
examples: [
{
title: 'Disabled FileUploader',
filename: 'Disabled',
module: DisabledFileUploader
},
{
title: 'Multiple FileUploader',
filename: 'Multiple',
module: MultipleFileUploader
},
{
title: 'Validated FileUploader',
filename: 'Validated',
module: ValidatedFileUploader
},
{
title: 'FileUploader with custom validator',
filename: 'CustomValidator',
module: CustomValidatorFileUploader
},
{
title: 'Controlled FileUploader',
filename: 'Controlled',
module: ControlledFileUploader
}
]
},
'floating-action-button': {
overview: {
example: {
Expand Down
21 changes: 21 additions & 0 deletions src/examples/src/widgets/file-upload-input/Basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import icache from '@dojo/framework/core/middleware/icache';
import { FileUploadInput } from '@dojo/widgets/file-upload-input';
import Example from '../../Example';

const factory = create({ icache });

export default factory(function Basic({ middleware: { icache } }) {
const selectedFiles: File[] = icache.getOrSet('selectedFiles', []);

function onValue(files: File[]) {
icache.set('selectedFiles', files);
}

return (
<Example>
<FileUploadInput onValue={onValue} />
<div>Selected file: {selectedFiles.length ? selectedFiles[0].name : 'none'}</div>
</Example>
);
});
17 changes: 17 additions & 0 deletions src/examples/src/widgets/file-upload-input/Disabled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import { FileUploadInput } from '@dojo/widgets/file-upload-input';
import Example from '../../Example';

const factory = create();

export default factory(function Disabled() {
function onValue() {
// do something with files
}

return (
<Example>
<FileUploadInput disabled onValue={onValue} />
</Example>
);
});
25 changes: 25 additions & 0 deletions src/examples/src/widgets/file-upload-input/Labelled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import icache from '@dojo/framework/core/middleware/icache';
import { FileUploadInput } from '@dojo/widgets/file-upload-input';
import Example from '../../Example';

const factory = create({ icache });

export default factory(function Labelled({ middleware: { icache } }) {
const selectedFiles: File[] = icache.getOrSet('selectedFiles', []);

function onValue(files: File[]) {
icache.set('selectedFiles', files);
}

return (
<Example>
<FileUploadInput accept="image/*" onValue={onValue}>
{{
label: 'Upload a profile image'
}}
</FileUploadInput>
<div>Selected file: {selectedFiles.length ? selectedFiles[0].name : 'none'}</div>
</Example>
);
});
49 changes: 49 additions & 0 deletions src/examples/src/widgets/file-upload-input/Multiple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import icache from '@dojo/framework/core/middleware/icache';
import { FileUploadInput } from '@dojo/widgets/file-upload-input';
import Example from '../../Example';

import * as css from './multiple.m.css';

const factory = create({ icache });

export default factory(function Multiple({ middleware: { icache } }) {
const selectedFiles: File[] = icache.getOrSet('selectedFiles', []);

function onValue(files: File[]) {
icache.set('selectedFiles', files);
}

return (
<Example>
<FileUploadInput onValue={onValue} multiple>
{{
content: selectedFiles.length ? (
<table classes={[css.table]}>
<thead>
<th>Name</th>
<th>Modified</th>
<th>Type</th>
<th>Bytes</th>
</thead>
<tbody>
{selectedFiles.map(function(file) {
return (
<tr key={file.name}>
<td>{file.name}</td>
<td>{new Date(file.lastModified).toLocaleString()}</td>
<td>{file.type}</td>
<td>{String(file.size)}</td>
</tr>
);
})}
</tbody>
</table>
) : (
''
)
}}
</FileUploadInput>
</Example>
);
});
21 changes: 21 additions & 0 deletions src/examples/src/widgets/file-upload-input/NoDrop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import icache from '@dojo/framework/core/middleware/icache';
import { FileUploadInput } from '@dojo/widgets/file-upload-input';
import Example from '../../Example';

const factory = create({ icache });

export default factory(function NoDrop({ middleware: { icache } }) {
const selectedFiles: File[] = icache.getOrSet('selectedFiles', []);

function onValue(files: File[]) {
icache.set('selectedFiles', files);
}

return (
<Example>
<FileUploadInput allowDnd={false} onValue={onValue} />
<div>Selected file: {selectedFiles.length ? selectedFiles[0].name : 'none'}</div>
</Example>
);
});
3 changes: 3 additions & 0 deletions src/examples/src/widgets/file-upload-input/multiple.m.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.table {
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const table: string;
17 changes: 17 additions & 0 deletions src/examples/src/widgets/file-uploader/Basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import FileUploader from '@dojo/widgets/file-uploader';
import Example from '../../Example';

const factory = create();

export default factory(function Basic() {
function onValue() {
// do something with files
}

return (
<Example>
<FileUploader onValue={onValue} />
</Example>
);
});
46 changes: 46 additions & 0 deletions src/examples/src/widgets/file-uploader/Controlled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import icache from '@dojo/framework/core/middleware/icache';
import FileUploader, { FileWithValidation } from '@dojo/widgets/file-uploader';
import Example from '../../Example';

const factory = create({ icache });

export default factory(function Controlled({ middleware: { icache } }) {
function validateFiles(files: FileWithValidation[]) {
return files.map(function(file) {
// Files bigger than 100KB are marked invalid
const valid = file.size <= 100 * 1024;
file.valid = valid;
// Each file can include a message for the valid state as well as invalid
file.message = valid ? 'File is valid' : 'File is too big';

return file;
});
}

// onValue receives any files selected from the file dialog or
// dragged and dropped from the OS
function onValue(files: File[]) {
// Validation and manipulation of the selected files is done
// entirely external to the FileUploader widget.
// This line both validates the files and truncates the total count to 4.
const validatedFiles = validateFiles(files).slice(0, 4);

icache.set('files', validatedFiles);
}

// If FileUploader receives a value for `files` then it will only render that.
// If it receives a falsy value then it will render whatever files the user selects.
// To ensure no files are rendered pass an empty array.
const files = icache.getOrSet('files', []);

return (
<Example>
<FileUploader files={files} multiple onValue={onValue}>
{{
label: 'Controlled FileUploader'
}}
</FileUploader>
</Example>
);
});
32 changes: 32 additions & 0 deletions src/examples/src/widgets/file-uploader/CustomValidator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import FileUploader from '@dojo/widgets/file-uploader';
import Example from '../../Example';

const factory = create();

export default factory(function CustomValidator() {
function onValue() {
// do something with files
}

function validateName(file: File) {
if (file.name === 'validfile.txt') {
return { valid: true };
} else {
return {
message: 'File name must be "validfile.txt"',
valid: false
};
}
}

return (
<Example>
<FileUploader customValidator={validateName} onValue={onValue}>
{{
label: 'Upload a file named "validfile.txt"'
}}
</FileUploader>
</Example>
);
});
17 changes: 17 additions & 0 deletions src/examples/src/widgets/file-uploader/Disabled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import FileUploader from '@dojo/widgets/file-uploader';
import Example from '../../Example';

const factory = create();

export default factory(function Disabled() {
function onValue() {
// do something with files
}

return (
<Example>
<FileUploader disabled onValue={onValue} />
</Example>
);
});
17 changes: 17 additions & 0 deletions src/examples/src/widgets/file-uploader/Multiple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import FileUploader from '@dojo/widgets/file-uploader';
import Example from '../../Example';

const factory = create();

export default factory(function Multiple() {
function onValue() {
// do something with files
}

return (
<Example>
<FileUploader multiple onValue={onValue} />
</Example>
);
});
20 changes: 20 additions & 0 deletions src/examples/src/widgets/file-uploader/Validated.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { create, tsx } from '@dojo/framework/core/vdom';
import FileUploader from '@dojo/widgets/file-uploader';
import Example from '../../Example';

const factory = create();

export default factory(function Validated() {
const accept = 'image/jpeg,image/png';
const maxSize = 50000;

function onValue() {
// do something with files
}

return (
<Example>
<FileUploader multiple accept={accept} maxSize={maxSize} onValue={onValue} />
</Example>
);
});
Loading