- Notifications
You must be signed in to change notification settings - Fork54
Auto-complete input values from server search results.
License
github/auto-complete-element
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Auto-complete input values from server search results.
$ npm install --save @github/auto-complete-element
Import as ES modules:
import'@github/auto-complete-element'
With a script tag:
<scripttype="module"src="./node_modules/@github/auto-complete-element/dist/bundle.js">
<auto-completesrc="/users/search"for="users-popup"><inputtype="text"name="users"><!-- Optional clear button: - id must match the id of the input or the name of the input plus "-clear" - recommended to be *before* UL elements to avoid conflicting with their blur logic Please see Note below on this button for more details --><buttonid="users-clear">X</button><ulid="users-popup"></ul><!-- Optional div for screen reader feedback. Note the ID matches the ul, but with -feedback appended. Recommended: Use a "Screen Reader Only" class to position the element off the visual boundary of the page. --><divid="users-popup-feedback"class="sr-only"></div></auto-complete>
If you want to enable auto-select (pressing Enter in the input will select the first option), using the above example:
<auto-completedata-autoselect="true"src="/users/search"for="users-popup">...</auto-complete>
The server response should include the items that matched the search query.
<lirole="option">Hubot</li><lirole="option">Bender</li><lirole="option">BB-8</li><lirole="option"aria-disabled="true">R2-D2 (powered down)</li>
Thedata-autocomplete-value
attribute can be used to define the value for anitem whose display text needs to be different:
<lirole="option"data-autocomplete-value="bb8">BB-8 (astromech)</li>
Usedata-no-result-found="true"
to show a no results message inside the autocomplete popover. Be sure to addrole="presentation"
to this element so that screen readers do not mistake this as an auto-complete option. The auto-complete-element has built in functionality thathandles aria-live announcing number of search results so this should be purely decorative.
<lirole="presentation"aria-hidden="true"data-no-result-found="true">No results found!</li>
Whileinput type="search"
comes with anx
that clears the content of the field and refocuses it on many browsers, the implementation for this control is not keyboard accessible, and so we've opted to enable a customizable clear button so that your keyboard users will be able to interact with it.
As an example:
In Chrome, this 'x' isn't a button but a div with a pseudo="-webkit-search-cancel-button". It doesn't have a tab index or a way to navigate to it without a mouse. Additionally, this control is only visible on mouse hover.
open
is true when the auto-complete result list is visiblevalue
is the selected value from the list or the empty string when cleared
fetchResult
you can override the default method used to query for results by overriding this property:document.querySelector('auto-complete').fetchResult = async (url) => (await fetch(url)).text()
Request lifecycle events are dispatched on the<auto-complete>
element. These events do not bubble.
loadstart
- The server fetch has started.load
- The network request completed successfully.error
- The network request failed.loadend
- The network request has completed.
Network events are useful for displaying progress states while the request is in-flight.
constcompleter=document.querySelector('auto-complete')constcontainer=completer.parentElementcompleter.addEventListener('loadstart',()=>container.classList.add('is-loading'))completer.addEventListener('loadend',()=>container.classList.remove('is-loading'))completer.addEventListener('load',()=>container.classList.add('is-success'))completer.addEventListener('error',()=>container.classList.add('is-error'))
auto-complete-change
is dispatched after a value is selected. Inevent
you can find:
relatedTarget
: The HTMLInputElement controlling the auto-complete result list.
completer.addEventListener('auto-complete-change',function(event){console.log('Auto-completed value chosen or cleared',completer.value)console.log('Related input element',event.relatedTarget)})
You can callsetCSPTrustedTypesPolicy(policy: TrustedTypePolicy | Promise<TrustedTypePolicy> | null)
from JavaScript to set aCSP trusted types policy, which can perform(synchronous) filtering or rejection of thefetch
response before it isinserted into the page:
importAutoCompleteElementfrom'auto-complete-element'importDOMPurifyfrom'dompurify'// Using https://github.com/cure53/DOMPurify// This policy removes all HTML markup except links.constpolicy=trustedTypes.createPolicy('links-only',{createHTML:(htmlText:string)=>{returnDOMPurify.sanitize(htmlText,{ALLOWED_TAGS:['a'],ALLOWED_ATTR:['href'],RETURN_TRUSTED_TYPE:true})}})AutoCompleteElement.setCSPTrustedTypesPolicy(policy)
The policy has access to thefetch
response object. Due to platformconstraints, only synchronous information from the response (in addition to theHTML text body) can be used in the policy:
importAutoCompleteElementfrom'auto-complete-element'constpolicy=trustedTypes.createPolicy('require-server-header',{createHTML:(htmlText:string,response:Response)=>{if(response.headers.get('X-Server-Sanitized')!=='sanitized=true'){// Note: this will reject the contents, but the error may be caught before it shows in the JS console.thrownewError('Rejecting HTML that was not marked by the server as sanitized.')}returnhtmlText}})AutoCompleteElement.setCSPTrustedTypesPolicy(policy)
Note that:
- Only a single policy can be set, shared by all
AutoCompleteElement
fetches. - You should call
setCSPTrustedTypesPolicy()
ahead of any other load ofauto-complete
element in your code.- If your policy itself requires asynchronous work to construct, you can alsopass a
Promise<TrustedTypePolicy>
. - Pass
null
to remove the policy.
- If your policy itself requires asynchronous work to construct, you can alsopass a
- Not all browserssupport the trusted types API in JavaScript.You may want to use therecommended tinyfill toconstruct a policy without causing issues in other browsers.
Browsers without nativecustom element support require apolyfill.
- Chrome
- Firefox
- Safari
- Microsoft Edge
npm installnpm test
To view changes locally, runnpm run examples
.
Inexamples/index.html
, uncomment<!--<script type="module" src="./dist/bundle.js"></script>-->
and comment out the script referencing theunpkg
version. This allows you to use thesrc
code in this repo. Otherwise, you will be pulling the latest published code, which will not reflect the local changes you are making.
We have included some custom rules that assist in providing guardrails to confirm this component is being used accessibly.
If you are using theaxe-core
library in your project,
importaxefrom'axe-core'importautoCompleteRulesBuilderfrom'@github/auto-complete-element/validator'constautoCompleteRules=autoCompleteRulesBuilder()// optionally, pass in your app's custom rules object, it will build and return the full objectaxe.configure(autoCompleteRules)axe.run(document)
To confirm your usage is working as designed,
import{validate}from'@github/auto-complete-element/validator'validate(document)
Passes and failures may be determined by the length of thepasses
andviolations
arrays on the returned object:
{passes:[],violations:[]}
Distributed under the MIT license. See LICENSE for details.
About
Auto-complete input values from server search results.
Topics
Resources
License
Code of conduct
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.