orc-shared 5.99.0-dev.5 → 5.99.0-dev.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Form/Inputs/MultiSelector.js +67 -12
- package/dist/components/Form/Inputs/Selector.js +13 -10
- package/dist/components/MaterialUI/Inputs/Select.js +170 -114
- package/dist/components/MaterialUI/Inputs/SelectProps.js +10 -2
- package/dist/hooks/useWindowSize.js +88 -0
- package/dist/sharedMessages.js +8 -0
- package/package.json +1 -1
- package/src/components/Form/Inputs/MultiSelector.js +55 -5
- package/src/components/Form/Inputs/MultiSelector.test.js +259 -39
- package/src/components/Form/Inputs/Selector.js +12 -4
- package/src/components/Form/Inputs/Selector.test.js +27 -12
- package/src/components/MaterialUI/Inputs/Select.js +140 -87
- package/src/components/MaterialUI/Inputs/Select.test.js +170 -30
- package/src/components/MaterialUI/Inputs/SelectProps.js +9 -1
- package/src/components/MaterialUI/Inputs/SelectProps.test.js +8 -0
- package/src/hooks/useMultipleFieldEditState.test.js +0 -1
- package/src/hooks/useWindowSize.js +39 -0
- package/src/hooks/useWindowSize.test.js +68 -0
- package/src/sharedMessages.js +8 -0
- package/src/translations/en-US.json +2 -0
- package/src/translations/fr-CA.json +2 -0
|
@@ -8,11 +8,13 @@ import TooltippedTypography from "./../DataDisplay/TooltippedElements/Tooltipped
|
|
|
8
8
|
import Icon from "./../DataDisplay/Icon";
|
|
9
9
|
import IconButton from "@material-ui/core/IconButton";
|
|
10
10
|
import { ListSubheader } from "@material-ui/core";
|
|
11
|
+
import FormControl from "@material-ui/core/FormControl";
|
|
12
|
+
import useWindowSize from "../../../hooks/useWindowSize";
|
|
11
13
|
|
|
12
14
|
const useStyles = makeStyles(theme => ({
|
|
13
|
-
baseItem: {
|
|
14
|
-
maxWidth: theme.spacing(35),
|
|
15
|
-
},
|
|
15
|
+
baseItem: props => ({
|
|
16
|
+
...(props.autoWidth ? { maxWidth: theme.spacing(35) } : { maxWidth: theme.spacing(props.multipleWidthSpacing) }),
|
|
17
|
+
}),
|
|
16
18
|
level0: {},
|
|
17
19
|
level1: {
|
|
18
20
|
paddingLeft: theme.spacing(theme.indent),
|
|
@@ -42,10 +44,8 @@ const useStyles = makeStyles(theme => ({
|
|
|
42
44
|
display: "flex",
|
|
43
45
|
flexDirection: "column",
|
|
44
46
|
},
|
|
45
|
-
selectPaper: {
|
|
47
|
+
selectPaper: props => ({
|
|
46
48
|
border: `1px solid ${theme.palette.grey.borders}`,
|
|
47
|
-
minWidth: `auto !important`,
|
|
48
|
-
width: `auto !important`,
|
|
49
49
|
"& ul": {
|
|
50
50
|
minWidth: theme.spacing(17.5),
|
|
51
51
|
maxHeight: theme.spacing(30),
|
|
@@ -62,16 +62,29 @@ const useStyles = makeStyles(theme => ({
|
|
|
62
62
|
borderRadius: 0,
|
|
63
63
|
whiteSpace: "normal",
|
|
64
64
|
"&:hover": {
|
|
65
|
-
backgroundColor: theme.palette.primary.
|
|
65
|
+
backgroundColor: theme.palette.primary.main,
|
|
66
|
+
"&:not(.Mui-selected) > p": {
|
|
67
|
+
color: `${theme.palette.primary.contrastText}`,
|
|
68
|
+
},
|
|
69
|
+
"&.Mui-selected": {
|
|
70
|
+
backgroundColor: theme.palette.secondary.light,
|
|
71
|
+
},
|
|
66
72
|
},
|
|
67
73
|
"&:focus, &:active": {
|
|
68
74
|
borderRadius: 0,
|
|
75
|
+
boxShadow: props.multiple ? "none" : `0 0 ${theme.spacing(0.4)} #4fa1f0`,
|
|
69
76
|
"&:hover": {
|
|
70
|
-
backgroundColor: theme.palette.primary.
|
|
77
|
+
backgroundColor: theme.palette.primary.main,
|
|
71
78
|
},
|
|
72
79
|
},
|
|
73
80
|
},
|
|
74
|
-
|
|
81
|
+
...(props.autoWidth
|
|
82
|
+
? {
|
|
83
|
+
minWidth: `auto !important`,
|
|
84
|
+
width: `auto !important`,
|
|
85
|
+
}
|
|
86
|
+
: {}),
|
|
87
|
+
}),
|
|
75
88
|
label: {
|
|
76
89
|
fontSize: theme.typography.fontSize,
|
|
77
90
|
color: theme.palette.grey.dark,
|
|
@@ -104,6 +117,10 @@ const useStyles = makeStyles(theme => ({
|
|
|
104
117
|
backgroundColor: theme.palette.grey.light,
|
|
105
118
|
border: 0,
|
|
106
119
|
},
|
|
120
|
+
formControl: props => ({
|
|
121
|
+
maxWidth: theme.spacing(props.multipleWidthSpacing),
|
|
122
|
+
minWidth: theme.spacing(props.multipleWidthSpacing),
|
|
123
|
+
}),
|
|
107
124
|
}));
|
|
108
125
|
|
|
109
126
|
const MenuProps = {
|
|
@@ -145,11 +162,16 @@ export const SelectIconButton = props => {
|
|
|
145
162
|
);
|
|
146
163
|
};
|
|
147
164
|
|
|
148
|
-
const renderMultipleValues =
|
|
165
|
+
export const renderMultipleValues = (value, options) => {
|
|
166
|
+
return options
|
|
167
|
+
.filter(x => value.indexOf(x.value) !== -1)
|
|
168
|
+
.map(x => x.label)
|
|
169
|
+
.join(", ");
|
|
170
|
+
};
|
|
149
171
|
|
|
150
172
|
const selectEmptyValue = "~~#~~";
|
|
151
173
|
|
|
152
|
-
const Select = ({ options, selectProps, children }) => {
|
|
174
|
+
const Select = ({ options = [], selectProps, children }) => {
|
|
153
175
|
if (isSelectProps(selectProps) === false) {
|
|
154
176
|
throw new TypeError("selectProps property is not of type SelectProps");
|
|
155
177
|
}
|
|
@@ -157,8 +179,6 @@ const Select = ({ options, selectProps, children }) => {
|
|
|
157
179
|
const [open, setOpen] = useState(false);
|
|
158
180
|
const ref = useRef(null);
|
|
159
181
|
|
|
160
|
-
const classes = useStyles();
|
|
161
|
-
|
|
162
182
|
const update = selectProps?.get(SelectProps.propNames.update);
|
|
163
183
|
const value = selectProps?.get(SelectProps.propNames.value) ?? "";
|
|
164
184
|
const sortType = selectProps?.get(SelectProps.propNames.sortType) || sortTypeEnum.none;
|
|
@@ -171,36 +191,86 @@ const Select = ({ options, selectProps, children }) => {
|
|
|
171
191
|
const native = selectProps?.get(SelectProps.propNames.native);
|
|
172
192
|
const onClose = selectProps?.get(SelectProps.propNames.onClose);
|
|
173
193
|
const inputProps = selectProps?.get(SelectProps.propNames.inputProps);
|
|
174
|
-
const multiple = selectProps?.get(SelectProps.propNames.multiple);
|
|
194
|
+
const multiple = selectProps?.get(SelectProps.propNames.multiple) || false;
|
|
195
|
+
const renderValue = selectProps?.get(SelectProps.propNames.renderValue);
|
|
196
|
+
const autoWidth = selectProps?.get(SelectProps.propNames.autoWidth);
|
|
197
|
+
const autoFocus = selectProps?.get(SelectProps.propNames.autoFocus);
|
|
198
|
+
const multipleSelectWidth = selectProps?.get(SelectProps.propNames.multipleSelectWidth);
|
|
175
199
|
const hasError = !!error;
|
|
176
200
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
return a.label.localeCompare(b.label);
|
|
195
|
-
});
|
|
196
|
-
}
|
|
201
|
+
const windowSize = useWindowSize();
|
|
202
|
+
|
|
203
|
+
// When too many elements are selected from the list, the component can be longer than the screen, not very convenient
|
|
204
|
+
// We need a fix length unfortunately, for large screen, we use 100% of the multipleSelectWidth, for medium length, 75%
|
|
205
|
+
// But for very small width, we use the inner width of the browser minus 150px (completely arbitrary value), otherwise
|
|
206
|
+
// the drop-down is too large and hard to read
|
|
207
|
+
const multipleSelectWidthFactor = windowSize.innerWidth > 1200 ? 1 : 0.75;
|
|
208
|
+
const multipleWidthSpacing =
|
|
209
|
+
windowSize.innerWidth > 750
|
|
210
|
+
? (multipleSelectWidth / 10) * multipleSelectWidthFactor
|
|
211
|
+
: (windowSize.innerWidth - 150) / 10;
|
|
212
|
+
const classes = useStyles({
|
|
213
|
+
multiple,
|
|
214
|
+
autoWidth,
|
|
215
|
+
multipleWidthSpacing,
|
|
216
|
+
});
|
|
197
217
|
|
|
198
|
-
|
|
199
|
-
options
|
|
200
|
-
|
|
201
|
-
|
|
218
|
+
const buildOptionsItems = () => {
|
|
219
|
+
const allOptions = [...options];
|
|
220
|
+
|
|
221
|
+
if (sortType === sortTypeEnum.numeric) {
|
|
222
|
+
allOptions.sort((a, b) =>
|
|
223
|
+
a.sortOrder.localeCompare(b.sortOrder, undefined, {
|
|
224
|
+
numeric: true,
|
|
225
|
+
sensitivity: "base",
|
|
226
|
+
}),
|
|
227
|
+
);
|
|
228
|
+
} else if (sortType === sortTypeEnum.default) {
|
|
229
|
+
allOptions.sort((a, b) => (a.sortOrder > b.sortOrder ? 1 : -1));
|
|
230
|
+
} else if (sortType === sortTypeEnum.alphabetical) {
|
|
231
|
+
allOptions.sort((a, b) => {
|
|
232
|
+
if (a.value === selectEmptyValue) {
|
|
233
|
+
return -1;
|
|
234
|
+
}
|
|
235
|
+
if (b.value === selectEmptyValue) {
|
|
236
|
+
return 1;
|
|
237
|
+
}
|
|
238
|
+
return a.label.localeCompare(b.label);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (showAllValue && showAllLabel) {
|
|
243
|
+
allOptions.unshift({
|
|
244
|
+
value: showAllValue,
|
|
245
|
+
label: showAllLabel,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return allOptions.map(option => {
|
|
250
|
+
const clss = option?.level ? classes["level" + option.level] : "";
|
|
251
|
+
const appliedClasses = classNames(classes.baseItem, clss);
|
|
252
|
+
const labelClss = classNames({
|
|
253
|
+
[classes.label]: true,
|
|
254
|
+
[classes.emptyLabel]: option.value === "" || option.value === selectEmptyValue,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
const disabled = !!option.disabled;
|
|
258
|
+
const groupHeader = !!option.isGroupHeader;
|
|
259
|
+
if (groupHeader) {
|
|
260
|
+
return (
|
|
261
|
+
<ListSubheader key={option.value} className={appliedClasses}>
|
|
262
|
+
{option.label}
|
|
263
|
+
</ListSubheader>
|
|
264
|
+
);
|
|
265
|
+
} else {
|
|
266
|
+
return (
|
|
267
|
+
<MenuItem key={option.value} value={option.value} className={appliedClasses} disabled={disabled}>
|
|
268
|
+
<TooltippedTypography noWrap className={labelClss} children={option.label} titleValue={option.label} />
|
|
269
|
+
</MenuItem>
|
|
270
|
+
);
|
|
271
|
+
}
|
|
202
272
|
});
|
|
203
|
-
}
|
|
273
|
+
};
|
|
204
274
|
|
|
205
275
|
const handleChange = event => {
|
|
206
276
|
update(event.target.value);
|
|
@@ -208,102 +278,85 @@ const Select = ({ options, selectProps, children }) => {
|
|
|
208
278
|
|
|
209
279
|
const defaultMenuProps = {
|
|
210
280
|
classes: { paper: classNames(classes.selectPaper, selectProps?.getStyle(SelectProps.ruleNames.paper)) },
|
|
281
|
+
autoFocus,
|
|
211
282
|
...MenuProps,
|
|
212
283
|
...positionOverride,
|
|
213
284
|
};
|
|
214
285
|
|
|
215
286
|
const iconSelectMenuProps = {
|
|
216
287
|
classes: { paper: classNames(classes.selectPaper, selectProps?.getStyle(SelectProps.ruleNames.paper)) },
|
|
288
|
+
autoFocus,
|
|
217
289
|
...positionOverride,
|
|
218
290
|
...getIconButtonMenuProps(ref.current),
|
|
219
291
|
};
|
|
220
292
|
|
|
221
|
-
const items =
|
|
222
|
-
let clss = option?.level ? classes["level" + option.level] : "";
|
|
223
|
-
const appliedClasses = classNames(classes.baseItem, clss);
|
|
224
|
-
const labelClss = classNames({
|
|
225
|
-
[classes.label]: true,
|
|
226
|
-
[classes.emptyLabel]: option.value === "" || option.value === selectEmptyValue,
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
const disabled = !!option.disabled;
|
|
230
|
-
const groupHeader = !!option.isGroupHeader;
|
|
231
|
-
if (groupHeader) {
|
|
232
|
-
return (
|
|
233
|
-
<ListSubheader key={option.value} className={appliedClasses}>
|
|
234
|
-
{option.label}
|
|
235
|
-
</ListSubheader>
|
|
236
|
-
);
|
|
237
|
-
} else {
|
|
238
|
-
return (
|
|
239
|
-
<MenuItem key={option.value} value={option.value} className={appliedClasses} disabled={disabled}>
|
|
240
|
-
<TooltippedTypography noWrap className={labelClss} children={option.label} titleValue={option.label} />
|
|
241
|
-
</MenuItem>
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
});
|
|
293
|
+
const items = native ? null : buildOptionsItems();
|
|
245
294
|
|
|
246
|
-
const
|
|
295
|
+
const iconSelect = isIconSelect && (
|
|
247
296
|
<SelectMUI
|
|
297
|
+
open={open}
|
|
248
298
|
value={value}
|
|
299
|
+
ref={ref}
|
|
249
300
|
onChange={handleChange}
|
|
250
|
-
onClose={onClose}
|
|
251
301
|
disableUnderline={true}
|
|
252
|
-
IconComponent={
|
|
253
|
-
MenuProps={
|
|
302
|
+
IconComponent={SelectIconButton}
|
|
303
|
+
MenuProps={iconSelectMenuProps}
|
|
254
304
|
disabled={disabled}
|
|
255
305
|
error={hasError}
|
|
256
306
|
native={native}
|
|
257
307
|
inputProps={inputProps}
|
|
258
308
|
multiple={multiple}
|
|
259
|
-
renderValue={multiple ? renderMultipleValues : undefined}
|
|
260
309
|
classes={{
|
|
261
310
|
icon: classes.icon,
|
|
262
311
|
root: selectProps?.getStyle(SelectProps.ruleNames.root),
|
|
312
|
+
select: classes.displayNone,
|
|
263
313
|
disabled: classes.disabled,
|
|
264
314
|
}}
|
|
315
|
+
onClick={() => setOpen(!open)}
|
|
265
316
|
>
|
|
266
|
-
{
|
|
317
|
+
{items ?? children}
|
|
267
318
|
</SelectMUI>
|
|
268
319
|
);
|
|
269
320
|
|
|
270
|
-
|
|
321
|
+
// Render the normal select is the icon one is NULL
|
|
322
|
+
const selectToRender = iconSelect || (
|
|
271
323
|
<SelectMUI
|
|
272
|
-
open={open}
|
|
273
324
|
value={value}
|
|
274
|
-
ref={ref}
|
|
275
325
|
onChange={handleChange}
|
|
326
|
+
onClose={onClose}
|
|
276
327
|
disableUnderline={true}
|
|
277
|
-
IconComponent={
|
|
278
|
-
|
|
328
|
+
IconComponent={SelectIcon}
|
|
329
|
+
autoWidth={autoWidth}
|
|
330
|
+
MenuProps={defaultMenuProps}
|
|
279
331
|
disabled={disabled}
|
|
280
332
|
error={hasError}
|
|
281
333
|
native={native}
|
|
282
334
|
inputProps={inputProps}
|
|
283
335
|
multiple={multiple}
|
|
284
|
-
renderValue={multiple ? renderMultipleValues : undefined}
|
|
336
|
+
renderValue={renderValue ?? (multiple ? value => renderMultipleValues(value, options) : undefined)}
|
|
285
337
|
classes={{
|
|
286
338
|
icon: classes.icon,
|
|
287
339
|
root: selectProps?.getStyle(SelectProps.ruleNames.root),
|
|
288
|
-
select: classes.displayNone,
|
|
289
340
|
disabled: classes.disabled,
|
|
290
341
|
}}
|
|
291
|
-
onClick={() => setOpen(!open)}
|
|
292
342
|
>
|
|
293
|
-
{
|
|
343
|
+
{items ?? children}
|
|
294
344
|
</SelectMUI>
|
|
295
345
|
);
|
|
296
346
|
|
|
297
|
-
const
|
|
347
|
+
const selectToRenderWithError = hasError && (
|
|
348
|
+
<div className={classes.container}>
|
|
349
|
+
{selectToRender}
|
|
350
|
+
<div className={classNames(classes.errorText)}>{error}</div>
|
|
351
|
+
</div>
|
|
352
|
+
);
|
|
298
353
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
)) ||
|
|
306
|
-
select
|
|
354
|
+
const selectControl = selectToRenderWithError || selectToRender;
|
|
355
|
+
|
|
356
|
+
return multiple === false ? (
|
|
357
|
+
selectControl
|
|
358
|
+
) : (
|
|
359
|
+
<FormControl className={classes.formControl}>{selectControl}</FormControl>
|
|
307
360
|
);
|
|
308
361
|
};
|
|
309
362
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { mount } from "enzyme";
|
|
3
|
-
import Select, { SelectIconButton } from "./Select";
|
|
3
|
+
import Select, { renderMultipleValues, SelectIconButton } from "./Select";
|
|
4
4
|
import SelectMUI from "@material-ui/core/Select";
|
|
5
5
|
import sinon from "sinon";
|
|
6
6
|
import { ignoreConsoleError, createMuiTheme, TestWrapper } from "../../../utils/testUtils";
|
|
@@ -9,6 +9,7 @@ import TooltippedTypography from "./../DataDisplay/TooltippedElements/Tooltipped
|
|
|
9
9
|
import { ListSubheader, MuiThemeProvider } from "@material-ui/core";
|
|
10
10
|
import MenuItem from "@material-ui/core/MenuItem";
|
|
11
11
|
import Icon from "./../DataDisplay/Icon";
|
|
12
|
+
import FormControl from "@material-ui/core/FormControl";
|
|
12
13
|
|
|
13
14
|
describe("Select Component", () => {
|
|
14
15
|
let update, container;
|
|
@@ -75,13 +76,14 @@ describe("Select Component", () => {
|
|
|
75
76
|
expect(component, "when mounted", "to satisfy", expected);
|
|
76
77
|
});
|
|
77
78
|
|
|
78
|
-
it("Renders Select component with
|
|
79
|
+
it("Renders Select component without errors with a larger width", () => {
|
|
79
80
|
const options = [
|
|
80
|
-
{ value: "aValue", label: "aLabel"
|
|
81
|
-
{ value: "anotherValue", label: "anotherLabel"
|
|
82
|
-
{ value: "aThirdValue", label: "aThirdLabel", level: 2 },
|
|
81
|
+
{ value: "aValue", label: "aLabel" },
|
|
82
|
+
{ value: "anotherValue", label: "anotherLabel" },
|
|
83
83
|
];
|
|
84
84
|
|
|
85
|
+
Object.defineProperty(window, "innerWidth", { configurable: true, value: 1800 });
|
|
86
|
+
|
|
85
87
|
const selectProps = new SelectProps();
|
|
86
88
|
|
|
87
89
|
selectProps.set(SelectProps.propNames.update, update);
|
|
@@ -103,12 +105,49 @@ describe("Select Component", () => {
|
|
|
103
105
|
<MenuItem key="aValue" value="aValue">
|
|
104
106
|
<TooltippedTypography children="aLabel" titleValue="aLabel" />
|
|
105
107
|
</MenuItem>
|
|
106
|
-
<MenuItem key="anotherValue" value="anotherValue"
|
|
108
|
+
<MenuItem key="anotherValue" value="anotherValue">
|
|
107
109
|
<TooltippedTypography noWrap children="anotherLabel" titleValue="anotherLabel" />
|
|
108
110
|
</MenuItem>
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
</SelectMUI>
|
|
112
|
+
</TestWrapper>
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
expect(component, "when mounted", "to satisfy", expected);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("Renders Select component using native mode", () => {
|
|
119
|
+
const options = [
|
|
120
|
+
{ value: "aValue", label: "aLabel", level: 0 },
|
|
121
|
+
{ value: "anotherValue", label: "anotherLabel", level: 1 },
|
|
122
|
+
{ value: "aThirdValue", label: "aThirdLabel", level: 2 },
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
const selectProps = new SelectProps();
|
|
126
|
+
|
|
127
|
+
selectProps.set(SelectProps.propNames.update, update);
|
|
128
|
+
selectProps.set(SelectProps.propNames.native, true);
|
|
129
|
+
selectProps.set(SelectProps.propNames.value, "aValue");
|
|
130
|
+
|
|
131
|
+
const component = (
|
|
132
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
133
|
+
<Select options={options} selectProps={selectProps}>
|
|
134
|
+
<div>French Fries</div>
|
|
135
|
+
<div>Smashed Potatoes</div>
|
|
136
|
+
<div>Fried Green Tomatoes</div>
|
|
137
|
+
</Select>
|
|
138
|
+
</TestWrapper>
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const ChevronDown = props => {
|
|
142
|
+
return <Icon id="dropdown-chevron-down" {...props} />;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const expected = (
|
|
146
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
147
|
+
<SelectMUI native value="aValue" disableUnderline={true} IconComponent={ChevronDown} error={false}>
|
|
148
|
+
<div>French Fries</div>
|
|
149
|
+
<div>Smashed Potatoes</div>
|
|
150
|
+
<div>Fried Green Tomatoes</div>
|
|
112
151
|
</SelectMUI>
|
|
113
152
|
</TestWrapper>
|
|
114
153
|
);
|
|
@@ -262,8 +301,8 @@ describe("Select Component", () => {
|
|
|
262
301
|
};
|
|
263
302
|
|
|
264
303
|
const expected = (
|
|
265
|
-
<
|
|
266
|
-
<
|
|
304
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
305
|
+
<div>
|
|
267
306
|
<SelectMUI value="aValue" disableUnderline={true} IconComponent={ChevronDown} error={true}>
|
|
268
307
|
<MenuItem key="aValue" value="aValue">
|
|
269
308
|
<TooltippedTypography children="aLabel" titleValue="aLabel" />
|
|
@@ -272,9 +311,9 @@ describe("Select Component", () => {
|
|
|
272
311
|
<TooltippedTypography noWrap children="anotherLabel" titleValue="anotherLabel" />
|
|
273
312
|
</MenuItem>
|
|
274
313
|
</SelectMUI>
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
</
|
|
314
|
+
<div>an error message</div>
|
|
315
|
+
</div>
|
|
316
|
+
</TestWrapper>
|
|
278
317
|
);
|
|
279
318
|
|
|
280
319
|
expect(component, "when mounted", "to satisfy", expected);
|
|
@@ -637,6 +676,51 @@ describe("Select Component", () => {
|
|
|
637
676
|
expect(component, "when mounted", "to satisfy", expected);
|
|
638
677
|
});
|
|
639
678
|
|
|
679
|
+
it("Renders Icon Select component correctly using native mode", () => {
|
|
680
|
+
const options = [
|
|
681
|
+
{ value: "aValue", label: "aLabel" },
|
|
682
|
+
{ value: "anotherValue", label: "anotherLabel" },
|
|
683
|
+
];
|
|
684
|
+
|
|
685
|
+
const selectProps = new SelectProps();
|
|
686
|
+
|
|
687
|
+
selectProps.set(SelectProps.propNames.update, update);
|
|
688
|
+
selectProps.set(SelectProps.propNames.value, "aValue");
|
|
689
|
+
selectProps.set(SelectProps.propNames.iconSelect, true);
|
|
690
|
+
selectProps.set(SelectProps.propNames.native, true);
|
|
691
|
+
|
|
692
|
+
const theme = createMuiTheme();
|
|
693
|
+
|
|
694
|
+
const component = (
|
|
695
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
696
|
+
<Select options={options} selectProps={selectProps}>
|
|
697
|
+
<div>French Fries</div>
|
|
698
|
+
<div>Smashed Potatoes</div>
|
|
699
|
+
<div>Fried Green Tomatoes</div>
|
|
700
|
+
</Select>
|
|
701
|
+
</TestWrapper>
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
const expected = (
|
|
705
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
706
|
+
<SelectMUI
|
|
707
|
+
native
|
|
708
|
+
open={false}
|
|
709
|
+
value="aValue"
|
|
710
|
+
disableUnderline={true}
|
|
711
|
+
IconComponent={SelectIconButton}
|
|
712
|
+
error={false}
|
|
713
|
+
>
|
|
714
|
+
<div>French Fries</div>
|
|
715
|
+
<div>Smashed Potatoes</div>
|
|
716
|
+
<div>Fried Green Tomatoes</div>
|
|
717
|
+
</SelectMUI>
|
|
718
|
+
</TestWrapper>
|
|
719
|
+
);
|
|
720
|
+
|
|
721
|
+
expect(component, "when mounted", "to satisfy", expected);
|
|
722
|
+
});
|
|
723
|
+
|
|
640
724
|
it("Changes Icon Select open state on click", () => {
|
|
641
725
|
const options = [
|
|
642
726
|
{ value: "aValue", label: "aLabel" },
|
|
@@ -674,13 +758,14 @@ describe("Select Component", () => {
|
|
|
674
758
|
const options = [
|
|
675
759
|
{ value: "aValue", label: "aLabel" },
|
|
676
760
|
{ value: "anotherValue", label: "anotherLabel" },
|
|
761
|
+
{ value: "thirdValue", label: "thirdLabel" },
|
|
677
762
|
];
|
|
678
763
|
|
|
679
764
|
const selectProps = new SelectProps();
|
|
680
765
|
|
|
681
766
|
selectProps.set(SelectProps.propNames.update, update);
|
|
682
767
|
selectProps.set(SelectProps.propNames.multiple, true);
|
|
683
|
-
selectProps.set(SelectProps.propNames.value, ["aValue"]);
|
|
768
|
+
selectProps.set(SelectProps.propNames.value, ["aValue", "thirdValue"]);
|
|
684
769
|
|
|
685
770
|
const component = (
|
|
686
771
|
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
@@ -694,21 +779,76 @@ describe("Select Component", () => {
|
|
|
694
779
|
|
|
695
780
|
const expected = (
|
|
696
781
|
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
697
|
-
<
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
<
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
<
|
|
710
|
-
|
|
711
|
-
|
|
782
|
+
<FormControl>
|
|
783
|
+
<SelectMUI
|
|
784
|
+
value={["aValue", "thirdValue"]}
|
|
785
|
+
disableUnderline={true}
|
|
786
|
+
IconComponent={ChevronDown}
|
|
787
|
+
error={false}
|
|
788
|
+
multiple={true}
|
|
789
|
+
renderValue={value => renderMultipleValues(value, options)}
|
|
790
|
+
>
|
|
791
|
+
<MenuItem key="aValue" value="aValue">
|
|
792
|
+
<TooltippedTypography children="aLabel" titleValue="aLabel" />
|
|
793
|
+
</MenuItem>
|
|
794
|
+
<MenuItem key="anotherValue" value="anotherValue">
|
|
795
|
+
<TooltippedTypography noWrap children="anotherLabel" titleValue="anotherLabel" />
|
|
796
|
+
</MenuItem>
|
|
797
|
+
</SelectMUI>
|
|
798
|
+
</FormControl>
|
|
799
|
+
</TestWrapper>
|
|
800
|
+
);
|
|
801
|
+
|
|
802
|
+
expect(component, "when mounted", "to satisfy", expected);
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
it("Renders Icon Select component correctly using multiple mode and render value", () => {
|
|
806
|
+
const options = [
|
|
807
|
+
{ value: "aValue", label: "aLabel" },
|
|
808
|
+
{ value: "anotherValue", label: "anotherLabel" },
|
|
809
|
+
{ value: "thirdValue", label: "thirdLabel" },
|
|
810
|
+
];
|
|
811
|
+
|
|
812
|
+
const selectProps = new SelectProps();
|
|
813
|
+
|
|
814
|
+
const renderValues = values => values.join("#,#");
|
|
815
|
+
|
|
816
|
+
selectProps.set(SelectProps.propNames.update, update);
|
|
817
|
+
selectProps.set(SelectProps.propNames.multiple, true);
|
|
818
|
+
selectProps.set(SelectProps.propNames.value, ["aValue", "thirdValue"]);
|
|
819
|
+
selectProps.set(SelectProps.propNames.renderValue, renderValues);
|
|
820
|
+
|
|
821
|
+
const theme = createMuiTheme();
|
|
822
|
+
|
|
823
|
+
const component = (
|
|
824
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
825
|
+
<Select options={options} selectProps={selectProps} />
|
|
826
|
+
</TestWrapper>
|
|
827
|
+
);
|
|
828
|
+
|
|
829
|
+
const ChevronDown = props => {
|
|
830
|
+
return <Icon id="dropdown-chevron-down" {...props} />;
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
const expected = (
|
|
834
|
+
<TestWrapper stylesProvider muiThemeProvider={{ theme }}>
|
|
835
|
+
<FormControl>
|
|
836
|
+
<SelectMUI
|
|
837
|
+
value={["aValue", "thirdValue"]}
|
|
838
|
+
disableUnderline={true}
|
|
839
|
+
IconComponent={ChevronDown}
|
|
840
|
+
error={false}
|
|
841
|
+
multiple={true}
|
|
842
|
+
renderValue={renderValues}
|
|
843
|
+
>
|
|
844
|
+
<MenuItem key="aValue" value="aValue">
|
|
845
|
+
<TooltippedTypography children="aLabel" titleValue="aLabel" />
|
|
846
|
+
</MenuItem>
|
|
847
|
+
<MenuItem key="anotherValue" value="anotherValue">
|
|
848
|
+
<TooltippedTypography noWrap children="anotherLabel" titleValue="anotherLabel" />
|
|
849
|
+
</MenuItem>
|
|
850
|
+
</SelectMUI>
|
|
851
|
+
</FormControl>
|
|
712
852
|
</TestWrapper>
|
|
713
853
|
);
|
|
714
854
|
|
|
@@ -22,6 +22,10 @@ class SelectProps extends ComponentProps {
|
|
|
22
22
|
native: "native",
|
|
23
23
|
inputProps: "inputProps",
|
|
24
24
|
multiple: "multiple",
|
|
25
|
+
autoWidth: "autoWidth",
|
|
26
|
+
autoFocus: "autoFocus",
|
|
27
|
+
renderValue: "renderValue",
|
|
28
|
+
multipleSelectWidth: "multipleSelectWidth",
|
|
25
29
|
};
|
|
26
30
|
|
|
27
31
|
static ruleNames = {
|
|
@@ -43,7 +47,11 @@ class SelectProps extends ComponentProps {
|
|
|
43
47
|
this.componentProps.set(this.constructor.propNames.onClose, null);
|
|
44
48
|
this.componentProps.set(this.constructor.propNames.native, null);
|
|
45
49
|
this.componentProps.set(this.constructor.propNames.inputProps, null);
|
|
46
|
-
this.componentProps.set(this.constructor.propNames.multiple,
|
|
50
|
+
this.componentProps.set(this.constructor.propNames.multiple, false);
|
|
51
|
+
this.componentProps.set(this.constructor.propNames.autoWidth, true);
|
|
52
|
+
this.componentProps.set(this.constructor.propNames.autoFocus, true);
|
|
53
|
+
this.componentProps.set(this.constructor.propNames.renderValue, null);
|
|
54
|
+
this.componentProps.set(this.constructor.propNames.multipleSelectWidth, 700);
|
|
47
55
|
|
|
48
56
|
this.componentClasses.set(this.constructor.ruleNames.root, null);
|
|
49
57
|
this.componentClasses.set(this.constructor.ruleNames.paper, null);
|
|
@@ -16,6 +16,10 @@ describe("Select Props", () => {
|
|
|
16
16
|
"native",
|
|
17
17
|
"inputProps",
|
|
18
18
|
"multiple",
|
|
19
|
+
"autoWidth",
|
|
20
|
+
"autoFocus",
|
|
21
|
+
"renderValue",
|
|
22
|
+
"multipleSelectWidth",
|
|
19
23
|
];
|
|
20
24
|
|
|
21
25
|
expect(SelectProps.propNames, "to have keys", propNames);
|
|
@@ -36,6 +40,10 @@ describe("Select Props", () => {
|
|
|
36
40
|
"native",
|
|
37
41
|
"inputProps",
|
|
38
42
|
"multiple",
|
|
43
|
+
"autoWidth",
|
|
44
|
+
"autoFocus",
|
|
45
|
+
"renderValue",
|
|
46
|
+
"multipleSelectWidth",
|
|
39
47
|
];
|
|
40
48
|
|
|
41
49
|
const selectProps = new SelectProps();
|