@hipay/hipay-material-ui 2.0.0-beta.55 → 2.0.0-beta.57

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/HiBreadcrumb/HiBreadcrumb.js +14 -4
  3. package/HiBreadcrumb/HiStep.js +4 -1
  4. package/HiBreadcrumb/HiStepContent.js +0 -1
  5. package/HiBreadcrumb/HiStepLabel.js +12 -4
  6. package/HiBreadcrumb/HiStepper.js +1 -1
  7. package/HiButton/HiButton.js +7 -1
  8. package/HiCell/CellIcon.js +4 -4
  9. package/HiCell/CellImage.js +13 -1
  10. package/HiCell/CellRate.js +6 -3
  11. package/HiCell/CellSentinel.js +7 -10
  12. package/HiCell/CellTextStyled.js +29 -1
  13. package/HiColoredLabel/HiColoredLabel.js +1 -1
  14. package/HiDatePicker/Caption.js +16 -10
  15. package/HiDatePicker/HiDatePicker.js +9 -3
  16. package/HiDatePicker/HiDateRangePicker.js +36 -22
  17. package/HiDatePicker/HiDateRangeSelector.js +75 -21
  18. package/HiDatePicker/NavBar.js +8 -1
  19. package/HiDatePicker/Overlays/CustomOverlayLayout.js +26 -17
  20. package/HiDatePicker/Overlays/CustomOverlayLayoutWithoutFooter.js +123 -0
  21. package/HiDatePicker/Overlays/MonthPickerOverlay.js +4 -4
  22. package/HiDatePicker/Overlays/MonthPickerOverlay.spec.js +1 -0
  23. package/HiDatePicker/Overlays/Overlay.js +15 -8
  24. package/HiDatePicker/Overlays/Overlay.spec.js +1 -0
  25. package/HiDatePicker/Overlays/TimePickerOverlay.js +2 -2
  26. package/HiDatePicker/Overlays/TimePickerOverlay.spec.js +1 -0
  27. package/HiDatePicker/Overlays/YearPickerOverlay.js +4 -6
  28. package/HiDatePicker/Overlays/YearPickerOverlay.spec.js +1 -0
  29. package/HiDatePicker/hiLocaleUtils.js +144 -0
  30. package/HiDatePicker/stylesheet.js +33 -7
  31. package/HiDotsStepper/HiDot.js +108 -0
  32. package/HiDotsStepper/HiDotsStepper.js +121 -0
  33. package/HiExpansionPanel/HiExpansionPanel.js +1 -1
  34. package/HiForm/HiAddressField.js +176 -0
  35. package/HiForm/HiFormControl.js +2 -0
  36. package/HiForm/HiInput.js +3 -3
  37. package/HiForm/HiSlider.js +352 -0
  38. package/HiForm/HiUpload.js +204 -0
  39. package/HiForm/HiUploadField.js +182 -0
  40. package/HiForm/HiUploadInput.js +459 -0
  41. package/HiForm/index.js +16 -0
  42. package/HiMap/HiMap.js +345 -0
  43. package/HiMap/HiMapExpand.js +210 -0
  44. package/HiMap/index.js +23 -0
  45. package/HiNotice/HiKPI.js +238 -0
  46. package/HiNotice/HiKPINotice.js +96 -0
  47. package/HiNotice/index.js +23 -0
  48. package/HiPdfReader/HiPdfReader.js +269 -0
  49. package/HiPdfReader/index.js +15 -0
  50. package/HiPin/HiPin.js +1 -1
  51. package/HiRadio/HiRadio.js +74 -0
  52. package/HiRadio/index.js +15 -0
  53. package/HiSelect/HiSelect.js +73 -84
  54. package/HiSelect/HiSuggestSelect.js +35 -4
  55. package/HiSelect/SelectInput.js +9 -1
  56. package/HiSelectNew/HiNestedSelectContent.js +5 -1
  57. package/HiSelectNew/HiSelect.js +260 -179
  58. package/HiSelectNew/HiSelectContent.js +0 -8
  59. package/HiSelectNew/HiSelectInput.js +8 -9
  60. package/HiSelectableList/HiSelectableList.js +39 -4
  61. package/HiSelectableList/HiSelectableListItem.js +81 -38
  62. package/HiTable/HiCellBuilder.js +25 -12
  63. package/HiTable/HiTableHeader.js +16 -17
  64. package/HiTable/constants.js +3 -1
  65. package/README.md +248 -98
  66. package/es/HiBreadcrumb/HiBreadcrumb.js +14 -4
  67. package/es/HiBreadcrumb/HiStep.js +4 -1
  68. package/es/HiBreadcrumb/HiStepContent.js +0 -1
  69. package/es/HiBreadcrumb/HiStepLabel.js +13 -4
  70. package/es/HiBreadcrumb/HiStepper.js +1 -1
  71. package/es/HiButton/HiButton.js +7 -0
  72. package/es/HiCell/CellIcon.js +5 -5
  73. package/es/HiCell/CellImage.js +13 -1
  74. package/es/HiCell/CellRate.js +6 -3
  75. package/es/HiCell/CellSentinel.js +7 -10
  76. package/es/HiCell/CellTextStyled.js +28 -1
  77. package/es/HiColoredLabel/HiColoredLabel.js +1 -1
  78. package/es/HiDatePicker/Caption.js +14 -10
  79. package/es/HiDatePicker/HiDatePicker.js +8 -3
  80. package/es/HiDatePicker/HiDateRangePicker.js +40 -28
  81. package/es/HiDatePicker/HiDateRangeSelector.js +69 -21
  82. package/es/HiDatePicker/ListPicker.js +1 -1
  83. package/es/HiDatePicker/NavBar.js +7 -1
  84. package/es/HiDatePicker/Overlays/CustomOverlayLayout.js +30 -19
  85. package/es/HiDatePicker/Overlays/CustomOverlayLayoutWithoutFooter.js +106 -0
  86. package/es/HiDatePicker/Overlays/MonthPickerOverlay.js +5 -5
  87. package/es/HiDatePicker/Overlays/MonthPickerOverlay.spec.js +1 -0
  88. package/es/HiDatePicker/Overlays/Overlay.js +16 -9
  89. package/es/HiDatePicker/Overlays/Overlay.spec.js +1 -0
  90. package/es/HiDatePicker/Overlays/TimePickerOverlay.js +2 -2
  91. package/es/HiDatePicker/Overlays/TimePickerOverlay.spec.js +1 -0
  92. package/es/HiDatePicker/Overlays/YearPickerOverlay.js +4 -6
  93. package/es/HiDatePicker/Overlays/YearPickerOverlay.spec.js +1 -0
  94. package/es/HiDatePicker/hiLocaleUtils.js +131 -0
  95. package/es/HiDatePicker/stylesheet.js +32 -7
  96. package/es/HiDotsStepper/HiDot.js +66 -0
  97. package/es/HiDotsStepper/HiDotsStepper.js +73 -0
  98. package/es/HiExpansionPanel/HiExpansionPanel.js +1 -1
  99. package/es/HiForm/HiAddressField.js +134 -0
  100. package/es/HiForm/HiFormControl.js +2 -0
  101. package/es/HiForm/HiInput.js +3 -3
  102. package/es/HiForm/HiSlider.js +302 -0
  103. package/es/HiForm/HiUpload.js +158 -0
  104. package/es/HiForm/HiUploadField.js +140 -0
  105. package/es/HiForm/HiUploadInput.js +411 -0
  106. package/es/HiForm/index.js +2 -0
  107. package/es/HiMap/HiMap.js +290 -0
  108. package/es/HiMap/HiMapExpand.js +162 -0
  109. package/es/HiMap/index.js +2 -0
  110. package/es/HiNotice/HiKPI.js +196 -0
  111. package/es/HiNotice/HiKPINotice.js +78 -0
  112. package/es/HiNotice/index.js +2 -0
  113. package/es/HiPdfReader/HiPdfReader.js +214 -0
  114. package/es/HiPdfReader/index.js +1 -0
  115. package/es/HiPin/HiPin.js +1 -1
  116. package/es/HiRadio/HiRadio.js +55 -0
  117. package/es/HiRadio/index.js +1 -0
  118. package/es/HiSelect/HiSelect.js +68 -78
  119. package/es/HiSelect/HiSuggestSelect.js +30 -4
  120. package/es/HiSelect/SelectInput.js +9 -1
  121. package/es/HiSelectNew/HiNestedSelectContent.js +5 -1
  122. package/es/HiSelectNew/HiSelect.js +246 -162
  123. package/es/HiSelectNew/HiSelectContent.js +0 -7
  124. package/es/HiSelectNew/HiSelectInput.js +8 -9
  125. package/es/HiSelectableList/HiSelectableList.js +34 -6
  126. package/es/HiSelectableList/HiSelectableListItem.js +92 -40
  127. package/es/HiTable/HiCellBuilder.js +130 -123
  128. package/es/HiTable/HiTableHeader.js +14 -12
  129. package/es/HiTable/constants.js +1 -0
  130. package/es/index.js +9 -1
  131. package/es/utils/helpers.js +1 -1
  132. package/index.es.js +9 -1
  133. package/index.js +66 -2
  134. package/package.json +5 -2
  135. package/umd/hipay-material-ui.development.js +44450 -40930
  136. package/umd/hipay-material-ui.production.min.js +2 -2
  137. package/utils/helpers.js +1 -1
@@ -15,7 +15,7 @@ import withStyles from '../styles/withStyles';
15
15
  import { getNextItemSelectable, foldAccents } from '../utils/helpers';
16
16
  import HiIcon from '../HiIcon';
17
17
  import keycode from 'keycode';
18
- import classNames from "classnames";
18
+ import classNames from 'classnames';
19
19
  export const styles = theme => ({
20
20
  root: {
21
21
  backgroundColor: theme.palette.background2,
@@ -64,7 +64,10 @@ export const styles = theme => ({
64
64
  }, theme.typography.b1, {
65
65
  display: 'inline-flex',
66
66
  width: '100%'
67
- })
67
+ }),
68
+ separator: {
69
+ borderTop: `1px solid ${theme.palette.input.bottomLine}`
70
+ }
68
71
  });
69
72
  /**
70
73
  *
@@ -85,6 +88,104 @@ class HiSelect extends React.PureComponent {
85
88
  constructor(props) {
86
89
  super(props);
87
90
 
91
+ this.buildSelectProps = (options, value = [], search = '', loading = false) => {
92
+ // build item list
93
+ const itemList = [...(loading ? [{
94
+ id: '_loading',
95
+ type: 'loader',
96
+ disabled: true,
97
+ centered: true,
98
+ hideCheckbox: true,
99
+ label: 'loading'
100
+ }] : []), // simple one level filter on label
101
+ ...(search !== '' ? [...options.filter(item => item.label && foldAccents(item.label.toString().toLowerCase()).search(foldAccents(search.toLowerCase())) !== -1)] : [...(this.props.hasAll ? [_objectSpread({
102
+ id: '_all',
103
+ label: this.props.translations.all
104
+ }, this.props.iconAll && {
105
+ type: 'icon',
106
+ icon: this.props.iconAll
107
+ })] : []), ...options])];
108
+ return {
109
+ itemList,
110
+ inputValue: this.buildInputValue(options, value, loading)
111
+ };
112
+ };
113
+
114
+ this.buildInputValue = (options, value = [], loading = false) => {
115
+ const {
116
+ classes,
117
+ hasAll,
118
+ translations,
119
+ type
120
+ } = this.props; // build input value
121
+
122
+ let inputValue;
123
+
124
+ if (loading && value.length === 1) {
125
+ inputValue = translations.one_item_selected;
126
+ } else if (hasAll && options.length === value.length) {
127
+ inputValue = translations.all;
128
+ value.unshift('_all');
129
+ } else if (value.length > 1) {
130
+ inputValue = translations.n_items_selected.replace('%s', value.length);
131
+ } else if (value.length === 1) {
132
+ const item = options.find(o => o.id === value[0]);
133
+
134
+ if (item === undefined) {
135
+ inputValue = translations.one_item_selected;
136
+ } else if (type === 'icon' || item.type === 'icon') {
137
+ inputValue = React.createElement("span", {
138
+ className: classes.selectIconLabel
139
+ }, React.createElement(HiIcon, {
140
+ className: classes.labelIcon,
141
+ icon: item.icon
142
+ }), item.label);
143
+ } else if (type === 'image' || item.type === 'image') {
144
+ inputValue = React.createElement("span", {
145
+ className: classes.selectIconLabel
146
+ }, React.createElement("img", {
147
+ className: classes.labelImg,
148
+ src: item.img,
149
+ alt: item.label,
150
+ onError: e => {
151
+ if (item.fallbackImage) {
152
+ e.target.src = `${item.fallbackImage}`;
153
+ } else {
154
+ e.target.style.display = 'none';
155
+ }
156
+ }
157
+ }), item.label);
158
+ } else {
159
+ inputValue = item.label;
160
+ }
161
+ }
162
+
163
+ return inputValue;
164
+ };
165
+
166
+ this.focusOnFirstItem = () => {
167
+ const overlay = findDOMNode(this.overlay);
168
+ setTimeout(() => {
169
+ const item = overlay.getElementsByTagName('li')[0];
170
+ item.focus();
171
+ }, 1);
172
+ };
173
+
174
+ this.getInputElement = el => {
175
+ this.searchField = el;
176
+
177
+ if (this.props.inputRef) {
178
+ this.props.inputRef(this.searchField);
179
+ }
180
+ };
181
+
182
+ this.handleBlur = () => {
183
+ this.handleSearchReset();
184
+ this.setState({
185
+ focused: false
186
+ });
187
+ };
188
+
88
189
  this.handleClick = () => {
89
190
  if (this.state.open) {
90
191
  this.handleClose();
@@ -96,20 +197,58 @@ class HiSelect extends React.PureComponent {
96
197
  if (this.props.onClick) this.props.onClick(); // Gestion du focus
97
198
 
98
199
  if (!this.props.searchable) {
99
- // sinon focus sur le premier élément de la liste
100
- this.focusOnFirstItem();
200
+ // Sinon focus sur l'élément sélectionné
201
+ this.focusOnSelectedItem(this.props.value);
101
202
  }
102
203
  }
103
204
  };
104
205
 
105
- this.focusOnFirstItem = () => {
206
+ this.focusOnSelectedItem = selectedValue => {
106
207
  const overlay = findDOMNode(this.overlay);
107
208
  setTimeout(() => {
108
- const item = overlay.getElementsByTagName('li')[0];
109
- item.focus();
209
+ // On initialise au premier élément pour être sûr de ne pas se retrouver avec un focus of undefined
210
+ let item = overlay.getElementsByTagName('li')[0];
211
+
212
+ if (selectedValue && typeof selectedValue === 'string') {
213
+ item = overlay.getElementsByTagName('li')[selectedValue];
214
+ } else if (selectedValue && typeof selectedValue === 'number') {
215
+ item = overlay.getElementsByTagName('li')[selectedValue - 1];
216
+ }
217
+
218
+ if (item) {
219
+ item.focus();
220
+ }
110
221
  }, 1);
111
222
  };
112
223
 
224
+ this.handleClickAway = event => {
225
+ // Au clic sur le bouton, on laisse le handleClick fermer le select
226
+ if (!this.inputEl.contains(event.target)) {
227
+ this.handleClose(event);
228
+ }
229
+ };
230
+
231
+ this.handleClose = () => {
232
+ this.handleSearchReset();
233
+ this.setState({
234
+ open: false
235
+ });
236
+
237
+ if (this.props.onClose) {
238
+ this.props.onClose();
239
+ }
240
+
241
+ if (this.inputEl) {
242
+ this.inputEl.focus();
243
+ }
244
+ };
245
+
246
+ this.handleFocus = () => {
247
+ this.setState({
248
+ focused: true
249
+ });
250
+ };
251
+
113
252
  this.handleKeyDown = event => {
114
253
  let nextItem;
115
254
  const key = keycode(event);
@@ -120,7 +259,17 @@ class HiSelect extends React.PureComponent {
120
259
  } else if (key === 'up') {
121
260
  event.preventDefault();
122
261
  nextItem = getNextItemSelectable(document.activeElement, 'up');
123
- } else if (key === 'tab' || key === 'esc') {
262
+ }
263
+
264
+ if (nextItem) {
265
+ nextItem.focus();
266
+ }
267
+ };
268
+
269
+ this.handleKeyUp = event => {
270
+ const key = keycode(event);
271
+
272
+ if (key === 'tab' || key === 'esc') {
124
273
  this.setState({
125
274
  open: false
126
275
  });
@@ -132,10 +281,6 @@ class HiSelect extends React.PureComponent {
132
281
  event.preventDefault();
133
282
  this.handleClose();
134
283
  }
135
-
136
- if (nextItem) {
137
- nextItem.focus();
138
- }
139
284
  };
140
285
 
141
286
  this.handleKeyDownSearch = event => {
@@ -149,36 +294,9 @@ class HiSelect extends React.PureComponent {
149
294
  }
150
295
  };
151
296
 
152
- this.handleFocus = () => {
153
- this.setState({
154
- focused: true
155
- });
156
- };
157
-
158
- this.handleBlur = () => {
159
- this.setState({
160
- focused: false
161
- });
162
- };
163
-
164
- this.handleClose = () => {
165
- this.setState({
166
- open: false
167
- });
168
-
169
- if (this.props.onClose) {
170
- this.props.onClose();
171
- }
172
-
173
- if (this.inputEl) {
174
- this.inputEl.focus();
175
- }
176
- };
177
-
178
- this.handleClickAway = event => {
179
- // Au clic sur le bouton, on laisse le handleClick fermer le select
180
- if (!this.inputEl.contains(event.target)) {
181
- this.handleClose(event);
297
+ this.handleScroll = e => {
298
+ if (e.target.scrollHeight - e.target.clientHeight - e.target.scrollTop < 15) {
299
+ this.props.onScrollReachBottom();
182
300
  }
183
301
  };
184
302
 
@@ -244,12 +362,6 @@ class HiSelect extends React.PureComponent {
244
362
  }
245
363
  };
246
364
 
247
- this.handleScroll = e => {
248
- if (e.target.scrollHeight - e.target.clientHeight - e.target.scrollTop < 15) {
249
- this.props.onScrollReachBottom();
250
- }
251
- };
252
-
253
365
  this.handleSearch = (e, inputValue) => {
254
366
  const searchValue = inputValue && e.target.value ? inputValue : e.target.value;
255
367
 
@@ -270,79 +382,12 @@ class HiSelect extends React.PureComponent {
270
382
  }, '');
271
383
  };
272
384
 
273
- this.buildSelectProps = (options, value = [], search = '', loading = false) => {
274
- // build item list
275
- const itemList = [...(loading ? [{
276
- id: '_loading',
277
- type: 'loader',
278
- disabled: true,
279
- centered: true,
280
- hideCheckbox: true,
281
- label: 'loading'
282
- }] : []), // simple one level filter on label
283
- ...(search !== '' ? [...options.filter(item => item.label && foldAccents(item.label.toString().toLowerCase()).search(foldAccents(search.toLowerCase())) !== -1)] : [...(this.props.hasAll ? [_objectSpread({
284
- id: '_all',
285
- label: this.props.translations.all
286
- }, this.props.iconAll && {
287
- type: 'icon',
288
- icon: this.props.iconAll
289
- })] : []), ...options])];
290
- return {
291
- itemList,
292
- inputValue: this.buildInputValue(options, value, loading)
293
- };
294
- };
295
-
296
- this.buildInputValue = (options, value = [], loading = false) => {
297
- const {
298
- classes,
299
- hasAll,
300
- translations,
301
- type
302
- } = this.props; // build input value
303
-
304
- let inputValue;
305
-
306
- if (loading && value.length === 1) {
307
- inputValue = translations.one_item_selected;
308
- } else if (hasAll && options.length === value.length) {
309
- inputValue = translations.all;
310
- value.unshift('_all');
311
- } else if (value.length > 1) {
312
- inputValue = translations.n_items_selected.replace('%s', value.length);
313
- } else if (value.length === 1) {
314
- const item = options.find(o => o.id === value[0]);
315
-
316
- if (item === undefined) {
317
- inputValue = translations.one_item_selected;
318
- } else if (type === 'icon' || item.type === 'icon') {
319
- inputValue = React.createElement("span", {
320
- className: classes.selectIconLabel
321
- }, React.createElement(HiIcon, {
322
- className: classes.labelIcon,
323
- icon: item.icon
324
- }), item.label);
325
- } else if (type === 'image' || item.type === 'image') {
326
- inputValue = React.createElement("span", {
327
- className: classes.selectIconLabel
328
- }, React.createElement("img", {
329
- className: classes.labelImg,
330
- src: item.img,
331
- alt: item.label
332
- }), item.label);
333
- } else {
334
- inputValue = item.label;
335
- }
336
- }
337
-
338
- return inputValue;
339
- };
340
-
341
385
  this.state = {
342
386
  open: false,
343
387
  focused: false,
344
388
  searchValue: props.searchValue ? undefined : '',
345
- suggestions: props.options
389
+ suggestions: props.options,
390
+ openDown: true
346
391
  };
347
392
  this.handleClick = this.handleClick.bind(this);
348
393
  this.handleClose = this.handleClose.bind(this);
@@ -365,14 +410,15 @@ class HiSelect extends React.PureComponent {
365
410
 
366
411
  return null;
367
412
  }
413
+ /**
414
+ * Build itemList & inputValue from select props
415
+ * @param options
416
+ * @param value
417
+ * @param search
418
+ * @param loading
419
+ * @returns {{itemList: *[], inputValue: *}}
420
+ */
368
421
 
369
- getInputElement(el) {
370
- this.searchField = el;
371
-
372
- if (this.props.inputRef) {
373
- this.props.inputRef(this.searchField);
374
- }
375
- }
376
422
 
377
423
  render() {
378
424
  const {
@@ -387,6 +433,7 @@ class HiSelect extends React.PureComponent {
387
433
  value,
388
434
  multiple,
389
435
  translations,
436
+ hiSearchInputProps,
390
437
  hiSelectableListProps,
391
438
  hiSelectInputProps,
392
439
  id,
@@ -436,43 +483,74 @@ class HiSelect extends React.PureComponent {
436
483
  [classes.popperWidth]: !this.props.containerWidth,
437
484
  [classes.popperRightAlign]: this.props.containerWidth && this.props.align === 'right'
438
485
  });
439
- const content = React.createElement(ClickAwayListener, {
440
- onClickAway: this.handleClickAway
441
- }, React.createElement(Grow, {
442
- in: open,
443
- id: "menu-list",
444
- style: {
445
- transformOrigin: '0 0 0'
486
+
487
+ let searchInput = position => {
488
+ if (!!searchable) {
489
+ return React.createElement(HiInput, _extends({
490
+ value: searchValue,
491
+ autoFocus: true,
492
+ inputRef: this.getInputElement,
493
+ onKeyDown: this.handleKeyDownSearch,
494
+ onChange: this.handleSearch,
495
+ onReset: this.handleSearchReset,
496
+ placeholder: translations.search,
497
+ startAdornment: 'search',
498
+ tabIndex: 0,
499
+ className: classNames({
500
+ [classes.separator]: position === 'top'
501
+ })
502
+ }, hiSearchInputProps));
446
503
  }
447
- }, React.createElement(Paper, {
448
- className: classes.paper
449
- }, !!searchable && React.createElement(HiInput, {
450
- value: searchValue,
451
- autoFocus: true,
452
- inputRef: this.getInputElement,
453
- onKeyDown: this.handleKeyDownSearch,
454
- onChange: this.handleSearch,
455
- onReset: this.handleSearchReset,
456
- placeholder: translations.search,
457
- startAdornment: 'search',
458
- tabIndex: 0
459
- }), startAdornment, React.createElement(Scrollbars, _extends({
460
- ref: contentEl => {
461
- this.optionsContent = contentEl;
462
- },
463
- autoHeight: true,
464
- autoHeightMax: 400 // TODO ?
465
-
466
- }, onScrollReachBottom && {
467
- onScroll: this.handleScroll
468
- }), React.createElement(HiSelectableList, _extends({
469
- type: type,
470
- itemList: itemList,
471
- onKeyDown: this.handleKeyDown,
472
- onSelect: this.handleSelect,
473
- selectedItemIdList: selectedItemIdList,
474
- fallbackImage: this.props.fallbackImage
475
- }, hiSelectableListProps))))));
504
+
505
+ return null;
506
+ }; // Replace popper onSearch when popper displayed on top of selectButton
507
+
508
+
509
+ if (this.placement && this.placement.indexOf('top') >= 0 && !!searchable) {
510
+ // +1 for search input
511
+ let nbItems = itemList.length <= 10 ? itemList.length + 1 : 11;
512
+ popperStyle.transform = `translate3d(-1px, -${nbItems * 40 + 2}px, 0px)`;
513
+ } else if (this.placement && this.placement.indexOf('top') < 0 && !!searchable) {
514
+ popperStyle.transform = `translate3d(-1px, 40px, 0px)`;
515
+ }
516
+
517
+ let content = ({
518
+ placement
519
+ }) => {
520
+ if (placement !== this.placement) {
521
+ this.placement = placement;
522
+ }
523
+
524
+ return React.createElement(ClickAwayListener, {
525
+ onClickAway: this.handleClickAway
526
+ }, React.createElement(Grow, {
527
+ in: open,
528
+ id: "menu-list",
529
+ style: {
530
+ transformOrigin: '0 0 0'
531
+ }
532
+ }, React.createElement(Paper, {
533
+ className: classes.paper
534
+ }, (this.placement && this.placement.indexOf('bottom') >= 0 || staticPosition) && searchInput('bottom'), startAdornment, React.createElement(Scrollbars, _extends({
535
+ ref: contentEl => {
536
+ this.optionsContent = contentEl;
537
+ },
538
+ autoHeight: true,
539
+ autoHeightMax: 400 // TODO ?
540
+
541
+ }, onScrollReachBottom && {
542
+ onScroll: this.handleScroll
543
+ }), React.createElement(HiSelectableList, _extends({
544
+ type: type,
545
+ itemList: itemList,
546
+ onKeyDown: this.handleKeyDown,
547
+ onKeyUp: this.handleKeyUp,
548
+ onSelect: this.handleSelect,
549
+ selectedItemIdList: selectedItemIdList,
550
+ fallbackImage: this.props.fallbackImage
551
+ }, hiSelectableListProps))), this.placement && this.placement.indexOf('top') >= 0 && !staticPosition && searchInput('top'))));
552
+ };
553
+
476
554
  return React.createElement("div", {
477
555
  className: classes.root,
478
556
  ref: el => {
@@ -502,7 +580,7 @@ class HiSelect extends React.PureComponent {
502
580
  })), open && staticPosition ? React.createElement("div", {
503
581
  style: popperStyle,
504
582
  className: popperClass
505
- }, content) : React.createElement(Popper, {
583
+ }, content({})) : React.createElement(Popper, {
506
584
  anchorEl: this.inputEl,
507
585
  placement: "bottom-start",
508
586
  open: open,
@@ -522,6 +600,7 @@ HiSelect.defaultProps = {
522
600
  hasAll: false,
523
601
  hiSelectableListProps: {},
524
602
  hiSelectInputProps: {},
603
+ hiSearchInputProps: {},
525
604
  multiple: false,
526
605
  placeholder: '',
527
606
  searchable: false,
@@ -576,7 +655,12 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
576
655
  hasAll: PropTypes.bool,
577
656
 
578
657
  /**
579
- * Override HiSelectableList props (
658
+ * Override HiInput props (for search)
659
+ */
660
+ hiSearchInputProps: PropTypes.object,
661
+
662
+ /**
663
+ * Override HiSelectableList props
580
664
  */
581
665
  hiSelectableListProps: PropTypes.object,
582
666
 
@@ -7,7 +7,6 @@ import HiSelectableList from '../HiSelectableList';
7
7
  import HiInput from '../HiForm/HiInput';
8
8
  import withStyles from '../styles/withStyles';
9
9
  import { getNextItemSelectable, foldAccents } from '../utils/helpers';
10
- import HiIcon from '../HiIcon';
11
10
  import keycode from 'keycode';
12
11
  export const styles = theme => ({
13
12
  labelIcon: {
@@ -243,9 +242,6 @@ class HiSelectContent extends React.PureComponent {
243
242
 
244
243
  render() {
245
244
  const {
246
- classes,
247
- disabled,
248
- error,
249
245
  loading,
250
246
  options,
251
247
  searchable,
@@ -254,10 +250,7 @@ class HiSelectContent extends React.PureComponent {
254
250
  multiple,
255
251
  translations,
256
252
  hiSelectableListProps,
257
- hiSelectInputProps,
258
- id,
259
253
  onScrollReachBottom,
260
- onSubmit,
261
254
  startAdornment,
262
255
  searchValue = this.state.searchValue,
263
256
  buildSelectProps = this.buildSelectProps,
@@ -162,14 +162,12 @@ class HiSelectInput extends React.PureComponent {
162
162
  this.handleBlur = event => {
163
163
  if ((!this.input || !this.input.contains(event.relatedTarget)) && this.props.onBlur) {
164
164
  this.props.onBlur(event);
165
- } else {
166
- if (this.input && (!this.resetIcon || !this.resetIcon.contains(event.relatedTarget))) {
167
- this.input.focus();
168
- }
165
+ } else if (this.input && (!this.resetIcon || !this.resetIcon.contains(event.relatedTarget))) {
166
+ this.input.focus();
169
167
  }
170
168
  };
171
169
 
172
- this.handleRef = el => {
170
+ this.ref = el => {
173
171
  this.input = el;
174
172
 
175
173
  if (this.props.refElement) {
@@ -180,7 +178,7 @@ class HiSelectInput extends React.PureComponent {
180
178
  this.handleKeyDown = this.handleKeyDown.bind(this);
181
179
  this.handleClick = this.handleClick.bind(this);
182
180
  this.handleBlur = this.handleBlur.bind(this);
183
- this.handleRef = this.handleRef.bind(this);
181
+ this.ref = this.ref.bind(this);
184
182
  this.handleReset = this.handleReset.bind(this);
185
183
  }
186
184
 
@@ -219,7 +217,7 @@ class HiSelectInput extends React.PureComponent {
219
217
  onBlur: this.props.onBlur,
220
218
  role: "button",
221
219
  tabIndex: "0",
222
- ref: this.handleRef
220
+ ref: this.ref
223
221
  }, React.createElement("span", {
224
222
  className: classNames(classes.label, {
225
223
  [classes.placeholder]: value === undefined
@@ -235,8 +233,9 @@ class HiSelectInput extends React.PureComponent {
235
233
  onMouseLeave: this.props.onMouseLeave,
236
234
  onKeyDown: this.handleKeyDown,
237
235
  onFocus: this.props.onFocus,
238
- onBlur: this.handleBlur,
239
- buttonRef: this.handleRef
236
+ onBlur: this.handleBlur // buttref={this.ref}
237
+ ,
238
+ buttonRef: this.ref
240
239
  }, React.createElement("span", {
241
240
  className: classNames(classes.label, {
242
241
  [classes.placeholder]: value === undefined
@@ -5,7 +5,8 @@ import PropTypes from 'prop-types';
5
5
  import List from '@material-ui/core/List';
6
6
  import withStyles from '../styles/withStyles';
7
7
  import HiSelectableListItem from './HiSelectableListItem';
8
- import { foldAccents } from '../utils/helpers';
8
+ import { foldAccents, getNextItemSelectable } from '../utils/helpers';
9
+ import keycode from 'keycode';
9
10
  export const styles = () => ({
10
11
  root: {
11
12
  padding: 0
@@ -23,6 +24,31 @@ class HiSelectableList extends React.PureComponent {
23
24
  this.props.onSelect(event, item);
24
25
  };
25
26
 
27
+ this.handleKeyDown = event => {
28
+ let nextItem;
29
+ const key = keycode(event);
30
+
31
+ if (key === 'down') {
32
+ event.preventDefault();
33
+ nextItem = getNextItemSelectable(document.activeElement, 'down');
34
+ } else if (key === 'up') {
35
+ event.preventDefault();
36
+ nextItem = getNextItemSelectable(document.activeElement, 'up');
37
+ } else if (key === 'space' || key === 'enter' && !this.props.multiple) {
38
+ event.preventDefault();
39
+ const item = this.props.options.find(elem => String(elem.id) === event.target.id);
40
+ this.handleSelect(null, item);
41
+ }
42
+
43
+ if (nextItem) {
44
+ nextItem.focus();
45
+ }
46
+ };
47
+
48
+ this.handleKeyUp = () => {
49
+ return false;
50
+ };
51
+
26
52
  this.buildRecursiveListItem = (item, level = 0) => {
27
53
  const _this$props = this.props,
28
54
  {
@@ -33,9 +59,11 @@ class HiSelectableList extends React.PureComponent {
33
59
  hoverIcon,
34
60
  icon,
35
61
  selectedItemIdList,
36
- sort
62
+ sort,
63
+ onKeyDown = this.handleKeyDown,
64
+ onKeyUp = this.handleKeyUp
37
65
  } = _this$props,
38
- others = _objectWithoutProperties(_this$props, ["checkedIcon", "disabled", "disabledItemIdList", "hideCheckbox", "hoverIcon", "icon", "selectedItemIdList", "sort"]);
66
+ others = _objectWithoutProperties(_this$props, ["checkedIcon", "disabled", "disabledItemIdList", "hideCheckbox", "hoverIcon", "icon", "selectedItemIdList", "sort", "onKeyDown", "onKeyUp"]);
39
67
 
40
68
  if (sort && item.children) {
41
69
  item.children.sort(this.compareItem);
@@ -51,6 +79,8 @@ class HiSelectableList extends React.PureComponent {
51
79
  icon: icon,
52
80
  level: level,
53
81
  onSelect: this.handleSelect(item),
82
+ onKeyDown: onKeyDown,
83
+ onKeyUp: onKeyUp,
54
84
  selected: selectedItemIdList.includes(item.id) // item props override upper props (disabled, hideCheckbox, icon, level...)
55
85
 
56
86
  }, item)), item.children && item.children.length > 0 && item.children.filter(subItem => !(subItem.displayed === false)).map(subItem => this.buildRecursiveListItem(subItem, level + 1)));
@@ -79,7 +109,6 @@ class HiSelectableList extends React.PureComponent {
79
109
  const {
80
110
  classes,
81
111
  itemList,
82
- onKeyDown,
83
112
  sort
84
113
  } = this.props;
85
114
 
@@ -88,8 +117,7 @@ class HiSelectableList extends React.PureComponent {
88
117
  }
89
118
 
90
119
  return React.createElement(List, {
91
- className: classes.root,
92
- onKeyDown: onKeyDown
120
+ className: classes.root
93
121
  }, itemList.filter(item => !(item.displayed === false)) // don't remove if undefined
94
122
  .map(item => this.buildRecursiveListItem(item)));
95
123
  }