From e4959a0715fb5742f3329b37dfc488b096adbd26 Mon Sep 17 00:00:00 2001 From: mynamesleon Date: Wed, 29 Jan 2020 08:59:04 +0000 Subject: [PATCH] v1.1.0 prep changes --- CHANGELOG.md | 23 + README.md | 187 +- dist/aria-autocomplete.css | 241 + dist/aria-autocomplete.min.css | 1 - dist/aria-autocomplete.min.js | 23 +- index.html | 218 +- package-lock.json | 8982 ++++++----------- package.json | 30 +- src/aria-autocomplete-types.d.ts | 58 + src/aria-autocomplete.ts | 13 + src/autocomplete-api.ts | 54 + src/autocomplete-constants.ts | 20 + src/autocomplete-helpers.js | 222 - src/autocomplete-helpers.ts | 190 + ...utocomplete-ids.js => autocomplete-ids.ts} | 13 +- src/autocomplete-options.ts | 235 + src/{aria-autocomplete.js => autocomplete.ts} | 1125 +-- src/closest-polyfill.js | 15 - src/closest-polyfill.ts | 15 + src/default-options.js | 198 - tsconfig.json | 9 + webpack.config.js | 21 + 22 files changed, 4956 insertions(+), 6937 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 dist/aria-autocomplete.css delete mode 100644 dist/aria-autocomplete.min.css create mode 100644 src/aria-autocomplete-types.d.ts create mode 100644 src/aria-autocomplete.ts create mode 100644 src/autocomplete-api.ts create mode 100644 src/autocomplete-constants.ts delete mode 100644 src/autocomplete-helpers.js create mode 100644 src/autocomplete-helpers.ts rename src/{autocomplete-ids.js => autocomplete-ids.ts} (71%) create mode 100644 src/autocomplete-options.ts rename src/{aria-autocomplete.js => autocomplete.ts} (52%) delete mode 100644 src/closest-polyfill.js create mode 100644 src/closest-polyfill.ts delete mode 100644 src/default-options.js create mode 100644 tsconfig.json create mode 100644 webpack.config.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..92dd1fc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [1.1.0] - 2020-01-29 + +### Added + +- Home key usage to go to first item in the list +- End key usage to go to last item in the list +- `onAsyncError` callback option + +### Changed + +- Moved code and build over to TypeScript for: code improvements, self-documentation, and reduced bundle size by using an ES6 output from TypeScript that's bundled to UMD with webpack. + +### Fixed + +- Issue with the API filter method getting an error +- Issue when clicking on a single-select autocomplete with minLength of 0 with a current selection, which was correctly searching with an empty string, but the polling method was then triggering a search with the value afterwards. +- Screen reader announcements for results ignoring the number of results rendered + +[1.1.0]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.0.0...v1.1.0 diff --git a/README.md b/README.md index b10a12b..f345643 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Then import it, and call it on an element (ideally a text ``, but not n ```javascript import AriaAutocomplete from 'aria-autocomplete'; -new AriaAutocomplete(document.getElementById('some-element'), { +AriaAutocomplete(document.getElementById('some-element'), { source: ArrayOrStringOrFunction }); ``` @@ -41,15 +41,15 @@ new AriaAutocomplete(document.getElementById('some-element'), { At its core, the autocomplete requires only an element and a `source`. When the element is an input, its value will be set using the user's selection(s). If a `source` option isn't provided (is falsy, or an empty Array), and the element is either a `")),e.showAllControl&&s.push(''));var a=e.srListLabelText,o=e.listClassName?" ".concat(e.listClassName):"",c=a?' aria-label="'.concat(a,'"'):"";s.push('")),s.push('').concat(e.srAssistiveText,"")),s.push('')),s.push(""),this.element.insertAdjacentHTML("afterend",s.join(""))}},{key:"generateApi",value:function(){var e=this;this.api={open:function(){return e.show.call(e)},close:function(){return e.hide.call(e)},filter:function(t){return e.filter.call(e,t)}};for(var t=["options","destroy","enable","disable","input","wrapper","list","selected"],i=function(i,s){e.api[t[i]]="function"==typeof e[t[i]]?function(){return e[t[i]].call(e)}:e[t[i]]},s=0,n=t.length;s=48&&e<=57||e>=65&&e<=90||e>=96&&e<=111||e>=186&&e<=222||32===e||8===e||46===e){var a=String.fromCharCode(n);s+=a=t.shiftKey?a.toUpperCase():a.toLowerCase()}}!s&&(i=this.input.getAttribute("placeholder"))&&(s=i);var h=this.measureString(s)+4;this.options&&this.options.cache&&this.cache&&(this.cache[s]=h);var u=this.options&&this.options.minWidth;"number"==typeof u&&hc&&(h=c),h!==this.currentWidth&&(this.currentWidth=h,this.input.style.width=h+"px")}},t.prototype.destroy=function(){this.input.removeEventListener("blur",this.eventHandler),this.input.removeEventListener("input",this.eventHandler),this.input.removeEventListener("keyup",this.eventHandler),this.input.removeEventListener("keydown",this.eventHandler),this.input=this.cache=null},t}();e.default=r}])},function(t,e){var i=Element.prototype;i.matches||(i.matches=i.msMatchesSelector||i.webkitMatchesSelector),i.closest||(i.closest=function(t){var e=this;do{if(e.matches(t))return e;e=e.parentElement||e.parentNode}while(null!==e&&1===e.nodeType);return null})},function(t,e,i){"use strict";i.r(e);var s=i(0),n=i.n(s),r=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function o(t,e){if(t&&"number"==typeof t.length)for(var i=0,s=t.length;i-1&&this.selected[e]){var n=L(this.selected[e]),r=n.label;k(n.element,!1,this),this.selected.splice(e,1),this.triggerOptionCallback("onDelete",[n]),this.setSourceElementValues(),this.buildMultiSelected(),this.announce(r+" "+this.options.srDeletedText,0)}},t.prototype.createSelectElemFrom=function(t){var e=t.label,i=document.createElement("span");return i.setAttribute("aria-label",this.options.srDeleteText+" "+e),i.setAttribute("class",this.cssNameSpace+"__selected"),i.setAttribute("role","button"),i.setAttribute("tabindex","0"),i[c]=t,i.textContent=e,i},t.prototype.buildMultiSelected=function(){var t=this;if(this.multiple){this.multiple&&this.selected.length>=this.options.maxItems?this.disable():this.enable();var e=this.getSelectedElems();if(this.selected.length||e.length){var i=[];e.forEach((function(e){for(var s=e[c],n=0,r=t.selected.length;n=i.length)return this.currentSelectedIndex=i.length-1,void this.setOptionFocus(t,this.currentSelectedIndex);var s=i[e];if(s&&"string"==typeof s.getAttribute("tabindex"))return this.currentSelectedIndex=e,a(s,this.cssNameSpace+"__option--focused focused focus"),s.setAttribute("aria-selected","true"),void s.focus();this.currentSelectedIndex=-1},t.prototype.setSourceElementValues=function(){for(var t=[],e=0,i=this.selected.length;e=this.options.maxItems)&&this.filteredSource.length&&this.filteredSource[e]){for(var s=L(this.filteredSource[e]),n=!1,r=0,o=this.selected.length;r'+b+"")}e.length?(a(this.list,h+"__list--has-results"),o(this.list,h+"__list--no-results")):(o(this.list,h+"__list--has-results"),a(this.list,h+"__list--no-results"));var y=this.options.noResultsText;!e.length&&"string"==typeof y&&y.length&&(r=y,e.push('
  • '+y+"
  • ")),this.cancelFilterPrep(),r||(r=this.triggerOptionCallback("srResultsText",[f])),this.announce(r);var g=e.join("");if(this.currentListHtml!==g?(this.currentListHtml=g,this.list.innerHTML=g):this.resetOptionAttributes(),!e.length)return this.hide(),void(this.forceShowAll=!1);this.show(),this.forceShowAll=!1},t.prototype.handleAsync=function(t,e){var i=this;void 0===e&&(e=!1),this.xhr&&"function"==typeof this.xhr.abort&&this.xhr.abort();var s=new XMLHttpRequest,n=this.forceShowAll,r=e?null:this.api,o=this.multiple?this.selected.length:0,l=n||e||9999===this.options.maxResults,a=this.source+(/\?/.test(this.source)?"&":"?")+encodeURIComponent(this.options.asyncQueryParam)+"="+encodeURIComponent(t)+"&"+encodeURIComponent(this.options.asyncMaxResultsParam)+"="+(l?9999:o+this.options.maxResults);a=this.triggerOptionCallback("onAsyncPrep",[a],r)||a,s.open("GET",a),s.onload=function(){if(s.readyState===s.DONE&&s.status>=200&&s.status<300){i.forceShowAll=n;var o=F(i.triggerOptionCallback("onAsyncSuccess",[t,s],r)||s.responseText,i.options.sourceMapping,!1);e?(i.prepSelectedFromArray(o),i.setInputStartingStates(!1)):i.setListOptions(o)}},s.onerror=function(){i.triggerOptionCallback("onAsyncError",[t,s],r)},e||(this.xhr=s),s.send()},t.prototype.filter=function(t){var e=this;if("string"==typeof t){var i=this.forceShowAll;if(!i){var s=this.triggerOptionCallback("onSearch",[t]);"string"==typeof s&&(t=s)}if(this.term=t,"string"==typeof this.source&&this.source.length)return this.handleAsync(t),void(this.forceShowAll=!1);if("function"!=typeof this.source){t||(i=!0);var n,r,o=[];if(this.source&&this.source.length){var l=[u];if(!i){t=C(t,!0);var a=this.options.alsoSearchIn;Array.isArray(a)&&a.length&&(n=l.concat(a),r=[],n.forEach((function(t){if("string"==typeof t){for(var e=x(t),i="label"!==e,s=0,n=r.length;i&&s-1&&R(n,e,s))return!0}return!1}(e,t,l))&&o.push(e)}))}this.setListOptions(o)}else this.source.call(this.api,this.term,(function(t){var i=F(t,e.options.sourceMapping);e.setListOptions(i)}))}else this.cancelFilterPrep()},t.prototype.cancelFilterPrep=function(){clearTimeout(this.filterTimer),o(this.wrapper,this.cssNameSpace+"__wrapper--loading loading"),o(this.input,this.cssNameSpace+"__input--loading loading"),this.filtering=!1},t.prototype.filterPrep=function(t,e,i){var s=this;void 0===e&&(e=!1),void 0===i&&(i=!1);var n=this.forceShowAll,r=n||i?0:this.options.delay;this.cancelFilterPrep(),this.filtering=!0,this.filterTimer=setTimeout((function(){var i=s.input.value;if(s.inputPollingValue=i,(n||""===i||e&&!s.multiple&&s.selected.length&&x(s.selected[0].label)===x(i))&&(i=""),s.setInputDescription(),!n&&i.length=this.options.minLength)&&this.filterPrep(t)),this.menuOpen&&!this.filtering){var e=this.currentSelectedIndex;"number"!=typeof e||e<0?this.setOptionFocus(t,0):this.setOptionFocus(t,e+1)}},t.prototype.handleEndKey=function(t){if(!this.disabled&&this.menuOpen&&t.target!==this.input){var e=P(this.list);e.length&&(t.preventDefault(),this.setOptionFocus(t,e.length-1))}},t.prototype.handleHomeKey=function(t){!this.disabled&&this.menuOpen&&t.target!==this.input&&(t.preventDefault(),this.setOptionFocus(t,0))},t.prototype.handleEnterKey=function(t){var e=t.target;this.isSelectedElem(e)?this.removeEntryFromSelected(e[c]):this.disabled||(this.showAll&&e===this.showAll?this.filterPrepShowAll(t):(this.menuOpen&&(t.preventDefault(),this.currentSelectedIndex>-1&&this.handleOptionSelect(t,this.currentSelectedIndex)),e===this.input&&this.filterPrep(t,!1,!0)))},t.prototype.handleKeyDownDefault=function(t){var e=t.keyCode,i=t.target===this.input;if(e===m&&!i||this.isSelectedElem(t.target)&&e===S)return t.preventDefault(),void this.handleEnterKey(t);if(!this.disabled){var s=this.selected&&this.selected.length;if(this.options.deleteOnBackspace&&e===p&&""===this.input.value&&s&&i&&this.multiple)this.removeEntryFromSelected(this.selected[s-1]);else{var n=function(t){return t>=48&&t<=57||t>=65&&t<=90||t>=96&&t<=111||t>=186&&t<=222||32===t||8===t||46===t}(e),r=!i&&n;r&&this.input.focus(),(r||i&&n)&&this.filterPrep(t)}}},t.prototype.prepKeyDown=function(t){switch(t.keyCode){case y:this.handleUpKey(t);break;case g:this.handleDownKey(t);break;case v:this.handleEndKey(t);break;case b:this.handleHomeKey(t);break;case d:this.handleEnterKey(t);break;case f:this.handleComponentBlur(t,!0);break;default:this.handleKeyDownDefault(t)}},t.prototype.cancelPolling=function(){clearTimeout(this.pollingTimer)},t.prototype.startPolling=function(){var t=this;this.filtering||this.input.value===this.inputPollingValue||this.filterPrep({}),this.pollingTimer=setTimeout((function(){t.startPolling()}),200)},t.prototype.bindEvents=function(){var t=this;this.wrapper.addEventListener("focusout",(function(e){t.handleComponentBlur(e,!1)})),this.wrapper.addEventListener("focusin",(function(e){t.list.contains(e.target)||(t.currentSelectedIndex=-1)})),this.wrapper.addEventListener("keydown",(function(e){t.prepKeyDown(e)})),this.wrapper.addEventListener("click",(function(e){e.target!==t.wrapper?t.isSelectedElem(e.target)&&t.removeEntryFromSelected(e.target[c]):t.input.focus()}));var e=this.cssNameSpace+"__wrapper--focused focused focus",i=this.cssNameSpace+"__input--focused focused focus";this.input.addEventListener("blur",(function(){o(t.wrapper,e),o(t.input,i),t.cancelPolling()})),this.input.addEventListener("input",(function(e){t.filterPrep(e)})),this.input.addEventListener("click",(function(e){!t.menuOpen&&t.input.value.length>=t.options.minLength&&t.filterPrep(e,!0)})),this.input.addEventListener("focusin",(function(){a(t.wrapper,e),a(t.input,i),t.startPolling(),t.disabled||t.menuOpen||t.filterPrep(event,!0)})),this.showAll&&this.showAll.addEventListener("click",(function(e){t.filterPrepShowAll(e)})),this.list.addEventListener("mouseenter",(function(e){t.resetOptionAttributes()})),this.list.addEventListener("click",(function(e){if(e.target!==t.list){var i=P(t.list);if(i.length){var s=i.indexOf(e.target);t.handleOptionSelect(e,s)}}})),this.autoGrow&&(this.inputAutoWidth=new n.a(this.input))},t.prototype.prepListSourceCheckboxes=function(){this.multiple=!0,this.source=[];for(var t=this.element.querySelectorAll('input[type="checkbox"]'),e=0,i=t.length;e1&&(this.options.maxItems=1),this.source=[];for(var e=this.element.querySelectorAll("option"),i=0,s=e.length;i-1&&e.selected.push(t[s])}}))}},t.prototype.prepListSourceArray=function(){this.source=F(this.source,this.options.sourceMapping),this.prepSelectedFromArray(this.source)},t.prototype.prepListSourceAsync=function(){var t=this.element;this.elementIsInput&&t.value&&this.handleAsync(t.value,!0)},t.prototype.prepListSourceFunction=function(){var t=this,e=this.element;this.elementIsInput&&e.value&&this.source.call(void 0,e.value,(function(e){t.prepSelectedFromArray(F(e,t.options.sourceMapping)),t.setInputStartingStates(!1)}))},t.prototype.prepListSource=function(){return"function"==typeof this.source?this.prepListSourceFunction():"string"==typeof this.source&&this.source.length?this.prepListSourceAsync():Array.isArray(this.source)&&this.source.length?this.prepListSourceArray():this.elementIsSelect?this.prepListSourceDdl():void(this.element.querySelector('input[type="checkbox"]')&&this.prepListSourceCheckboxes())},t.prototype.setInputStartingStates=function(t){if(void 0===t&&(t=!0),t){if(this.ids.ELEMENT){var e=document.querySelector('[for="'+this.ids.ELEMENT+'"]');e&&(e._ariaAutocompleteLabelOriginallyFor=this.ids.ELEMENT,e.setAttribute("for",this.ids.INPUT))}var i=this.element.getAttribute("aria-describedby");i&&this.input.setAttribute("aria-describedby",i);var s=this.element.getAttribute("aria-labelledby");s&&this.input.setAttribute("aria-labelledby",s)}this.selected.length&&(this.multiple?this.buildMultiSelected():this.setInputValue(this.selected[0].label||"",!0)),this.setInputDescription(),this.element.disabled&&this.disable()},t.prototype.setHtml=function(){var t=this.options,e=this.cssNameSpace,i=t.wrapperClassName?" "+t.wrapperClassName:"",s=['
    '],n=t.name?" "+t.name:"",r=t.inputClassName?" "+t.inputClassName:"",o=t.placeholder?' placeholder="'+t.placeholder+'" aria-placeholder="'+t.placeholder+'"':"";s.push('"),t.showAllControl&&s.push('');var l=t.srListLabelText,a=t.listClassName?" "+t.listClassName:"",h=l?' aria-label="'+l+'"':"";s.push('"),s.push(''+t.srAssistiveText+""),s.push(''),s.push("
    "),this.element.insertAdjacentHTML("afterend",s.join(""))},t.prototype.destroy=function(){var t=document.querySelector('[for="'+this.ids.INPUT+'"]');t&&t._ariaAutocompleteLabelOriginallyFor&&(t.setAttribute("for",t._ariaAutocompleteLabelOriginallyFor),delete t._ariaAutocompleteLabelOriginallyFor),this.documentClickBound&&document.removeEventListener("click",this.documentClick),this.autoGrow&&this.inputAutoWidth&&this.inputAutoWidth.destroy(),this.element.parentNode.removeChild(this.wrapper),delete this.element.ariaAutocomplete,this.show(this.element)},t.prototype.init=function(t,e){this.selected=[],this.element=t,this.ids=new E(t.id),this.elementIsInput="INPUT"===t.nodeName,this.elementIsSelect="SELECT"===t.nodeName,this.options=new h(e),this.source=this.options.source,this.multiple=this.options.multiple,this.autoGrow=this.options.autoGrow,this.cssNameSpace=this.options.cssNameSpace,this.documentClick=this.handleComponentBlur.bind(this),this.setHtml(),this.list=document.getElementById(this.ids.LIST),this.input=document.getElementById(this.ids.INPUT),this.wrapper=document.getElementById(this.ids.WRAPPER),this.showAll=document.getElementById(this.ids.BUTTON),this.srAnnouncements=document.getElementById(this.ids.SR_ANNOUNCEMENTS),this.prepListSource();var i=[];this.options.showAllControl&&i.push(this.cssNameSpace+"__wrapper--show-all"),this.autoGrow&&i.push(this.cssNameSpace+"__wrapper--autogrow"),this.multiple&&i.push(this.cssNameSpace+"__wrapper--multiple"),i.length&&a(this.wrapper,i.join(" ")),this.hide(this.list),this.hide(this.element),this.setInputStartingStates(),this.bindEvents(),this.api=new A(this),this.triggerOptionCallback("onReady",[this.wrapper])},t}();function D(t,e){return t&&t.ariaAutocomplete&&t.ariaAutocomplete.open?t.ariaAutocomplete:new M(t,e).api}i.d(e,"AriaAutocomplete",(function(){return D}));e.default=D}])})); \ No newline at end of file diff --git a/index.html b/index.html index fa59b76..31d86e9 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,8 @@ name="twitter:description" content="Accessible, extensible, plain JavaScript autocomplete with multi-select" /> - + +