@redocly/react-dropdown-aria
Version:
Simple and accessible React dropdown component
17 lines (14 loc) • 12.8 kB
JavaScript
import{memo as e,useCallback as n,createElement as o,Fragment as t,useState as r,useRef as i,useMemo as a,useEffect as l}from"react";import d from"styled-components";
/*! *****************************************************************************
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.
***************************************************************************** */var c,s,u=function(){return(u=Object.assign||function(e){for(var n,o=1,t=arguments.length;o<t;o++)for(var r in n=arguments[o])Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r]);return e}).apply(this,arguments)};!function(e){e.Arrow="Arrow",e.DropdownSelector="DropdownSelector",e.DropdownWrapper="DropdownWrapper",e.SelectorSearch="SelectorSearch",e.SelectedValue="SelectedValue",e.Placeholder="Placeholder",e.GroupContainer="GroupContainer",e.GroupDivider="GroupDivider",e.GroupHeading="GroupHeading",e.OptionContainer="OptionContainer",e.OptionItem="OptionItem"}(c||(c={})),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"}(s||(s={}));var p=[s.ESCAPE,s.UP_ARROW,s.DOWN_ARROW,s.PAGE_UP,s.PAGE_DOWN],f={base:"#808080",dark:"#7C7C7C",darker:"#6e6d6d",light:"#CECECE",lighter:"#e0e0e0",lightest:"#f5f5f5"},h={disabled:"#ededed",focused:"#0080bc"};function g(e){return void 0!==e.groupOptions}var v=function(e,n){return g(n)?e.concat(n.groupOptions):e.concat(n)},m=function(e,n){return u(u({},e),{groupOptions:e.groupOptions.filter((function(e){return e.value.toLowerCase().includes(n)}))})};function b(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return e.filter(Boolean).map((function(e){return"string"==typeof e?e:e?Object.keys(e).filter((function(n){return e[n]})).join(" "):""})).join(" ")}var x=d.div((function(e){var n=e.width,o=e.height,t=e.disabled,r=e.open,i=e.dropdownFocused;return{backgroundColor:t?f.light:f.lightest,border:"2px solid "+(r||i?h.focused:f.dark),borderRadius:"7",cursor:t?"not-allowed":"pointer",display:"flex",flexDirection:"column",fontSize:"1em",height:o,position:"relative",width:n,"&:hover":{border:"2px solid "+(r||i?h.focused:f.darker)},"&:disabled":{backgroundColor:h.disabled,cursor:"unset"}}})),w=d.div((function(e){var n=e.searchable;return{alignItems:"center",boxSizing:"border-box",cursor:e.open&&n?"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%"}}})),C=d.span((function(){return{bottom:0,left:"11px",position:"absolute",right:"25px",top:0}})),O={bottom:0,left:"11px",lineHeight:"30px",overflow:"hidden",position:"absolute",right:"25px",textOverflow:"ellipsis",top:0,whiteSpace:"nowrap"},k=d.span((function(e){return u({textAlign:e.centerText?"center":"left",color:e.value&&!e.open?"black":f.base},O)})),y=d.span((function(e){var n=e.centerText;return u({color:f.base,textAlign:n?"center":"left"},O)})),N=d.div((function(){return{alignItems:"center",bottom:0,color:f.base,display:"flex",position:"absolute",right:"10px",top:0}})),E=d.span((function(e){var n=e.openUp,o=e.maxContentHeight,t=e.open;return{backgroundColor:"#ffffff",border:"2px solid "+f.darker,borderRadius:"4px",bottom:n?"105%":void 0,boxShadow:"0px "+(n?"-4px":"4px")+" 4px rgba(0, 0, 0, 0.25)",boxSizing:"border-box",color:"black",display:t?"block":"none",left:"0",listStyleType:"none",margin:"0",maxHeight:o||"175px",overflowX:"hidden",overflowY:"auto",padding:"2px 0",position:"absolute",top:n?void 0:"100%",width:"100%",zIndex:9999,".dropdown-selector-content--empty":{alignItems:"center",color:f.base,display:"flex",flexDirection:"column",justifyContent:"center",padding:"4px 0"},"&::-webkit-scrollbar":{width:"5px"},"&::-webkit-scrollbar-track":{background:"#ddd"},"&::-webkit-scrollbar-thumb":{background:"#666"}}})),R=d.div((function(){return{padding:"1em 0 0 0"}})),T=d.div((function(){return{color:"grey",display:"flex",flexDirection:"row",fontSize:"0.9em",padding:"0 10px 3px 5px"}})),A=d.div((function(){return{borderBottom:"1px solid "+f.dark,margin:"auto",paddingTop:10,width:"85%"}})),P=d.div((function(e){var n=e.selected,o=e.focused,t=f.lightest,r="inherit";return o&&n?(t=f.dark,r=f.lightest):o?t=f.lighter:n&&(t=f.light),{backgroundColor:t,border:"none",color:r,cursor:"pointer",fontSize:"0.95em",overflow:"hidden",padding:"5px 10px",textOverflow:"ellipsis",whiteSpace:"nowrap",width:"100%",display:"flex",alignItems:"center","&:hover":{backgroundColor:n?f.dark:f.light,color:n?f.lightest:void 0},".option-icon":{paddingRight:"5px"}}})),S=e((function(e){var r=e.onOptionClicked,i=e.option,a=e.optionClass,l=e.itemRenderer,d=e.index,c=e.selected,s=e.focused,u=n((function(e){e.stopPropagation(),r(i,!0)}),[r,i]),p=o(t,null,i.iconClass&&o("i",{className:i.iconClass+" dropdown-option-icon"}),i.value);return l&&(p=l(e,d)),o(P,{"aria-label":i.ariaLabel,"aria-selected":c,className:b("dropdown-option",a,{selected:c,focused:s}),onClick:u,title:i.title,selected:c,focused:s},p)})),D=function(e){var n=e.children,t=e.className,r=e.dim,i=void 0===r?24:r;return o("svg",{xmlns:"http://www.w3.org/2000/svg",width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"feather "+t},n)},_=function(){return o(D,{className:"feather-inbox"},o("polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12"}),o("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"}))},W=function(){return o(D,{className:"feather-chevron-down",dim:16},o("polyline",{points:"6 9 12 15 18 9"}))},I=function(){return o(D,{className:"feather-search",dim:16},o("circle",{cx:"11",cy:"11",r:"8"}),o("line",{x1:"21",y1:"21",x2:"16.65",y2:"16.65"}))};function L(e){var n=e.selectedOption,r=e.options,i=e.focusedIndex,a=e.onOptionClicked,l=e.optionItemRenderer;if(e.empty)return o("div",{className:"dropdown-selector-content--empty"},o(_,null),"No data");var d=l?function(e,n){return l(e,n)}:void 0,c=0,s=r.map((function(e){if(g(e)){var t=e.groupOptions,r=e.label,l=t.map((function(e){var t=e.value===n,r=c===i;return c+=1,o(S,{key:e.value,optionClass:e.className,onOptionClicked:a,option:e,itemRenderer:d,index:c-1,selected:t,focused:r})}));return l.length?o(R,{key:e.label},o(T,null,o("span",null,r.toUpperCase()," | "),o("span",null,t.length)),l,o(A,null)):null}var s=e.value,u=e.className,p=c===i;return o(S,{key:s,optionClass:u,onOptionClicked:a,option:e,itemRenderer:d,index:(c+=1)-1,selected:s===n,focused:p})}));return o(t,null,s)}var B={height:0,width:0,overflow:"hidden"},G=function(e,n,t){var r=e.map((function(e,r){return o("div",{role:"option",id:t+"_list_"+r,key:t+"_list_"+r,"aria-selected":r===n,"aria-label":e.value})}));return o("div",{role:"listbox",id:t+"_list",style:B},r)},U=function(e,o,t){var i=r(""),l=i[0],d=i[1],c=a((function(){return t&&l.trim()?function(e,n){for(var o=[],t=n.toLowerCase(),r=0,i=e;r<i.length;r++){var a=i[r];if(g(a)){var l=m(a,t);l.groupOptions.length>=0&&o.push(l)}else a.value.toLowerCase().includes(t)&&o.push(a)}return o}(o,l):o}),[o,l]),s=n((function(n,o){void 0===o&&(o=!0),d(n),o&&e(0)}),[e,d]);return{searchTerm:l,setSearchTerm:s,filteredOptions:c}},z=function(e,o){var t=e.options,d=e.searchable,c=e.onChange,s=e.disabled,u=e.ariaDescribedBy,p=e.ariaLabel,f=e.ariaLabelledBy,h=e.value,g=e.defaultOpen,m=r(0),b=m[0],x=m[1],w=r(g),C=w[0],O=w[1],k=i(null),y=i(null),N=i(null),E=r(!1),R=E[0],T=E[1],A=U(x,t,d),P=A.searchTerm,S=A.setSearchTerm,D=A.filteredOptions,_=a((function(){return D.reduce(v,[])}),[D]),W=a((function(){return _.map((function(e){return e.value})).indexOf(h)}),[_,h]),I=n((function(e){void 0===e&&(e=!1),S("",!1),O(!1),e&&y.current&&y.current.focus()}),[y.current,S,O]),L=n((function(){x(W>0?W:0),O(!0)}),[O,x,W]),B=n((function(e,n){void 0===n&&(n=!1),e&&(c(e),S("",!1)),n&&I(!0)}),[c,I,S]);!function(e,n){var o=function(o){n.current&&!n.current.contains(o.target)&&e()};l((function(){return document.addEventListener("mouseup",o,!1),document.addEventListener("touchend",o,!1),function(){document.removeEventListener("mouseup",o),document.removeEventListener("touchend",o)}}),[])}(I,k),function(e,n){l((function(){if(n.current&&e>=0){var o=n.current.getElementsByClassName("dropdown-option"),t=o&&o.length?o[e]:null;if(t&&t.getBoundingClientRect){var r=t.getBoundingClientRect().height,i=n.current.getBoundingClientRect().height,a=n.current.scrollTop,l=t.offsetTop<=a;t.offsetTop>=a&&t.offsetTop+r<=a+i||(l?n.current.scrollTo({top:t.offsetTop}):n.current.scrollTo({top:t.offsetTop-i+r+8}))}}}),[e])}(b,N);var z=a((function(){return{"aria-hidden":s,"aria-expanded":C,"aria-haspopup":"listbox","aria-activedescendant":o+"_list_"+b,"aria-controls":o+"_list","aria-label":p,"aria-labelledby":f,"aria-describedby":u}}),[s,C,o,b,p,f,u]);return{focusedIndex:b,setFocusedIndex:x,open:C,setOpen:O,searchTerm:P,setSearchTerm:S,dropdownFocused:R,setDropdownFocused:T,setValue:B,filteredOptions:D,openDropdown:L,closeDropdown:I,flattenedOptions:_,container:k,inputRef:y,listWrapper:N,ariaProps:z,ariaList:G(_,W,o)}},F=0,H=function(e){var t,r=e.arrowRenderer,i=e.contentClassName,l=e.className,d=e.disabled,c=e.hideArrow,f=e.id,h=e.optionItemRenderer,g=e.pageKeyTraverseSize,v=e.placeholder,m=e.searchable,O=e.value,R=e.selectedValueClassName,T=a((function(){return t||("test"!==process.env.NODE_ENV?(e=F,F+=1):e="test","react_dropdown_aria_"+e);var e}),[t=f]),A=z(e,T),P=A.open,S=A.dropdownFocused,D=A.focusedIndex,_=A.setFocusedIndex,B=A.setDropdownFocused,G=A.setValue,U=A.openDropdown,H=A.closeDropdown,j=A.searchTerm,V=A.setSearchTerm,K=A.filteredOptions,M=A.flattenedOptions,X=A.container,Y=A.inputRef,q=A.listWrapper,J=A.ariaProps,Q=A.ariaList,Z=n((function(){Y.current&&Y.current.focus()}),[Y.current]),$=n((function(){Z(),d||P&&m||(P?H(!0):U())}),[P,d,m,H,U]),ee=n((function(e){switch(e){case s.UP_ARROW:_((function(e){return 0===e?M.length-1:e-1}));break;case s.DOWN_ARROW:_((function(e){return(e+1)%M.length}));break;case s.PAGE_UP:_((function(e){return e-g<0&&0!==e?0:e-g<0?M.length-1:e-g}));break;case s.PAGE_DOWN:_((function(e){return e===M.length-1?0:e+g>M.length-1?M.length-1:(e+g)%M.length}));break;case s.ESCAPE:H(!0)}}),[_,M,g,H]),ne=n((function(e){var n=e.keyCode;-1!==p.indexOf(n)?(e.preventDefault(),e.stopPropagation(),ee(n)):n!==s.ENTER&&(n!==s.SPACE||m)||P?n!==s.TAB||m?(n===s.TAB||n===s.ENTER)&&M.length>0&&D>=0&&P&&(e.stopPropagation(),e.preventDefault(),G(M[D],!0)):H():(e.preventDefault(),U())}),[M,G,D,P,ee,U,m,H]),oe=n((function(e){V(e.target.value)}),[V]),te=n((function(){return B(!0)}),[B]),re=n((function(){return B(!1)}),[B]),ie=a((function(){if(c)return null;if(r)return o(N,{className:"dropdown-arrow"},r(P));var e=P&&m;return o(N,{className:"dropdown-arrow"},e&&o(I,null),!e&&o(W,null))}),[P,r,m,c]);return o(x,{ref:X,onFocus:Z,onClick:$,role:"button",width:e.width,height:e.height,disabled:d,open:P,dropdownFocused:S,className:b("dropdown",l)},o(w,{className:"dropdown-selector",open:P,searchable:e.searchable},o(C,{className:"dropdown-selector-search"},o("input",u({id:T,ref:Y,value:j,onChange:oe,onKeyDown:ne,onFocus:te,onBlur:re,readOnly:!P||!m,disabled:d,autoComplete:"off",role:"combobox"},J))),!O&&!j&&o(y,{className:"dropdown-selector-placeholder",centerText:e.centerText},v),O&&!j&&o(k,{className:b("dropdown-selector-value",R),centerText:e.centerText,value:O,open:P},O),ie),Q,o(E,{maxContentHeight:e.maxContentHeight,openUp:e.openUp,open:P,className:b("dropdown-selector-content",i),ref:q},o(L,{selectedOption:O,options:K,focusedIndex:D,onOptionClicked:G,optionItemRenderer:h,empty:0===M.length})))};H.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};export default H;export{c as StyleKeys};
//# sourceMappingURL=index.es.js.map