@hipay/hipay-material-ui 2.0.0-beta.61 → 2.0.0-beta.62

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/HiDatePicker/HiDateRangeSelector.js +1 -1
  3. package/{HiSelectNew → HiSelect}/HiDynamicSelect.js +3 -3
  4. package/{HiSelectNew → HiSelect}/HiNestedSelect.js +9 -9
  5. package/{HiSelectNew → HiSelect}/HiNestedSelectContent.js +9 -9
  6. package/HiSelect/HiSelect.js +489 -607
  7. package/{HiSelectNew → HiSelect}/HiSelectContent.js +7 -7
  8. package/HiSelect/index.js +41 -3
  9. package/HiSelectableList/HiSelectableList.js +59 -3
  10. package/HiSelectableList/HiSelectableListItem.js +22 -10
  11. package/README.md +15 -0
  12. package/es/HiDatePicker/HiDateRangeSelector.js +1 -1
  13. package/es/{HiSelectNew → HiSelect}/HiNestedSelect.js +1 -1
  14. package/es/{HiSelectNew → HiSelect}/HiNestedSelectContent.js +1 -1
  15. package/es/HiSelect/HiSelect.js +441 -564
  16. package/es/{HiSelectNew → HiSelect}/HiSelectContent.js +1 -1
  17. package/es/HiSelect/index.js +4 -1
  18. package/es/HiSelectableList/HiSelectableList.js +56 -4
  19. package/es/HiSelectableList/HiSelectableListItem.js +18 -10
  20. package/index.es.js +1 -1
  21. package/index.js +1 -1
  22. package/package.json +3 -2
  23. package/umd/hipay-material-ui.development.js +41669 -39595
  24. package/umd/hipay-material-ui.production.min.js +2 -2
  25. package/HiSelect/SelectInput.js +0 -369
  26. package/HiSelectNew/HiSelect.js +0 -929
  27. package/HiSelectNew/HiSelectField.js +0 -146
  28. package/HiSelectNew/index.js +0 -69
  29. package/es/HiSelect/SelectInput.js +0 -321
  30. package/es/HiSelectNew/HiSelect.js +0 -852
  31. package/es/HiSelectNew/HiSelectField.js +0 -111
  32. package/es/HiSelectNew/index.js +0 -6
  33. /package/{HiSelectNew → HiSelect}/HiDynamicSelectField.js +0 -0
  34. /package/{HiSelectNew → HiSelect}/HiNestedSelectField.js +0 -0
  35. /package/{HiSelectNew → HiSelect}/HiSelectInput.js +0 -0
  36. /package/es/{HiSelectNew → HiSelect}/HiDynamicSelect.js +0 -0
  37. /package/es/{HiSelectNew → HiSelect}/HiDynamicSelectField.js +0 -0
  38. /package/es/{HiSelectNew → HiSelect}/HiNestedSelectField.js +0 -0
  39. /package/es/{HiSelectNew → HiSelect}/HiSelectInput.js +0 -0
@@ -1,24 +1,20 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
2
  import _objectSpread from "@babel/runtime/helpers/objectSpread";
4
- // @inheritedComponent Input
5
3
  import React from 'react';
6
4
  import PropTypes from 'prop-types';
7
- import classNames from 'classnames';
8
- import Grow from '@material-ui/core/Grow';
9
- import { findDOMNode } from 'react-dom';
10
5
  import Scrollbars from 'react-custom-scrollbars';
6
+ import Grow from '@material-ui/core/Grow';
11
7
  import Paper from '@material-ui/core/Paper';
12
- import ClickAwayListener from '@material-ui/core/ClickAwayListener';
13
8
  import Popper from '@material-ui/core/Popper';
9
+ import ClickAwayListener from '@material-ui/core/ClickAwayListener';
14
10
  import HiSelectableList from '../HiSelectableList';
15
- import HiSearchField from '../HiForm/HiSearchField';
16
- import SelectInput from './SelectInput';
17
- import HiChip from '../HiChip/HiChip';
18
- import { withStyles } from '../styles';
19
- import { arrayUnique, getNextItemSelectable } from '../utils/helpers';
11
+ import HiInput from '../HiForm/HiInput';
12
+ import HiSelectInput from './HiSelectInput';
13
+ import withStyles from '../styles/withStyles';
14
+ import { getNextItemSelectable, foldAccents } from '../utils/helpers';
20
15
  import HiIcon from '../HiIcon';
21
- export const INFINITESCROLL_ERROR_MESSAGE = 'La propriété "loadMoreResults" est obligatoire si la prop "infiniteScroll" est à true';
16
+ import keycode from 'keycode';
17
+ import classNames from 'classnames';
22
18
  export const styles = theme => ({
23
19
  root: {
24
20
  backgroundColor: theme.palette.background2,
@@ -32,14 +28,24 @@ export const styles = theme => ({
32
28
  popperWidth: {
33
29
  width: '100% !important'
34
30
  },
31
+ popperRightAlign: {
32
+ right: 0,
33
+ left: 'unset!important'
34
+ },
35
35
  paper: {
36
36
  borderRadius: '0px 2px',
37
- maxHeight: 440,
37
+ maxHeight: 480,
38
38
  transition: 'none !important'
39
39
  },
40
40
  labelIcon: {
41
41
  marginRight: 10
42
42
  },
43
+ labelImg: {
44
+ height: 18,
45
+ width: 'auto',
46
+ margin: '0 4px',
47
+ verticalAlign: 'middle'
48
+ },
43
49
  selectIconLabel: _objectSpread({
44
50
  whiteSpace: 'nowrap',
45
51
  overflow: 'hidden',
@@ -48,8 +54,24 @@ export const styles = theme => ({
48
54
  }, theme.typography.b1, {
49
55
  display: 'inline-flex',
50
56
  width: '100%'
51
- })
57
+ }),
58
+ selectImgLabel: _objectSpread({
59
+ whiteSpace: 'nowrap',
60
+ overflow: 'hidden',
61
+ textOverflow: 'ellipsis',
62
+ paddingRight: 16
63
+ }, theme.typography.b1, {
64
+ display: 'inline-flex',
65
+ width: '100%'
66
+ }),
67
+ separator: {
68
+ borderTop: `1px solid ${theme.palette.input.bottomLine}`
69
+ }
52
70
  });
71
+
72
+ function filterValue(item, search) {
73
+ return search === '' || foldAccents(item.label.toString().toLowerCase()).search(foldAccents(search.toLowerCase())) !== -1;
74
+ }
53
75
  /**
54
76
  *
55
77
  * Utilisé pour tous types de selects dans les formulaires.
@@ -58,80 +80,113 @@ export const styles = theme => ({
58
80
  * - avec / sans barre de recherche
59
81
  * - avec / sans option "All"
60
82
  * - prise en compte du type des éléments (text, image, icon, ...)
83
+ * - les actions du clavier son capturés avec KeyDown
61
84
  *
62
85
  * Ce composant réuni les sous-composants
63
- * - SelectInput : affiche l'élément dans le formulaire
64
- * - HiSearchField : intègre une barre de recherche dans le Popper,
65
- * il filtre la liste des suggestions
86
+ * - HiSelectInput : affiche l'élément dans le formulaire
87
+ * - HiSearchField : intègre une barre de recherche dans le Popper, il filtre la liste des suggestions
66
88
  * - HiSelectableList : affiche la liste des suggestions selon le type des éléments
67
89
  */
68
90
 
91
+
69
92
  class HiSelect extends React.PureComponent {
70
- constructor(_props) {
71
- super(_props);
72
-
73
- this.buildHierarchyTrees = props => {
74
- // Construct two associative arrays
75
- // hierarchy[parentId] => children
76
- // hierarchySelected[parentId] => selected children
77
- const hierarchy = {};
78
- const hierarchySelected = {};
79
- let value = props.value || [];
80
- if (!Array.isArray(value)) value = [props.value];
81
- props.options.forEach(option => {
82
- if (option.hasChildren === true && !hierarchy.hasOwnProperty(option.id)) {
83
- hierarchy[option.id] = [];
84
- hierarchySelected[option.id] = [];
85
- } else if (option.hasOwnProperty('parentId')) {
86
- hierarchy[option.parentId].push(option.id);
87
-
88
- if (value.includes(option.id)) {
89
- hierarchySelected[option.parentId].push(option.id);
90
- }
91
- }
92
- });
93
+ constructor(props) {
94
+ super(props);
95
+
96
+ this.buildSelectProps = (options, value = [], search = '', loading = false) => {
97
+ // build item list
98
+ const itemList = [...(loading ? [{
99
+ id: '_loading',
100
+ type: 'loader',
101
+ disabled: true,
102
+ centered: true,
103
+ hideCheckbox: true,
104
+ label: 'loading'
105
+ }] : []), // simple one level filter on label
106
+ ...(search !== '' ? [...options.filter(item => this.props.filterFunc(item, search))] : [...(this.props.hasAll ? [_objectSpread({
107
+ id: '_all',
108
+ label: this.props.translations.all
109
+ }, this.props.iconAll && {
110
+ type: 'icon',
111
+ icon: this.props.iconAll
112
+ })] : []), ...options])];
93
113
  return {
94
- hierarchy,
95
- hierarchySelected
114
+ itemList,
115
+ inputValue: this.buildInputValue(options, value, loading)
96
116
  };
97
117
  };
98
118
 
99
- this.focusOnSelectedItem = () => {
100
- // On récupère la div parent "overlay"
101
- const overlay = findDOMNode(this.overlay);
102
- const multiple = this.props.multiple;
103
- const value = this.props.value;
104
- const selectedIdList = Array.isArray(value) ? value : [value];
105
- setTimeout(() => {
106
- let focused = false; // Si un ou plusieurs items sont selectionnés, on focus sur le dernier
107
-
108
- if (selectedIdList.length > 0) {
109
- const itemSelected = overlay.querySelector(`[data-id="${selectedIdList[selectedIdList.length - 1]}"]`);
110
-
111
- if (itemSelected && itemSelected.parentElement.tagName === 'LI') {
112
- itemSelected.parentElement.focus();
113
- focused = true;
114
- }
115
- } // Si pas d'item selectionné, ou pas visible (en cas de recherche), focus sur le premier
119
+ this.buildInputValue = (options, value = [], loading = false) => {
120
+ const {
121
+ classes,
122
+ hasAll,
123
+ translations,
124
+ type
125
+ } = this.props; // build input value
126
+
127
+ let inputValue;
128
+
129
+ if (loading && value.length === 1) {
130
+ inputValue = translations.one_item_selected;
131
+ } else if (hasAll && options.length === value.length) {
132
+ inputValue = translations.all;
133
+ value.unshift('_all');
134
+ } else if (value.length > 1) {
135
+ inputValue = translations.n_items_selected.replace('%s', value.length);
136
+ } else if (value.length === 1) {
137
+ const item = options.find(o => o.id === value[0]);
138
+
139
+ if (item === undefined) {
140
+ inputValue = translations.one_item_selected;
141
+ } else if (type === 'icon' || item.type === 'icon') {
142
+ inputValue = React.createElement("span", {
143
+ className: classes.selectIconLabel
144
+ }, React.createElement(HiIcon, {
145
+ className: classes.labelIcon,
146
+ icon: item.icon
147
+ }), item.label);
148
+ } else if (type === 'image' || item.type === 'image') {
149
+ inputValue = React.createElement("span", {
150
+ className: classes.selectIconLabel
151
+ }, React.createElement("img", {
152
+ className: classes.labelImg,
153
+ src: item.img,
154
+ alt: item.label,
155
+ onError: e => {
156
+ if (item.fallbackImage) {
157
+ e.target.src = `${item.fallbackImage}`;
158
+ } else {
159
+ e.target.style.display = 'none';
160
+ }
161
+ }
162
+ }), item.label);
163
+ } else {
164
+ inputValue = item.label;
165
+ }
166
+ }
116
167
 
168
+ return inputValue;
169
+ };
117
170
 
118
- if (selectedIdList.length === 0 || !focused) {
119
- // On recupère tous les items
120
- const items = overlay.getElementsByTagName('li');
121
- let itemToFocus = items[0]; // Si select multiple, et qu'au moins un selectionné, focus sur le 2e item
171
+ this.focusOnFirstItem = () => {
172
+ if (this.overlay && this.overlay.getElementsByTagName('li')[0]) {
173
+ setTimeout(() => {
174
+ const item = this.overlay.getElementsByTagName('li')[0];
175
+ item.focus();
176
+ }, 1);
177
+ }
178
+ };
122
179
 
123
- if (multiple && selectedIdList.length > 0) {
124
- itemToFocus = items[1];
125
- }
180
+ this.getInputElement = el => {
181
+ this.searchField = el;
126
182
 
127
- if (itemToFocus) {
128
- itemToFocus.focus();
129
- }
130
- }
131
- }, 1);
183
+ if (this.props.inputRef) {
184
+ this.props.inputRef(this.searchField);
185
+ }
132
186
  };
133
187
 
134
188
  this.handleBlur = () => {
189
+ this.handleSearchReset();
135
190
  this.setState({
136
191
  focused: false
137
192
  });
@@ -144,40 +199,55 @@ class HiSelect extends React.PureComponent {
144
199
  this.setState({
145
200
  open: true
146
201
  });
147
- const options = this.props.options.slice();
148
- this.handleSuggestions(options);
149
-
150
- if (this.props.onClick) {
151
- this.props.onClick();
152
- } // Gestion du focus
153
-
202
+ this.handleSuggestions(this.props.options);
203
+ if (this.props.onClick) this.props.onClick(); // Gestion du focus
154
204
 
155
205
  if (!this.props.searchable) {
156
- // sinon focus sur le dernier élément selectionné
157
- this.focusOnSelectedItem();
206
+ // Sinon focus sur l'élément sélectionné
207
+ this.focusOnSelectedItem(this.props.value);
158
208
  }
159
209
  }
160
210
  };
161
211
 
212
+ this.focusOnSelectedItem = selectedValue => {
213
+ if (this.overlay && this.overlay.getElementsByTagName('li')[0]) {
214
+ setTimeout(() => {
215
+ // On initialise au premier élément pour être sûr de ne pas se retrouver avec un focus of undefined
216
+ let item = this.overlay.getElementsByTagName('li')[0];
217
+
218
+ if (selectedValue && typeof selectedValue === 'string') {
219
+ item = this.overlay.getElementsByTagName('li')[selectedValue];
220
+ } else if (selectedValue && typeof selectedValue === 'number') {
221
+ item = this.overlay.getElementsByTagName('li')[selectedValue - 1];
222
+ }
223
+
224
+ if (item) {
225
+ item.focus();
226
+ }
227
+ }, 1);
228
+ }
229
+ };
230
+
162
231
  this.handleClickAway = event => {
163
232
  // Au clic sur le bouton, on laisse le handleClick fermer le select
164
- if (!this.selectInputElement.contains(event.target)) {
233
+ if (!this.inputEl.contains(event.target)) {
165
234
  this.handleClose(event);
166
235
  }
167
236
  };
168
237
 
169
238
  this.handleClose = () => {
239
+ this.handleSearchReset();
240
+ this.setState({
241
+ open: false
242
+ });
243
+
170
244
  if (this.props.onClose) {
171
245
  this.props.onClose();
172
246
  }
173
247
 
174
- if (this.selectInputElement) {
175
- this.selectInputElement.focus();
248
+ if (this.inputEl) {
249
+ this.inputEl.focus();
176
250
  }
177
-
178
- this.setState({
179
- open: false
180
- });
181
251
  };
182
252
 
183
253
  this.handleFocus = () => {
@@ -186,310 +256,199 @@ class HiSelect extends React.PureComponent {
186
256
  });
187
257
  };
188
258
 
189
- this.handleKeyDown = event => {
190
- let nextItem;
191
-
192
- if (event.key === 'ArrowDown') {
193
- nextItem = getNextItemSelectable(document.activeElement, 'down');
194
- } else if (event.key === 'ArrowUp') {
195
- nextItem = getNextItemSelectable(document.activeElement, 'up');
196
- } else if (event.key === 'Tab' || event.key === 'Escape') {
197
- /* if (!this.props.staticPosition) {
198
- document.body.style.overflow = 'auto';
199
- } */
200
- this.setState({
201
- open: false
202
- });
259
+ this.handleKeyDownCapture = event => {
260
+ const key = keycode(event);
261
+
262
+ if (key === 'enter') {
263
+ if (this.state.open) {
264
+ if (this.props.multiple) {
265
+ event.stopPropagation();
266
+ this.handleClose();
267
+ }
268
+ }
203
269
  }
270
+ };
204
271
 
205
- if (nextItem) {
206
- nextItem.focus();
272
+ this.handleKeyDown = event => {
273
+ const key = keycode(event);
274
+
275
+ if (key === 'esc') {
276
+ event.preventDefault();
277
+ this.handleClose();
278
+ } else if (key === 'enter') {
279
+ if (this.state.open) {
280
+ if (this.props.multiple) {
281
+ this.handleClose();
282
+ }
283
+ }
284
+ } else if (key === 'space') {
285
+ event.preventDefault();
286
+
287
+ if (this.state.open) {
288
+ if (!this.props.multiple) {
289
+ this.setState({
290
+ open: false
291
+ });
292
+ }
293
+ } else {
294
+ this.setState({
295
+ open: true
296
+ });
297
+ }
298
+ } else if (key === 'tab') {
299
+ this.handleClose();
207
300
  }
208
301
  };
209
302
 
210
303
  this.handleKeyDownSearch = event => {
211
- if (this.overlay && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
212
- this.focusOnSelectedItem();
213
- } else if (event.key === 'Enter' && this.props.onSubmit) {
214
- this.props.onSubmit(event);
215
- } else if (event.key === 'Tab' || event.key === 'Escape') {
304
+ const key = keycode(event);
305
+
306
+ if (this.overlay && (key === 'down' || key === 'up')) {
307
+ this.focusOnFirstItem();
308
+ } else if (this.overlay && key === 'esc' || key === 'enter') {
309
+ event.preventDefault();
310
+ this.handleClose();
311
+ } else if (key === 'tab') {
216
312
  this.setState({
217
313
  open: false
218
314
  });
219
315
  }
220
316
  };
221
317
 
222
- this.handleRequestDelete = event => {
223
- event.stopPropagation();
224
- this.props.onChange(this.props.name, []);
225
- };
226
-
227
- this.handleReset = event => {
228
- if (this.props.onReset) {
229
- event.stopPropagation();
230
- this.props.onReset(event);
231
- }
232
- };
233
-
234
- this.handleScroll = event => {
235
- if (!this.props.loadingMoreResults && this.props.hasMore && event.target.scrollHeight - event.target.clientHeight - event.target.scrollTop < 15) {
236
- this.props.loadMoreResults(this.state.resultsPageNumber + 1);
237
- this.setState(prevState => ({
238
- resultsPageNumber: prevState.resultsPageNumber + 1
239
- }));
318
+ this.handleScroll = e => {
319
+ if (e.target.scrollHeight - e.target.clientHeight - e.target.scrollTop < 15) {
320
+ this.props.onScrollReachBottom();
240
321
  }
241
322
  };
242
323
 
243
324
  this.handleSelect = (event, item) => {
244
325
  const {
326
+ hasAll,
245
327
  multiple,
246
- value,
247
328
  onChange,
248
329
  options,
249
- hierarchic,
250
- pinnedItem
330
+ value
251
331
  } = this.props;
252
- const {
253
- hierarchySelected,
254
- hierarchy,
255
- nbOptions
256
- } = this.state;
257
-
258
- const hiSelected = _objectSpread({}, hierarchySelected);
259
-
260
- if (multiple) {
261
- let valueList = value;
262
-
263
- if (item.id === '_all') {
264
- if (valueList.length === nbOptions) {
265
- valueList = [];
266
-
267
- if (hierarchic) {
268
- // if hierarchic select => empty associative array of selected children
269
- Object.keys(hiSelected).forEach(key => {
270
- hiSelected[key] = [];
271
- });
272
- }
273
- } else {
274
- options.forEach(option => {
275
- if (option.hasChildren !== true && !valueList.includes(option.id) && option.id !== '_all') {
276
- valueList.push(option.id);
277
- } else if (option.hasChildren === true) {
278
- // if hierarchic select => fill associative array of selected children
279
- hiSelected[option.id] = hierarchy[option.id];
280
- }
281
- });
282
- }
283
- } else if (valueList.includes(item.id) || item.hasChildren === true && hierarchySelected[item.id].length === hierarchy[item.id].length) {
284
- // item déjà sélectionné => on le déselectionne
285
- if (item.hasChildren !== true) {
286
- valueList = valueList.filter(val => {
287
- return val !== item.id;
288
- });
289
- }
290
332
 
291
- if (item.hasChildren === true) {
292
- // remove all children
293
- valueList = valueList.filter(val => {
294
- return !this.state.hierarchy[item.id].includes(val);
295
- });
296
- hiSelected[item.id] = [];
297
- } else if (item.hasOwnProperty('parentId')) {
298
- // Si item est un enfant on l'enlève du tableau associatif des
299
- // elmts sélectionnés
300
- hiSelected[item.parentId].splice(hiSelected[item.parentId].indexOf(item.id), 1);
301
- }
333
+ if (!multiple) {
334
+ // single value
335
+ this.handleClose();
336
+ onChange(event, item.id, item);
337
+ } else if (hasAll && item.id === '_all') {
338
+ if (value.length === options.length) {
339
+ // unselect _all options
340
+ onChange(event, [], item);
302
341
  } else {
303
- if (pinnedItem && item.id === pinnedItem.id) {
304
- Object.keys(hiSelected).map(parentItemId => {
305
- hiSelected[parentItemId] = [];
306
- return true;
307
- });
308
- valueList = [item.id];
309
- } else {
310
- // item non sélectionné => on le sélectionne
311
- if (item.hasChildren !== true) valueList.push(item.id);
312
-
313
- if (pinnedItem && valueList.includes(pinnedItem.id)) {
314
- valueList.splice(valueList.indexOf(pinnedItem.id), 1);
315
- }
316
- }
317
-
318
- if (item.hasChildren === true) {
319
- // Si item parent => on ajoute tous les enfants
320
- // Ou on les supprime s'ils sont déjà tous sélectionnés (dans une liste filtrée)
321
- const idsInSuggestions = [];
322
- this.state.suggestions.forEach(suggestion => {
323
- if (this.state.hierarchy[item.id].includes(suggestion.id)) {
324
- idsInSuggestions.push(suggestion.id);
325
- }
326
- }); // if(hierarchySelected[item.id].length > 0) {}
327
-
328
- let allChildrenSuggestionsSelected = true;
329
- idsInSuggestions.forEach(id => {
330
- if (!hierarchySelected[item.id].includes(id)) {
331
- allChildrenSuggestionsSelected = false;
332
- }
333
- });
334
-
335
- if (allChildrenSuggestionsSelected === true) {
336
- // On supprime les enfants car déjà tous sélectionnés
337
- idsInSuggestions.forEach(id => {
338
- valueList.splice(valueList.indexOf(id), 1);
339
- hiSelected[item.id].splice(hiSelected[item.id].indexOf(id), 1);
340
- });
341
- } else {
342
- // On ajoute tous les enfants filtrés au éléments sélectionnés
343
- valueList = arrayUnique(valueList.concat(idsInSuggestions));
344
- hiSelected[item.id] = arrayUnique(hiSelected[item.id].concat(idsInSuggestions));
345
- }
346
-
347
- this.setState({
348
- hierarchySelected: hiSelected
349
- });
350
- } else if (item.hasOwnProperty('parentId')) {
351
- // Si item est un enfant on l'ajoute du tableau associatif des
352
- // elmts sélectionnés
353
- hiSelected[item.parentId].push(item.id);
354
- }
342
+ // select _all options
343
+ onChange(event, options.map(option => option.id), item);
355
344
  }
356
-
357
- this.setState({
358
- hierarchySelected: hiSelected
359
- });
360
- onChange(event, valueList, item);
345
+ } else if (value.includes(item.id)) {
346
+ // unselect item
347
+ onChange(event, value.filter(id => id !== item.id), item);
361
348
  } else {
362
- onChange(event, item.id, item);
363
- this.handleClose();
349
+ onChange(event, [...value, item.id], item);
364
350
  }
365
351
  };
366
352
 
367
353
  this.handleSuggestions = suggestions => {
368
354
  const {
369
- options,
370
355
  hasAll,
371
356
  iconAll,
372
- translations,
373
- multiple
357
+ translations
374
358
  } = this.props;
375
359
 
376
360
  if (suggestions.length === 0) {
377
- // Handle No Result
378
- // FIX to remove all item
379
- suggestions = [];
380
- suggestions.push({
381
- id: '_no_result',
382
- type: 'text',
383
- disabled: true,
384
- centered: true,
385
- checkbox: false,
386
- label: translations.no_result_match
387
- });
388
- } else if (hasAll && suggestions.length > 0 && suggestions.length === options.length && multiple === true) {
389
- // Handle 'All'
390
- if (suggestions.filter(suggestion => suggestion.id === '_all').length === 0) {
391
- const allItem = {
361
+ // Add '_no_result' suggestion
362
+ this.setState(prevState => _objectSpread({}, prevState, {
363
+ suggestions: [{
364
+ id: '_no_result',
365
+ type: 'text',
366
+ disabled: true,
367
+ centered: true,
368
+ hideCheckbox: true,
369
+ label: translations.no_result_match
370
+ }]
371
+ }));
372
+ } else {
373
+ this.setState({
374
+ suggestions: [// Add '_all' suggestion
375
+ ...(hasAll ? [_objectSpread({
392
376
  id: '_all',
393
- icon: iconAll,
394
377
  label: translations.all
395
- };
378
+ }, iconAll && {
379
+ type: 'icon',
380
+ icon: iconAll
381
+ })] : []), ...suggestions]
382
+ });
383
+ }
384
+ };
396
385
 
397
- if (iconAll !== false) {
398
- allItem.type = 'icon';
399
- }
386
+ this.handleSearch = (e, inputValue) => {
387
+ const searchValue = inputValue && e.target.value ? inputValue : e.target.value;
400
388
 
401
- suggestions.unshift(allItem);
402
- }
389
+ if (this.props.onSearch) {
390
+ this.props.onSearch(e, searchValue);
391
+ } else {
392
+ this.setState({
393
+ searchValue
394
+ });
403
395
  }
396
+ };
404
397
 
405
- this.setState({
406
- suggestions
407
- });
398
+ this.handleSearchReset = () => {
399
+ this.handleSearch({
400
+ target: {
401
+ value: ''
402
+ }
403
+ }, '');
408
404
  };
409
405
 
410
406
  this.state = {
411
407
  open: false,
412
408
  focused: false,
413
- suggestions: [],
414
- hierarchySelected: {},
415
- hierarchy: {},
416
- nbOptions: 0,
417
- dynamic: _props.dynamic || false,
418
- resultsPageNumber: 1
419
- }; // Check if value is in options
420
-
421
- let valueInOptions = false;
422
- const _val = _props.value; // No options provided.
423
-
424
- if (!_props.options.length || !_val || !_val.length) {
425
- valueInOptions = true;
426
- } else {
427
- // Check if an option match value prop.
428
- _props.options.forEach(item => {
429
- if (!valueInOptions && _val.indexOf(item.id) !== -1) {
430
- valueInOptions = true;
431
- }
432
- });
433
-
434
- if (!valueInOptions && _props.pinnedItem) {
435
- if (_props.value.indexOf(_props.pinnedItem.id) >= 0) {
436
- valueInOptions = true;
437
- }
438
- }
439
- }
440
-
441
- if (!valueInOptions) {
442
- throw new Error('prop value provided does not match any option.');
443
- }
444
-
445
- if (_props.hierarchic === true && _props.options.length > 1) {
446
- const hierarchyTrees = this.buildHierarchyTrees(_props);
447
- this.state.hierarchy = hierarchyTrees.hierarchy;
448
- this.state.hierarchySelected = hierarchyTrees.hierarchySelected;
449
- }
450
-
451
- if (_props.options.length > 0) {
452
- // Get real options number (parent & _all are not real options)
453
- let optionsLength = 0;
409
+ searchValue: props.searchValue ? undefined : '',
410
+ suggestions: props.options,
411
+ openDown: true
412
+ };
413
+ this.handleBlur = this.handleBlur.bind(this);
414
+ this.handleClick = this.handleClick.bind(this);
415
+ this.handleClose = this.handleClose.bind(this);
416
+ this.handleClickAway = this.handleClickAway.bind(this);
417
+ this.handleFocus = this.handleFocus.bind(this);
418
+ this.handleSearch = this.handleSearch.bind(this);
419
+ this.handleSearchReset = this.handleSearchReset.bind(this);
420
+ this.handleSelect = this.handleSelect.bind(this);
421
+ this.handleSuggestions = this.handleSuggestions.bind(this);
422
+ this.getInputElement = this.getInputElement.bind(this);
423
+ }
454
424
 
455
- _props.options.forEach(option => {
456
- if (option.hasChildren !== true && option.id !== '_all') {
457
- optionsLength += 1;
458
- }
425
+ static getDerivedStateFromProps(nextProps, prevState) {
426
+ if (nextProps.options !== prevState.suggestions) {
427
+ return _objectSpread({}, prevState, {
428
+ suggestions: nextProps.options
459
429
  });
460
-
461
- this.state.nbOptions = optionsLength;
462
- } else if (!_props.dynamic) {
463
- this.state.dynamic = true;
464
430
  }
431
+
432
+ return null;
465
433
  }
434
+ /**
435
+ * Build itemList & inputValue from select props
436
+ * @param options
437
+ * @param value
438
+ * @param search
439
+ * @param loading
440
+ * @returns {{itemList: *[], inputValue: *}}
441
+ */
466
442
 
467
- componentWillReceiveProps(nextProps) {
468
- if (typeof this.props.onSearch !== 'undefined' && this.props.options && this.props.options.length > 0) {
469
- this.handleSuggestions(nextProps.options);
470
- let optionsLength = 0;
471
- nextProps.options.forEach(option => {
472
- if (option.hasChildren !== true && option.id !== '_all') {
473
- optionsLength += 1;
474
- }
475
- });
476
- this.setState({
477
- nbOptions: optionsLength
478
- });
479
- }
480
443
 
481
- if (nextProps.hierarchic === true && nextProps.options.length > 1) {
482
- const hierarchyTrees = this.buildHierarchyTrees(nextProps);
483
- this.setState({
484
- hierarchy: hierarchyTrees.hierarchy,
485
- hierarchySelected: hierarchyTrees.hierarchySelected
486
- });
444
+ componentDidMount() {
445
+ if (this.props.autoFocus) {
446
+ this.inputEl.focus();
487
447
  }
488
448
  }
489
449
 
490
450
  render() {
491
- const _this$props = this.props,
492
- {
451
+ const {
493
452
  classes,
494
453
  disabled,
495
454
  error,
@@ -499,105 +458,42 @@ class HiSelect extends React.PureComponent {
499
458
  displayAsChip,
500
459
  type,
501
460
  value,
461
+ multiple,
502
462
  translations,
503
- parentItemSelectable,
504
- icon,
505
- parentIcon,
506
- hoverIcon,
507
- checkedIcon,
463
+ hiSearchInputProps,
464
+ hiSelectableListProps,
465
+ hiSelectInputProps,
508
466
  id,
467
+ onScrollReachBottom,
468
+ onSubmit,
509
469
  placeholder,
470
+ startAdornment,
510
471
  staticPosition,
511
- pinnedItem,
512
- hasAll,
513
- infiniteScroll,
514
- loadingMoreResults,
515
- multiple
516
- } = _this$props,
517
- other = _objectWithoutProperties(_this$props, ["classes", "disabled", "error", "loading", "options", "searchable", "displayAsChip", "type", "value", "translations", "parentItemSelectable", "icon", "parentIcon", "hoverIcon", "checkedIcon", "id", "placeholder", "staticPosition", "pinnedItem", "hasAll", "infiniteScroll", "loadingMoreResults", "multiple"]);
472
+ searchValue = this.state.searchValue,
473
+ buildSelectProps = this.buildSelectProps // use parent builder if defined
518
474
 
475
+ } = this.props;
519
476
  const {
520
477
  open,
521
- suggestions: stateSuggestions,
522
- focused,
523
- dynamic
478
+ focused
524
479
  } = this.state;
525
- let display = '';
526
- let selectedIdList;
527
-
528
- if (Array.isArray(value)) {
529
- selectedIdList = value;
530
- } else if (value) {
531
- selectedIdList = [value];
532
- } else {
533
- selectedIdList = [];
534
- }
535
-
536
- const suggestions = [...stateSuggestions];
537
-
538
- if (pinnedItem) {
539
- suggestions.unshift(pinnedItem);
540
- } // If loading
541
-
542
-
543
- if (loading && !loadingMoreResults) {
544
- suggestions.unshift({
545
- id: '_loading',
546
- type: 'loader',
547
- disabled: true,
548
- centered: true,
549
- checkbox: false,
550
- label: 'loading'
551
- });
552
- }
553
-
554
- if ((dynamic || loading) && selectedIdList.length === 1) {
555
- display = translations.one_item_selected;
556
- } else if ((this.state.nbOptions !== selectedIdList.length || !hasAll) && selectedIdList.length > 1) {
557
- display = translations.n_items_selected.replace('%s', selectedIdList.length);
558
- } else if (this.state.nbOptions === selectedIdList.length && this.state.nbOptions > 1) {
559
- display = translations.all;
560
- } else if (selectedIdList.length === 1) {
561
- let item = options.find(o => o.id === selectedIdList[0]);
562
-
563
- if (item === undefined) {
564
- display = translations.one_item_selected;
565
- } else if (type !== 'icon') {
566
- if (pinnedItem) {
567
- item = pinnedItem;
568
- }
569
480
 
570
- display = item.label;
571
- } else {
572
- display = React.createElement("span", {
573
- className: classes.selectIconLabel
574
- }, React.createElement(HiIcon, {
575
- icon: item.icon,
576
- className: classes.labelIcon
577
- }), item.label);
578
- }
579
- }
580
-
581
- if (displayAsChip) {
582
- const chipFilter = React.createElement(HiChip, {
583
- label: placeholder || display,
584
- onDelete: this.handleRequestDelete
585
- });
586
-
587
- if (display) {
588
- display = chipFilter;
481
+ if (multiple) {
482
+ if (!Array.isArray(value)) {
483
+ throw new Error('HiPay Material-UI: the `value` property must be an array ' + 'when using the `HiSelect` component with `multiple`.');
589
484
  }
590
485
  }
591
486
 
592
- const popperClass = classNames(classes.popper, {
593
- [classes.popperWidth]: !this.props.containerWidth
594
- });
595
- let allSelected = false;
487
+ let selectedItemIdList = [];
596
488
 
597
- if (selectedIdList.length === this.state.nbOptions) {
598
- allSelected = true;
489
+ if (value) {
490
+ selectedItemIdList = multiple ? [...value] : [value];
599
491
  }
600
492
 
493
+ const {
494
+ itemList,
495
+ inputValue = this.buildInputValue(options, selectedItemIdList, loading)
496
+ } = buildSelectProps(options, selectedItemIdList, searchValue, loading);
601
497
  let popperStyle = {};
602
498
 
603
499
  if (this.props.containerWidth > 0) {
@@ -610,69 +506,87 @@ class HiSelect extends React.PureComponent {
610
506
  }
611
507
  }
612
508
 
613
- if (infiniteScroll && loadingMoreResults) {
614
- suggestions.push({
615
- id: '_loading',
616
- type: 'loader',
617
- disabled: true,
618
- centered: true,
619
- checkbox: false,
620
- label: 'loading'
621
- });
509
+ const popperClass = classNames(classes.popper, {
510
+ [classes.popperWidth]: !this.props.containerWidth,
511
+ [classes.popperRightAlign]: this.props.containerWidth && this.props.align === 'right'
512
+ });
513
+
514
+ const searchInput = position => {
515
+ if (searchable) {
516
+ return React.createElement(HiInput, _extends({
517
+ value: searchValue,
518
+ autoFocus: true,
519
+ inputRef: this.getInputElement,
520
+ onKeyDown: this.handleKeyDownSearch,
521
+ onChange: this.handleSearch,
522
+ onReset: this.handleSearchReset,
523
+ placeholder: translations.search,
524
+ startAdornment: 'search',
525
+ tabIndex: 0,
526
+ className: classNames({
527
+ [classes.separator]: position === 'top'
528
+ })
529
+ }, hiSearchInputProps));
530
+ }
531
+
532
+ return null;
533
+ }; // Replace popper onSearch when popper displayed on top of selectButton
534
+
535
+
536
+ if (this.placement && this.placement.indexOf('top') >= 0 && !!searchable) {
537
+ // +1 for search input
538
+ const nbItems = itemList.length <= 10 ? itemList.length + 1 : 11;
539
+ popperStyle.transform = `translate3d(-1px, -${nbItems * 40 + 2}px, 0px)`;
540
+ } else if (this.placement && this.placement.indexOf('top') < 0 && !!searchable) {
541
+ popperStyle.transform = 'translate3d(-1px, 40px, 0px)';
622
542
  }
623
543
 
624
- const content = React.createElement(ClickAwayListener, {
625
- onClickAway: this.handleClickAway
626
- }, React.createElement(Grow, {
627
- in: open,
628
- id: "menu-list",
629
- style: {
630
- transformOrigin: '0 0 0'
544
+ const content = ({
545
+ placement
546
+ }) => {
547
+ if (placement !== this.placement) {
548
+ this.placement = placement;
631
549
  }
632
- }, React.createElement(Paper, {
633
- className: classes.paper
634
- }, !!searchable && React.createElement(HiSearchField, {
635
- itemList: options,
636
- onFilteredList: this.handleSuggestions,
637
- filterPropertyList: ['label'],
638
- placeholder: translations.search,
639
- autoFocus: true,
640
- onSearch: this.props.onSearch,
641
- inputRef: el => {
642
- this.searchField = el;
643
- },
644
- onKeyDown: this.handleKeyDownSearch
645
- }), React.createElement(Scrollbars, {
646
- ref: contentEl => {
647
- this.optionsContent = contentEl;
648
- },
649
- autoHeight: true,
650
- autoHeightMax: 400,
651
- onScroll: this.handleScroll
652
- }, React.createElement(HiSelectableList, _extends({
653
- type: type,
654
- parentItemSelectable: parentItemSelectable,
655
- itemList: suggestions,
656
- onSelect: this.handleSelect,
657
- selectedItemIdList: selectedIdList,
658
- hideCheckbox: !multiple,
659
- translations: translations,
660
- icon: icon,
661
- parentIcon: parentIcon,
662
- hoverIcon: hoverIcon,
663
- checkedIcon: checkedIcon,
664
- allSelected: allSelected,
665
- value: value,
666
- onKeyDown: this.handleKeyDown
667
- }, other))))));
550
+
551
+ return React.createElement(ClickAwayListener, {
552
+ onClickAway: this.handleClickAway
553
+ }, React.createElement(Grow, {
554
+ in: open,
555
+ id: "menu-list",
556
+ style: {
557
+ transformOrigin: '0 0 0'
558
+ }
559
+ }, React.createElement(Paper, {
560
+ className: classes.paper
561
+ }, (this.placement && this.placement.indexOf('bottom') >= 0 || staticPosition) && searchInput('bottom'), startAdornment, React.createElement(Scrollbars, _extends({
562
+ ref: contentEl => {
563
+ this.optionsContent = contentEl;
564
+ },
565
+ autoHeight: true,
566
+ autoHeightMax: 430
567
+ }, onScrollReachBottom && {
568
+ onScroll: this.handleScroll
569
+ }), React.createElement(HiSelectableList, _extends({
570
+ type: type,
571
+ itemList: itemList,
572
+ onSelect: this.handleSelect,
573
+ selectedItemIdList: selectedItemIdList,
574
+ fallbackImage: this.props.fallbackImage,
575
+ overlay: this.overlay,
576
+ value: value
577
+ }, hiSelectableListProps))), this.placement && this.placement.indexOf('top') >= 0 && !staticPosition && searchInput('top'))));
578
+ };
579
+
668
580
  return React.createElement("div", {
669
581
  className: classes.root,
670
582
  ref: el => {
671
583
  this.overlay = el;
672
- }
673
- }, React.createElement(SelectInput, {
584
+ },
585
+ onKeyDown: this.handleKeyDown,
586
+ onKeyDownCapture: this.handleKeyDownCapture
587
+ }, React.createElement(HiSelectInput, _extends({
674
588
  id: id,
675
- value: placeholder || display,
589
+ value: inputValue,
676
590
  open: open,
677
591
  focused: focused,
678
592
  type: type,
@@ -682,42 +596,44 @@ class HiSelect extends React.PureComponent {
682
596
  onClick: this.handleClick,
683
597
  onFocus: this.handleFocus,
684
598
  onBlur: this.handleBlur,
685
- onKeyDown: this.handleKeyDown,
599
+ onSubmit: onSubmit,
686
600
  onMouseEnter: this.props.onMouseEnter,
687
601
  onMouseLeave: this.props.onMouseLeave,
602
+ onReset: this.props.onReset,
603
+ placeholder: placeholder
604
+ }, hiSelectInputProps, {
688
605
  refElement: el => {
689
- this.selectInputElement = el;
690
- },
691
- onReset: this.props.onReset
692
- }), open && staticPosition ? React.createElement("div", {
693
- style: popperStyle
694
- }, content) : React.createElement(Popper, {
606
+ this.inputEl = el;
607
+ }
608
+ })), open && staticPosition ? React.createElement("div", {
609
+ style: popperStyle,
610
+ className: popperClass
611
+ }, content({})) : React.createElement(Popper, {
695
612
  anchorEl: this.inputEl,
696
613
  placement: "bottom-start",
697
614
  open: open,
698
615
  className: popperClass,
699
- style: popperStyle,
700
- disablePortal: true
616
+ disablePortal: true,
617
+ style: popperStyle
701
618
  }, content));
702
619
  }
703
620
 
704
621
  }
705
622
 
706
623
  HiSelect.defaultProps = {
707
- containerWidth: 0,
624
+ align: 'left',
625
+ autoFocus: false,
708
626
  disabled: false,
709
627
  displayAsChip: false,
710
- dynamic: false,
711
628
  error: false,
712
629
  hasAll: false,
713
- hasMore: false,
714
- hierarchic: false,
715
- iconAll: false,
716
- infiniteScroll: false,
717
- loadingMoreResults: false,
630
+ hiSelectableListProps: {},
631
+ hiSelectInputProps: {},
632
+ hiSearchInputProps: {},
718
633
  multiple: false,
719
- parentItemSelectable: false,
720
- type: 'text',
634
+ placeholder: '',
635
+ searchable: false,
636
+ staticPosition: false,
721
637
  translations: {
722
638
  all: 'All',
723
639
  no_result_match: 'No result match',
@@ -727,14 +643,16 @@ HiSelect.defaultProps = {
727
643
  n_children: '%s items',
728
644
  one_child: '%s item'
729
645
  },
730
- searchable: false,
731
- staticPosition: false
646
+ type: 'text',
647
+ filterFunc: filterValue
732
648
  };
733
649
  HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
650
+ align: PropTypes.oneOf(['left', 'right']),
651
+
734
652
  /**
735
- * Icon affiché lorsque l'item est sélectionné
653
+ * Permet de forcer le focus sur le composant
736
654
  */
737
- checkedIcon: PropTypes.node,
655
+ autoFocus: PropTypes.bool,
738
656
 
739
657
  /**
740
658
  * Useful to extend the style applied to components.
@@ -756,77 +674,56 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
756
674
  */
757
675
  displayAsChip: PropTypes.bool,
758
676
 
759
- /**
760
- * Option permettant de définir si les options du select sont dynamiques.
761
- * Si les options du select sont initialisées à vide, alors ce sera mis à true
762
- * automatiquement.
763
- */
764
- dynamic: PropTypes.bool,
765
-
766
677
  /**
767
678
  * Applique le style error
768
679
  */
769
680
  error: PropTypes.bool,
770
681
 
771
682
  /**
772
- * Affiche l'élément 'All'
683
+ * Chemin vers l'image à afficher par défaut si une image n'est pas trouvée
773
684
  */
774
- hasAll: PropTypes.bool,
685
+ fallbackImage: PropTypes.string,
686
+
687
+ /*
688
+ * Fonction de filtrage custom
689
+ */
690
+ filterFunc: PropTypes.func,
775
691
 
776
692
  /**
777
- * Indique si l'infinite scroll doit rechercher de nouveaux résultats
693
+ * Affiche l'élément 'All'
778
694
  */
779
- hasMore: PropTypes.bool,
695
+ hasAll: PropTypes.bool,
780
696
 
781
697
  /**
782
- * Les items sont hiérarchisés
698
+ * Override HiInput props (for search)
783
699
  */
784
- hierarchic: PropTypes.bool,
700
+ hiSearchInputProps: PropTypes.object,
785
701
 
786
702
  /**
787
- * Icon affiché lorsque l'item n'est pas sélectionné et qu'on le survole
703
+ * Override HiSelectableList props
788
704
  */
789
- hoverIcon: PropTypes.node,
705
+ hiSelectableListProps: PropTypes.object,
790
706
 
791
707
  /**
792
- * Icon affiché lorsque l'item n'est pas sélectionné
708
+ * Override HiSelectInput props
793
709
  */
794
- icon: PropTypes.node,
710
+ hiSelectInputProps: PropTypes.object,
795
711
 
796
712
  /**
797
713
  * Nom de l'icône
798
714
  */
799
- iconAll: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
715
+ iconAll: PropTypes.string,
800
716
 
801
717
  /**
802
718
  * id du select
803
719
  */
804
720
  id: PropTypes.string,
805
721
 
806
- /**
807
- * Infinite scroll dans le select dans le cas où il y a beaucoup de résultats à afficher
808
- * afin d'éviter un lag du navigateur
809
- */
810
- infiniteScroll: PropTypes.bool,
811
-
812
722
  /**
813
723
  * Ajoute un loader
814
724
  */
815
725
  loading: PropTypes.bool,
816
726
 
817
- /**
818
- * Ajoute un loader en bas pour l'infiniteScroll
819
- */
820
- loadingMoreResults: PropTypes.bool,
821
-
822
- /**
823
- * Fonction de callback appelée lorsque l'utilisateur arrive en bas de la liste des options
824
- * afin de charger les nouvelles options
825
- *
826
- * @param {int} pageNumber
827
- */
828
- loadMoreResults: PropTypes.func,
829
-
830
727
  /**
831
728
  * Autorise la sélection de plusieurs valeurs
832
729
  */
@@ -845,11 +742,6 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
845
742
  */
846
743
  onChange: PropTypes.func.isRequired,
847
744
 
848
- /**
849
- * Fonction de callback appelée click dans l'input
850
- */
851
- onClick: PropTypes.func,
852
-
853
745
  /**
854
746
  * Fonction de callback appelée lorsqu'on ferme le select
855
747
  */
@@ -871,18 +763,14 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
871
763
  onReset: PropTypes.func,
872
764
 
873
765
  /**
874
- * Fonction de callback appelée lorsqu'on écrit dans la barre de recherche
875
- * A utiliser pour les selects avec des données dynamiques
876
- *
877
- * @param {object} event
878
- * @param {string} value
766
+ * Fonction de callback appelée lorsque le scroll atteint le bas de la liste
879
767
  */
880
- onSearch: PropTypes.func,
768
+ onScrollReachBottom: PropTypes.func,
881
769
 
882
770
  /**
883
- * Fonction de callback à la pression de la touche "Entrée"
771
+ * Fonction de callback appelée lorsque le champs de recherche est utilisé
884
772
  */
885
- onSubmit: PropTypes.func,
773
+ onSearch: PropTypes.func,
886
774
 
887
775
  /**
888
776
  * Listes des options du select
@@ -890,23 +778,7 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
890
778
  options: PropTypes.array.isRequired,
891
779
 
892
780
  /**
893
- * Icon affiché lorsqu'un item parent n'est pas sélectionné
894
- */
895
- parentIcon: PropTypes.node,
896
-
897
- /**
898
- * Les items parents sont sélectionnables
899
- */
900
- parentItemSelectable: PropTypes.bool,
901
-
902
- /**
903
- * Item épinglé en début de liste
904
- */
905
- pinnedItem: PropTypes.object,
906
-
907
- /**
908
- * Placeholder affiché lorsque le select est fermé
909
- * Surcharge le placeholder par défaut
781
+ * Placeholder affiché lorsque l'input est vide
910
782
  */
911
783
  placeholder: PropTypes.string,
912
784
 
@@ -916,7 +788,12 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
916
788
  searchable: PropTypes.bool,
917
789
 
918
790
  /**
919
- * Si true, le contenu du select sera dans une div static plutot que dans une popper absolute
791
+ * Node qui s'ajoute entre la barre de recherche et la liste de résultats
792
+ */
793
+ startAdornment: PropTypes.object,
794
+
795
+ /**
796
+ * Si true, le contenu du select sera dans une div static plutôt que dans une popper absolute
920
797
  */
921
798
  staticPosition: PropTypes.bool,
922
799