|
1 | | -import React from "react" |
| 1 | +import React, { useMemo } from "react" |
2 | 2 | import styled from "styled-components" |
3 | 3 | import ReactSelect, { components as defaultComponents } from "react-select" |
4 | | -import { capitalizeFirstLetter } from "src/utils" |
5 | 4 |
|
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 | | - } |
| 5 | +const withDataAttrs = Component => props => { |
| 6 | + const { "data-ga": dataGA, "data-testid": dataTestId } = props.selectProps |
19 | 7 |
|
20 | | -const makeDataAttrs = (ga, testId) => type => { |
21 | | - const dataAttrs = {} |
| 8 | + const ga = useMemo(() => { |
| 9 | + if (!dataGA) return dataGA |
22 | 10 |
|
23 | | - if (ga) { |
24 | | - const gaParts = ga.split("::") |
25 | | - gaParts[1] = `${gaParts[1]}-${type}` |
26 | | - dataAttrs.ga = gaParts.join("::") |
27 | | - } |
| 11 | + const gaParts = dataGA.split("::") |
| 12 | + if (!gaParts[1]) return dataGA |
28 | 13 |
|
29 | | - if (testId) { |
30 | | - dataAttrs.testId = `${testId}${capitalizeFirstLetter(type)}` |
31 | | - } |
| 14 | + gaParts[1] = `${gaParts[1]}-${Component.displayName}` |
| 15 | + return gaParts.join("::") |
| 16 | + }, [dataGA]) |
32 | 17 |
|
33 | | - return dataAttrs |
| 18 | + const testId = `${dataTestId || ""}${Component.displayName}` |
| 19 | + |
| 20 | + return <Component data-ga={ga} data-testid={testId} {...props} /> |
34 | 21 | } |
35 | 22 |
|
36 | | -const makeCustomComponents = (components, makeComponentDataAttrs) => ({ |
| 23 | +const customComponents = { |
37 | 24 | ...defaultComponents, |
38 | | - ClearIndicator: withDataAttrs( |
39 | | - defaultComponents.ClearIndicator, |
40 | | - makeComponentDataAttrs("clearIndicator") |
41 | | - ), |
42 | | - Control: withDataAttrs(defaultComponents.Control, makeComponentDataAttrs("clearIndicator")), |
43 | | - DropdownIndicator: withDataAttrs( |
44 | | - defaultComponents.DropdownIndicator, |
45 | | - makeComponentDataAttrs("dropdownIndicator") |
46 | | - ), |
47 | | - DownChevron: withDataAttrs(defaultComponents.DownChevron, makeComponentDataAttrs("downChevron")), |
48 | | - CrossIcon: withDataAttrs(defaultComponents.CrossIcon, makeComponentDataAttrs("crossIcon")), |
49 | | - Group: withDataAttrs(defaultComponents.Group, makeComponentDataAttrs("group")), |
50 | | - GroupHeading: withDataAttrs( |
51 | | - defaultComponents.GroupHeading, |
52 | | - makeComponentDataAttrs("groupHeading") |
53 | | - ), |
54 | | - IndicatorsContainer: withDataAttrs( |
55 | | - defaultComponents.IndicatorsContainer, |
56 | | - makeComponentDataAttrs("indicatorsContainer") |
57 | | - ), |
58 | | - IndicatorSeparator: withDataAttrs( |
59 | | - defaultComponents.IndicatorSeparator, |
60 | | - makeComponentDataAttrs("indicatorSeparator") |
61 | | - ), |
62 | | - Input: withDataAttrs(defaultComponents.Input, makeComponentDataAttrs("input"), false), |
63 | | - LoadingIndicator: withDataAttrs( |
64 | | - defaultComponents.LoadingIndicator, |
65 | | - makeComponentDataAttrs("loadingIndicator") |
66 | | - ), |
67 | | - Menu: withDataAttrs(defaultComponents.Menu, makeComponentDataAttrs("menu")), |
68 | | - MenuList: withDataAttrs(defaultComponents.MenuList, makeComponentDataAttrs("menuList")), |
69 | | - MenuPortal: withDataAttrs(defaultComponents.MenuPortal, makeComponentDataAttrs("menuPortal")), |
70 | | - LoadingMessage: withDataAttrs( |
71 | | - defaultComponents.LoadingMessage, |
72 | | - makeComponentDataAttrs("loadingMessage") |
73 | | - ), |
74 | | - NoOptionsMessage: withDataAttrs( |
75 | | - defaultComponents.NoOptionsMessage, |
76 | | - makeComponentDataAttrs("noOptionsMessage") |
77 | | - ), |
78 | | - MultiValue: withDataAttrs(defaultComponents.MultiValue, makeComponentDataAttrs("multiValue")), |
79 | | - MultiValueContainer: withDataAttrs( |
80 | | - defaultComponents.MultiValueContainer, |
81 | | - makeComponentDataAttrs("multiValueContainer") |
82 | | - ), |
83 | | - MultiValueLabel: withDataAttrs( |
84 | | - defaultComponents.MultiValueLabel, |
85 | | - makeComponentDataAttrs("multiValueLabel") |
86 | | - ), |
87 | | - MultiValueRemove: withDataAttrs( |
88 | | - defaultComponents.MultiValueRemove, |
89 | | - makeComponentDataAttrs("multiValueRemove") |
90 | | - ), |
91 | | - Option: withDataAttrs(defaultComponents.Option, makeComponentDataAttrs("option")), |
92 | | - Placeholder: withDataAttrs(defaultComponents.Placeholder, makeComponentDataAttrs("placeholder")), |
93 | | - SelectContainer: withDataAttrs( |
94 | | - defaultComponents.SelectContainer, |
95 | | - makeComponentDataAttrs("selectContainer") |
96 | | - ), |
97 | | - SingleValue: withDataAttrs(defaultComponents.SingleValue, makeComponentDataAttrs("singleValue")), |
98 | | - ValueContainer: withDataAttrs( |
99 | | - defaultComponents.ValueContainer, |
100 | | - makeComponentDataAttrs("valueContainer") |
101 | | - ), |
102 | | - ...components, |
103 | | -}) |
| 25 | + ClearIndicator: withDataAttrs(defaultComponents.ClearIndicator), |
| 26 | + Control: withDataAttrs(defaultComponents.Control), |
| 27 | + DropdownIndicator: withDataAttrs(defaultComponents.DropdownIndicator), |
| 28 | + DownChevron: withDataAttrs(defaultComponents.DownChevron), |
| 29 | + CrossIcon: withDataAttrs(defaultComponents.CrossIcon), |
| 30 | + Group: withDataAttrs(defaultComponents.Group), |
| 31 | + GroupHeading: withDataAttrs(defaultComponents.GroupHeading), |
| 32 | + IndicatorsContainer: withDataAttrs(defaultComponents.IndicatorsContainer), |
| 33 | + IndicatorSeparator: withDataAttrs(defaultComponents.IndicatorSeparator), |
| 34 | + Input: withDataAttrs(defaultComponents.Input), |
| 35 | + LoadingIndicator: withDataAttrs(defaultComponents.LoadingIndicator), |
| 36 | + Menu: withDataAttrs(defaultComponents.Menu), |
| 37 | + MenuList: withDataAttrs(defaultComponents.MenuList), |
| 38 | + MenuPortal: withDataAttrs(defaultComponents.MenuPortal), |
| 39 | + LoadingMessage: withDataAttrs(defaultComponents.LoadingMessage), |
| 40 | + NoOptionsMessage: withDataAttrs(defaultComponents.NoOptionsMessage), |
| 41 | + MultiValue: withDataAttrs(defaultComponents.MultiValue), |
| 42 | + MultiValueContainer: withDataAttrs(defaultComponents.MultiValueContainer), |
| 43 | + MultiValueLabel: withDataAttrs(defaultComponents.MultiValueLabel), |
| 44 | + MultiValueRemove: withDataAttrs(defaultComponents.MultiValueRemove), |
| 45 | + Option: withDataAttrs(defaultComponents.Option), |
| 46 | + Placeholder: withDataAttrs(defaultComponents.Placeholder), |
| 47 | + SelectContainer: withDataAttrs(defaultComponents.SelectContainer), |
| 48 | + SingleValue: withDataAttrs(defaultComponents.SingleValue), |
| 49 | + ValueContainer: withDataAttrs(defaultComponents.ValueContainer), |
| 50 | +} |
104 | 51 |
|
105 | 52 | const makeCustomTheme = theme => selectTheme => { |
106 | 53 | return { |
@@ -212,13 +159,11 @@ const makeCustomStyles = (theme, { size, ...providedStyles } = {}) => ({ |
212 | 159 | ...providedStyles, |
213 | 160 | }) |
214 | 161 |
|
215 | | -const Select = styled(ReactSelect).attrs( |
216 | | - ({ "data-ga": ga, "data-testid": testId, components, ...props }) => ({ |
217 | | - ...props, |
218 | | - components: makeCustomComponents(components, makeDataAttrs(ga, testId)), |
219 | | - theme: makeCustomTheme(props.theme), |
220 | | - styles: makeCustomStyles(props.theme, props.styles), |
221 | | - }) |
222 | | -)`` |
| 162 | +const Select = styled(ReactSelect).attrs(props => ({ |
| 163 | + ...props, |
| 164 | + components: { ...customComponents, ...props.components }, |
| 165 | + theme: makeCustomTheme(props.theme), |
| 166 | + styles: makeCustomStyles(props.theme, props.styles), |
| 167 | +}))`` |
223 | 168 |
|
224 | 169 | export default Select |
0 commit comments