@hipay/hipay-material-ui 2.0.0-beta.50 → 2.0.0-beta.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HiCell/CellAddress.js +0 -1
- package/HiForm/HiInput.js +1 -5
- package/HiSelectNew/HiNestedSelectContent.js +472 -0
- package/HiSelectNew/HiSelectContent.js +525 -0
- package/HiSelectNew/index.js +31 -1
- package/HiSelectableList/HiSelectableListItem.js +1 -2
- package/es/HiCell/CellAddress.js +0 -1
- package/es/HiForm/HiInput.js +1 -5
- package/es/HiSelectNew/HiNestedSelectContent.js +406 -0
- package/es/HiSelectNew/HiSelectContent.js +457 -0
- package/es/HiSelectNew/index.js +3 -1
- package/es/HiSelectableList/HiSelectableListItem.js +1 -2
- package/index.es.js +1 -1
- package/index.js +1 -1
- package/package.json +1 -1
- package/umd/hipay-material-ui.development.js +3 -8
- package/umd/hipay-material-ui.production.min.js +2 -2
@@ -0,0 +1,457 @@
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
2
|
+
import _objectSpread from "@babel/runtime/helpers/objectSpread";
|
3
|
+
import React from 'react';
|
4
|
+
import PropTypes from 'prop-types';
|
5
|
+
import Scrollbars from 'react-custom-scrollbars';
|
6
|
+
import HiSelectableList from '../HiSelectableList';
|
7
|
+
import HiInput from '../HiForm/HiInput';
|
8
|
+
import withStyles from '../styles/withStyles';
|
9
|
+
import { getNextItemSelectable, foldAccents } from '../utils/helpers';
|
10
|
+
import HiIcon from '../HiIcon';
|
11
|
+
import keycode from 'keycode';
|
12
|
+
export const styles = theme => ({
|
13
|
+
labelIcon: {
|
14
|
+
marginRight: 10
|
15
|
+
},
|
16
|
+
labelImg: {
|
17
|
+
height: 18,
|
18
|
+
width: 'auto',
|
19
|
+
margin: '0 4px',
|
20
|
+
verticalAlign: 'middle'
|
21
|
+
},
|
22
|
+
selectIconLabel: _objectSpread({
|
23
|
+
whiteSpace: 'nowrap',
|
24
|
+
overflow: 'hidden',
|
25
|
+
textOverflow: 'ellipsis',
|
26
|
+
paddingRight: 16
|
27
|
+
}, theme.typography.b1, {
|
28
|
+
display: 'inline-flex',
|
29
|
+
width: '100%'
|
30
|
+
}),
|
31
|
+
selectImgLabel: _objectSpread({
|
32
|
+
whiteSpace: 'nowrap',
|
33
|
+
overflow: 'hidden',
|
34
|
+
textOverflow: 'ellipsis',
|
35
|
+
paddingRight: 16
|
36
|
+
}, theme.typography.b1, {
|
37
|
+
display: 'inline-flex',
|
38
|
+
width: '100%'
|
39
|
+
})
|
40
|
+
});
|
41
|
+
/**
|
42
|
+
*
|
43
|
+
* Utilisé pour tous types de selects dans les formulaires.
|
44
|
+
* - single / multiple ( multi-select )
|
45
|
+
* - avec / sans checkboxes
|
46
|
+
* - avec / sans barre de recherche
|
47
|
+
* - avec / sans option "All"
|
48
|
+
* - prise en compte du type des éléments (text, image, icon, ...)
|
49
|
+
*
|
50
|
+
* Ce composant réuni les sous-composants
|
51
|
+
* - HiSelectInput : affiche l'élément dans le formulaire
|
52
|
+
* - HiSearchField : intègre une barre de recherche dans le Popper, il filtre la liste des suggestions
|
53
|
+
* - HiSelectableList : affiche la liste des suggestions selon le type des éléments
|
54
|
+
*/
|
55
|
+
|
56
|
+
class HiSelectContent extends React.PureComponent {
|
57
|
+
constructor(props) {
|
58
|
+
super(props);
|
59
|
+
|
60
|
+
this.handleKeyDown = event => {
|
61
|
+
let nextItem;
|
62
|
+
const key = keycode(event);
|
63
|
+
|
64
|
+
if (key === 'down') {
|
65
|
+
event.preventDefault();
|
66
|
+
nextItem = getNextItemSelectable(document.activeElement, 'down');
|
67
|
+
} else if (key === 'up') {
|
68
|
+
event.preventDefault();
|
69
|
+
nextItem = getNextItemSelectable(document.activeElement, 'up');
|
70
|
+
} else if (key === 'tab' || key === 'esc') {
|
71
|
+
this.setState({
|
72
|
+
open: false
|
73
|
+
});
|
74
|
+
} else if (key === 'space' || key === 'enter' && !this.props.multiple) {
|
75
|
+
event.preventDefault();
|
76
|
+
const item = this.props.options.find(elem => String(elem.id) === event.target.id);
|
77
|
+
this.handleSelect(null, item);
|
78
|
+
} else if (key === 'enter' && this.props.multiple) {
|
79
|
+
event.preventDefault();
|
80
|
+
this.handleClose();
|
81
|
+
}
|
82
|
+
|
83
|
+
if (nextItem) {
|
84
|
+
nextItem.focus();
|
85
|
+
}
|
86
|
+
};
|
87
|
+
|
88
|
+
this.handleKeyDownSearch = event => {
|
89
|
+
const key = keycode(event);
|
90
|
+
|
91
|
+
if (this.overlay && (key === 'down' || key === 'up')) {
|
92
|
+
this.focusOnFirstItem();
|
93
|
+
} else if (this.overlay && key === 'esc' || key === 'enter') {
|
94
|
+
event.preventDefault();
|
95
|
+
this.handleClose();
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
99
|
+
this.handleSelect = (event, item) => {
|
100
|
+
const {
|
101
|
+
hasAll,
|
102
|
+
multiple,
|
103
|
+
onChange,
|
104
|
+
options,
|
105
|
+
value
|
106
|
+
} = this.props;
|
107
|
+
|
108
|
+
if (!multiple) {
|
109
|
+
// single value
|
110
|
+
this.handleClose();
|
111
|
+
onChange(event, item.id, item);
|
112
|
+
} else if (hasAll && item.id === '_all') {
|
113
|
+
if (value.length === options.length) {
|
114
|
+
// unselect _all options
|
115
|
+
onChange(event, [], item);
|
116
|
+
} else {
|
117
|
+
// select _all options
|
118
|
+
onChange(event, options.map(option => option.id), item);
|
119
|
+
}
|
120
|
+
} else if (value.includes(item.id)) {
|
121
|
+
// unselect item
|
122
|
+
onChange(event, value.filter(id => id !== item.id), item);
|
123
|
+
} else {
|
124
|
+
onChange(event, [...value, item.id], item);
|
125
|
+
}
|
126
|
+
};
|
127
|
+
|
128
|
+
this.handleClose = () => {
|
129
|
+
if (this.props.onClose) this.props.onClose();
|
130
|
+
};
|
131
|
+
|
132
|
+
this.handleSuggestions = suggestions => {
|
133
|
+
const {
|
134
|
+
hasAll,
|
135
|
+
iconAll,
|
136
|
+
translations
|
137
|
+
} = this.props;
|
138
|
+
|
139
|
+
if (suggestions.length === 0) {
|
140
|
+
// Add '_no_result' suggestion
|
141
|
+
this.setState(prevState => _objectSpread({}, prevState, {
|
142
|
+
suggestions: [{
|
143
|
+
id: '_no_result',
|
144
|
+
type: 'text',
|
145
|
+
disabled: true,
|
146
|
+
centered: true,
|
147
|
+
hideCheckbox: true,
|
148
|
+
label: translations.no_result_match
|
149
|
+
}]
|
150
|
+
}));
|
151
|
+
} else {
|
152
|
+
this.setState({
|
153
|
+
suggestions: [// Add '_all' suggestion
|
154
|
+
...(hasAll ? [_objectSpread({
|
155
|
+
id: '_all',
|
156
|
+
label: translations.all
|
157
|
+
}, iconAll && {
|
158
|
+
type: 'icon',
|
159
|
+
icon: iconAll
|
160
|
+
})] : []), ...suggestions]
|
161
|
+
});
|
162
|
+
}
|
163
|
+
};
|
164
|
+
|
165
|
+
this.handleScroll = e => {
|
166
|
+
if (e.target.scrollHeight - e.target.clientHeight - e.target.scrollTop < 15) {
|
167
|
+
this.props.onScrollReachBottom();
|
168
|
+
}
|
169
|
+
};
|
170
|
+
|
171
|
+
this.handleSearch = (e, inputValue) => {
|
172
|
+
const searchValue = inputValue && e.target.value ? inputValue : e.target.value;
|
173
|
+
|
174
|
+
if (this.props.onSearch) {
|
175
|
+
this.props.onSearch(e, searchValue);
|
176
|
+
} else {
|
177
|
+
this.setState({
|
178
|
+
searchValue
|
179
|
+
});
|
180
|
+
}
|
181
|
+
};
|
182
|
+
|
183
|
+
this.handleSearchReset = () => {
|
184
|
+
this.handleSearch({
|
185
|
+
target: {
|
186
|
+
value: ''
|
187
|
+
}
|
188
|
+
}, '');
|
189
|
+
};
|
190
|
+
|
191
|
+
this.buildSelectProps = (options, value = [], search = '', loading = false) => {
|
192
|
+
// build item list
|
193
|
+
const itemList = [...(loading ? [{
|
194
|
+
id: '_loading',
|
195
|
+
type: 'loader',
|
196
|
+
disabled: true,
|
197
|
+
centered: true,
|
198
|
+
hideCheckbox: true,
|
199
|
+
label: 'loading'
|
200
|
+
}] : []), // simple one level filter on label
|
201
|
+
...(search !== '' ? [...options.filter(item => item.label && foldAccents(item.label.toString().toLowerCase()).search(foldAccents(search.toLowerCase())) !== -1)] : [...(this.props.hasAll ? [_objectSpread({
|
202
|
+
id: '_all',
|
203
|
+
label: this.props.translations.all
|
204
|
+
}, this.props.iconAll && {
|
205
|
+
type: 'icon',
|
206
|
+
icon: this.props.iconAll
|
207
|
+
})] : []), ...options])];
|
208
|
+
return {
|
209
|
+
itemList
|
210
|
+
};
|
211
|
+
};
|
212
|
+
|
213
|
+
this.getInputElement = el => {
|
214
|
+
this.searchField = el;
|
215
|
+
|
216
|
+
if (this.props.inputRef) {
|
217
|
+
this.props.inputRef(this.searchField);
|
218
|
+
}
|
219
|
+
};
|
220
|
+
|
221
|
+
this.state = {
|
222
|
+
open: false,
|
223
|
+
focused: false,
|
224
|
+
searchValue: props.searchValue ? undefined : '',
|
225
|
+
suggestions: props.options
|
226
|
+
};
|
227
|
+
this.handleSearch = this.handleSearch.bind(this);
|
228
|
+
this.handleSearchReset = this.handleSearchReset.bind(this);
|
229
|
+
this.handleSelect = this.handleSelect.bind(this);
|
230
|
+
this.handleSuggestions = this.handleSuggestions.bind(this);
|
231
|
+
}
|
232
|
+
|
233
|
+
static getDerivedStateFromProps(nextProps, prevState) {
|
234
|
+
if (nextProps.options !== prevState.suggestions) {
|
235
|
+
return _objectSpread({}, prevState, {
|
236
|
+
suggestions: nextProps.options
|
237
|
+
});
|
238
|
+
}
|
239
|
+
|
240
|
+
return null;
|
241
|
+
} // Key down on list items
|
242
|
+
|
243
|
+
|
244
|
+
render() {
|
245
|
+
const {
|
246
|
+
classes,
|
247
|
+
disabled,
|
248
|
+
error,
|
249
|
+
loading,
|
250
|
+
options,
|
251
|
+
searchable,
|
252
|
+
type,
|
253
|
+
value,
|
254
|
+
multiple,
|
255
|
+
translations,
|
256
|
+
hiSelectableListProps,
|
257
|
+
hiSelectInputProps,
|
258
|
+
id,
|
259
|
+
onScrollReachBottom,
|
260
|
+
onSubmit,
|
261
|
+
startAdornment,
|
262
|
+
searchValue = this.state.searchValue,
|
263
|
+
buildSelectProps = this.buildSelectProps,
|
264
|
+
// use parent builder if defined
|
265
|
+
autoHeight,
|
266
|
+
height
|
267
|
+
} = this.props;
|
268
|
+
|
269
|
+
if (multiple) {
|
270
|
+
if (!Array.isArray(value)) {
|
271
|
+
throw new Error('HiPay Material-UI: the `value` property must be an array ' + 'when using the `HiSelect` component with `multiple`.');
|
272
|
+
}
|
273
|
+
}
|
274
|
+
|
275
|
+
let selectedItemIdList = [];
|
276
|
+
|
277
|
+
if (value) {
|
278
|
+
selectedItemIdList = multiple ? [...value] : [value];
|
279
|
+
}
|
280
|
+
|
281
|
+
const {
|
282
|
+
itemList
|
283
|
+
} = buildSelectProps(options, selectedItemIdList, searchValue, loading);
|
284
|
+
return React.createElement(React.Fragment, null, !!searchable && React.createElement(HiInput, {
|
285
|
+
value: searchValue,
|
286
|
+
autoFocus: true,
|
287
|
+
inputRef: this.getInputElement,
|
288
|
+
onKeyDown: this.handleKeyDownSearch,
|
289
|
+
onChange: this.handleSearch,
|
290
|
+
onReset: this.handleSearchReset,
|
291
|
+
placeholder: translations.search,
|
292
|
+
startAdornment: 'search',
|
293
|
+
tabIndex: 0
|
294
|
+
}), startAdornment, React.createElement(Scrollbars, _extends({
|
295
|
+
ref: contentEl => {
|
296
|
+
this.optionsContent = contentEl;
|
297
|
+
}
|
298
|
+
}, autoHeight ? {
|
299
|
+
autoHeight: true,
|
300
|
+
autoHeightMax: height
|
301
|
+
} : {
|
302
|
+
autoHeightMax: height,
|
303
|
+
autoHeightMin: height
|
304
|
+
}, {
|
305
|
+
autoHeight: true,
|
306
|
+
autoHeightMax: height // TODO ?
|
307
|
+
|
308
|
+
}, onScrollReachBottom && {
|
309
|
+
onScroll: this.handleScroll
|
310
|
+
}), React.createElement(HiSelectableList, _extends({
|
311
|
+
type: type,
|
312
|
+
itemList: itemList,
|
313
|
+
onKeyDown: this.handleKeyDown,
|
314
|
+
onSelect: this.handleSelect,
|
315
|
+
selectedItemIdList: selectedItemIdList,
|
316
|
+
fallbackImage: this.props.fallbackImage
|
317
|
+
}, hiSelectableListProps))));
|
318
|
+
}
|
319
|
+
|
320
|
+
}
|
321
|
+
|
322
|
+
HiSelectContent.defaultProps = {
|
323
|
+
autoHeight: true,
|
324
|
+
height: 400,
|
325
|
+
disabled: false,
|
326
|
+
error: false,
|
327
|
+
hasAll: false,
|
328
|
+
hiSelectableListProps: {},
|
329
|
+
hiSelectInputProps: {},
|
330
|
+
multiple: false,
|
331
|
+
searchable: false,
|
332
|
+
translations: {
|
333
|
+
all: 'All',
|
334
|
+
no_result_match: 'No result match',
|
335
|
+
search: 'Search',
|
336
|
+
n_items_selected: '%s items selected',
|
337
|
+
one_item_selected: '%s item selected',
|
338
|
+
n_children: '%s items',
|
339
|
+
one_child: '%s item'
|
340
|
+
},
|
341
|
+
type: 'text'
|
342
|
+
};
|
343
|
+
HiSelectContent.propTypes = process.env.NODE_ENV !== "production" ? {
|
344
|
+
autoHeight: PropTypes.bool,
|
345
|
+
|
346
|
+
/**
|
347
|
+
* Useful to extend the style applied to components.
|
348
|
+
*/
|
349
|
+
classes: PropTypes.object,
|
350
|
+
|
351
|
+
/**
|
352
|
+
* Inactif
|
353
|
+
*/
|
354
|
+
disabled: PropTypes.bool,
|
355
|
+
|
356
|
+
/**
|
357
|
+
* Applique le style error
|
358
|
+
*/
|
359
|
+
error: PropTypes.bool,
|
360
|
+
|
361
|
+
/**
|
362
|
+
* Chemin vers l'image à afficher par défaut si une image n'est pas trouvée
|
363
|
+
*/
|
364
|
+
fallbackImage: PropTypes.string,
|
365
|
+
|
366
|
+
/**
|
367
|
+
* Affiche l'élément 'All'
|
368
|
+
*/
|
369
|
+
hasAll: PropTypes.bool,
|
370
|
+
|
371
|
+
/**
|
372
|
+
* Hauteur du container scrollable
|
373
|
+
*/
|
374
|
+
height: PropTypes.number,
|
375
|
+
|
376
|
+
/**
|
377
|
+
* Override HiSelectableList props (
|
378
|
+
*/
|
379
|
+
hiSelectableListProps: PropTypes.object,
|
380
|
+
|
381
|
+
/**
|
382
|
+
* Override HiSelectInput props
|
383
|
+
*/
|
384
|
+
hiSelectInputProps: PropTypes.object,
|
385
|
+
|
386
|
+
/**
|
387
|
+
* Nom de l'icône
|
388
|
+
*/
|
389
|
+
iconAll: PropTypes.string,
|
390
|
+
|
391
|
+
/**
|
392
|
+
* id du select
|
393
|
+
*/
|
394
|
+
id: PropTypes.string,
|
395
|
+
|
396
|
+
/**
|
397
|
+
* Ajoute un loader
|
398
|
+
*/
|
399
|
+
loading: PropTypes.bool,
|
400
|
+
|
401
|
+
/**
|
402
|
+
* Autorise la sélection de plusieurs valeurs
|
403
|
+
*/
|
404
|
+
multiple: PropTypes.bool,
|
405
|
+
|
406
|
+
/**
|
407
|
+
* Fonction de callback qui renvoit la/les valeurs sélectionnées
|
408
|
+
*
|
409
|
+
* @param {object} event
|
410
|
+
* @param {string || array} value
|
411
|
+
*/
|
412
|
+
onChange: PropTypes.func.isRequired,
|
413
|
+
|
414
|
+
/**
|
415
|
+
* Fonction de callback appelée lorsque le scroll atteint le bas de la liste
|
416
|
+
*/
|
417
|
+
onScrollReachBottom: PropTypes.func,
|
418
|
+
|
419
|
+
/**
|
420
|
+
* Fonction de callback appelée lorsque le champs de recherche est utilisé
|
421
|
+
*/
|
422
|
+
onSearch: PropTypes.func,
|
423
|
+
|
424
|
+
/**
|
425
|
+
* Listes des options du select
|
426
|
+
*/
|
427
|
+
options: PropTypes.array.isRequired,
|
428
|
+
|
429
|
+
/**
|
430
|
+
* Affiche un input de recherche permettant de filtrer les options
|
431
|
+
*/
|
432
|
+
searchable: PropTypes.bool,
|
433
|
+
|
434
|
+
/**
|
435
|
+
* Node qui s'ajoute entre la barre de recherche et la liste de résultats
|
436
|
+
*/
|
437
|
+
startAdornment: PropTypes.object,
|
438
|
+
|
439
|
+
/**
|
440
|
+
* Traductions (par défaut en anglais)
|
441
|
+
*/
|
442
|
+
translations: PropTypes.object,
|
443
|
+
|
444
|
+
/**
|
445
|
+
* Type des éléments du select, définit le rendu d'un élément
|
446
|
+
*/
|
447
|
+
type: PropTypes.oneOf(['icon', 'text', 'image', 'primary-highlight']),
|
448
|
+
|
449
|
+
/**
|
450
|
+
* Value(s) du select
|
451
|
+
*/
|
452
|
+
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.array])
|
453
|
+
} : {};
|
454
|
+
export default withStyles(styles, {
|
455
|
+
hiComponent: true,
|
456
|
+
name: 'HmuiHiSelectContent'
|
457
|
+
})(HiSelectContent);
|
package/es/HiSelectNew/index.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
export { default } from './HiSelect';
|
2
2
|
export { default as HiNestedSelect } from './HiNestedSelect';
|
3
3
|
export { default as HiSelectField } from './HiSelectField';
|
4
|
-
export { default as HiSelectInput } from './HiSelectInput';
|
4
|
+
export { default as HiSelectInput } from './HiSelectInput';
|
5
|
+
export { default as HiSelectContent } from './HiSelectContent';
|
6
|
+
export { default as HiNestedSelectContent, findFinalItemRecursively, getRecursiveFinalItemIdList } from './HiNestedSelectContent';
|
package/index.es.js
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/** @license HiPay-Material-UI v2.0.0-beta.
|
1
|
+
/** @license HiPay-Material-UI v2.0.0-beta.51
|
2
2
|
*
|
3
3
|
* This source code is licensed under the MIT license found in the
|
4
4
|
* LICENSE file in the root directory of this source tree.
|
@@ -68768,12 +68768,8 @@
|
|
68768
68768
|
}, {
|
68769
68769
|
key: "handleChange",
|
68770
68770
|
value: function handleChange(event) {
|
68771
|
-
var authorizedChar = '1234567890TOto<>';
|
68772
|
-
|
68773
68771
|
if (this.props.onChange) {
|
68774
|
-
|
68775
|
-
this.props.onChange(event);
|
68776
|
-
}
|
68772
|
+
this.props.onChange(event);
|
68777
68773
|
}
|
68778
68774
|
}
|
68779
68775
|
}, {
|
@@ -98066,8 +98062,7 @@
|
|
98066
98062
|
textOverflow: 'ellipsis',
|
98067
98063
|
textAlign: 'right',
|
98068
98064
|
margin: '4px 12px 4px 8px',
|
98069
|
-
alignSelf: 'center'
|
98070
|
-
width: '100%'
|
98065
|
+
alignSelf: 'center'
|
98071
98066
|
}),
|
98072
98067
|
checkbox: {
|
98073
98068
|
marginTop: 3
|