@hipay/hipay-material-ui 1.0.0-beta.26 → 1.0.0-beta.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. package/HI-CHANGELOG.md +37 -0
  2. package/HiCheckbox/HiCheckbox.js +6 -3
  3. package/HiColoredLabel/HiColoredLabel.js +2 -2
  4. package/HiDatePicker/HiDateRangeSelector.js +32 -9
  5. package/HiForm/HiFormControl.js +4 -4
  6. package/HiForm/HiSearchField.js +7 -1
  7. package/HiSelect/HiSelect.js +195 -83
  8. package/HiSelect/HiSuggestSelect.js +22 -6
  9. package/HiSelect/SelectInput.js +63 -10
  10. package/HiSelectableList/HiSelectableListItem.js +2 -1
  11. package/HiTable/BodyCellBuilder.js +22 -16
  12. package/HiTable/BodyCells/CellAccount.js +1 -5
  13. package/HiTable/BodyCells/CellAddress.js +3 -50
  14. package/HiTable/BodyCells/CellCountry.js +0 -4
  15. package/HiTable/BodyCells/CellDate.js +4 -13
  16. package/HiTable/BodyCells/CellIcon.js +10 -27
  17. package/HiTable/BodyCells/CellImage.js +1 -21
  18. package/HiTable/BodyCells/CellLayout.js +11 -4
  19. package/HiTable/BodyCells/CellNumeric.js +3 -23
  20. package/HiTable/BodyCells/CellRate.js +3 -3
  21. package/HiTable/BodyCells/CellSentinel.js +20 -49
  22. package/HiTable/BodyCells/CellStatus.js +11 -19
  23. package/HiTable/BodyCells/CellText.js +3 -10
  24. package/HiTable/BodyCells/CellThirdPartySecurity.js +4 -18
  25. package/HiTable/BodyCells/index.js +0 -9
  26. package/HiTable/BodyRow.js +15 -17
  27. package/HiTable/HiTable.js +41 -26
  28. package/HiTable/HiTableBody.js +2 -1
  29. package/HiTable/HiTableContextMenu.js +4 -3
  30. package/HiTable/HiTableFooter.js +5 -6
  31. package/HiTable/constants.js +2 -2
  32. package/es/HiCheckbox/HiCheckbox.js +6 -3
  33. package/es/HiColoredLabel/HiColoredLabel.js +2 -2
  34. package/es/HiDatePicker/HiDateRangeSelector.js +27 -9
  35. package/es/HiForm/HiFormControl.js +4 -4
  36. package/es/HiForm/HiSearchField.js +2 -1
  37. package/es/HiSelect/HiSelect.js +141 -42
  38. package/es/HiSelect/HiSuggestSelect.js +22 -7
  39. package/es/HiSelect/SelectInput.js +50 -10
  40. package/es/HiSelectableList/HiSelectableListItem.js +2 -1
  41. package/es/HiTable/BodyCellBuilder.js +21 -19
  42. package/es/HiTable/BodyCells/CellAccount.js +1 -5
  43. package/es/HiTable/BodyCells/CellAddress.js +3 -44
  44. package/es/HiTable/BodyCells/CellCountry.js +0 -2
  45. package/es/HiTable/BodyCells/CellDate.js +4 -10
  46. package/es/HiTable/BodyCells/CellIcon.js +10 -24
  47. package/es/HiTable/BodyCells/CellImage.js +1 -21
  48. package/es/HiTable/BodyCells/CellLayout.js +10 -4
  49. package/es/HiTable/BodyCells/CellNumeric.js +3 -16
  50. package/es/HiTable/BodyCells/CellRate.js +3 -3
  51. package/es/HiTable/BodyCells/CellSentinel.js +20 -46
  52. package/es/HiTable/BodyCells/CellStatus.js +11 -16
  53. package/es/HiTable/BodyCells/CellText.js +3 -7
  54. package/es/HiTable/BodyCells/CellThirdPartySecurity.js +3 -15
  55. package/es/HiTable/BodyCells/index.js +0 -2
  56. package/es/HiTable/BodyRow.js +12 -14
  57. package/es/HiTable/HiTable.js +41 -26
  58. package/es/HiTable/HiTableBody.js +2 -1
  59. package/es/HiTable/HiTableContextMenu.js +4 -3
  60. package/es/HiTable/HiTableFooter.js +6 -6
  61. package/es/HiTable/constants.js +7 -7
  62. package/es/utils/HiIconBuilder.js +12 -4
  63. package/es/utils/hiHelpers.js +1 -1
  64. package/index.es.js +1 -1
  65. package/index.js +1 -1
  66. package/package.json +1 -1
  67. package/umd/hipay-material-ui.development.js +9093 -9629
  68. package/umd/hipay-material-ui.production.min.js +5 -5
  69. package/utils/HiIconBuilder.js +13 -3
  70. package/utils/hiHelpers.js +1 -1
  71. package/HiTable/BodyCells/CellAccountNumber.js +0 -229
  72. package/es/HiTable/BodyCells/CellAccountNumber.js +0 -171
@@ -72,7 +72,7 @@ export function buildDateRangeOptionByKey(key, t, format) {
72
72
  label = t.previous_quarter;
73
73
  from = moment().subtract(1, 'quarter').startOf('quarter');
74
74
  to = moment().subtract(1, 'quarter').endOf('quarter');
75
- info = `${from.format('YYYY')}-Q${from.format('Q')}, ${to.diff(from, 'days')} ${t.days}`;
75
+ info = `${from.format('YYYY')}-${t.short_quarter}${from.format('Q')}, ${to.diff(from, 'days')} ${t.days}`;
76
76
  break;
77
77
  case 'cy':
78
78
  label = t.current_year;
@@ -129,21 +129,38 @@ class HiDateRangeSelector extends React.Component {
129
129
  this.props.onChange('from', selectedOption.from.toDate());
130
130
  this.props.onChange('to', selectedOption.to.toDate());
131
131
  }
132
+ } else {
133
+ this.setState({
134
+ defaultFrom: undefined,
135
+ defaultTo: undefined
136
+ });
132
137
  }
133
138
  if (this.props.returnSelectValue === true) {
134
139
  this.props.onChange('period', value);
135
140
  }
136
141
  };
137
142
 
138
- this.state = {
139
- selectedPreset: props.defaultPreset,
140
- containerWidth: 0
141
- };
142
-
143
143
  this.handleReset = this.handleReset.bind(this);
144
144
  this.handleSelectChange = this.handleSelectChange.bind(this);
145
145
 
146
146
  this.options = props.availableOptionKeys.map(key => buildDateRangeOptionByKey(key, props.translations, props.format));
147
+
148
+ let from;
149
+ let to;
150
+ if (props.defaultPreset !== 'custom') {
151
+ const selectedOption = this.options.find(option => option.id === props.defaultPreset);
152
+ if (selectedOption) {
153
+ from = selectedOption.from.toDate();
154
+ to = selectedOption.to.toDate();
155
+ }
156
+ }
157
+
158
+ this.state = {
159
+ selectedPreset: props.defaultPreset,
160
+ containerWidth: 0,
161
+ defaultFrom: from,
162
+ defaultTo: to
163
+ };
147
164
  }
148
165
 
149
166
  static getDerivedStateFromProps(props, state) {
@@ -192,7 +209,7 @@ class HiDateRangeSelector extends React.Component {
192
209
  } = _props,
193
210
  props = _objectWithoutProperties(_props, ['disabled', 'enableTime', 'error', 'errorText', 'helperIcon', 'helperText', 'idRange', 'idSelect', 'label', 'from', 'onChange', 'required', 'to', 'translations', 'classes', 'selectProps', 'staticPosition']);
194
211
 
195
- const { selectedPreset } = this.state;
212
+ const { defaultFrom, defaultTo, selectedPreset } = this.state;
196
213
 
197
214
  return React.createElement(
198
215
  Grid,
@@ -230,8 +247,8 @@ class HiDateRangeSelector extends React.Component {
230
247
  React.createElement(HiDateRangePicker, _extends({
231
248
  classes: { root: classes.dateRangePicker },
232
249
  id: idRange,
233
- from: from,
234
- to: to,
250
+ from: from || defaultFrom,
251
+ to: to || defaultTo,
235
252
  enableTime: enableTime,
236
253
  onChange: onChange,
237
254
  onReset: this.handleReset,
@@ -260,6 +277,7 @@ HiDateRangeSelector.defaultProps = {
260
277
  quarter: 'Quarter',
261
278
  week: 'Week',
262
279
  short_week: 'W',
280
+ short_quarter: 'Q',
263
281
  year: 'Year',
264
282
  days: 'days',
265
283
  custom_period: 'Custom Period',
@@ -150,7 +150,7 @@ class HiFormControl extends React.PureComponent {
150
150
  error: error,
151
151
  ref: rootRef
152
152
  }, others),
153
- !disabled && error && errorText && helperOpen && React.createElement(
153
+ error && errorText && helperOpen && React.createElement(
154
154
  'div',
155
155
  { className: classes.errorDiv },
156
156
  React.createElement('div', {
@@ -158,7 +158,7 @@ class HiFormControl extends React.PureComponent {
158
158
  }),
159
159
  errorText
160
160
  ),
161
- !disabled && helperIcon && helperText && !error && helperOpen && React.createElement(
161
+ helperIcon && helperText && !error && helperOpen && React.createElement(
162
162
  'div',
163
163
  {
164
164
  className: classes.helperDiv
@@ -181,11 +181,11 @@ class HiFormControl extends React.PureComponent {
181
181
  disabled: disabled,
182
182
  focused: !disabled && (focused || hovered)
183
183
  }, InputLabelProps),
184
- !disabled && error && React.createElement(Alert, {
184
+ error && React.createElement(Alert, {
185
185
  className: classes.errorIcon,
186
186
  onClick: this.handleHelperClick
187
187
  }),
188
- !disabled && helperIcon && helperText && !error && React.createElement(Information, {
188
+ helperIcon && helperText && !error && React.createElement(Information, {
189
189
  className: classNames(classes.helperIcon, {
190
190
  [classes.helperIconActive]: helperOpen
191
191
  }),
@@ -2,6 +2,7 @@ import _extends from 'babel-runtime/helpers/extends';
2
2
  import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
3
3
  import React from 'react';
4
4
  import PropTypes from 'prop-types';
5
+ import isRequiredIf from 'react-proptype-conditional-require';
5
6
  import HiInput from '../HiForm/HiInput';
6
7
 
7
8
  /**
@@ -112,7 +113,7 @@ HiSearchField.propTypes = process.env.NODE_ENV !== "production" ? {
112
113
  *
113
114
  * @param {array} suggestions
114
115
  */
115
- callbackFilteredList: PropTypes.func.isRequired,
116
+ callbackFilteredList: isRequiredIf(PropTypes.func, props => !props.hasOwnProperty('onSearch'), 'callbackFilteredList required'),
116
117
  /**
117
118
  * Liste des propriété de l'élément sur lesquelles filtrer (par défaut l'item lui même)
118
119
  */
@@ -1,4 +1,5 @@
1
1
  import _Object$keys from 'babel-runtime/core-js/object/keys';
2
+ import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
2
3
  import _extends from 'babel-runtime/helpers/extends';
3
4
  // @inheritedComponent Input
4
5
 
@@ -11,6 +12,7 @@ import Paper from 'material-ui/Paper';
11
12
  import ClickAwayListener from 'material-ui/utils/ClickAwayListener';
12
13
  import { Manager, Target, Popper } from 'react-popper';
13
14
  import { CheckboxBlankOutline, CheckboxMarked } from 'mdi-material-ui';
15
+ import isRequiredIf from 'react-proptype-conditional-require';
14
16
  import HiSelectableList from '../HiSelectableList';
15
17
  import { HiSearchField } from '../HiForm';
16
18
  import SelectInput from './SelectInput';
@@ -19,6 +21,8 @@ import { withStyles } from '../styles';
19
21
  import { arrayUnique, getNextItemSelectable } from '../utils/hiHelpers';
20
22
  import HiIconBuilder from '../utils/HiIconBuilder';
21
23
 
24
+ export const INFINITESCROLL_ERROR_MESSAGE = 'La propriété "loadMoreResults" est obligatoire si la prop "infiniteScroll" est à true';
25
+
22
26
  export const styles = theme => ({
23
27
  root: {
24
28
  backgroundColor: theme.palette.background2,
@@ -78,7 +82,8 @@ class HiSelect extends React.PureComponent {
78
82
  hierarchySelected: {},
79
83
  hierarchy: {},
80
84
  nbOptions: 0,
81
- dynamic: props.dynamic || false
85
+ dynamic: props.dynamic || false,
86
+ resultsPageNumber: 1
82
87
  };
83
88
 
84
89
  // Check if value is in options
@@ -135,6 +140,21 @@ class HiSelect extends React.PureComponent {
135
140
  this.handleBlur = this.handleBlur.bind(this);
136
141
  }
137
142
 
143
+ componentDidUpdate(prevProps, prevState, prevContext) {
144
+ if (this.props.infiniteScroll && !prevState.open && this.state.open && this.optionsContent) {
145
+ let optionList = this.optionsContent.querySelector('div').querySelector('div');
146
+ optionList.addEventListener('scroll', event => {
147
+ if (optionList.scrollTop >= event.target.scrollHeight - optionList.offsetHeight && !this.props.loadingMoreResults && this.props.hasMore) {
148
+ this.props.loadMoreResults(this.state.resultsPageNumber + 1);
149
+ this.setState({ resultsPageNumber: this.state.resultsPageNumber + 1 });
150
+ }
151
+ });
152
+ } else if (this.optionsContent && this.props.infiniteScroll && !this.state.open && prevState.open) {
153
+ let optionList = this.optionsContent.querySelector('div').querySelector('div');
154
+ optionList.removeEventListener('scroll');
155
+ }
156
+ }
157
+
138
158
  componentWillReceiveProps(nextProps) {
139
159
  if (typeof this.props.onSearch !== 'undefined' && this.props.options && this.props.options.length > 0) {
140
160
  this.handleSuggestions(nextProps.options);
@@ -175,6 +195,13 @@ class HiSelect extends React.PureComponent {
175
195
  return { hierarchy, hierarchySelected };
176
196
  }
177
197
 
198
+ handleReset(event) {
199
+ if (this.props.onReset) {
200
+ event.stopPropagation();
201
+ this.props.onReset(event);
202
+ }
203
+ }
204
+
178
205
  // Key down on list items
179
206
 
180
207
 
@@ -202,7 +229,8 @@ class HiSelect extends React.PureComponent {
202
229
 
203
230
 
204
231
  render() {
205
- const {
232
+ const _props = this.props,
233
+ {
206
234
  classes,
207
235
  disabled,
208
236
  error,
@@ -224,8 +252,13 @@ class HiSelect extends React.PureComponent {
224
252
  placeholder,
225
253
  staticPosition,
226
254
  pinnedItem,
227
- hasAll
228
- } = this.props;
255
+ hasAll,
256
+ infiniteScroll,
257
+ loadingMoreResults,
258
+ showNoResults,
259
+ showMinLength
260
+ } = _props,
261
+ other = _objectWithoutProperties(_props, ['classes', 'disabled', 'error', 'loading', 'options', 'checkbox', 'searchable', 'displayAsChip', 'type', 'value', 'translations', 'parentItemSelectable', 'icon', 'parentIcon', 'hoverIcon', 'checkedIcon', 'hierarchic', 'id', 'placeholder', 'staticPosition', 'pinnedItem', 'hasAll', 'infiniteScroll', 'loadingMoreResults', 'showNoResults', 'showMinLength']);
229
262
 
230
263
  const { open, suggestions, focused, dynamic } = this.state;
231
264
 
@@ -239,7 +272,7 @@ class HiSelect extends React.PureComponent {
239
272
  }
240
273
 
241
274
  // If loading
242
- if (loading) {
275
+ if (loading && !loadingMoreResults) {
243
276
  _suggestions.unshift({
244
277
  id: '_loading',
245
278
  type: 'loader',
@@ -296,6 +329,28 @@ class HiSelect extends React.PureComponent {
296
329
  popperStyle = { width: this.props.containerWidth };
297
330
  }
298
331
 
332
+ if (infiniteScroll && loadingMoreResults) {
333
+ _suggestions.push({
334
+ id: '_loading',
335
+ type: 'loader',
336
+ disabled: true,
337
+ centered: true,
338
+ checkbox: false,
339
+ label: 'loading'
340
+ });
341
+ }
342
+
343
+ if (!loading && !loadingMoreResults && _suggestions.length === 0 && (showNoResults || showMinLength)) {
344
+ suggestions.push({
345
+ id: '_no_result',
346
+ type: 'text',
347
+ disabled: true,
348
+ centered: true,
349
+ checkbox: false,
350
+ label: showNoResults ? translations.no_result_match : translations.min_length
351
+ });
352
+ }
353
+
299
354
  const content = React.createElement(
300
355
  ClickAwayListener,
301
356
  { onClickAway: this.handleClickAway },
@@ -317,25 +372,29 @@ class HiSelect extends React.PureComponent {
317
372
  },
318
373
  onKeyDown: this.handleKeyDownSearch
319
374
  }),
320
- React.createElement(HiSelectableList, {
321
- type: type,
322
- parentItemSelectable: parentItemSelectable,
323
- itemList: _suggestions,
324
- onSelect: this.handleSelect,
325
- selectedIdList: selectedIdList,
326
- checkbox: checkbox,
327
- hierarchy: this.state.hierarchy,
328
- hierarchic: hierarchic,
329
- hierarchySelected: this.state.hierarchySelected,
330
- translations: translations,
331
- icon: icon,
332
- parentIcon: parentIcon,
333
- hoverIcon: hoverIcon,
334
- checkedIcon: checkedIcon,
335
- allSelected: allSelected,
336
- value: value,
337
- onKeyDown: this.handleKeyDown
338
- })
375
+ React.createElement(
376
+ 'div',
377
+ { ref: content => this.optionsContent = content },
378
+ React.createElement(HiSelectableList, _extends({
379
+ type: type,
380
+ parentItemSelectable: parentItemSelectable,
381
+ itemList: _suggestions,
382
+ onSelect: this.handleSelect,
383
+ selectedIdList: selectedIdList,
384
+ checkbox: checkbox,
385
+ hierarchy: this.state.hierarchy,
386
+ hierarchic: hierarchic,
387
+ hierarchySelected: this.state.hierarchySelected,
388
+ translations: translations,
389
+ icon: icon,
390
+ parentIcon: parentIcon,
391
+ hoverIcon: hoverIcon,
392
+ checkedIcon: checkedIcon,
393
+ allSelected: allSelected,
394
+ value: value,
395
+ onKeyDown: this.handleKeyDown
396
+ }, other))
397
+ )
339
398
  )
340
399
  )
341
400
  );
@@ -370,7 +429,9 @@ class HiSelect extends React.PureComponent {
370
429
  onMouseLeave: this.props.onMouseLeave,
371
430
  refElement: el => {
372
431
  this.selectInputElement = el;
373
- }
432
+ },
433
+ onSubmit: this.props.onSubmit,
434
+ onReset: this.props.onReset
374
435
  })
375
436
  ),
376
437
  open && (staticPosition ? React.createElement(
@@ -405,12 +466,14 @@ HiSelect.defaultProps = {
405
466
  parentItemSelectable: false,
406
467
  displayAsChip: false,
407
468
  dynamic: false,
469
+ infiniteScroll: false,
408
470
  icon: React.createElement(CheckboxBlankOutline, { style: { width: 20, height: 20 } }),
409
471
  parentIcon: React.createElement(CheckboxBlankOutline, { style: { width: 20, height: 20 } }),
410
472
  hoverIcon: React.createElement(CheckboxBlankOutline, { style: { width: 20, height: 20 } }),
411
473
  checkedIcon: React.createElement(CheckboxMarked, { style: { width: 20, height: 20 } }),
412
474
  translations: {
413
475
  all: 'All',
476
+ min_length: 'Veuillez saisir 3 caractères minimum',
414
477
  no_result_match: 'No result match',
415
478
  search: 'Search',
416
479
  n_items_selected: '%s items selected',
@@ -418,7 +481,9 @@ HiSelect.defaultProps = {
418
481
  n_children: '%s items',
419
482
  one_child: '%s item'
420
483
  },
421
- staticPosition: false
484
+ staticPosition: false,
485
+ loadingMoreResults: false,
486
+ hasMore: false
422
487
  };
423
488
 
424
489
  var _initialiseProps = function () {
@@ -426,9 +491,9 @@ var _initialiseProps = function () {
426
491
  if (this.state.open) {
427
492
  this.handleClose();
428
493
  } else {
429
- if (!this.props.staticPosition) {
430
- //document.body.style.overflow = 'hidden';
431
- }
494
+ /*if (!this.props.staticPosition) {
495
+ // document.body.style.overflow = 'hidden';
496
+ }*/
432
497
  this.setState({ open: true });
433
498
  const options = this.props.options.slice();
434
499
  this.handleSuggestions(options);
@@ -438,13 +503,7 @@ var _initialiseProps = function () {
438
503
  }
439
504
 
440
505
  // Gestion du focus
441
- if (this.searchField) {
442
- // si searchable, focus sur le champs de recherche
443
- const searchField = this.searchField;
444
- setTimeout(() => {
445
- searchField.focus();
446
- }, 1);
447
- } else if (this.overlay) {
506
+ if (!this.props.searchable) {
448
507
  // sinon focus sur le dernier élément selectionné
449
508
  this.focusOnSelectedItem();
450
509
  }
@@ -490,9 +549,11 @@ var _initialiseProps = function () {
490
549
  } else if (event.key === 'ArrowUp') {
491
550
  nextItem = getNextItemSelectable(document.activeElement, 'up');
492
551
  } else if (event.key === 'Tab') {
493
- if (!this.props.staticPosition) {
494
- //document.body.style.overflow = 'auto';
495
- }
552
+ /* if (!this.props.staticPosition) {
553
+ document.body.style.overflow = 'auto';
554
+ } */
555
+ this.setState({ open: false });
556
+ } else if (event.key === 'Escape') {
496
557
  this.setState({ open: false });
497
558
  }
498
559
  if (nextItem) {
@@ -503,6 +564,8 @@ var _initialiseProps = function () {
503
564
  this.handleKeyDownSearch = event => {
504
565
  if (this.overlay && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
505
566
  this.focusOnSelectedItem();
567
+ } else if (event.key === 'Enter' && this.props.onSubmit) {
568
+ this.props.onSubmit(event);
506
569
  }
507
570
  };
508
571
 
@@ -643,9 +706,9 @@ var _initialiseProps = function () {
643
706
  };
644
707
 
645
708
  this.handleSuggestions = suggestions => {
646
- const { options, hasAll, iconAll, translations, multiple } = this.props;
709
+ const { options, hasAll, iconAll, translations, multiple, showNoResults, showMinLength } = this.props;
647
710
 
648
- if (suggestions.length === 0) {
711
+ if (suggestions.length === 0 && (showNoResults || showMinLength)) {
649
712
  // Handle No Result
650
713
  // FIX to remove all item
651
714
  suggestions = [];
@@ -655,7 +718,7 @@ var _initialiseProps = function () {
655
718
  disabled: true,
656
719
  centered: true,
657
720
  checkbox: false,
658
- label: translations.no_result_match
721
+ label: showNoResults ? translations.no_result_match : translations.min_length
659
722
  });
660
723
  } else if (hasAll && suggestions.length > 0 && suggestions.length === options.length && multiple === true) {
661
724
  // Handle 'All'
@@ -722,6 +785,10 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
722
785
  * Les items sont hiérarchisés
723
786
  */
724
787
  hierarchic: PropTypes.bool,
788
+ /**
789
+ * Indique si l'infinite scroll doit rechercher de nouveaux résultats
790
+ */
791
+ hasMore: PropTypes.bool,
725
792
  /**
726
793
  * Icon affiché lorsque l'item n'est pas sélectionné et qu'on le survole
727
794
  */
@@ -738,10 +805,26 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
738
805
  * id du select
739
806
  */
740
807
  id: PropTypes.string,
808
+ /**
809
+ * Infinite scroll dans le select dans le cas où il y a beaucoup de résultats à afficher
810
+ * afin d'éviter un lag du navigateur
811
+ */
812
+ infiniteScroll: PropTypes.bool.isRequired,
741
813
  /**
742
814
  * Ajoute un loader
743
815
  */
744
816
  loading: PropTypes.bool,
817
+ /**
818
+ * Ajoute un loader en bas pour l'infiniteScroll
819
+ */
820
+ loadingMoreResults: PropTypes.bool,
821
+ /**
822
+ * Fonction de callback appelée lorsque l'utilisateur arrive en bas de la liste des options
823
+ * afin de charger les nouvelles options
824
+ *
825
+ * @param {int} pageNumber
826
+ */
827
+ loadMoreResults: isRequiredIf(PropTypes.func, props => props.hasOwnProperty('infiniteScroll') && props.infiniteScroll === true, INFINITESCROLL_ERROR_MESSAGE),
745
828
  /**
746
829
  * Autorise la sélection de plusieurs valeurs
747
830
  */
@@ -769,6 +852,10 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
769
852
  * Fonction de callback appelée lorsque le curseur quitte le champs
770
853
  */
771
854
  onMouseLeave: PropTypes.func,
855
+ /**
856
+ * Fonction de callback appelée lorsqu'on vide le champs
857
+ */
858
+ onReset: PropTypes.func,
772
859
  /**
773
860
  * Fonction de callback appelée lorsqu'on écrit dans la barre de recherche
774
861
  * A utiliser pour les selects avec des données dynamiques
@@ -777,6 +864,10 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
777
864
  * @param {string} value
778
865
  */
779
866
  onSearch: PropTypes.func,
867
+ /**
868
+ * Fonction de callback à la pression de la touche "Entrée"
869
+ */
870
+ onSubmit: PropTypes.func,
780
871
  /**
781
872
  * Listes des options du select
782
873
  */
@@ -806,6 +897,14 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
806
897
  * Si true, le contenu du select sera dans une div static plutot que dans une popper absolute
807
898
  */
808
899
  staticPosition: PropTypes.bool,
900
+ /**
901
+ * Permet d'afficher un message si pas assez de caractères
902
+ */
903
+ showMinLength: PropTypes.bool,
904
+ /**
905
+ * Permet d'afficher un message si aucune options n'est présente
906
+ */
907
+ showNoResults: PropTypes.bool,
809
908
  /**
810
909
  * Traductions (par défaut en anglais)
811
910
  */
@@ -116,24 +116,35 @@ class HiSuggestSelect extends React.PureComponent {
116
116
 
117
117
  render() {
118
118
  const _props = this.props,
119
- { classes, id, showMinLength, showNoResults, onSearch, translations } = _props,
120
- otherProps = _objectWithoutProperties(_props, ['classes', 'id', 'showMinLength', 'showNoResults', 'onSearch', 'translations']);
119
+ { classes, id, loading, showMinLength, showNoResults, onSearch, translations } = _props,
120
+ otherProps = _objectWithoutProperties(_props, ['classes', 'id', 'loading', 'showMinLength', 'showNoResults', 'onSearch', 'translations']);
121
121
 
122
122
  const { focused, options } = this.state;
123
123
 
124
124
  let optionsShown = options;
125
125
 
126
- // If no results match
127
- if (options.length === 0 && (showNoResults || showMinLength)) {
126
+ // If loading
127
+ if (loading) {
128
128
  optionsShown = [{
129
- id: '_no_result',
130
- type: 'text',
129
+ id: '_loading',
130
+ type: 'loader',
131
131
  disabled: true,
132
132
  centered: true,
133
133
  checkbox: false,
134
- label: showNoResults ? translations.no_result_match : translations.min_length
134
+ label: 'loading'
135
135
  }];
136
136
  }
137
+ // If no results match
138
+ else if (options.length === 0 && (showNoResults || showMinLength)) {
139
+ optionsShown = [{
140
+ id: '_no_result',
141
+ type: 'text',
142
+ disabled: true,
143
+ centered: true,
144
+ checkbox: false,
145
+ label: showNoResults ? translations.no_result_match : translations.min_length
146
+ }];
147
+ }
137
148
 
138
149
  const open = !!optionsShown.length && focused;
139
150
 
@@ -211,6 +222,10 @@ HiSuggestSelect.propTypes = process.env.NODE_ENV !== "production" ? {
211
222
  * id de l'élément input
212
223
  */
213
224
  id: PropTypes.string,
225
+ /**
226
+ * Ajoute un loader
227
+ */
228
+ loading: PropTypes.bool,
214
229
  /**
215
230
  * Fonction de callback appelée lorsqu'on écrit dans le champ
216
231
  */
@@ -2,12 +2,13 @@ import _extends from 'babel-runtime/helpers/extends';
2
2
  import React from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import classNames from 'classnames';
5
-
6
- import ArrowDropDownIcon from '../svg-icons/ArrowDropDown';
5
+ import keycode from 'keycode';
7
6
  import Icon from 'material-ui/Icon';
8
- import { withStyles } from '../styles';
9
-
7
+ import IconButton from 'material-ui/IconButton';
10
8
  import ButtonBase from 'material-ui/ButtonBase';
9
+ import ArrowDropDownIcon from '../svg-icons/ArrowDropDown';
10
+ import { withStyles } from '../styles';
11
+ import HiIconBuilder from '../utils/HiIconBuilder';
11
12
 
12
13
  export const styles = theme => ({
13
14
  root: {
@@ -87,6 +88,11 @@ export const styles = theme => ({
87
88
  backgroundColor: theme.palette.background3
88
89
  },
89
90
  error: {},
91
+ eraseButton: {
92
+ height: 24,
93
+ width: 24,
94
+ display: 'inline-block'
95
+ },
90
96
  label: _extends({
91
97
  whiteSpace: 'nowrap',
92
98
  overflow: 'hidden',
@@ -120,14 +126,24 @@ class SelectInput extends React.PureComponent {
120
126
  super(props);
121
127
 
122
128
  this.handleKeyDown = event => {
123
- if (event.key === 'ArrowDown') {
124
- this.props.onClick();
125
- } else if (event.key === 'ArrowUp') {
129
+ const key = keycode(event);
130
+ if (['up', 'down', 'space'].includes(key)) {
131
+ event.preventDefault();
126
132
  this.props.onClick();
133
+ } else if (key === 'enter' && this.props.onSubmit) {
134
+ event.preventDefault();
135
+ this.props.onSubmit(event);
136
+ }
137
+ };
138
+
139
+ this.handleClick = event => {
140
+ if ((!this.resetIcon || !this.resetIcon.contains(event.target)) && this.props.onClick) {
141
+ this.props.onClick(event);
127
142
  }
128
143
  };
129
144
 
130
145
  this.handleKeyDown = this.handleKeyDown.bind(this);
146
+ this.handleClick = this.handleClick.bind(this);
131
147
  }
132
148
 
133
149
  render() {
@@ -141,7 +157,9 @@ class SelectInput extends React.PureComponent {
141
157
  focused,
142
158
  error,
143
159
  id,
144
- refElement
160
+ refElement,
161
+ onReset,
162
+ theme
145
163
  } = this.props;
146
164
 
147
165
  // On utilise classNames pour variabiliser les styles et merge les classes appliquées
@@ -185,7 +203,7 @@ class SelectInput extends React.PureComponent {
185
203
  {
186
204
  id: id,
187
205
  className: rootClass,
188
- onClick: onClick,
206
+ onClick: this.handleClick,
189
207
  disabled: disabled,
190
208
  onMouseEnter: this.props.onMouseEnter,
191
209
  onMouseLeave: this.props.onMouseLeave,
@@ -201,6 +219,20 @@ class SelectInput extends React.PureComponent {
201
219
  { className: classes.label },
202
220
  value
203
221
  ),
222
+ onReset && React.createElement(
223
+ 'div',
224
+ {
225
+ ref: el => {
226
+ this.resetIcon = el;
227
+ }
228
+ },
229
+ React.createElement(HiIconBuilder, {
230
+ icon: 'close',
231
+ size: 24,
232
+ color: theme.palette.neutral.normal,
233
+ onClick: onReset
234
+ })
235
+ ),
204
236
  React.createElement(
205
237
  Icon,
206
238
  { classes: { root: iconClass } },
@@ -262,6 +294,14 @@ SelectInput.propTypes = process.env.NODE_ENV !== "production" ? {
262
294
  * Fonction de callback à la pression de touche
263
295
  */
264
296
  onKeyDown: PropTypes.func,
297
+ /**
298
+ * Fonction de callback appelée lorsqu'on vide le champs
299
+ */
300
+ onReset: PropTypes.func,
301
+ /**
302
+ * Fonction de callback à la pression de la touche "Entrée"
303
+ */
304
+ onSubmit: PropTypes.func,
265
305
  /**
266
306
  * Applique le style open et effectue une rotation de l'icône
267
307
  */
@@ -275,4 +315,4 @@ SelectInput.propTypes = process.env.NODE_ENV !== "production" ? {
275
315
  */
276
316
  value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.node])
277
317
  } : {};
278
- export default withStyles(styles, { name: 'HmuiSelectInput' })(SelectInput);
318
+ export default withStyles(styles, { name: 'HmuiSelectInput', withTheme: true })(SelectInput);
@@ -368,7 +368,8 @@ class HiSelectableListItem extends React.Component {
368
368
  checkedIcon: checkedIcon,
369
369
  indeterminate: indeterminate,
370
370
  classes: { checked: classes.listItemIconChecked },
371
- className: classes.checkbox
371
+ className: classes.checkbox,
372
+ disabled: effectiveDisabled
372
373
  }),
373
374
  this.buildListItem(),
374
375
  !!item.info && React.createElement(