33 * and hosts it in the component. When the component is selected, it
44 * drops-down the contentComponent and applies the contentProps.
55 */
6- import { css } from "goober" ;
76import React , { useEffect , useRef , useState } from "react" ;
87
98import { useDidUpdateEffect } from "../hooks/use-did-update-effect" ;
9+ import { useKey } from "../hooks/use-key" ;
1010import { useMultiSelect } from "../hooks/use-multi-select" ;
11- import { cn } from "../lib/classnames " ;
11+ import { KEY } from "../lib/constants " ;
1212import SelectPanel from "../select-panel" ;
1313import { Cross } from "../select-panel/cross" ;
1414import { Arrow } from "./arrow" ;
1515import { DropdownHeader } from "./header" ;
1616import { Loading } from "./loading" ;
1717
18- const PanelContainer = css ( {
19- position : "absolute" ,
20- zIndex : 1 ,
21- top : "100%" ,
22- width : "100%" ,
23- paddingTop : "8px" ,
24- ".panel-content" : {
25- maxHeight : "300px" ,
26- overflowY : "auto" ,
27- borderRadius : "var(--rmsc-radius)" ,
28- background : "var(--rmsc-bg)" ,
29- boxShadow : "0 0 0 1px rgba(0, 0, 0, 0.1), 0 4px 11px rgba(0, 0, 0, 0.1)" ,
30- } ,
31- } ) ;
32-
33- const DropdownContainer = css ( {
34- position : "relative" ,
35- outline : 0 ,
36- backgroundColor : "var(--rmsc-bg)" ,
37- border : "1px solid var(--rmsc-border)" ,
38- borderRadius : "var(--rmsc-radius)" ,
39- "&:focus-within" : {
40- boxShadow : "var(--rmsc-main) 0 0 0 1px" ,
41- borderColor : "var(--rmsc-main)" ,
42- } ,
43- } ) ;
44-
45- const DropdownHeading = css ( {
46- position : "relative" ,
47- padding : "0 var(--rmsc-p)" ,
48- display : "flex" ,
49- alignItems : "center" ,
50- width : "100%" ,
51- height : "var(--rmsc-h)" ,
52- cursor : "default" ,
53- outline : 0 ,
54- ".dropdown-heading-value" : {
55- overflow : "hidden" ,
56- textOverflow : "ellipsis" ,
57- whiteSpace : "nowrap" ,
58- flex : 1 ,
59- } ,
60- } ) ;
61-
62- const ClearSelectedButton = css ( {
63- cursor : "pointer" ,
64- background : "none" ,
65- border : 0 ,
66- padding : 0 ,
67- display : "flex" ,
68- } ) ;
69-
7018const Dropdown = ( ) => {
7119 const {
7220 t,
@@ -103,24 +51,20 @@ const Dropdown = () => {
10351
10452 const handleKeyDown = ( e ) => {
10553 if ( isInternalExpand ) {
106- switch ( e . which ) {
107- case 27 : // Escape
108- case 38 : // Up Arrow
109- setExpanded ( false ) ;
110- wrapper ?. current ?. focus ( ) ;
111- break ;
112- case 32 : // Space
113- case 13 : // Enter Key
114- case 40 : // Down Arrow
115- setExpanded ( true ) ;
116- break ;
117- default :
118- return ;
54+ if ( e . code === KEY . ESCAPE ) {
55+ setExpanded ( false ) ;
56+ wrapper ?. current ?. focus ( ) ;
57+ } else {
58+ setExpanded ( true ) ;
11959 }
12060 }
12161 e . preventDefault ( ) ;
12262 } ;
12363
64+ useKey ( [ KEY . ENTER , KEY . ARROW_DOWN , KEY . SPACE , KEY . ESCAPE ] , handleKeyDown , {
65+ target : wrapper ,
66+ } ) ;
67+
12468 const handleHover = ( iexpanded : boolean ) => {
12569 isInternalExpand && shouldToggleOnHover && setExpanded ( iexpanded ) ;
12670 } ;
@@ -151,30 +95,26 @@ const Dropdown = () => {
15195 return (
15296 < div
15397 tabIndex = { 0 }
154- className = { cn ( DropdownContainer , "dropdown-container" ) }
98+ className = "dropdown-container"
15599 aria-labelledby = { labelledBy }
156100 aria-expanded = { expanded }
157101 aria-readonly = { true }
158102 aria-disabled = { disabled }
159103 ref = { wrapper }
160- onKeyDown = { handleKeyDown }
161104 onFocus = { handleFocus }
162105 onBlur = { handleBlur }
163106 onMouseEnter = { handleMouseEnter }
164107 onMouseLeave = { handleMouseLeave }
165108 >
166- < div
167- className = { cn ( DropdownHeading , "dropdown-heading" ) }
168- onClick = { toggleExpanded }
169- >
109+ < div className = "dropdown-heading" onClick = { toggleExpanded } >
170110 < div className = "dropdown-heading-value" >
171111 < DropdownHeader />
172112 </ div >
173113 { isLoading && < Loading /> }
174114 { value . length > 0 && (
175115 < button
176116 type = "button"
177- className = { cn ( ClearSelectedButton , "clear-selected-button" ) }
117+ className = "clear-selected-button"
178118 onClick = { handleClearSelected }
179119 disabled = { disabled }
180120 aria-label = { t ( "clearSelected" ) }
@@ -185,7 +125,7 @@ const Dropdown = () => {
185125 < FinalArrow expanded = { expanded } />
186126 </ div >
187127 { expanded && (
188- < div className = { cn ( PanelContainer , "dropdown-content" ) } >
128+ < div className = "dropdown-content" >
189129 < div className = "panel-content" >
190130 < SelectPanel />
191131 </ div >
0 commit comments