1- import ReactSelect from "react-select "
1+ import React from "react"
22import styled from "styled-components"
3+ import ReactSelect , { components } from "react-select"
4+ import { capitalizeFirstLetter } from "src/utils"
5+
6+ const withDataAttrs =
7+ ( Component , { ga, testId } , hasInnerProps = true ) =>
8+ ( { innerProps, ...rest } ) => {
9+ const dataProps = {
10+ ...( ga ? { "data-ga" : ga } : { } ) ,
11+ ...( testId ? { "data-testid" : testId } : { } ) ,
12+ }
13+ const props = {
14+ ...rest ,
15+ ...( hasInnerProps ? { innerProps : { ...innerProps , ...dataProps } } : { ...dataProps } ) ,
16+ }
17+ return < Component { ...props } />
18+ }
19+
20+ const makeDataAttrs = ( ga , testId ) => type => {
21+ const dataAttrs = { }
22+
23+ if ( ga ) {
24+ const gaParts = ga . split ( "::" )
25+ gaParts [ 1 ] = `${ gaParts [ 1 ] } -${ type } `
26+ dataAttrs . ga = gaParts . join ( "::" )
27+ }
28+
29+ if ( testId ) {
30+ dataAttrs . testId = `${ testId } ${ capitalizeFirstLetter ( type ) } `
31+ }
32+
33+ return dataAttrs
34+ }
35+
36+ const makeCustomComponents = makeComponentDataAttrs => ( {
37+ ClearIndicator : withDataAttrs (
38+ components . ClearIndicator ,
39+ makeComponentDataAttrs ( "clearIndicator" )
40+ ) ,
41+ Control : withDataAttrs ( components . Control , makeComponentDataAttrs ( "clearIndicator" ) ) ,
42+ DropdownIndicator : withDataAttrs (
43+ components . DropdownIndicator ,
44+ makeComponentDataAttrs ( "dropdownIndicator" )
45+ ) ,
46+ DownChevron : withDataAttrs ( components . DownChevron , makeComponentDataAttrs ( "downChevron" ) ) ,
47+ CrossIcon : withDataAttrs ( components . CrossIcon , makeComponentDataAttrs ( "crossIcon" ) ) ,
48+ Group : withDataAttrs ( components . Group , makeComponentDataAttrs ( "group" ) ) ,
49+ GroupHeading : withDataAttrs ( components . GroupHeading , makeComponentDataAttrs ( "groupHeading" ) ) ,
50+ IndicatorsContainer : withDataAttrs (
51+ components . IndicatorsContainer ,
52+ makeComponentDataAttrs ( "indicatorsContainer" )
53+ ) ,
54+ IndicatorSeparator : withDataAttrs (
55+ components . IndicatorSeparator ,
56+ makeComponentDataAttrs ( "indicatorSeparator" )
57+ ) ,
58+ Input : withDataAttrs ( components . Input , makeComponentDataAttrs ( "input" ) , false ) ,
59+ LoadingIndicator : withDataAttrs (
60+ components . LoadingIndicator ,
61+ makeComponentDataAttrs ( "loadingIndicator" )
62+ ) ,
63+ Menu : withDataAttrs ( components . Menu , makeComponentDataAttrs ( "menu" ) ) ,
64+ MenuList : withDataAttrs ( components . MenuList , makeComponentDataAttrs ( "menuList" ) ) ,
65+ MenuPortal : withDataAttrs ( components . MenuPortal , makeComponentDataAttrs ( "menuPortal" ) ) ,
66+ LoadingMessage : withDataAttrs (
67+ components . LoadingMessage ,
68+ makeComponentDataAttrs ( "loadingMessage" )
69+ ) ,
70+ NoOptionsMessage : withDataAttrs (
71+ components . NoOptionsMessage ,
72+ makeComponentDataAttrs ( "noOptionsMessage" )
73+ ) ,
74+ MultiValue : withDataAttrs ( components . MultiValue , makeComponentDataAttrs ( "multiValue" ) ) ,
75+ MultiValueContainer : withDataAttrs (
76+ components . MultiValueContainer ,
77+ makeComponentDataAttrs ( "multiValueContainer" )
78+ ) ,
79+ MultiValueLabel : withDataAttrs (
80+ components . MultiValueLabel ,
81+ makeComponentDataAttrs ( "multiValueLabel" )
82+ ) ,
83+ MultiValueRemove : withDataAttrs (
84+ components . MultiValueRemove ,
85+ makeComponentDataAttrs ( "multiValueRemove" )
86+ ) ,
87+ Option : withDataAttrs ( components . Option , makeComponentDataAttrs ( "option" ) ) ,
88+ Placeholder : withDataAttrs ( components . Placeholder , makeComponentDataAttrs ( "placeholder" ) ) ,
89+ SelectContainer : withDataAttrs (
90+ components . SelectContainer ,
91+ makeComponentDataAttrs ( "selectContainer" )
92+ ) ,
93+ SingleValue : withDataAttrs ( components . SingleValue , makeComponentDataAttrs ( "singleValue" ) ) ,
94+ ValueContainer : withDataAttrs (
95+ components . ValueContainer ,
96+ makeComponentDataAttrs ( "valueContainer" )
97+ ) ,
98+ } )
399
4100const makeCustomTheme = theme => selectTheme => {
5101 return {
@@ -41,26 +137,29 @@ const makeCustomStyles = (theme, { size, ...providedStyles } = {}) => ({
41137 borderColor : theme . colors . inputBorderHover ,
42138 } ,
43139 } ) ,
44- input : ( styles , state ) => ( {
140+ input : ( styles , state ) => ( {
45141 ...styles ,
46142 color : state . isDisabled ? theme . colors . placeholder : theme . colors . textDescription ,
47- ...( size === "tiny" ? {
48- lineHeight : "18px" ,
49- paddingBottom : 0 ,
50- paddingTop : 0
51- } : { } ) ,
143+ ...( size === "tiny"
144+ ? {
145+ lineHeight : "18px" ,
146+ paddingBottom : 0 ,
147+ paddingTop : 0 ,
148+ }
149+ : { } ) ,
52150 } ) ,
53151 menu : styles => ( { ...styles , zIndex : 100 } ) ,
54152 menuPortal : styles => ( { ...styles , zIndex : 9999 } ) ,
55- multiValue : ( styles ) => ( {
153+ multiValue : styles => ( {
56154 ...styles ,
57155 fontSize : size === "tiny" ? "12px" : "14px" ,
156+ flexDirection : "row-reverse" ,
58157 ...( size === "tiny" ? { minHeight : 18 } : { } ) ,
59158 } ) ,
60159 multiValueLabel : ( styles , state ) => ( {
61160 ...styles ,
62161 backgroundColor : theme . colors . disabled ,
63- borderRadius : "2px 0 0 2px" ,
162+ borderRadius : "0 2px 2px 0 " ,
64163 color : state . isDisabled ? theme . colors . placeholder : theme . colors . textDescription ,
65164 ...( size === "tiny" ? { padding : "1px" } : { } ) ,
66165 paddingRight : state . data . isDisabled ? "8px" : "" ,
@@ -70,13 +169,13 @@ const makeCustomStyles = (theme, { size, ...providedStyles } = {}) => ({
70169 ...( state . data . isDisabled
71170 ? { ...styles , display : "none" }
72171 : {
73- ...styles ,
74- borderRadius : "0 2px 2px 0 " ,
75- background : theme . colors . disabled ,
76- ":hover" : {
77- background : theme . colors . borderSecondary ,
78- } ,
79- } ) ,
172+ ...styles ,
173+ borderRadius : "2px 0 0 2px " ,
174+ background : theme . colors . disabled ,
175+ ":hover" : {
176+ background : theme . colors . tabsBorder ,
177+ } ,
178+ } ) ,
80179 } ) ,
81180 option : ( styles , state ) => ( {
82181 ...styles ,
@@ -86,33 +185,33 @@ const makeCustomStyles = (theme, { size, ...providedStyles } = {}) => ({
86185 placeholder : styles => ( {
87186 ...styles ,
88187 color : theme . colors . placeholder ,
89- ...( size === "tiny"
90- ? { fontSize : "12px" , lineHeight : "18px" }
91- : { } )
188+ ...( size === "tiny" ? { fontSize : "12px" , lineHeight : "18px" } : { } ) ,
92189 } ) ,
93190 singleValue : ( styles , state ) => ( {
94191 ...styles ,
95192 color : state . isDisabled ? theme . colors . placeholder : theme . colors . textDescription ,
96- fontSize : size === "tiny" ? "12px" : "14px"
193+ fontSize : size === "tiny" ? "12px" : "14px" ,
97194 } ) ,
98195 ...( size === "tiny"
99196 ? {
100- dropdownIndicator : styles => ( { ...styles , padding : "3px" } ) ,
101- clearIndicator : styles => ( { ...styles , padding : "3px" } ) ,
102- indicatorsContainer : styles => ( { ...styles , minHeight : 28 } ) ,
103- valueContainer : styles => ( {
104- ...styles ,
105- minHeight : 28 ,
106- padding : "1px 6px" ,
107- } ) ,
108- }
197+ dropdownIndicator : styles => ( { ...styles , padding : "3px" } ) ,
198+ clearIndicator : styles => ( { ...styles , padding : "3px" } ) ,
199+ indicatorsContainer : styles => ( { ...styles , minHeight : 28 } ) ,
200+ valueContainer : styles => ( {
201+ ...styles ,
202+ minHeight : 28 ,
203+ padding : "1px 6px" ,
204+ } ) ,
205+ }
109206 : { } ) ,
110207 ...providedStyles ,
111208} )
112209
113- // @TODO check react-select for rendering data attributes
114- export const Select = styled ( ReactSelect ) . attrs ( props => ( {
210+ const Select = styled ( ReactSelect ) . attrs ( ( { "data-ga" : ga , "data-testid" : testId , ...props } ) => ( {
115211 ...props ,
212+ components : makeCustomComponents ( makeDataAttrs ( ga , testId ) ) ,
116213 theme : makeCustomTheme ( props . theme ) ,
117214 styles : makeCustomStyles ( props . theme , props . styles ) ,
118215} ) ) ``
216+
217+ export default Select
0 commit comments