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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/HiAlertModal/HiAlertModal.js +56 -13
  3. package/HiColoredLabel/HiColoredLabel.js +16 -4
  4. package/HiForm/HiFormControl.js +2 -4
  5. package/HiForm/HiInput.js +29 -4
  6. package/HiForm/HiUploadField.js +2 -1
  7. package/HiSelect/HiSelect.js +6 -5
  8. package/HiSelect/HiSuggestSelect.js +5 -4
  9. package/HiSelect/SelectInput.js +1 -0
  10. package/HiSelectNew/HiNestedSelect.js +20 -6
  11. package/HiSelectNew/HiNestedSelectContent.js +20 -6
  12. package/HiSelectNew/HiSelect.js +104 -32
  13. package/HiSelectNew/HiSelectContent.js +16 -4
  14. package/HiSelectNew/HiSelectInput.js +10 -3
  15. package/HiSelectableList/HiSelectableList.js +2 -35
  16. package/HiSelectableList/HiSelectableListItem.js +6 -4
  17. package/es/HiAlertModal/HiAlertModal.js +55 -13
  18. package/es/HiColoredLabel/HiColoredLabel.js +21 -4
  19. package/es/HiForm/HiFormControl.js +2 -4
  20. package/es/HiForm/HiInput.js +29 -4
  21. package/es/HiForm/HiUploadField.js +2 -1
  22. package/es/HiSelect/HiSelect.js +6 -5
  23. package/es/HiSelect/HiSuggestSelect.js +5 -4
  24. package/es/HiSelect/SelectInput.js +1 -0
  25. package/es/HiSelectNew/HiNestedSelect.js +17 -7
  26. package/es/HiSelectNew/HiNestedSelectContent.js +16 -6
  27. package/es/HiSelectNew/HiSelect.js +106 -31
  28. package/es/HiSelectNew/HiSelectContent.js +11 -2
  29. package/es/HiSelectNew/HiSelectInput.js +10 -3
  30. package/es/HiSelectableList/HiSelectableList.js +3 -29
  31. package/es/HiSelectableList/HiSelectableListItem.js +6 -4
  32. package/index.es.js +1 -1
  33. package/index.js +1 -1
  34. package/package.json +1 -1
  35. package/umd/hipay-material-ui.development.js +15551 -16279
  36. package/umd/hipay-material-ui.production.min.js +2 -2
@@ -8,7 +8,7 @@ import withStyles from '../styles/withStyles';
8
8
  import { capitalize } from '../utils/helpers';
9
9
  import { fade } from '../styles/colorManipulator';
10
10
  export const styles = theme => ({
11
- root: _objectSpread({}, theme.typography.b3, {
11
+ root: {
12
12
  display: 'inline-block',
13
13
  alignItems: 'baseline',
14
14
  maxWidth: '100%',
@@ -18,7 +18,12 @@ export const styles = theme => ({
18
18
  overflow: 'hidden',
19
19
  whiteSpace: 'nowrap',
20
20
  lineHeight: 1
21
- }),
21
+ },
22
+ body1: _objectSpread({}, theme.typography.b1),
23
+ body2: _objectSpread({}, theme.typography.b2),
24
+ body3: _objectSpread({}, theme.typography.b3),
25
+ body4: _objectSpread({}, theme.typography.b4),
26
+ body5: _objectSpread({}, theme.typography.b5),
22
27
  color: {
23
28
  fontWeight: 400
24
29
  },
@@ -111,6 +116,7 @@ function HiColoredLabel(props) {
111
116
  const {
112
117
  classes,
113
118
  className,
119
+ fontSize,
114
120
  label,
115
121
  color,
116
122
  active,
@@ -119,7 +125,7 @@ function HiColoredLabel(props) {
119
125
  style,
120
126
  theme
121
127
  } = props,
122
- other = _objectWithoutProperties(props, ["classes", "className", "label", "color", "active", "outlined", "fontWeight", "style", "theme"]);
128
+ other = _objectWithoutProperties(props, ["classes", "className", "fontSize", "label", "color", "active", "outlined", "fontWeight", "style", "theme"]);
123
129
 
124
130
  const isHiColor = ['primary', 'secondary', 'positive', 'negative', 'middle', 'neutral'].includes(color);
125
131
  const isHexColor = !isHiColor && /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color);
@@ -129,7 +135,12 @@ function HiColoredLabel(props) {
129
135
  [classes.activeColor]: active,
130
136
  [classes.outlined]: outlined,
131
137
  [classes[`activeColor${capitalize(color)}`]]: active && isHiColor,
132
- [classes[`color${capitalize(color)}`]]: !active && isHiColor
138
+ [classes[`color${capitalize(color)}`]]: !active && isHiColor,
139
+ [classes.body1]: fontSize >= 15,
140
+ [classes.body2]: fontSize === 14,
141
+ [classes.body3]: fontSize === 13,
142
+ [classes.body4]: fontSize === 12,
143
+ [classes.body5]: fontSize <= 11
133
144
  }, className),
134
145
  style: _objectSpread({}, style, isHexColor && {
135
146
  backgroundColor: active ? color : fade(color, 0.08),
@@ -162,6 +173,11 @@ HiColoredLabel.propTypes = process.env.NODE_ENV !== "production" ? {
162
173
  */
163
174
  color: PropTypes.string,
164
175
 
176
+ /**
177
+ * Taille du text
178
+ */
179
+ fontSize: PropTypes.number,
180
+
165
181
  /**
166
182
  * Graisse du text
167
183
  */
@@ -180,6 +196,7 @@ HiColoredLabel.propTypes = process.env.NODE_ENV !== "production" ? {
180
196
  HiColoredLabel.defaultProps = {
181
197
  active: false,
182
198
  color: 'primary',
199
+ fontSize: 15,
183
200
  outlined: false
184
201
  };
185
202
  export default withStyles(styles, {
@@ -199,16 +199,14 @@ class HiFormControl extends React.PureComponent {
199
199
  focused: !disabled && (focused || hovered)
200
200
  }, InputLabelProps), error && errorText && React.createElement(HiIconButton, {
201
201
  className: classNames(classes.iconButton, classes.iconButtonError),
202
- onClick: this.handleHelperClick,
203
- onKeyDown: this.handleKeyDown
202
+ onClick: this.handleHelperClick
204
203
  }, React.createElement(Warning, {
205
204
  className: classNames(classes.icon)
206
205
  })), helperIcon && helperText && !error && React.createElement(HiIconButton, {
207
206
  className: classNames(classes.iconButton, classes.iconButtonInfo, {
208
207
  [classes.iconButtonInfoActive]: helperOpen
209
208
  }),
210
- onClick: this.handleHelperClick,
211
- onKeyDown: this.handleKeyDown
209
+ onClick: this.handleHelperClick
212
210
  }, React.createElement(Info, {
213
211
  className: classNames(classes.icon)
214
212
  }))), React.createElement("div", {
@@ -127,6 +127,13 @@ var _ref = React.createElement(HiIcon, {
127
127
  class HiInput extends React.PureComponent {
128
128
  constructor() {
129
129
  super();
130
+
131
+ this.handleClick = () => {
132
+ if (this.props.onClick) {
133
+ this.props.onClick();
134
+ }
135
+ };
136
+
130
137
  this.state = {
131
138
  focused: false
132
139
  };
@@ -177,10 +184,15 @@ class HiInput extends React.PureComponent {
177
184
  // Si on click sur un élément de HiInput, on garde le focus
178
185
  // Par exemple sur l'icone reset
179
186
  if (event.relatedTarget && this.overlayNode && this.overlayNode.contains(event.relatedTarget)) {
180
- if (this.endAdornmentNode.contains(event.relatedTarget) && this.props.onBlur) {
187
+ // If blur came from erase icon => stay focused and don't call onBlur props
188
+ if (this.eraseIconNode && this.eraseIconNode.contains(event.relatedTarget)) {
189
+ event.preventDefault();
190
+ event.stopPropagation();
191
+ } else if (this.endAdornmentNode.contains(event.relatedTarget) && this.props.onBlur) {
181
192
  this.props.onBlur(event);
182
193
  }
183
194
 
195
+ event.preventDefault();
184
196
  event.stopPropagation();
185
197
  } else {
186
198
  this.setState({
@@ -201,9 +213,13 @@ class HiInput extends React.PureComponent {
201
213
  this.setState({
202
214
  focused: true
203
215
  });
204
- }
216
+ } // If focus came from erase icon => stay focused and don't call onFocus props
217
+
205
218
 
206
- if (this.props.onFocus) {
219
+ if (this.eraseIconNode && this.eraseIconNode.contains(event.relatedTarget)) {
220
+ event.preventDefault();
221
+ event.stopPropagation();
222
+ } else if (this.props.onFocus) {
207
223
  this.props.onFocus(event);
208
224
  }
209
225
  }
@@ -306,7 +322,10 @@ class HiInput extends React.PureComponent {
306
322
  label: classes.eraseButtonLabel
307
323
  },
308
324
  onClick: this.handleReset,
309
- onBlur: this.handleBlur
325
+ onBlur: this.handleBlur,
326
+ buttonRef: el => {
327
+ this.eraseIconNode = el;
328
+ }
310
329
  }, _ref);
311
330
  let endAdornment = endAdornmentProps;
312
331
 
@@ -335,6 +354,7 @@ class HiInput extends React.PureComponent {
335
354
  placeholder: placeholder,
336
355
  onFocus: this.handleFocus,
337
356
  onKeyDown: this.props.onKeyDown,
357
+ onClick: this.handleClick,
338
358
  onBlur: this.handleBlur,
339
359
  inputRef: this.getInputElement,
340
360
  disabled: disabled,
@@ -454,6 +474,11 @@ HiInput.propTypes = process.env.NODE_ENV !== "production" ? {
454
474
  */
455
475
  onChange: PropTypes.func,
456
476
 
477
+ /**
478
+ * Fonction de callback appelée au click dans l'input
479
+ */
480
+ onClick: PropTypes.func,
481
+
457
482
  /**
458
483
  * Fonction de callback appelée au focus du champs
459
484
  */
@@ -22,7 +22,8 @@ export const styles = theme => ({
22
22
  fontSize: '80px'
23
23
  },
24
24
  inputContainer: {
25
- flex: '1'
25
+ flex: '1',
26
+ width: 'calc(100% - 88px)'
26
27
  },
27
28
  empty: {
28
29
  border: `1px solid ${theme.palette.input.bottomLine}`,
@@ -193,17 +193,13 @@ class HiSelect extends React.PureComponent {
193
193
  nextItem = getNextItemSelectable(document.activeElement, 'down');
194
194
  } else if (event.key === 'ArrowUp') {
195
195
  nextItem = getNextItemSelectable(document.activeElement, 'up');
196
- } else if (event.key === 'Tab') {
196
+ } else if (event.key === 'Tab' || event.key === 'Escape') {
197
197
  /* if (!this.props.staticPosition) {
198
198
  document.body.style.overflow = 'auto';
199
199
  } */
200
200
  this.setState({
201
201
  open: false
202
202
  });
203
- } else if (event.key === 'Escape') {
204
- this.setState({
205
- open: false
206
- });
207
203
  }
208
204
 
209
205
  if (nextItem) {
@@ -216,6 +212,10 @@ class HiSelect extends React.PureComponent {
216
212
  this.focusOnSelectedItem();
217
213
  } else if (event.key === 'Enter' && this.props.onSubmit) {
218
214
  this.props.onSubmit(event);
215
+ } else if (event.key === 'Tab' || event.key === 'Escape') {
216
+ this.setState({
217
+ open: false
218
+ });
219
219
  }
220
220
  };
221
221
 
@@ -682,6 +682,7 @@ class HiSelect extends React.PureComponent {
682
682
  onClick: this.handleClick,
683
683
  onFocus: this.handleFocus,
684
684
  onBlur: this.handleBlur,
685
+ onKeyDown: this.handleKeyDown,
685
686
  onMouseEnter: this.props.onMouseEnter,
686
687
  onMouseLeave: this.props.onMouseLeave,
687
688
  refElement: el => {
@@ -24,7 +24,8 @@ export const styles = theme => ({
24
24
  width: '100% !important',
25
25
  transform: 'none !important',
26
26
  zIndex: '9 !important',
27
- top: '100% !important'
27
+ top: '100% !important',
28
+ textOverflow: 'ellipsis'
28
29
  },
29
30
  paper: {
30
31
  borderRadius: '0px 2px',
@@ -143,10 +144,10 @@ class HiSuggestSelect extends React.PureComponent {
143
144
  options: [],
144
145
  focused: false
145
146
  });
146
- }
147
147
 
148
- if (this.props.onBlurInput) {
149
- this.props.onBlurInput(event);
148
+ if (this.props.onBlurInput) {
149
+ this.props.onBlurInput(event);
150
+ }
150
151
  }
151
152
  }
152
153
 
@@ -185,6 +185,7 @@ class SelectInput extends React.PureComponent {
185
185
  className: iconClass,
186
186
  icon: "arrow_drop_down"
187
187
  })) : React.createElement(ButtonBase, {
188
+ component: "div",
188
189
  id: id,
189
190
  classes: {
190
191
  root: rootClass
@@ -45,6 +45,10 @@ function findFinalItemRecursively(itemList, searchId) {
45
45
  });
46
46
  return foundItem;
47
47
  }
48
+
49
+ export var filterValue = function (item, searchValue) {
50
+ return searchValue === '' || foldAccents(item.label.toString().toLowerCase()).search(foldAccents(searchValue.toLowerCase())) !== -1;
51
+ };
48
52
  /**
49
53
  * Build item list by settings item props relative to the nested parent/child situation
50
54
  * Reduce the item list to build specified items (displayed, pinned, disabled, selected, indeterminate)
@@ -62,15 +66,14 @@ function findFinalItemRecursively(itemList, searchId) {
62
66
  * @returns {*}
63
67
  */
64
68
 
65
-
66
- function buildFilteredItemList(itemList, selectedItemIdList = [], searchValue = '', visibleParent = false, pinnedParent = false, disabledParent = false, nbChildrenAsInfo = false, translations) {
69
+ function buildFilteredItemList(itemList, selectedItemIdList = [], searchValue = '', visibleParent = false, pinnedParent = false, disabledParent = false, nbChildrenAsInfo = false, translations, filterFunc = filterValue) {
67
70
  return itemList.reduce(({
68
71
  l: memoItemList,
69
72
  s: memoSelected,
70
73
  u: memoUnselected,
71
74
  v: memoVisible
72
75
  }, item) => {
73
- const itemVisible = searchValue === '' || foldAccents(item.label.toString().toLowerCase()).search(foldAccents(searchValue.toLowerCase())) !== -1; // Parent item
76
+ const itemVisible = filterFunc(item, searchValue); // Parent item
74
77
 
75
78
  if (item.children) {
76
79
  const {
@@ -78,7 +81,7 @@ function buildFilteredItemList(itemList, selectedItemIdList = [], searchValue =
78
81
  s: selected,
79
82
  u: unselected,
80
83
  v: visible
81
- } = buildFilteredItemList(item.children, selectedItemIdList, searchValue, itemVisible, pinnedParent, disabledParent);
84
+ } = buildFilteredItemList(item.children, selectedItemIdList, searchValue, itemVisible, pinnedParent, disabledParent, nbChildrenAsInfo, translations, filterFunc);
82
85
 
83
86
  if (nbChildrenAsInfo) {
84
87
  item.info = translations.n_children.replace('%s', item.children.length);
@@ -227,7 +230,8 @@ class HiNestedSelect extends React.PureComponent {
227
230
  multiple,
228
231
  nbChildrenAsInfo,
229
232
  pinnedParent,
230
- translations
233
+ translations,
234
+ filterFunc
231
235
  } = this.props; // build item list
232
236
 
233
237
  const {
@@ -235,7 +239,7 @@ class HiNestedSelect extends React.PureComponent {
235
239
  s: allSelected,
236
240
  u: allUnselected,
237
241
  v: visible
238
- } = buildFilteredItemList(options, value, search, false, pinnedParent, disabledParent || !multiple, nbChildrenAsInfo, translations);
242
+ } = buildFilteredItemList(options, value, search, false, pinnedParent, disabledParent || !multiple, nbChildrenAsInfo, translations, filterFunc);
239
243
  const itemList = !visible ? [...(loading ? [{
240
244
  id: '_loading',
241
245
  type: 'loader',
@@ -367,7 +371,8 @@ HiNestedSelect.defaultProps = {
367
371
  one_item_selected: '%s item selected',
368
372
  n_children: '%s',
369
373
  one_child: '%s item'
370
- }
374
+ },
375
+ filterFunc: filterValue
371
376
  };
372
377
  HiNestedSelect.propTypes = process.env.NODE_ENV !== "production" ? {
373
378
  /**
@@ -385,6 +390,11 @@ HiNestedSelect.propTypes = process.env.NODE_ENV !== "production" ? {
385
390
  */
386
391
  displayAsChip: PropTypes.bool,
387
392
 
393
+ /*
394
+ * Fonction de filtrage custom
395
+ */
396
+ filterFunc: PropTypes.func,
397
+
388
398
  /**
389
399
  * Affiche l'élément 'All'
390
400
  */
@@ -42,6 +42,9 @@ export function findFinalItemRecursively(itemList, searchId) {
42
42
  });
43
43
  return foundItem;
44
44
  }
45
+ export var filterValue = function (item, searchValue) {
46
+ return searchValue === '' || foldAccents(item.label.toString().toLowerCase()).search(foldAccents(searchValue.toLowerCase())) !== -1;
47
+ };
45
48
  /**
46
49
  * Build item list by settings item props relative to the nested parent/child situation
47
50
  * Reduce the item list to build specified items (displayed, pinned, disabled, selected, indeterminate)
@@ -59,14 +62,14 @@ export function findFinalItemRecursively(itemList, searchId) {
59
62
  * @returns {*}
60
63
  */
61
64
 
62
- function buildFilteredItemList(itemList, selectedItemIdList = [], searchValue = '', visibleParent = false, pinnedParent = false, disabledParent = false, nbChildrenAsInfo = false, translations) {
65
+ function buildFilteredItemList(itemList, selectedItemIdList = [], searchValue = '', visibleParent = false, pinnedParent = false, disabledParent = false, nbChildrenAsInfo = false, translations, filterFunc = filterValue) {
63
66
  return itemList.reduce(({
64
67
  l: memoItemList,
65
68
  s: memoSelected,
66
69
  u: memoUnselected,
67
70
  v: memoVisible
68
71
  }, item) => {
69
- const itemVisible = searchValue === '' || foldAccents(item.label.toString().toLowerCase()).search(foldAccents(searchValue.toLowerCase())) !== -1; // Parent item
72
+ const itemVisible = filterFunc(item, searchValue); // Parent item
70
73
 
71
74
  if (item.children) {
72
75
  const {
@@ -74,7 +77,7 @@ function buildFilteredItemList(itemList, selectedItemIdList = [], searchValue =
74
77
  s: selected,
75
78
  u: unselected,
76
79
  v: visible
77
- } = buildFilteredItemList(item.children, selectedItemIdList, searchValue, itemVisible, pinnedParent, disabledParent);
80
+ } = buildFilteredItemList(item.children, selectedItemIdList, searchValue, itemVisible, pinnedParent, disabledParent, nbChildrenAsInfo, translations, filterFunc);
78
81
 
79
82
  if (nbChildrenAsInfo) {
80
83
  item.info = translations.n_children.replace('%s', item.children.length);
@@ -181,7 +184,8 @@ class HiNestedSelectContent extends React.PureComponent {
181
184
  multiple,
182
185
  nbChildrenAsInfo,
183
186
  pinnedParent,
184
- translations
187
+ translations,
188
+ filterFunc
185
189
  } = this.props; // build item list
186
190
 
187
191
  const {
@@ -189,7 +193,7 @@ class HiNestedSelectContent extends React.PureComponent {
189
193
  s: allSelected,
190
194
  u: allUnselected,
191
195
  v: visible
192
- } = buildFilteredItemList(options, value, search, false, pinnedParent, disabledParent || !multiple, nbChildrenAsInfo, translations);
196
+ } = buildFilteredItemList(options, value, search, false, pinnedParent, disabledParent || !multiple, nbChildrenAsInfo, translations, filterFunc);
193
197
  const itemList = !visible ? [...(loading ? [{
194
198
  id: '_loading',
195
199
  type: 'loader',
@@ -272,7 +276,8 @@ HiNestedSelectContent.defaultProps = {
272
276
  search: 'Search',
273
277
  n_children: '%s',
274
278
  one_child: '%s item'
275
- }
279
+ },
280
+ filterFunc: filterValue
276
281
  };
277
282
  HiNestedSelectContent.propTypes = process.env.NODE_ENV !== "production" ? {
278
283
  /**
@@ -285,6 +290,11 @@ HiNestedSelectContent.propTypes = process.env.NODE_ENV !== "production" ? {
285
290
  */
286
291
  disabledParent: PropTypes.bool,
287
292
 
293
+ /*
294
+ * Fonction de filtrage custom
295
+ */
296
+ filterFunc: PropTypes.func,
297
+
288
298
  /**
289
299
  * Affiche l'élément 'All'
290
300
  */
@@ -6,7 +6,6 @@ import Scrollbars from 'react-custom-scrollbars';
6
6
  import Grow from '@material-ui/core/Grow';
7
7
  import Paper from '@material-ui/core/Paper';
8
8
  import Popper from '@material-ui/core/Popper';
9
- import { findDOMNode } from 'react-dom';
10
9
  import ClickAwayListener from '@material-ui/core/ClickAwayListener';
11
10
  import HiSelectableList from '../HiSelectableList';
12
11
  import HiInput from '../HiForm/HiInput';
@@ -69,6 +68,10 @@ export const styles = theme => ({
69
68
  borderTop: `1px solid ${theme.palette.input.bottomLine}`
70
69
  }
71
70
  });
71
+
72
+ function filterValue(item, search) {
73
+ return search === '' || foldAccents(item.label.toString().toLowerCase()).search(foldAccents(search.toLowerCase())) !== -1;
74
+ }
72
75
  /**
73
76
  *
74
77
  * Utilisé pour tous types de selects dans les formulaires.
@@ -84,6 +87,7 @@ export const styles = theme => ({
84
87
  * - HiSelectableList : affiche la liste des suggestions selon le type des éléments
85
88
  */
86
89
 
90
+
87
91
  class HiSelect extends React.PureComponent {
88
92
  constructor(props) {
89
93
  super(props);
@@ -98,7 +102,7 @@ class HiSelect extends React.PureComponent {
98
102
  hideCheckbox: true,
99
103
  label: 'loading'
100
104
  }] : []), // 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({
105
+ ...(search !== '' ? [...options.filter(item => this.props.filterFunc(item, search))] : [...(this.props.hasAll ? [_objectSpread({
102
106
  id: '_all',
103
107
  label: this.props.translations.all
104
108
  }, this.props.iconAll && {
@@ -164,11 +168,12 @@ class HiSelect extends React.PureComponent {
164
168
  };
165
169
 
166
170
  this.focusOnFirstItem = () => {
167
- const overlay = findDOMNode(this.overlay);
168
- setTimeout(() => {
169
- const item = overlay.getElementsByTagName('li')[0];
170
- item.focus();
171
- }, 1);
171
+ if (this.overlay && this.overlay.getElementsByTagName('li')[0]) {
172
+ setTimeout(() => {
173
+ const item = this.overlay.getElementsByTagName('li')[0];
174
+ item.focus();
175
+ }, 1);
176
+ }
172
177
  };
173
178
 
174
179
  this.getInputElement = el => {
@@ -204,21 +209,22 @@ class HiSelect extends React.PureComponent {
204
209
  };
205
210
 
206
211
  this.focusOnSelectedItem = selectedValue => {
207
- const overlay = findDOMNode(this.overlay);
208
- setTimeout(() => {
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
- }
221
- }, 1);
212
+ if (this.overlay && this.overlay.getElementsByTagName('li')[0]) {
213
+ setTimeout(() => {
214
+ // On initialise au premier élément pour être sûr de ne pas se retrouver avec un focus of undefined
215
+ let item = this.overlay.getElementsByTagName('li')[0];
216
+
217
+ if (selectedValue && typeof selectedValue === 'string') {
218
+ item = this.overlay.getElementsByTagName('li')[selectedValue];
219
+ } else if (selectedValue && typeof selectedValue === 'number') {
220
+ item = this.overlay.getElementsByTagName('li')[selectedValue - 1];
221
+ }
222
+
223
+ if (item) {
224
+ item.focus();
225
+ }
226
+ }, 1);
227
+ }
222
228
  };
223
229
 
224
230
  this.handleClickAway = event => {
@@ -249,6 +255,17 @@ class HiSelect extends React.PureComponent {
249
255
  });
250
256
  };
251
257
 
258
+ this.handleKeyDownInput = event => {
259
+ const key = keycode(event);
260
+
261
+ if (key === 'down' || key === 'up') {
262
+ this.handleClick();
263
+ } else if (key === 'enter' && this.props.onSubmit) {
264
+ event.preventDefault();
265
+ this.props.onSubmit(event);
266
+ }
267
+ };
268
+
252
269
  this.handleKeyDown = event => {
253
270
  let nextItem;
254
271
  const key = keycode(event);
@@ -259,6 +276,13 @@ class HiSelect extends React.PureComponent {
259
276
  } else if (key === 'up') {
260
277
  event.preventDefault();
261
278
  nextItem = getNextItemSelectable(document.activeElement, 'up');
279
+ } else if (key === 'tab' || key === 'esc') {
280
+ this.setState({
281
+ open: false
282
+ });
283
+ } else if (key === 'space') {
284
+ // Cancel scroll
285
+ event.preventDefault();
262
286
  }
263
287
 
264
288
  if (nextItem) {
@@ -266,17 +290,57 @@ class HiSelect extends React.PureComponent {
266
290
  }
267
291
  };
268
292
 
293
+ this.getItemById = id => {
294
+ let item;
295
+
296
+ if (this.props.hasAll && String(id) === '_all') {
297
+ return {
298
+ id: '_all'
299
+ };
300
+ }
301
+
302
+ for (let i = 0; i < this.props.options.length; i += 1) {
303
+ const elem = this.props.options[i];
304
+
305
+ if (String(elem.id) === String(id)) {
306
+ item = elem;
307
+ break;
308
+ }
309
+
310
+ if (elem.children) {
311
+ for (let j = 0; j < elem.children.length; j += 1) {
312
+ if (String(elem.children[j].id) === String(id)) {
313
+ item = elem.children[j];
314
+ break;
315
+ }
316
+ }
317
+ }
318
+ }
319
+
320
+ return item;
321
+ };
322
+
269
323
  this.handleKeyUp = event => {
270
324
  const key = keycode(event);
271
325
 
272
- if (key === 'tab' || key === 'esc') {
326
+ if (key === 'esc') {
273
327
  this.setState({
274
328
  open: false
275
329
  });
276
330
  } else if (key === 'space' || key === 'enter' && !this.props.multiple) {
277
331
  event.preventDefault();
278
- const item = this.props.options.find(elem => String(elem.id) === event.target.id);
279
- this.handleSelect(null, item);
332
+ const item = this.getItemById(event.target.id);
333
+
334
+ if (item) {
335
+ // Select for nested select
336
+ if (this.props.hiSelectableListProps && this.props.hiSelectableListProps.onSelect) {
337
+ this.props.hiSelectableListProps.onSelect(null, item);
338
+ } else {
339
+ this.handleSelect(null, item);
340
+ }
341
+ } else {
342
+ console.warn(`Can not find item #${event.target.id}`);
343
+ }
280
344
  } else if (key === 'enter' && this.props.multiple) {
281
345
  event.preventDefault();
282
346
  this.handleClose();
@@ -291,6 +355,10 @@ class HiSelect extends React.PureComponent {
291
355
  } else if (this.overlay && key === 'esc' || key === 'enter') {
292
356
  event.preventDefault();
293
357
  this.handleClose();
358
+ } else if (key === 'tab') {
359
+ this.setState({
360
+ open: false
361
+ });
294
362
  }
295
363
  };
296
364
 
@@ -484,8 +552,8 @@ class HiSelect extends React.PureComponent {
484
552
  [classes.popperRightAlign]: this.props.containerWidth && this.props.align === 'right'
485
553
  });
486
554
 
487
- let searchInput = position => {
488
- if (!!searchable) {
555
+ const searchInput = position => {
556
+ if (searchable) {
489
557
  return React.createElement(HiInput, _extends({
490
558
  value: searchValue,
491
559
  autoFocus: true,
@@ -508,13 +576,13 @@ class HiSelect extends React.PureComponent {
508
576
 
509
577
  if (this.placement && this.placement.indexOf('top') >= 0 && !!searchable) {
510
578
  // +1 for search input
511
- let nbItems = itemList.length <= 10 ? itemList.length + 1 : 11;
579
+ const nbItems = itemList.length <= 10 ? itemList.length + 1 : 11;
512
580
  popperStyle.transform = `translate3d(-1px, -${nbItems * 40 + 2}px, 0px)`;
513
581
  } else if (this.placement && this.placement.indexOf('top') < 0 && !!searchable) {
514
- popperStyle.transform = `translate3d(-1px, 40px, 0px)`;
582
+ popperStyle.transform = 'translate3d(-1px, 40px, 0px)';
515
583
  }
516
584
 
517
- let content = ({
585
+ const content = ({
518
586
  placement
519
587
  }) => {
520
588
  if (placement !== this.placement) {
@@ -568,6 +636,7 @@ class HiSelect extends React.PureComponent {
568
636
  onClick: this.handleClick,
569
637
  onFocus: this.handleFocus,
570
638
  onBlur: this.handleBlur,
639
+ onKeyDown: this.handleKeyDownInput,
571
640
  onSubmit: onSubmit,
572
641
  onMouseEnter: this.props.onMouseEnter,
573
642
  onMouseLeave: this.props.onMouseLeave,
@@ -614,7 +683,8 @@ HiSelect.defaultProps = {
614
683
  n_children: '%s items',
615
684
  one_child: '%s item'
616
685
  },
617
- type: 'text'
686
+ type: 'text',
687
+ filterFunc: filterValue
618
688
  };
619
689
  HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
620
690
  align: PropTypes.oneOf(['left', 'right']),
@@ -649,6 +719,11 @@ HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
649
719
  */
650
720
  fallbackImage: PropTypes.string,
651
721
 
722
+ /*
723
+ * Fonction de filtrage custom
724
+ */
725
+ filterFunc: PropTypes.func,
726
+
652
727
  /**
653
728
  * Affiche l'élément 'All'
654
729
  */