downshift
Version:
A set of primitives to build simple, flexible, WAI-ARIA compliant React autocomplete components
3 lines (2 loc) • 16.6 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("react"),require("prop-types")):"function"==typeof define&&define.amd?define(["react","prop-types"],t):e.Downshift=t(e.React,e.PropTypes)}(this,function(e,t){"use strict";function n(e){var t=A[A.length-1]===e;A=t?[].concat(O(A),[e]):[e],i().innerHTML=""+A.filter(Boolean).map(o).join("")}function o(e,t){return'<div style="display:'+(t===A.length-1?"block":"none")+';">'+e+"</div>"}function i(){return D||((D=document.createElement("div")).setAttribute("id","a11y-status-message"),D.setAttribute("role","status"),D.setAttribute("aria-live","assertive"),D.setAttribute("aria-relevant","additions text"),Object.assign(D.style,{border:"0",clip:"rect(0 0 0 0)",height:"1px",margin:"-1px",overflow:"hidden",padding:"0",position:"absolute",width:"1px"}),document.body.appendChild(D),D)}function r(e){return"function"==typeof e?e:u}function u(){}function s(e,t,n){return null!==t&&t!==n.parentNode?e(t)?t:s(e,t.parentNode,n):null}function l(e,t){var n=H(e,t);if(null!==n){var o=getComputedStyle(n),i=n.getBoundingClientRect(),r=parseInt(o.borderTopWidth,10),u=parseInt(o.borderBottomWidth,10),s=i.top+r,l=e.getBoundingClientRect(),a=l.top+n.scrollTop-s;a<n.scrollTop?n.scrollTop=a:a+l.height+r+u>n.scrollTop+i.height&&(n.scrollTop=a+l.height-i.height+r+u)}}function a(e,t){var n=void 0;return function(){for(var o=arguments.length,i=Array(o),r=0;r<o;r++)i[r]=arguments[r];n&&clearTimeout(n),n=setTimeout(function(){n=null,e.apply(void 0,i)},t)}}function p(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];return function(e){for(var n=arguments.length,o=Array(n>1?n-1:0),i=1;i<n;i++)o[i-1]=arguments[i];return t.some(function(t){return t&&t.apply(void 0,[e].concat(o)),e.defaultPrevented})}}function d(e){return e+"-"+T++}function h(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.find(function(e){return void 0!==e})}function c(e){return e===e&&"number"==typeof e}function g(e,t){return!(e=Array.isArray(e)?e[0]:e)&&t?t:e}function f(e){return e.nodeName?"string"==typeof e.nodeName:"string"==typeof e.type}function m(e){return e.props||e.attributes}function y(e,t){throw new Error('The property "'+t+'" is required in "'+e+'"')}function I(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t={};return E.forEach(function(n){e.hasOwnProperty(n)&&(t[n]=e[n])}),t}function v(e,t){var n=t.refKey,o="ref"!==n,i=!f(e);if(i&&!o)throw new Error("downshift: You returned a non-DOM element. You must specify a refKey in getRootProps");if(!i&&o)throw new Error('downshift: You returned a DOM element. You should not specify a refKey in getRootProps. You specified "'+n+'"');if(!m(e).hasOwnProperty(n))throw new Error('downshift: You must apply the ref prop "'+n+'" from getRootProps onto your root element.');if(!m(e).hasOwnProperty("onClick"))throw new Error('downshift: You must apply the "onClick" prop from getRootProps onto your root element.')}var w="default"in e?e.default:e;t=t&&t.hasOwnProperty("default")?t.default:t;var _=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},b=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),S=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},C=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},k=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)},x=function(e,t){var n={};for(var o in e)t.indexOf(o)>=0||Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n},P=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},O=function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)},D="undefined"==typeof document?null:document.getElementById("a11y-status-message"),A=[],T=1,H=s.bind(null,function(e){return e.scrollHeight>e.clientHeight}),E=["highlightedIndex","inputValue","isOpen","selectedItem","type"],M=function(e){function t(){var e;_(this,t);for(var n=arguments.length,o=Array(n),i=0;i<n;i++)o[i]=arguments[i];var r=P(this,(e=t.__proto__||Object.getPrototypeOf(t)).call.apply(e,[this].concat(o)));R.call(r);var u=r.getState({highlightedIndex:r.props.defaultHighlightedIndex,isOpen:r.props.defaultIsOpen,inputValue:r.props.defaultInputValue,selectedItem:r.props.defaultSelectedItem});return u.selectedItem&&(u.inputValue=r.props.itemToString(u.selectedItem)),r.state=u,r}return k(t,e),b(t,[{key:"getState",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.state;return Object.keys(t).reduce(function(n,o){return n[o]=e.isControlledProp(o)?e.props[o]:t[o],n},{})}},{key:"isControlledProp",value:function(e){return void 0!==this.props[e]}},{key:"getItemCount",value:function(){return void 0===this.props.itemCount?this.items.length:this.props.itemCount}},{key:"internalSetState",value:function(e,n){var o=this,i=void 0,u={};return this.setState(function(n){n=o.getState(n);var r={},s={};return(e="function"==typeof e?e(n):e).hasOwnProperty("selectedItem")&&e.selectedItem!==n.selectedItem&&(i=e.selectedItem),e.type=e.type||t.stateChangeTypes.unknown,Object.keys(e).forEach(function(t){n[t]!==e[t]&&(u[t]=e[t]),"type"!==t&&(s[t]=e[t],o.isControlledProp(t)||(r[t]=e[t]))}),r},function(){r(n)(),Object.keys(u).length>1&&o.props.onStateChange(u,o.getStateAndHelpers()),void 0!==i&&o.props.onChange(i,o.getStateAndHelpers()),o.props.onUserAction(u,o.getStateAndHelpers())})}},{key:"getStateAndHelpers",value:function(){var e=this.getState(),t=e.highlightedIndex,n=e.inputValue,o=e.selectedItem,i=e.isOpen,r=this.props.itemToString,u=this.getRootProps,s=this.getButtonProps,l=this.getLabelProps,a=this.getInputProps,p=this.getItemProps,d=this.openMenu,h=this.closeMenu,c=this.toggleMenu,g=this.selectItem,f=this.selectItemAtIndex,m=this.selectHighlightedItem,y=this.setHighlightedIndex,I=this.clearSelection;return{getRootProps:u,getButtonProps:s,getLabelProps:l,getInputProps:a,getItemProps:p,reset:this.reset,openMenu:d,closeMenu:h,toggleMenu:c,selectItem:g,selectItemAtIndex:f,selectHighlightedItem:m,setHighlightedIndex:y,clearSelection:I,itemToString:r,highlightedIndex:t,inputValue:n,isOpen:i,selectedItem:o}}},{key:"getItemId",value:function(e){return this.id+"-item-"+e}},{key:"getItemIndexFromId",value:function(e){return e?Number(e.split(this.id+"-item-")[1]):null}},{key:"componentDidMount",value:function(){var e=this;this._isMounted=!0;var n=function(){e.isMouseDown=!0},o=function(n){e.isMouseDown=!1,n.target!==e._rootNode&&e._rootNode.contains(n.target)||!e.getState().isOpen||e.reset({type:t.stateChangeTypes.mouseUp})};window.addEventListener("mousedown",n),window.addEventListener("mouseup",o),this.cleanup=function(){e._isMounted=!1,window.removeEventListener("mousedown",n),window.removeEventListener("mouseup",o)}}},{key:"componentDidUpdate",value:function(e){this.isControlledProp("selectedItem")&&this.props.selectedItem!==e.selectedItem&&this.internalSetState({type:t.stateChangeTypes.controlledPropUpdatedSelectedItem,inputValue:this.props.itemToString(this.props.selectedItem)}),this.updateStatus()}},{key:"componentWillUnmount",value:function(){this.cleanup()}},{key:"render",value:function(){var e=g(this.props.children,u);this.items=[],this.getRootProps.called=!1,this.getRootProps.refKey=void 0,this.getLabelProps.called=!1,this.getInputProps.called=!1;var t=g(e(this.getStateAndHelpers()));if(!t)return null;if(this.getRootProps.called)return v(t,this.getRootProps),t;if(f(t))return w.cloneElement(t,this.getRootProps(m(t)));throw new Error("downshift: If you return a non-DOM element, you must use apply the getRootProps function")}}]),t}(e.Component);M.propTypes={children:t.func,defaultHighlightedIndex:t.number,defaultSelectedItem:t.any,defaultInputValue:t.string,defaultIsOpen:t.bool,getA11yStatusMessage:t.func,itemToString:t.func,onChange:t.func,onStateChange:t.func,onUserAction:t.func,onClick:t.func,itemCount:t.number,selectedItem:t.any,isOpen:t.bool,inputValue:t.string,highlightedIndex:t.number},M.defaultProps={defaultHighlightedIndex:null,defaultSelectedItem:null,defaultInputValue:"",defaultIsOpen:!1,getA11yStatusMessage:function(e){var t=e.isOpen,n=e.highlightedItem,o=e.selectedItem,i=e.resultCount,r=e.previousResultCount,u=e.itemToString;if(!t)return o?u(o):"";var s=i!==r;return i?!n||s?i+" "+(1===i?"result is":"results are")+" available, use up and down arrow keys to navigate.":u(n):"No results."},itemToString:function(e){return null==e?"":String(e)},onStateChange:function(){},onUserAction:function(){},onChange:function(){}},M.stateChangeTypes={unknown:"__autocomplete_unknown__",mouseUp:"__autocomplete_mouseup__",itemMouseEnter:"__autocomplete_item_mouseenter__",keyDownArrowUp:"__autocomplete_keydown_arrow_up__",keyDownArrowDown:"__autocomplete_keydown_arrow_down__",keyDownEscape:"__autocomplete_keydown_escape__",keyDownEnter:"__autocomplete_keydown_enter__",blurInput:"__autocomplete_blur_input__",changeInput:"__autocomplete_change_input__",keyDownSpaceButton:"__autocomplete_keydown_space_button__",clickButton:"__autocomplete_click_button__",controlledPropUpdatedSelectedItem:"__autocomplete_controlled_prop_updated_selected_item__"};var R=function(){var e=this;this.id=d("downshift"),this.root_handleClick=p(this.props.onClick,this.root_handleClick),this.input=null,this.items=[],this.previousResultCount=0,this.getItemNodeFromIndex=function(t){return document.getElementById(e.getItemId(t))},this.setHighlightedIndex=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:e.props.defaultHighlightedIndex,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};n=I(n),e.internalSetState(C({highlightedIndex:t},n),function(){l(e.getItemNodeFromIndex(e.getState().highlightedIndex),e._rootNode)})},this.openAndHighlightDefaultIndex=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e.setHighlightedIndex(void 0,C({isOpen:!0},t))},this.highlightDefaultIndex=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e.setHighlightedIndex(void 0,t)},this.moveHighlightedIndex=function(t,n){e.getState().isOpen?e.changeHighlightedIndex(t,n):e.openAndHighlightDefaultIndex(n)},this.changeHighlightedIndex=function(t,n){var o=e.getItemCount()-1;if(!(o<0)){var i=e.getState().highlightedIndex;null===i&&(i=t>0?-1:o+1);var r=i+t;r<0?r=o:r>o&&(r=0),e.setHighlightedIndex(r,n)}},this.clearSelection=function(t){e.internalSetState({selectedItem:null,inputValue:"",isOpen:!1},function(){var n=e._rootNode.querySelector("#"+e.inputId);n&&n.focus&&n.focus(),r(t)()})},this.selectItem=function(t,n,o){n=I(n),e.internalSetState(C({isOpen:!1,highlightedIndex:null,selectedItem:t,inputValue:e.props.itemToString(t)},n),r(o))},this.selectItemAtIndex=function(t,n,o){var i=e.items[t];i&&e.selectItem(i,n,o)},this.selectHighlightedItem=function(t,n){return e.selectItemAtIndex(e.getState().highlightedIndex,t,n)},this.rootRef=function(t){return e._rootNode=t},this.getRootProps=function(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},o=n.refKey,i=void 0===o?"ref":o,r=n.onClick,u=x(n,["refKey","onClick"]);return e.getRootProps.called=!0,e.getRootProps.refKey=i,C((t={},S(t,i,e.rootRef),S(t,"onClick",p(r,e.root_handleClick)),t),u)},this.root_handleClick=function(t){t.preventDefault();var n=s(function(t){return c(e.getItemIndexFromId(t.getAttribute("id")))},t.target,e._rootNode);n&&e.selectItemAtIndex(e.getItemIndexFromId(n.getAttribute("id")))},this.keyDownHandlers={ArrowDown:function(e){e.preventDefault();var t=e.shiftKey?5:1;this.moveHighlightedIndex(t,{type:M.stateChangeTypes.keyDownArrowDown})},ArrowUp:function(e){e.preventDefault();var t=e.shiftKey?-5:-1;this.moveHighlightedIndex(t,{type:M.stateChangeTypes.keyDownArrowUp})},Enter:function(e){this.getState().isOpen&&(e.preventDefault(),this.selectHighlightedItem({type:M.stateChangeTypes.keyDownEnter}))},Escape:function(e){e.preventDefault(),this.reset({type:M.stateChangeTypes.keyDownEscape})}},this.buttonKeyDownHandlers=C({},this.keyDownHandlers,{" ":function(e){e.preventDefault(),this.toggleMenu({type:M.stateChangeTypes.keyDownSpaceButton})}}),this.getButtonProps=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.onClick,o=t.onKeyDown,i=x(t,["onClick","onKeyDown"]),r=e.getState().isOpen;return C({role:"button","aria-label":r?"close menu":"open menu","aria-expanded":r,"aria-haspopup":!0,onClick:p(n,e.button_handleClick),onKeyDown:p(o,e.button_handleKeyDown)},i)},this.button_handleKeyDown=function(t){e.buttonKeyDownHandlers[t.key]&&e.buttonKeyDownHandlers[t.key].call(e,t)},this.button_handleClick=function(t){t.preventDefault(),e.toggleMenu({type:M.stateChangeTypes.clickButton})},this.getLabelProps=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(e.getLabelProps.called=!0,e.getInputProps.called&&t.htmlFor&&t.htmlFor!==e.inputId)throw new Error('downshift: You provided the htmlFor of "'+t.htmlFor+'" for your label, but the id of your input is "'+e.inputId+'". You must either remove the id from your input or set the htmlFor of the label equal to the input id.');return e.inputId=h(e.inputId,t.htmlFor,d("downshift-input")),C({},t,{htmlFor:e.inputId})},this.getInputProps=function(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},o=n.onKeyDown,i=n.onBlur,r=n.onChange,u=n.onInput,s=x(n,["onKeyDown","onBlur","onChange","onInput"]);if(e.getInputProps.called=!0,e.getLabelProps.called&&s.id&&s.id!==e.inputId)throw new Error('downshift: You provided the id of "'+s.id+'" for your input, but the htmlFor of your label is "'+e.inputId+'". You must either remove the id from your input or set the htmlFor of the label equal to the input id.');e.inputId=h(e.inputId,s.id,d("downshift-input"));var l=e.getState(),a=l.inputValue,c=l.isOpen,g=l.highlightedIndex;return C((t={role:"combobox","aria-autocomplete":"list","aria-expanded":c,"aria-activedescendant":"number"==typeof g&&g>=0?e.getItemId(g):null,autoComplete:"off",value:a},S(t,"onChange",p(r,u,e.input_handleChange)),S(t,"onKeyDown",p(o,e.input_handleKeyDown)),S(t,"onBlur",p(i,e.input_handleBlur)),t),s,{id:e.inputId})},this.input_handleKeyDown=function(t){t.key&&e.keyDownHandlers[t.key]&&e.keyDownHandlers[t.key].call(e,t)},this.input_handleChange=function(t){e.internalSetState({type:M.stateChangeTypes.changeInput,isOpen:!0,inputValue:t.target.value})},this.input_handleBlur=function(){e.isMouseDown||e.reset({type:M.stateChangeTypes.blurInput})},this.getItemProps=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.onMouseEnter,o=t.index,i=t.item,r=void 0===i?y("getItemProps","item"):i,u=x(t,["onMouseEnter","index","item"]);return void 0===o?(e.items.push(r),o=e.items.indexOf(r)):e.items[o]=r,C({id:e.getItemId(o),onMouseEnter:p(n,function(){e.setHighlightedIndex(o,{type:M.stateChangeTypes.itemMouseEnter})})},u)},this.reset=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=arguments[1];t=I(t),e.internalSetState(function(n){var o=n.selectedItem;return C({isOpen:!1,highlightedIndex:null,inputValue:e.props.itemToString(o)},t)},r(n))},this.toggleMenu=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=arguments[1];t=I(t),e.internalSetState(function(e){var n=e.isOpen;return C({isOpen:!n},t)},function(){e.getState().isOpen&&e.highlightDefaultIndex(),r(n)()})},this.openMenu=function(t){e.internalSetState({isOpen:!0},r(t))},this.closeMenu=function(t){e.internalSetState({isOpen:!1},r(t))},this.updateStatus=a(function(){if(e._isMounted){var t=e.getState(),o=e.items[t.highlightedIndex]||{},i=e.getItemCount(),r=e.props.getA11yStatusMessage(C({itemToString:e.props.itemToString,previousResultCount:e.previousResultCount,resultCount:i,highlightedItem:o},t));e.previousResultCount=i,n(r)}},200)};return M.default=M,M});
//# sourceMappingURL=downshift.umd.min.js.map