feat(file-uploader-drop-container): rework FileUploaderDropContainer (#1125)

- convert `FileList` to `File[]` to be consistent with `FileUploader` and `FileUploaderButton`
- add `files` prop for two-way binding
- dispatch instead of forward the `change` event (detail signature: `File[]`)
This commit is contained in:
metonym 2022-02-21 13:33:11 -08:00 committed by GitHub
commit 8d3ac75170
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 32 deletions

View file

@ -1329,18 +1329,19 @@ None.
### Props ### Props
| Prop name | Kind | Reactive | Type | Default value | Description | | Prop name | Kind | Reactive | Type | Default value | Description |
| :------------ | :--------------- | :------- | :----------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | :------------ | :--------------- | :------- | :---------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| ref | <code>let</code> | Yes | <code>null &#124; HTMLInputElement</code> | <code>null</code> | Obtain a reference to the input HTML element | | ref | <code>let</code> | Yes | <code>null &#124; HTMLInputElement</code> | <code>null</code> | Obtain a reference to the input HTML element |
| accept | <code>let</code> | No | <code>string[]</code> | <code>[]</code> | Specify the accepted file types | | files | <code>let</code> | Yes | <code>File[]</code> | <code>[]</code> | Obtain a reference to the uploaded files |
| multiple | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to allow multiple files | | accept | <code>let</code> | No | <code>string[]</code> | <code>[]</code> | Specify the accepted file types |
| validateFiles | <code>let</code> | No | <code>(files: FileList) => FileList</code> | <code>(files) => files</code> | Override the default behavior of validating uploaded files<br />The default behavior does not validate files | | multiple | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to allow multiple files |
| labelText | <code>let</code> | No | <code>string</code> | <code>"Add file"</code> | Specify the label text | | validateFiles | <code>let</code> | No | <code>(files: File) => File</code> | <code>(files) => files</code> | Override the default behavior of validating uploaded files<br />The default behavior does not validate files |
| role | <code>let</code> | No | <code>string</code> | <code>"button"</code> | Specify the `role` attribute of the drop container | | labelText | <code>let</code> | No | <code>string</code> | <code>"Add file"</code> | Specify the label text |
| disabled | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable the input | | role | <code>let</code> | No | <code>string</code> | <code>"button"</code> | Specify the `role` attribute of the drop container |
| tabindex | <code>let</code> | No | <code>string</code> | <code>"0"</code> | Specify `tabindex` attribute | | disabled | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable the input |
| id | <code>let</code> | No | <code>string</code> | <code>"ccs-" + Math.random().toString(36)</code> | Set an id for the input element | | tabindex | <code>let</code> | No | <code>string</code> | <code>"0"</code> | Specify `tabindex` attribute |
| name | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify a name attribute for the input | | id | <code>let</code> | No | <code>string</code> | <code>"ccs-" + Math.random().toString(36)</code> | Set an id for the input element |
| name | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify a name attribute for the input |
### Slots ### Slots
@ -1350,15 +1351,15 @@ None.
### Events ### Events
| Event name | Type | Detail | | Event name | Type | Detail |
| :--------- | :--------- | :-------------------- | | :--------- | :--------- | :------------------ |
| add | dispatched | <code>FileList</code> | | add | dispatched | <code>File[]</code> |
| dragover | forwarded | -- | | change | dispatched | <code>File[]</code> |
| dragleave | forwarded | -- | | dragover | forwarded | -- |
| drop | forwarded | -- | | dragleave | forwarded | -- |
| keydown | forwarded | -- | | drop | forwarded | -- |
| change | forwarded | -- | | keydown | forwarded | -- |
| click | forwarded | -- | | click | forwarded | -- |
## `FileUploaderItem` ## `FileUploaderItem`

View file

@ -3760,6 +3760,17 @@
"constant": false, "constant": false,
"reactive": false "reactive": false
}, },
{
"name": "files",
"kind": "let",
"description": "Obtain a reference to the uploaded files",
"type": "File[]",
"value": "[]",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": true
},
{ {
"name": "multiple", "name": "multiple",
"kind": "let", "kind": "let",
@ -3775,7 +3786,7 @@
"name": "validateFiles", "name": "validateFiles",
"kind": "let", "kind": "let",
"description": "Override the default behavior of validating uploaded files\nThe default behavior does not validate files", "description": "Override the default behavior of validating uploaded files\nThe default behavior does not validate files",
"type": "(files: FileList) => FileList", "type": "(files: File) => File",
"value": "(files) => files", "value": "(files) => files",
"isFunction": true, "isFunction": true,
"isFunctionDeclaration": false, "isFunctionDeclaration": false,
@ -3869,12 +3880,12 @@
} }
], ],
"events": [ "events": [
{ "type": "dispatched", "name": "add", "detail": "FileList" }, { "type": "dispatched", "name": "add", "detail": "File[]" },
{ "type": "dispatched", "name": "change", "detail": "File[]" },
{ "type": "forwarded", "name": "dragover", "element": "div" }, { "type": "forwarded", "name": "dragover", "element": "div" },
{ "type": "forwarded", "name": "dragleave", "element": "div" }, { "type": "forwarded", "name": "dragleave", "element": "div" },
{ "type": "forwarded", "name": "drop", "element": "div" }, { "type": "forwarded", "name": "drop", "element": "div" },
{ "type": "forwarded", "name": "keydown", "element": "label" }, { "type": "forwarded", "name": "keydown", "element": "label" },
{ "type": "forwarded", "name": "change", "element": "input" },
{ "type": "forwarded", "name": "click", "element": "input" } { "type": "forwarded", "name": "click", "element": "input" }
], ],
"typedefs": [], "typedefs": [],

View file

@ -1,6 +1,7 @@
<script> <script>
/** /**
* @event {FileList} add * @event {File[]} add
* @event {File[]} change
*/ */
/** /**
@ -9,13 +10,19 @@
*/ */
export let accept = []; export let accept = [];
/**
* Obtain a reference to the uploaded files
* @type {File[]}
*/
export let files = [];
/** Set to `true` to allow multiple files */ /** Set to `true` to allow multiple files */
export let multiple = false; export let multiple = false;
/** /**
* Override the default behavior of validating uploaded files * Override the default behavior of validating uploaded files
* The default behavior does not validate files * The default behavior does not validate files
* @type {(files: FileList) => FileList} * @type {(files: File) => File}
*/ */
export let validateFiles = (files) => files; export let validateFiles = (files) => files;
@ -68,7 +75,9 @@
on:drop|preventDefault|stopPropagation="{({ dataTransfer }) => { on:drop|preventDefault|stopPropagation="{({ dataTransfer }) => {
if (!disabled) { if (!disabled) {
over = false; over = false;
dispatch('add', validateFiles(dataTransfer.files)); files = validateFiles([...dataTransfer.files]);
dispatch('add', files);
dispatch('change', files);
} }
}}" }}"
> >
@ -104,9 +113,10 @@
name="{name}" name="{name}"
multiple="{multiple}" multiple="{multiple}"
class:bx--file-input="{true}" class:bx--file-input="{true}"
on:change
on:change="{({ target }) => { on:change="{({ target }) => {
dispatch('add', validateFiles(target.files)); files = validateFiles([...target.files]);
dispatch('add', files);
dispatch('change', files);
}}" }}"
on:click on:click
on:click="{({ target }) => { on:click="{({ target }) => {

View file

@ -9,6 +9,12 @@ export interface FileUploaderDropContainerProps
*/ */
accept?: string[]; accept?: string[];
/**
* Obtain a reference to the uploaded files
* @default []
*/
files?: File[];
/** /**
* Set to `true` to allow multiple files * Set to `true` to allow multiple files
* @default false * @default false
@ -20,7 +26,7 @@ export interface FileUploaderDropContainerProps
* The default behavior does not validate files * The default behavior does not validate files
* @default (files) => files * @default (files) => files
*/ */
validateFiles?: (files: FileList) => FileList; validateFiles?: (files: File) => File;
/** /**
* Specify the label text * Specify the label text
@ -68,12 +74,12 @@ export interface FileUploaderDropContainerProps
export default class FileUploaderDropContainer extends SvelteComponentTyped< export default class FileUploaderDropContainer extends SvelteComponentTyped<
FileUploaderDropContainerProps, FileUploaderDropContainerProps,
{ {
add: CustomEvent<FileList>; add: CustomEvent<File[]>;
change: CustomEvent<File[]>;
dragover: WindowEventMap["dragover"]; dragover: WindowEventMap["dragover"];
dragleave: WindowEventMap["dragleave"]; dragleave: WindowEventMap["dragleave"];
drop: WindowEventMap["drop"]; drop: WindowEventMap["drop"];
keydown: WindowEventMap["keydown"]; keydown: WindowEventMap["keydown"];
change: WindowEventMap["change"];
click: WindowEventMap["click"]; click: WindowEventMap["click"];
}, },
{ labelText: {} } { labelText: {} }