UNPKG

@redocly/react-dropdown-aria

Version:

Simple and accessible React dropdown component

17 lines (14 loc) 13.7 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n,r,o=t(require("styled-components")),a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)}; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */(n=exports.StyleKeys||(exports.StyleKeys={})).Arrow="Arrow",n.DropdownSelector="DropdownSelector",n.DropdownWrapper="DropdownWrapper",n.SelectorSearch="SelectorSearch",n.SelectedValue="SelectedValue",n.Placeholder="Placeholder",n.GroupContainer="GroupContainer",n.GroupDivider="GroupDivider",n.GroupHeading="GroupHeading",n.OptionContainer="OptionContainer",n.OptionItem="OptionItem",function(e){e[e.DOWN_ARROW=40]="DOWN_ARROW",e[e.ENTER=13]="ENTER",e[e.ESCAPE=27]="ESCAPE",e[e.PAGE_DOWN=34]="PAGE_DOWN",e[e.PAGE_UP=33]="PAGE_UP",e[e.TAB=9]="TAB",e[e.UP_ARROW=38]="UP_ARROW",e[e.SPACE=32]="SPACE"}(r||(r={}));var l=[r.ESCAPE,r.UP_ARROW,r.DOWN_ARROW,r.PAGE_UP,r.PAGE_DOWN],i={base:"#808080",dark:"#7C7C7C",darker:"#6e6d6d",light:"#CECECE",lighter:"#e0e0e0",lightest:"#f5f5f5"},c={disabled:"#ededed",focused:"#0080bc"};function s(e){return void 0!==e.groupOptions}var u=function(e,t){return s(t)?e.concat(t.groupOptions):e.concat(t)},d=function(e,t){return a(a({},e),{groupOptions:e.groupOptions.filter((function(e){return e.value.toLowerCase().includes(t)}))})};function p(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return e.filter(Boolean).map((function(e){return"string"==typeof e?e:e?Object.keys(e).filter((function(t){return e[t]})).join(" "):""})).join(" ")}var f=o.default.div((function(e){var t=e.width,n=e.height,r=e.disabled,o=e.open,a=e.dropdownFocused;return{backgroundColor:r?i.light:i.lightest,border:"2px solid "+(o||a?c.focused:i.dark),borderRadius:"7",cursor:r?"not-allowed":"pointer",display:"flex",flexDirection:"column",fontSize:"1em",height:n,position:"relative",width:t,"&:hover":{border:"2px solid "+(o||a?c.focused:i.darker)},"&:disabled":{backgroundColor:c.disabled,cursor:"unset"}}})),m=o.default.div((function(e){var t=e.searchable;return{alignItems:"center",boxSizing:"border-box",cursor:e.open&&t?"text":"inherit",display:"flex",height:"32px",padding:"0 11px",position:"relative",width:"100%",input:{backgroundColor:"inherit",border:"none",fontSize:"inherit",height:"30px",outline:"none",width:"100%"}}})),h=o.default.span((function(){return{bottom:0,left:"11px",position:"absolute",right:"25px",top:0}})),g={bottom:0,left:"11px",lineHeight:"30px",overflow:"hidden",position:"absolute",right:"25px",textOverflow:"ellipsis",top:0,whiteSpace:"nowrap"},v=o.default.span((function(e){return a({textAlign:e.centerText?"center":"left",color:e.value&&!e.open?"black":i.base},g)})),b=o.default.span((function(e){var t=e.centerText;return a({color:i.base,textAlign:t?"center":"left"},g)})),x=o.default.div((function(){return{alignItems:"center",bottom:0,color:i.base,display:"flex",position:"absolute",right:"10px",top:0}})),w=o.default.span((function(e){var t=e.openUp,n=e.maxContentHeight,r=e.open;return{backgroundColor:"#ffffff",border:"2px solid "+i.darker,borderRadius:"4px",bottom:t?"105%":void 0,boxShadow:"0px "+(t?"-4px":"4px")+" 4px rgba(0, 0, 0, 0.25)",boxSizing:"border-box",color:"black",display:r?"block":"none",left:"0",listStyleType:"none",margin:"0",maxHeight:n||"175px",overflowX:"hidden",overflowY:"auto",padding:"2px 0",position:"absolute",top:t?void 0:"100%",width:"100%",zIndex:9999,".dropdown-selector-content--empty":{alignItems:"center",color:i.base,display:"flex",flexDirection:"column",justifyContent:"center",padding:"4px 0"},"&::-webkit-scrollbar":{width:"5px"},"&::-webkit-scrollbar-track":{background:"#ddd"},"&::-webkit-scrollbar-thumb":{background:"#666"}}})),E=o.default.div((function(){return{padding:"1em 0 0 0"}})),C=o.default.div((function(){return{color:"grey",display:"flex",flexDirection:"row",fontSize:"0.9em",padding:"0 10px 3px 5px"}})),k=o.default.div((function(){return{borderBottom:"1px solid "+i.dark,margin:"auto",paddingTop:10,width:"85%"}})),O=o.default.div((function(e){var t=e.selected,n=e.focused,r=i.lightest,o="inherit";return n&&t?(r=i.dark,o=i.lightest):n?r=i.lighter:t&&(r=i.light),{backgroundColor:r,border:"none",color:o,cursor:"pointer",fontSize:"0.95em",overflow:"hidden",padding:"5px 10px",textOverflow:"ellipsis",whiteSpace:"nowrap",width:"100%",display:"flex",alignItems:"center","&:hover":{backgroundColor:t?i.dark:i.light,color:t?i.lightest:void 0},".option-icon":{paddingRight:"5px"}}})),y=e.memo((function(t){var n=t.onOptionClicked,r=t.option,o=t.optionClass,a=t.itemRenderer,l=t.index,i=t.selected,c=t.focused,s=e.useCallback((function(e){e.stopPropagation(),n(r,!0)}),[n,r]),u=e.createElement(e.Fragment,null,r.iconClass&&e.createElement("i",{className:r.iconClass+" dropdown-option-icon"}),r.value);return a&&(u=a(t,l)),e.createElement(O,{"aria-label":r.ariaLabel,"aria-selected":i,className:p("dropdown-option",o,{selected:i,focused:c}),onClick:s,title:r.title,selected:i,focused:c},u)})),N=function(t){var n=t.children,r=t.className,o=t.dim,a=void 0===o?24:o;return e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:a,height:a,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"feather "+r},n)},R=function(){return e.createElement(N,{className:"feather-inbox"},e.createElement("polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12"}),e.createElement("path",{d:"M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"}))},S=function(){return e.createElement(N,{className:"feather-chevron-down",dim:16},e.createElement("polyline",{points:"6 9 12 15 18 9"}))},T=function(){return e.createElement(N,{className:"feather-search",dim:16},e.createElement("circle",{cx:"11",cy:"11",r:"8"}),e.createElement("line",{x1:"21",y1:"21",x2:"16.65",y2:"16.65"}))};function A(t){var n=t.selectedOption,r=t.options,o=t.focusedIndex,a=t.onOptionClicked,l=t.optionItemRenderer;if(t.empty)return e.createElement("div",{className:"dropdown-selector-content--empty"},e.createElement(R,null),"No data");var i=l?function(e,t){return l(e,t)}:void 0,c=0,u=r.map((function(t){if(s(t)){var r=t.groupOptions,l=t.label,u=r.map((function(t){var r=t.value===n,l=c===o;return c+=1,e.createElement(y,{key:t.value,optionClass:t.className,onOptionClicked:a,option:t,itemRenderer:i,index:c-1,selected:r,focused:l})}));return u.length?e.createElement(E,{key:t.label},e.createElement(C,null,e.createElement("span",null,l.toUpperCase()," |  "),e.createElement("span",null,r.length)),u,e.createElement(k,null)):null}var d=t.value,p=t.className,f=c===o,m=d===n;return c+=1,e.createElement(y,{key:d,optionClass:p,onOptionClicked:a,option:t,itemRenderer:i,index:c-1,selected:m,focused:f})}));return e.createElement(e.Fragment,null,u)}var P={height:0,width:0,overflow:"hidden"},D=function(t,n,r){var o=t.map((function(t,o){return e.createElement("div",{role:"option",id:r+"_list_"+o,key:r+"_list_"+o,"aria-selected":o===n,"aria-label":t.value})}));return e.createElement("div",{role:"listbox",id:r+"_list",style:P},o)},_=function(t,n,r){var o=e.useState(""),a=o[0],l=o[1],i=e.useMemo((function(){return r&&a.trim()?function(e,t){for(var n=[],r=t.toLowerCase(),o=0,a=e;o<a.length;o++){var l=a[o];if(s(l)){var i=d(l,r);i.groupOptions.length>=0&&n.push(i)}else l.value.toLowerCase().includes(r)&&n.push(l)}return n}(n,a):n}),[n,a]),c=e.useCallback((function(e,n){void 0===n&&(n=!0),l(e),n&&t(0)}),[t,l]);return{searchTerm:a,setSearchTerm:c,filteredOptions:i}},W=function(t,n){var r=t.options,o=t.searchable,a=t.onChange,l=t.disabled,i=t.ariaDescribedBy,c=t.ariaLabel,s=t.ariaLabelledBy,d=t.value,p=t.defaultOpen,f=e.useState(0),m=f[0],h=f[1],g=e.useState(p),v=g[0],b=g[1],x=e.useRef(null),w=e.useRef(null),E=e.useRef(null),C=e.useState(!1),k=C[0],O=C[1],y=_(h,r,o),N=y.searchTerm,R=y.setSearchTerm,S=y.filteredOptions,T=e.useMemo((function(){return S.reduce(u,[])}),[S]),A=e.useMemo((function(){return T.map((function(e){return e.value})).indexOf(d)}),[T,d]),P=e.useCallback((function(e){void 0===e&&(e=!1),R("",!1),b(!1),e&&w.current&&w.current.focus()}),[w.current,R,b]),W=e.useCallback((function(){h(A>0?A:0),b(!0)}),[b,h,A]),I=e.useCallback((function(e,t){void 0===t&&(t=!1),e&&(a(e),R("",!1)),t&&P(!0)}),[a,P,R]);!function(t,n){var r=function(e){n.current&&!n.current.contains(e.target)&&t()};e.useEffect((function(){return document.addEventListener("mouseup",r,!1),document.addEventListener("touchend",r,!1),function(){document.removeEventListener("mouseup",r),document.removeEventListener("touchend",r)}}),[])}(P,x),function(t,n){e.useEffect((function(){if(n.current&&t>=0){var e=n.current.getElementsByClassName("dropdown-option"),r=e&&e.length?e[t]:null;if(r&&r.getBoundingClientRect){var o=r.getBoundingClientRect().height,a=n.current.getBoundingClientRect().height,l=n.current.scrollTop,i=r.offsetTop<=l;r.offsetTop>=l&&r.offsetTop+o<=l+a||(i?n.current.scrollTo({top:r.offsetTop}):n.current.scrollTo({top:r.offsetTop-a+o+8}))}}}),[t])}(m,E);var L=e.useMemo((function(){return{"aria-hidden":l,"aria-expanded":v,"aria-haspopup":"listbox","aria-activedescendant":n+"_list_"+m,"aria-controls":n+"_list","aria-label":c,"aria-labelledby":s,"aria-describedby":i}}),[l,v,n,m,c,s,i]);return{focusedIndex:m,setFocusedIndex:h,open:v,setOpen:b,searchTerm:N,setSearchTerm:R,dropdownFocused:k,setDropdownFocused:O,setValue:I,filteredOptions:S,openDropdown:W,closeDropdown:P,flattenedOptions:T,container:x,inputRef:w,listWrapper:E,ariaProps:L,ariaList:D(T,A,n)}},I=0,L=function(t){var n,o=t.arrowRenderer,i=t.contentClassName,c=t.className,s=t.disabled,u=t.hideArrow,d=t.id,g=t.optionItemRenderer,E=t.pageKeyTraverseSize,C=t.placeholder,k=t.searchable,O=t.value,y=t.selectedValueClassName,N=(n=d,e.useMemo((function(){return n||("test"!==process.env.NODE_ENV?(e=I,I+=1):e="test","react_dropdown_aria_"+e);var e}),[n])),R=W(t,N),P=R.open,D=R.dropdownFocused,_=R.focusedIndex,L=R.setFocusedIndex,B=R.setDropdownFocused,G=R.setValue,U=R.openDropdown,F=R.closeDropdown,z=R.searchTerm,j=R.setSearchTerm,H=R.filteredOptions,M=R.flattenedOptions,V=R.container,K=R.inputRef,q=R.listWrapper,X=R.ariaProps,Y=R.ariaList,J=e.useCallback((function(){K.current&&K.current.focus()}),[K.current]),Q=e.useCallback((function(){J(),s||P&&k||(P?F(!0):U())}),[P,s,k,F,U]),Z=e.useCallback((function(e){switch(e){case r.UP_ARROW:L((function(e){return 0===e?M.length-1:e-1}));break;case r.DOWN_ARROW:L((function(e){return(e+1)%M.length}));break;case r.PAGE_UP:L((function(e){return e-E<0&&0!==e?0:e-E<0?M.length-1:e-E}));break;case r.PAGE_DOWN:L((function(e){return e===M.length-1?0:e+E>M.length-1?M.length-1:(e+E)%M.length}));break;case r.ESCAPE:F(!0)}}),[L,M,E,F]),$=e.useCallback((function(e){var t=e.keyCode;-1!==l.indexOf(t)?(e.preventDefault(),e.stopPropagation(),Z(t)):t!==r.ENTER&&(t!==r.SPACE||k)||P?t!==r.TAB||k?(t===r.TAB||t===r.ENTER)&&M.length>0&&_>=0&&P&&(e.stopPropagation(),e.preventDefault(),G(M[_],!0)):F():(e.preventDefault(),U())}),[M,G,_,P,Z,U,k,F]),ee=e.useCallback((function(e){j(e.target.value)}),[j]),te=e.useCallback((function(){return B(!0)}),[B]),ne=e.useCallback((function(){return B(!1)}),[B]),re=e.useMemo((function(){if(u)return null;if(o)return e.createElement(x,{className:"dropdown-arrow"},o(P));var t=P&&k;return e.createElement(x,{className:"dropdown-arrow"},t&&e.createElement(T,null),!t&&e.createElement(S,null))}),[P,o,k,u]);return e.createElement(f,{ref:V,onFocus:J,onClick:Q,role:"button",width:t.width,height:t.height,disabled:s,open:P,dropdownFocused:D,className:p("dropdown",c)},e.createElement(m,{className:"dropdown-selector",open:P,searchable:t.searchable},e.createElement(h,{className:"dropdown-selector-search"},e.createElement("input",a({id:N,ref:K,value:z,onChange:ee,onKeyDown:$,onFocus:te,onBlur:ne,readOnly:!P||!k,disabled:s,autoComplete:"off",role:"combobox"},X))),!O&&!z&&e.createElement(b,{className:"dropdown-selector-placeholder",centerText:t.centerText},C),O&&!z&&e.createElement(v,{className:p("dropdown-selector-value",y),centerText:t.centerText,value:O,open:P},O),re),Y,e.createElement(w,{maxContentHeight:t.maxContentHeight,openUp:t.openUp,open:P,className:p("dropdown-selector-content",i),ref:q},e.createElement(A,{selectedOption:O,options:H,focusedIndex:_,onOptionClicked:G,optionItemRenderer:g,empty:0===M.length})))};L.defaultProps={ariaDescribedBy:null,ariaLabel:null,ariaLabelledBy:null,arrowRenderer:void 0,centerText:!1,className:void 0,contentClassName:null,defaultOpen:!1,disabled:!1,height:null,hideArrow:!1,id:null,maxContentHeight:150,openUp:!1,optionItemRenderer:void 0,pageKeyTraverseSize:10,placeholder:"Select ...",searchable:!1,selectedValueClassName:null,style:{},value:void 0,width:null},exports.default=L; //# sourceMappingURL=index.js.map