Skip to content

Commit 5b69b93

Browse files
authored
Merge pull request #4 from github/input
Add support for file inputs
2 parents 41032a7 + 2a4bdbd commit 5b69b93

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@ import '@github/file-attachment-element'
1515
```
1616

1717
```html
18-
<file-attachment directory>
18+
<file-attachment directory input="upload">
19+
<input id="upload" type="file" multiple>
1920
</file-attachment>
2021
```
2122

23+
### Optional attributes
24+
25+
- `file-attachment[directory]` enables traversing directories.
26+
- `file-attachment[input]` points to the ID of a file input inside of `<file-attachment>`. Files selected from the `<input>` will be attached to `<file-attachment>`. Supplying an input is strongly recommended in order to ensure users can upload files without a mouse or knowing where to paste files.
27+
2228
### Styling drag state
2329

2430
A boolean `[hover]` attribute is present on `<file-attachment>` while files are dragged over the element.

src/file-attachment-element.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class FileAttachmentElement extends HTMLElement {
88
this.addEventListener('dragleave', onDragleave)
99
this.addEventListener('drop', onDrop)
1010
this.addEventListener('paste', onPaste)
11+
this.addEventListener('change', onChange)
1112
}
1213

1314
get directory(): boolean {
@@ -132,3 +133,18 @@ function onPaste(event: ClipboardEvent) {
132133
container.attach(files)
133134
event.preventDefault()
134135
}
136+
137+
function onChange(event: Event) {
138+
const container = event.currentTarget
139+
if (!(container instanceof FileAttachmentElement)) return
140+
const input = event.target
141+
if (!(input instanceof HTMLInputElement)) return
142+
const id = container.getAttribute('input')
143+
if (!id || input.id !== id) return
144+
145+
const files = input.files
146+
if (!files || files.length === 0) return
147+
148+
container.attach(files)
149+
input.value = ''
150+
}

test/test.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,15 @@ describe('file-attachment', function() {
5858
})
5959

6060
describe('element', function() {
61-
let fileAttachment
61+
let fileAttachment, input
6262
beforeEach(function() {
63-
document.body.innerHTML = `<file-attachment></file-attachment>`
63+
document.body.innerHTML = `
64+
<file-attachment input="upload">
65+
<input type="file" id="upload">
66+
</file-attachment>`
6467

6568
fileAttachment = document.querySelector('file-attachment')
69+
input = document.querySelector('input')
6670
})
6771

6872
afterEach(function() {
@@ -106,6 +110,20 @@ describe('file-attachment', function() {
106110
const event = await listener
107111
assert.equal('test.png', event.detail.attachments[0].file.name)
108112
})
113+
114+
it('attaches files via input', async function() {
115+
const listener = once('file-attachment-accepted')
116+
117+
const dataTransfer = new DataTransfer()
118+
const file = new File(['hubot'], 'test.png', {type: 'image/png'})
119+
dataTransfer.items.add(file)
120+
input.files = dataTransfer.files
121+
input.dispatchEvent(new Event('change', {bubbles: true}))
122+
123+
const event = await listener
124+
assert.equal('test.png', event.detail.attachments[0].file.name)
125+
assert.equal(0, input.files.length)
126+
})
109127
})
110128
})
111129

0 commit comments

Comments
 (0)