-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathInputGroup.jsx
109 lines (102 loc) · 3.15 KB
/
InputGroup.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
* TEAM: frontend_infra
* WATCHERS: uforic
* @flow strict
*/
/* eslint-disable react/prefer-stateless-function */
import {StyleSheet, css} from "aphrodite";
import * as React from "react";
import InputGroupContext, {
CENTER_INPUT,
LEFT_INPUT,
RIGHT_INPUT,
} from "./context/InputGroupContext";
import invariant from "./tools/invariant";
type CustomWidthSetting = {|
flex?: number,
width?: number,
minWidth?: number,
maxWidth?: number,
|};
export type InputGroupProps = {|
+customWidthSettings?: $ReadOnlyArray<CustomWidthSetting>,
+children: React.Node,
|};
/**
* @category Layout
* @short Groups supported inputs into a continuous section
* @brandStatus V2
* @status Stable
* You may want to use TextInput with InputError or TextInputPrefixSuffix, decorators that
* modify the look and feel of TextInput. If you need a multiline input, think about using
* TextareaInput.
* @extends React.Component */
class InputGroup extends React.PureComponent<InputGroupProps> {
render() {
const {children, customWidthSettings: _customWidthSettings} = this.props;
const customWidthSettings = _customWidthSettings;
if (customWidthSettings) {
invariant(
customWidthSettings.length === React.Children.count(children),
"If you are using custom width settings, you need to pass in custom widths for every input element"
);
}
const childComponents = React.Children.map(children, child => child);
const leftComponent = (
<InputGroupContext.Provider key={0} value={LEFT_INPUT}>
<span
className={css(styles.thang)}
style={{
...(customWidthSettings && customWidthSettings[0]),
}}
>
{childComponents[0]}
</span>
</InputGroupContext.Provider>
);
const centerElements = (
<InputGroupContext.Provider key={1} value={CENTER_INPUT}>
{childComponents.slice(1, -1).map((childComponent, idx) => (
<span
// eslint-disable-next-line react/no-array-index-key
key={idx}
className={css(styles.thang)}
style={{
...(customWidthSettings && customWidthSettings[idx + 1]),
marginLeft: `${-1 * (idx + 2)}px`,
}}
>
{childComponent}
</span>
))}
</InputGroupContext.Provider>
);
const rightComponent = (
<InputGroupContext.Provider key={2} value={RIGHT_INPUT}>
<span
className={css(styles.thang)}
style={{
...(customWidthSettings &&
customWidthSettings[childComponents.length - 1]),
marginLeft: `${-1 * childComponents.length}px`,
}}
>
{childComponents[childComponents.length - 1]}
</span>
</InputGroupContext.Provider>
);
const providerChildren = [leftComponent, centerElements, rightComponent];
return <div className={css(styles.innerBorder)}>{providerChildren}</div>;
}
}
const styles = StyleSheet.create({
innerBorder: {
display: "flex",
flexDirection: "row",
},
thang: {
":focus-within": {zIndex: 2},
":hover": {zIndex: 1},
},
});
export default InputGroup;