Skip to content

Commit fddebe5

Browse files
authored
Merge pull request #2 from github/api
Add Flow definition
2 parents 26e4705 + 1a12884 commit fddebe5

File tree

5 files changed

+60
-44
lines changed

5 files changed

+60
-44
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ import '@github/remote-input-element'
2222
<ul id="results"></ul>
2323
```
2424

25+
A GET request will be sent to `/query?q=${input.value}`.
26+
27+
The parameter name (`q`) is customizable with the `[param]` attribute:
28+
2529
```html
2630
<!-- Live preview of Markdown -->
27-
<remote-input src="/preview" aria-owns="md-preview">
31+
<remote-input src="/preview" aria-owns="md-preview" param="body">
2832
<textarea></textarea>
2933
</remote-input>
3034
<div id="md-preview"></div>

index.js

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class RemoteInputElement extends HTMLElement {
1111

1212
attributeChangedCallback(name: string, oldValue: string) {
1313
if (oldValue && name === 'src') {
14-
this.fetchResults(false)
14+
fetchResults(this, false)
1515
}
1616
}
1717

@@ -22,8 +22,8 @@ class RemoteInputElement extends HTMLElement {
2222
input.setAttribute('autocomplete', 'off')
2323
input.setAttribute('spellcheck', 'false')
2424

25-
this.debounceInputChange = debounce(this.fetchResults.bind(this))
26-
this.boundFetchResults = this.fetchResults.bind(this)
25+
this.debounceInputChange = debounce(() => fetchResults(this))
26+
this.boundFetchResults = () => fetchResults(this)
2727
input.addEventListener('focus', this.boundFetchResults)
2828
input.addEventListener('change', this.boundFetchResults)
2929
input.addEventListener('input', this.debounceInputChange)
@@ -43,53 +43,42 @@ class RemoteInputElement extends HTMLElement {
4343
return input instanceof HTMLInputElement || input instanceof HTMLTextAreaElement ? input : null
4444
}
4545

46-
get resultsContainer(): ?HTMLElement {
47-
return document.getElementById(this.getAttribute('aria-owns') || '')
48-
}
49-
5046
get src(): string {
5147
return this.getAttribute('src') || ''
5248
}
5349

5450
set src(url: string) {
5551
this.setAttribute('src', url)
5652
}
53+
}
5754

58-
get name(): string {
59-
return this.getAttribute('name') || 'q'
60-
}
61-
62-
set name(name: string) {
63-
this.setAttribute('name', name)
64-
}
65-
66-
async fetchResults(checkCurrentQuery: boolean = true) {
67-
if (!this.input) return
68-
const query = this.input.value
69-
if (checkCurrentQuery && this.currentQuery === query) return
70-
this.currentQuery = query
71-
const src = this.src
72-
if (!src) return
73-
const resultsContainer = this.resultsContainer
74-
if (!resultsContainer) return
75-
76-
const url = new URL(src, window.location.origin)
77-
const params = new URLSearchParams(url.search)
78-
params.append(this.name, query)
79-
url.search = params.toString()
80-
81-
this.dispatchEvent(new CustomEvent('loadstart'))
82-
this.setAttribute('loading', '')
83-
try {
84-
const html = await fetch(url).then(data => data.text())
85-
this.dispatchEvent(new CustomEvent('load'))
86-
resultsContainer.innerHTML = html
87-
} catch {
88-
this.dispatchEvent(new CustomEvent('error'))
89-
}
90-
this.removeAttribute('loading')
91-
this.dispatchEvent(new CustomEvent('loadend'))
55+
async function fetchResults(remoteInput: RemoteInputElement, checkCurrentQuery: boolean = true) {
56+
const input = remoteInput.input
57+
if (!input) return
58+
const query = input.value
59+
if (checkCurrentQuery && remoteInput.currentQuery === query) return
60+
remoteInput.currentQuery = query
61+
const src = remoteInput.src
62+
if (!src) return
63+
const resultsContainer = document.getElementById(remoteInput.getAttribute('aria-owns') || '')
64+
if (!resultsContainer) return
65+
66+
const url = new URL(src, window.location.origin)
67+
const params = new URLSearchParams(url.search)
68+
params.append(remoteInput.getAttribute('param') || 'q', query)
69+
url.search = params.toString()
70+
71+
remoteInput.dispatchEvent(new CustomEvent('loadstart'))
72+
remoteInput.setAttribute('loading', '')
73+
try {
74+
const html = await fetch(url).then(data => data.text())
75+
remoteInput.dispatchEvent(new CustomEvent('load'))
76+
resultsContainer.innerHTML = html
77+
} catch {
78+
remoteInput.dispatchEvent(new CustomEvent('error'))
9279
}
80+
remoteInput.removeAttribute('loading')
81+
remoteInput.dispatchEvent(new CustomEvent('loadend'))
9382
}
9483

9584
function debounce(callback) {

index.js.flow

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* @flow strict */
2+
3+
declare module '@github/remote-input-element' {
4+
declare export default class RemoteInputElement extends HTMLElement {
5+
get input(): ?HTMLInputElement;
6+
get src(): string;
7+
set src(url: string): void;
8+
}
9+
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"clean": "rm -rf dist",
1414
"lint": "github-lint",
1515
"prebuild": "npm run clean && npm run lint && mkdir dist",
16-
"build-umd": "BABEL_ENV=umd babel index.js -o dist/index.umd.js",
17-
"build-esm": "BABEL_ENV=esm babel index.js -o dist/index.esm.js",
16+
"build-umd": "BABEL_ENV=umd babel index.js -o dist/index.umd.js && cp index.js.flow dist/index.umd.js.flow",
17+
"build-esm": "BABEL_ENV=esm babel index.js -o dist/index.esm.js && cp index.js.flow dist/index.esm.js.flow",
1818
"build": "npm run build-umd && npm run build-esm",
1919
"pretest": "npm run build",
2020
"test": "karma start test/karma.config.js",

test/test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ describe('remote-input', function() {
3838
input.focus()
3939
})
4040

41+
it('repects param attribute', function(done) {
42+
const remoteInput = document.querySelector('remote-input')
43+
const input = document.querySelector('input')
44+
const results = document.querySelector('#results')
45+
remoteInput.setAttribute('param', 'robot')
46+
assert.equal(results.innerHTML, '')
47+
remoteInput.addEventListener('loadend', function() {
48+
assert.equal(results.querySelector('ol').getAttribute('data-src'), '/results?robot=test')
49+
done()
50+
})
51+
input.value = 'test'
52+
input.focus()
53+
})
54+
4155
it('loads content again after src is changed', function(done) {
4256
const remoteInput = document.querySelector('remote-input')
4357
const input = document.querySelector('input')

0 commit comments

Comments
 (0)