@hipay/hipay-material-ui 2.0.0-beta.60 → 2.0.0-beta.62
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/CHANGELOG.md +126 -0
- package/HiDatePicker/HiDatePicker.js +37 -12
- package/HiDatePicker/HiDateRangePicker.js +71 -57
- package/HiDatePicker/HiDateRangeSelector.js +34 -20
- package/HiDatePicker/stylesheet.js +32 -17
- package/HiSelect/HiSelect.js +489 -607
- package/HiSelect/index.js +41 -3
- package/HiSelectableList/HiSelectableList.js +68 -3
- package/HiSelectableList/HiSelectableListItem.js +22 -10
- package/README.md +15 -0
- package/es/HiDatePicker/HiDatePicker.js +30 -10
- package/es/HiDatePicker/HiDateRangePicker.js +38 -21
- package/es/HiDatePicker/HiDateRangeSelector.js +24 -13
- package/es/HiDatePicker/stylesheet.js +32 -17
- package/es/{HiSelectNew → HiSelect}/HiNestedSelect.js +1 -1
- package/es/{HiSelectNew → HiSelect}/HiNestedSelectContent.js +1 -1
- package/es/HiSelect/HiSelect.js +441 -564
- package/es/{HiSelectNew → HiSelect}/HiSelectContent.js +1 -1
- package/es/HiSelect/index.js +4 -1
- package/es/HiSelectableList/HiSelectableList.js +65 -4
- package/es/HiSelectableList/HiSelectableListItem.js +18 -10
- package/es/styles/createPalette.js +1 -1
- package/es/utils/helpers.js +9 -1
- package/index.es.js +1 -1
- package/index.js +1 -1
- package/package.json +1 -1
- package/styles/createPalette.js +1 -1
- package/umd/hipay-material-ui.development.js +7860 -7749
- package/umd/hipay-material-ui.production.min.js +2 -2
- package/utils/helpers.js +9 -1
- package/HiSelect/SelectInput.js +0 -369
- package/HiSelectNew/HiSelect.js +0 -929
- package/HiSelectNew/HiSelectField.js +0 -146
- package/HiSelectNew/index.js +0 -69
- package/es/HiSelect/SelectInput.js +0 -321
- package/es/HiSelectNew/HiSelect.js +0 -852
- package/es/HiSelectNew/HiSelectField.js +0 -111
- package/es/HiSelectNew/index.js +0 -6
- /package/{HiSelectNew → HiSelect}/HiDynamicSelect.js +0 -0
- /package/{HiSelectNew → HiSelect}/HiDynamicSelectField.js +0 -0
- /package/{HiSelectNew → HiSelect}/HiNestedSelect.js +0 -0
- /package/{HiSelectNew → HiSelect}/HiNestedSelectContent.js +0 -0
- /package/{HiSelectNew → HiSelect}/HiNestedSelectField.js +0 -0
- /package/{HiSelectNew → HiSelect}/HiSelectContent.js +0 -0
- /package/{HiSelectNew → HiSelect}/HiSelectInput.js +0 -0
- /package/es/{HiSelectNew → HiSelect}/HiDynamicSelect.js +0 -0
- /package/es/{HiSelectNew → HiSelect}/HiDynamicSelectField.js +0 -0
- /package/es/{HiSelectNew → HiSelect}/HiNestedSelectField.js +0 -0
- /package/es/{HiSelectNew → HiSelect}/HiSelectInput.js +0 -0
@@ -1,852 +0,0 @@
|
|
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 Grow from '@material-ui/core/Grow';
|
7
|
-
import Paper from '@material-ui/core/Paper';
|
8
|
-
import Popper from '@material-ui/core/Popper';
|
9
|
-
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
|
10
|
-
import HiSelectableList from '../HiSelectableList';
|
11
|
-
import HiInput from '../HiForm/HiInput';
|
12
|
-
import HiSelectInput from './HiSelectInput';
|
13
|
-
import withStyles from '../styles/withStyles';
|
14
|
-
import { getNextItemSelectable, foldAccents } from '../utils/helpers';
|
15
|
-
import HiIcon from '../HiIcon';
|
16
|
-
import keycode from 'keycode';
|
17
|
-
import classNames from 'classnames';
|
18
|
-
export const styles = theme => ({
|
19
|
-
root: {
|
20
|
-
backgroundColor: theme.palette.background2,
|
21
|
-
maxWidth: 500,
|
22
|
-
width: '100%',
|
23
|
-
position: 'relative'
|
24
|
-
},
|
25
|
-
popper: {
|
26
|
-
zIndex: 1200
|
27
|
-
},
|
28
|
-
popperWidth: {
|
29
|
-
width: '100% !important'
|
30
|
-
},
|
31
|
-
popperRightAlign: {
|
32
|
-
right: 0,
|
33
|
-
left: 'unset!important'
|
34
|
-
},
|
35
|
-
paper: {
|
36
|
-
borderRadius: '0px 2px',
|
37
|
-
maxHeight: 480,
|
38
|
-
transition: 'none !important'
|
39
|
-
},
|
40
|
-
labelIcon: {
|
41
|
-
marginRight: 10
|
42
|
-
},
|
43
|
-
labelImg: {
|
44
|
-
height: 18,
|
45
|
-
width: 'auto',
|
46
|
-
margin: '0 4px',
|
47
|
-
verticalAlign: 'middle'
|
48
|
-
},
|
49
|
-
selectIconLabel: _objectSpread({
|
50
|
-
whiteSpace: 'nowrap',
|
51
|
-
overflow: 'hidden',
|
52
|
-
textOverflow: 'ellipsis',
|
53
|
-
paddingRight: 16
|
54
|
-
}, theme.typography.b1, {
|
55
|
-
display: 'inline-flex',
|
56
|
-
width: '100%'
|
57
|
-
}),
|
58
|
-
selectImgLabel: _objectSpread({
|
59
|
-
whiteSpace: 'nowrap',
|
60
|
-
overflow: 'hidden',
|
61
|
-
textOverflow: 'ellipsis',
|
62
|
-
paddingRight: 16
|
63
|
-
}, theme.typography.b1, {
|
64
|
-
display: 'inline-flex',
|
65
|
-
width: '100%'
|
66
|
-
}),
|
67
|
-
separator: {
|
68
|
-
borderTop: `1px solid ${theme.palette.input.bottomLine}`
|
69
|
-
}
|
70
|
-
});
|
71
|
-
|
72
|
-
function filterValue(item, search) {
|
73
|
-
return search === '' || foldAccents(item.label.toString().toLowerCase()).search(foldAccents(search.toLowerCase())) !== -1;
|
74
|
-
}
|
75
|
-
/**
|
76
|
-
*
|
77
|
-
* Utilisé pour tous types de selects dans les formulaires.
|
78
|
-
* - single / multiple ( multi-select )
|
79
|
-
* - avec / sans checkboxes
|
80
|
-
* - avec / sans barre de recherche
|
81
|
-
* - avec / sans option "All"
|
82
|
-
* - prise en compte du type des éléments (text, image, icon, ...)
|
83
|
-
*
|
84
|
-
* Ce composant réuni les sous-composants
|
85
|
-
* - HiSelectInput : affiche l'élément dans le formulaire
|
86
|
-
* - HiSearchField : intègre une barre de recherche dans le Popper, il filtre la liste des suggestions
|
87
|
-
* - HiSelectableList : affiche la liste des suggestions selon le type des éléments
|
88
|
-
*/
|
89
|
-
|
90
|
-
|
91
|
-
class HiSelect extends React.PureComponent {
|
92
|
-
constructor(props) {
|
93
|
-
super(props);
|
94
|
-
|
95
|
-
this.buildSelectProps = (options, value = [], search = '', loading = false) => {
|
96
|
-
// build item list
|
97
|
-
const itemList = [...(loading ? [{
|
98
|
-
id: '_loading',
|
99
|
-
type: 'loader',
|
100
|
-
disabled: true,
|
101
|
-
centered: true,
|
102
|
-
hideCheckbox: true,
|
103
|
-
label: 'loading'
|
104
|
-
}] : []), // simple one level filter on label
|
105
|
-
...(search !== '' ? [...options.filter(item => this.props.filterFunc(item, search))] : [...(this.props.hasAll ? [_objectSpread({
|
106
|
-
id: '_all',
|
107
|
-
label: this.props.translations.all
|
108
|
-
}, this.props.iconAll && {
|
109
|
-
type: 'icon',
|
110
|
-
icon: this.props.iconAll
|
111
|
-
})] : []), ...options])];
|
112
|
-
return {
|
113
|
-
itemList,
|
114
|
-
inputValue: this.buildInputValue(options, value, loading)
|
115
|
-
};
|
116
|
-
};
|
117
|
-
|
118
|
-
this.buildInputValue = (options, value = [], loading = false) => {
|
119
|
-
const {
|
120
|
-
classes,
|
121
|
-
hasAll,
|
122
|
-
translations,
|
123
|
-
type
|
124
|
-
} = this.props; // build input value
|
125
|
-
|
126
|
-
let inputValue;
|
127
|
-
|
128
|
-
if (loading && value.length === 1) {
|
129
|
-
inputValue = translations.one_item_selected;
|
130
|
-
} else if (hasAll && options.length === value.length) {
|
131
|
-
inputValue = translations.all;
|
132
|
-
value.unshift('_all');
|
133
|
-
} else if (value.length > 1) {
|
134
|
-
inputValue = translations.n_items_selected.replace('%s', value.length);
|
135
|
-
} else if (value.length === 1) {
|
136
|
-
const item = options.find(o => o.id === value[0]);
|
137
|
-
|
138
|
-
if (item === undefined) {
|
139
|
-
inputValue = translations.one_item_selected;
|
140
|
-
} else if (type === 'icon' || item.type === 'icon') {
|
141
|
-
inputValue = React.createElement("span", {
|
142
|
-
className: classes.selectIconLabel
|
143
|
-
}, React.createElement(HiIcon, {
|
144
|
-
className: classes.labelIcon,
|
145
|
-
icon: item.icon
|
146
|
-
}), item.label);
|
147
|
-
} else if (type === 'image' || item.type === 'image') {
|
148
|
-
inputValue = React.createElement("span", {
|
149
|
-
className: classes.selectIconLabel
|
150
|
-
}, React.createElement("img", {
|
151
|
-
className: classes.labelImg,
|
152
|
-
src: item.img,
|
153
|
-
alt: item.label,
|
154
|
-
onError: e => {
|
155
|
-
if (item.fallbackImage) {
|
156
|
-
e.target.src = `${item.fallbackImage}`;
|
157
|
-
} else {
|
158
|
-
e.target.style.display = 'none';
|
159
|
-
}
|
160
|
-
}
|
161
|
-
}), item.label);
|
162
|
-
} else {
|
163
|
-
inputValue = item.label;
|
164
|
-
}
|
165
|
-
}
|
166
|
-
|
167
|
-
return inputValue;
|
168
|
-
};
|
169
|
-
|
170
|
-
this.focusOnFirstItem = () => {
|
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
|
-
}
|
177
|
-
};
|
178
|
-
|
179
|
-
this.getInputElement = el => {
|
180
|
-
this.searchField = el;
|
181
|
-
|
182
|
-
if (this.props.inputRef) {
|
183
|
-
this.props.inputRef(this.searchField);
|
184
|
-
}
|
185
|
-
};
|
186
|
-
|
187
|
-
this.handleBlur = () => {
|
188
|
-
this.handleSearchReset();
|
189
|
-
this.setState({
|
190
|
-
focused: false
|
191
|
-
});
|
192
|
-
};
|
193
|
-
|
194
|
-
this.handleClick = () => {
|
195
|
-
if (this.state.open) {
|
196
|
-
this.handleClose();
|
197
|
-
} else {
|
198
|
-
this.setState({
|
199
|
-
open: true
|
200
|
-
});
|
201
|
-
this.handleSuggestions(this.props.options);
|
202
|
-
if (this.props.onClick) this.props.onClick(); // Gestion du focus
|
203
|
-
|
204
|
-
if (!this.props.searchable) {
|
205
|
-
// Sinon focus sur l'élément sélectionné
|
206
|
-
this.focusOnSelectedItem(this.props.value);
|
207
|
-
}
|
208
|
-
}
|
209
|
-
};
|
210
|
-
|
211
|
-
this.focusOnSelectedItem = selectedValue => {
|
212
|
-
setTimeout(() => {
|
213
|
-
// On initialise au premier élément pour être sûr de ne pas se retrouver avec un focus of undefined
|
214
|
-
let item = this.overlay.getElementsByTagName('li')[0];
|
215
|
-
|
216
|
-
if (selectedValue && typeof selectedValue === 'string') {
|
217
|
-
item = this.overlay.getElementsByTagName('li')[selectedValue];
|
218
|
-
} else if (selectedValue && typeof selectedValue === 'number') {
|
219
|
-
item = this.overlay.getElementsByTagName('li')[selectedValue - 1];
|
220
|
-
}
|
221
|
-
|
222
|
-
if (item) {
|
223
|
-
item.focus();
|
224
|
-
}
|
225
|
-
}, 1);
|
226
|
-
};
|
227
|
-
|
228
|
-
this.handleClickAway = event => {
|
229
|
-
// Au clic sur le bouton, on laisse le handleClick fermer le select
|
230
|
-
if (!this.inputEl.contains(event.target)) {
|
231
|
-
this.handleClose(event);
|
232
|
-
}
|
233
|
-
};
|
234
|
-
|
235
|
-
this.handleClose = () => {
|
236
|
-
this.handleSearchReset();
|
237
|
-
this.setState({
|
238
|
-
open: false
|
239
|
-
});
|
240
|
-
|
241
|
-
if (this.props.onClose) {
|
242
|
-
this.props.onClose();
|
243
|
-
}
|
244
|
-
|
245
|
-
if (this.inputEl) {
|
246
|
-
this.inputEl.focus();
|
247
|
-
}
|
248
|
-
};
|
249
|
-
|
250
|
-
this.handleFocus = () => {
|
251
|
-
this.setState({
|
252
|
-
focused: true
|
253
|
-
});
|
254
|
-
};
|
255
|
-
|
256
|
-
this.handleKeyDownInput = event => {
|
257
|
-
const key = keycode(event);
|
258
|
-
|
259
|
-
if (key === 'down' || key === 'up') {
|
260
|
-
this.handleClick();
|
261
|
-
} else if (key === 'enter' && this.props.onSubmit) {
|
262
|
-
event.preventDefault();
|
263
|
-
this.props.onSubmit(event);
|
264
|
-
}
|
265
|
-
};
|
266
|
-
|
267
|
-
this.handleKeyDown = event => {
|
268
|
-
let nextItem;
|
269
|
-
const key = keycode(event);
|
270
|
-
|
271
|
-
if (key === 'down') {
|
272
|
-
event.preventDefault();
|
273
|
-
nextItem = getNextItemSelectable(document.activeElement, 'down');
|
274
|
-
} else if (key === 'up') {
|
275
|
-
event.preventDefault();
|
276
|
-
nextItem = getNextItemSelectable(document.activeElement, 'up');
|
277
|
-
} else if (key === 'tab' || key === 'esc') {
|
278
|
-
this.setState({
|
279
|
-
open: false
|
280
|
-
});
|
281
|
-
} else if (key === 'space') {
|
282
|
-
// Cancel scroll
|
283
|
-
event.preventDefault();
|
284
|
-
}
|
285
|
-
|
286
|
-
if (nextItem) {
|
287
|
-
nextItem.focus();
|
288
|
-
}
|
289
|
-
};
|
290
|
-
|
291
|
-
this.getItemById = id => {
|
292
|
-
let item;
|
293
|
-
|
294
|
-
if (this.props.hasAll && String(id) === '_all') {
|
295
|
-
return {
|
296
|
-
id: '_all'
|
297
|
-
};
|
298
|
-
}
|
299
|
-
|
300
|
-
for (let i = 0; i < this.props.options.length; i += 1) {
|
301
|
-
const elem = this.props.options[i];
|
302
|
-
|
303
|
-
if (String(elem.id) === String(id)) {
|
304
|
-
item = elem;
|
305
|
-
break;
|
306
|
-
}
|
307
|
-
|
308
|
-
if (elem.children) {
|
309
|
-
for (let j = 0; j < elem.children.length; j += 1) {
|
310
|
-
if (String(elem.children[j].id) === String(id)) {
|
311
|
-
item = elem.children[j];
|
312
|
-
break;
|
313
|
-
}
|
314
|
-
}
|
315
|
-
}
|
316
|
-
}
|
317
|
-
|
318
|
-
return item;
|
319
|
-
};
|
320
|
-
|
321
|
-
this.handleKeyUp = event => {
|
322
|
-
const key = keycode(event);
|
323
|
-
|
324
|
-
if (key === 'esc') {
|
325
|
-
this.setState({
|
326
|
-
open: false
|
327
|
-
});
|
328
|
-
} else if (key === 'space' || key === 'enter' && !this.props.multiple) {
|
329
|
-
event.preventDefault();
|
330
|
-
const item = this.getItemById(event.target.id);
|
331
|
-
|
332
|
-
if (item) {
|
333
|
-
// Select for nested select
|
334
|
-
if (this.props.hiSelectableListProps && this.props.hiSelectableListProps.onSelect) {
|
335
|
-
this.props.hiSelectableListProps.onSelect(null, item);
|
336
|
-
} else {
|
337
|
-
this.handleSelect(null, item);
|
338
|
-
}
|
339
|
-
} else {
|
340
|
-
console.warn(`Can not find item #${event.target.id}`);
|
341
|
-
}
|
342
|
-
} else if (key === 'enter' && this.props.multiple) {
|
343
|
-
event.preventDefault();
|
344
|
-
this.handleClose();
|
345
|
-
}
|
346
|
-
};
|
347
|
-
|
348
|
-
this.handleKeyDownSearch = event => {
|
349
|
-
const key = keycode(event);
|
350
|
-
|
351
|
-
if (this.overlay && (key === 'down' || key === 'up')) {
|
352
|
-
this.focusOnFirstItem();
|
353
|
-
} else if (this.overlay && key === 'esc' || key === 'enter') {
|
354
|
-
event.preventDefault();
|
355
|
-
this.handleClose();
|
356
|
-
} else if (key === 'tab') {
|
357
|
-
this.setState({
|
358
|
-
open: false
|
359
|
-
});
|
360
|
-
}
|
361
|
-
};
|
362
|
-
|
363
|
-
this.handleScroll = e => {
|
364
|
-
if (e.target.scrollHeight - e.target.clientHeight - e.target.scrollTop < 15) {
|
365
|
-
this.props.onScrollReachBottom();
|
366
|
-
}
|
367
|
-
};
|
368
|
-
|
369
|
-
this.handleSelect = (event, item) => {
|
370
|
-
const {
|
371
|
-
hasAll,
|
372
|
-
multiple,
|
373
|
-
onChange,
|
374
|
-
options,
|
375
|
-
value
|
376
|
-
} = this.props;
|
377
|
-
|
378
|
-
if (!multiple) {
|
379
|
-
// single value
|
380
|
-
this.handleClose();
|
381
|
-
onChange(event, item.id, item);
|
382
|
-
} else if (hasAll && item.id === '_all') {
|
383
|
-
if (value.length === options.length) {
|
384
|
-
// unselect _all options
|
385
|
-
onChange(event, [], item);
|
386
|
-
} else {
|
387
|
-
// select _all options
|
388
|
-
onChange(event, options.map(option => option.id), item);
|
389
|
-
}
|
390
|
-
} else if (value.includes(item.id)) {
|
391
|
-
// unselect item
|
392
|
-
onChange(event, value.filter(id => id !== item.id), item);
|
393
|
-
} else {
|
394
|
-
onChange(event, [...value, item.id], item);
|
395
|
-
}
|
396
|
-
};
|
397
|
-
|
398
|
-
this.handleSuggestions = suggestions => {
|
399
|
-
const {
|
400
|
-
hasAll,
|
401
|
-
iconAll,
|
402
|
-
translations
|
403
|
-
} = this.props;
|
404
|
-
|
405
|
-
if (suggestions.length === 0) {
|
406
|
-
// Add '_no_result' suggestion
|
407
|
-
this.setState(prevState => _objectSpread({}, prevState, {
|
408
|
-
suggestions: [{
|
409
|
-
id: '_no_result',
|
410
|
-
type: 'text',
|
411
|
-
disabled: true,
|
412
|
-
centered: true,
|
413
|
-
hideCheckbox: true,
|
414
|
-
label: translations.no_result_match
|
415
|
-
}]
|
416
|
-
}));
|
417
|
-
} else {
|
418
|
-
this.setState({
|
419
|
-
suggestions: [// Add '_all' suggestion
|
420
|
-
...(hasAll ? [_objectSpread({
|
421
|
-
id: '_all',
|
422
|
-
label: translations.all
|
423
|
-
}, iconAll && {
|
424
|
-
type: 'icon',
|
425
|
-
icon: iconAll
|
426
|
-
})] : []), ...suggestions]
|
427
|
-
});
|
428
|
-
}
|
429
|
-
};
|
430
|
-
|
431
|
-
this.handleSearch = (e, inputValue) => {
|
432
|
-
const searchValue = inputValue && e.target.value ? inputValue : e.target.value;
|
433
|
-
|
434
|
-
if (this.props.onSearch) {
|
435
|
-
this.props.onSearch(e, searchValue);
|
436
|
-
} else {
|
437
|
-
this.setState({
|
438
|
-
searchValue
|
439
|
-
});
|
440
|
-
}
|
441
|
-
};
|
442
|
-
|
443
|
-
this.handleSearchReset = () => {
|
444
|
-
this.handleSearch({
|
445
|
-
target: {
|
446
|
-
value: ''
|
447
|
-
}
|
448
|
-
}, '');
|
449
|
-
};
|
450
|
-
|
451
|
-
this.state = {
|
452
|
-
open: false,
|
453
|
-
focused: false,
|
454
|
-
searchValue: props.searchValue ? undefined : '',
|
455
|
-
suggestions: props.options,
|
456
|
-
openDown: true
|
457
|
-
};
|
458
|
-
this.handleBlur = this.handleBlur.bind(this);
|
459
|
-
this.handleClick = this.handleClick.bind(this);
|
460
|
-
this.handleClose = this.handleClose.bind(this);
|
461
|
-
this.handleClickAway = this.handleClickAway.bind(this);
|
462
|
-
this.handleFocus = this.handleFocus.bind(this);
|
463
|
-
this.handleKeyDownInput = this.handleKeyDownInput.bind(this);
|
464
|
-
this.handleSearch = this.handleSearch.bind(this);
|
465
|
-
this.handleSearchReset = this.handleSearchReset.bind(this);
|
466
|
-
this.handleSelect = this.handleSelect.bind(this);
|
467
|
-
this.handleSuggestions = this.handleSuggestions.bind(this);
|
468
|
-
this.getInputElement = this.getInputElement.bind(this);
|
469
|
-
}
|
470
|
-
|
471
|
-
static getDerivedStateFromProps(nextProps, prevState) {
|
472
|
-
if (nextProps.options !== prevState.suggestions) {
|
473
|
-
return _objectSpread({}, prevState, {
|
474
|
-
suggestions: nextProps.options
|
475
|
-
});
|
476
|
-
}
|
477
|
-
|
478
|
-
return null;
|
479
|
-
}
|
480
|
-
/**
|
481
|
-
* Build itemList & inputValue from select props
|
482
|
-
* @param options
|
483
|
-
* @param value
|
484
|
-
* @param search
|
485
|
-
* @param loading
|
486
|
-
* @returns {{itemList: *[], inputValue: *}}
|
487
|
-
*/
|
488
|
-
|
489
|
-
|
490
|
-
render() {
|
491
|
-
const {
|
492
|
-
classes,
|
493
|
-
disabled,
|
494
|
-
error,
|
495
|
-
loading,
|
496
|
-
options,
|
497
|
-
searchable,
|
498
|
-
displayAsChip,
|
499
|
-
type,
|
500
|
-
value,
|
501
|
-
multiple,
|
502
|
-
translations,
|
503
|
-
hiSearchInputProps,
|
504
|
-
hiSelectableListProps,
|
505
|
-
hiSelectInputProps,
|
506
|
-
id,
|
507
|
-
onScrollReachBottom,
|
508
|
-
onSubmit,
|
509
|
-
placeholder,
|
510
|
-
startAdornment,
|
511
|
-
staticPosition,
|
512
|
-
searchValue = this.state.searchValue,
|
513
|
-
buildSelectProps = this.buildSelectProps // use parent builder if defined
|
514
|
-
|
515
|
-
} = this.props;
|
516
|
-
const {
|
517
|
-
open,
|
518
|
-
focused
|
519
|
-
} = this.state;
|
520
|
-
|
521
|
-
if (multiple) {
|
522
|
-
if (!Array.isArray(value)) {
|
523
|
-
throw new Error('HiPay Material-UI: the `value` property must be an array ' + 'when using the `HiSelect` component with `multiple`.');
|
524
|
-
}
|
525
|
-
}
|
526
|
-
|
527
|
-
let selectedItemIdList = [];
|
528
|
-
|
529
|
-
if (value) {
|
530
|
-
selectedItemIdList = multiple ? [...value] : [value];
|
531
|
-
}
|
532
|
-
|
533
|
-
const {
|
534
|
-
itemList,
|
535
|
-
inputValue = this.buildInputValue(options, selectedItemIdList, loading)
|
536
|
-
} = buildSelectProps(options, selectedItemIdList, searchValue, loading);
|
537
|
-
let popperStyle = {};
|
538
|
-
|
539
|
-
if (this.props.containerWidth > 0) {
|
540
|
-
popperStyle = {
|
541
|
-
width: this.props.containerWidth
|
542
|
-
};
|
543
|
-
|
544
|
-
if (!staticPosition) {
|
545
|
-
popperStyle.position = 'absolute';
|
546
|
-
}
|
547
|
-
}
|
548
|
-
|
549
|
-
const popperClass = classNames(classes.popper, {
|
550
|
-
[classes.popperWidth]: !this.props.containerWidth,
|
551
|
-
[classes.popperRightAlign]: this.props.containerWidth && this.props.align === 'right'
|
552
|
-
});
|
553
|
-
|
554
|
-
const searchInput = position => {
|
555
|
-
if (searchable) {
|
556
|
-
return React.createElement(HiInput, _extends({
|
557
|
-
value: searchValue,
|
558
|
-
autoFocus: true,
|
559
|
-
inputRef: this.getInputElement,
|
560
|
-
onKeyDown: this.handleKeyDownSearch,
|
561
|
-
onChange: this.handleSearch,
|
562
|
-
onReset: this.handleSearchReset,
|
563
|
-
placeholder: translations.search,
|
564
|
-
startAdornment: 'search',
|
565
|
-
tabIndex: 0,
|
566
|
-
className: classNames({
|
567
|
-
[classes.separator]: position === 'top'
|
568
|
-
})
|
569
|
-
}, hiSearchInputProps));
|
570
|
-
}
|
571
|
-
|
572
|
-
return null;
|
573
|
-
}; // Replace popper onSearch when popper displayed on top of selectButton
|
574
|
-
|
575
|
-
|
576
|
-
if (this.placement && this.placement.indexOf('top') >= 0 && !!searchable) {
|
577
|
-
// +1 for search input
|
578
|
-
const nbItems = itemList.length <= 10 ? itemList.length + 1 : 11;
|
579
|
-
popperStyle.transform = `translate3d(-1px, -${nbItems * 40 + 2}px, 0px)`;
|
580
|
-
} else if (this.placement && this.placement.indexOf('top') < 0 && !!searchable) {
|
581
|
-
popperStyle.transform = 'translate3d(-1px, 40px, 0px)';
|
582
|
-
}
|
583
|
-
|
584
|
-
const content = ({
|
585
|
-
placement
|
586
|
-
}) => {
|
587
|
-
if (placement !== this.placement) {
|
588
|
-
this.placement = placement;
|
589
|
-
}
|
590
|
-
|
591
|
-
return React.createElement(ClickAwayListener, {
|
592
|
-
onClickAway: this.handleClickAway
|
593
|
-
}, React.createElement(Grow, {
|
594
|
-
in: open,
|
595
|
-
id: "menu-list",
|
596
|
-
style: {
|
597
|
-
transformOrigin: '0 0 0'
|
598
|
-
}
|
599
|
-
}, React.createElement(Paper, {
|
600
|
-
className: classes.paper
|
601
|
-
}, (this.placement && this.placement.indexOf('bottom') >= 0 || staticPosition) && searchInput('bottom'), startAdornment, React.createElement(Scrollbars, _extends({
|
602
|
-
ref: contentEl => {
|
603
|
-
this.optionsContent = contentEl;
|
604
|
-
},
|
605
|
-
autoHeight: true,
|
606
|
-
autoHeightMax: 400 // TODO ?
|
607
|
-
|
608
|
-
}, onScrollReachBottom && {
|
609
|
-
onScroll: this.handleScroll
|
610
|
-
}), React.createElement(HiSelectableList, _extends({
|
611
|
-
type: type,
|
612
|
-
itemList: itemList,
|
613
|
-
onKeyDown: this.handleKeyDown,
|
614
|
-
onKeyUp: this.handleKeyUp,
|
615
|
-
onSelect: this.handleSelect,
|
616
|
-
selectedItemIdList: selectedItemIdList,
|
617
|
-
fallbackImage: this.props.fallbackImage
|
618
|
-
}, hiSelectableListProps))), this.placement && this.placement.indexOf('top') >= 0 && !staticPosition && searchInput('top'))));
|
619
|
-
};
|
620
|
-
|
621
|
-
return React.createElement("div", {
|
622
|
-
className: classes.root,
|
623
|
-
ref: el => {
|
624
|
-
this.overlay = el;
|
625
|
-
}
|
626
|
-
}, React.createElement(HiSelectInput, _extends({
|
627
|
-
id: id,
|
628
|
-
value: inputValue,
|
629
|
-
open: open,
|
630
|
-
focused: focused,
|
631
|
-
type: type,
|
632
|
-
disabled: disabled,
|
633
|
-
noButton: displayAsChip,
|
634
|
-
error: error,
|
635
|
-
onClick: this.handleClick,
|
636
|
-
onFocus: this.handleFocus,
|
637
|
-
onBlur: this.handleBlur,
|
638
|
-
onKeyDown: this.handleKeyDownInput,
|
639
|
-
onSubmit: onSubmit,
|
640
|
-
onMouseEnter: this.props.onMouseEnter,
|
641
|
-
onMouseLeave: this.props.onMouseLeave,
|
642
|
-
onReset: this.props.onReset,
|
643
|
-
placeholder: placeholder
|
644
|
-
}, hiSelectInputProps, {
|
645
|
-
refElement: el => {
|
646
|
-
this.inputEl = el;
|
647
|
-
}
|
648
|
-
})), open && staticPosition ? React.createElement("div", {
|
649
|
-
style: popperStyle,
|
650
|
-
className: popperClass
|
651
|
-
}, content({})) : React.createElement(Popper, {
|
652
|
-
anchorEl: this.inputEl,
|
653
|
-
placement: "bottom-start",
|
654
|
-
open: open,
|
655
|
-
className: popperClass,
|
656
|
-
disablePortal: true,
|
657
|
-
style: popperStyle
|
658
|
-
}, content));
|
659
|
-
}
|
660
|
-
|
661
|
-
}
|
662
|
-
|
663
|
-
HiSelect.defaultProps = {
|
664
|
-
align: 'left',
|
665
|
-
disabled: false,
|
666
|
-
displayAsChip: false,
|
667
|
-
error: false,
|
668
|
-
hasAll: false,
|
669
|
-
hiSelectableListProps: {},
|
670
|
-
hiSelectInputProps: {},
|
671
|
-
hiSearchInputProps: {},
|
672
|
-
multiple: false,
|
673
|
-
placeholder: '',
|
674
|
-
searchable: false,
|
675
|
-
staticPosition: false,
|
676
|
-
translations: {
|
677
|
-
all: 'All',
|
678
|
-
no_result_match: 'No result match',
|
679
|
-
search: 'Search',
|
680
|
-
n_items_selected: '%s items selected',
|
681
|
-
one_item_selected: '%s item selected',
|
682
|
-
n_children: '%s items',
|
683
|
-
one_child: '%s item'
|
684
|
-
},
|
685
|
-
type: 'text',
|
686
|
-
filterFunc: filterValue
|
687
|
-
};
|
688
|
-
HiSelect.propTypes = process.env.NODE_ENV !== "production" ? {
|
689
|
-
align: PropTypes.oneOf(['left', 'right']),
|
690
|
-
|
691
|
-
/**
|
692
|
-
* Useful to extend the style applied to components.
|
693
|
-
*/
|
694
|
-
classes: PropTypes.object,
|
695
|
-
|
696
|
-
/**
|
697
|
-
* Popper width
|
698
|
-
*/
|
699
|
-
containerWidth: PropTypes.number,
|
700
|
-
|
701
|
-
/**
|
702
|
-
* Inactif
|
703
|
-
*/
|
704
|
-
disabled: PropTypes.bool,
|
705
|
-
|
706
|
-
/**
|
707
|
-
* Option permettant d'afficher les sélection sous forme de Chip.
|
708
|
-
*/
|
709
|
-
displayAsChip: PropTypes.bool,
|
710
|
-
|
711
|
-
/**
|
712
|
-
* Applique le style error
|
713
|
-
*/
|
714
|
-
error: PropTypes.bool,
|
715
|
-
|
716
|
-
/**
|
717
|
-
* Chemin vers l'image à afficher par défaut si une image n'est pas trouvée
|
718
|
-
*/
|
719
|
-
fallbackImage: PropTypes.string,
|
720
|
-
|
721
|
-
/*
|
722
|
-
* Fonction de filtrage custom
|
723
|
-
*/
|
724
|
-
filterFunc: PropTypes.func,
|
725
|
-
|
726
|
-
/**
|
727
|
-
* Affiche l'élément 'All'
|
728
|
-
*/
|
729
|
-
hasAll: PropTypes.bool,
|
730
|
-
|
731
|
-
/**
|
732
|
-
* Override HiInput props (for search)
|
733
|
-
*/
|
734
|
-
hiSearchInputProps: PropTypes.object,
|
735
|
-
|
736
|
-
/**
|
737
|
-
* Override HiSelectableList props
|
738
|
-
*/
|
739
|
-
hiSelectableListProps: PropTypes.object,
|
740
|
-
|
741
|
-
/**
|
742
|
-
* Override HiSelectInput props
|
743
|
-
*/
|
744
|
-
hiSelectInputProps: PropTypes.object,
|
745
|
-
|
746
|
-
/**
|
747
|
-
* Nom de l'icône
|
748
|
-
*/
|
749
|
-
iconAll: PropTypes.string,
|
750
|
-
|
751
|
-
/**
|
752
|
-
* id du select
|
753
|
-
*/
|
754
|
-
id: PropTypes.string,
|
755
|
-
|
756
|
-
/**
|
757
|
-
* Ajoute un loader
|
758
|
-
*/
|
759
|
-
loading: PropTypes.bool,
|
760
|
-
|
761
|
-
/**
|
762
|
-
* Autorise la sélection de plusieurs valeurs
|
763
|
-
*/
|
764
|
-
multiple: PropTypes.bool,
|
765
|
-
|
766
|
-
/**
|
767
|
-
* Nom du champ de formulaire
|
768
|
-
*/
|
769
|
-
name: PropTypes.string.isRequired,
|
770
|
-
|
771
|
-
/**
|
772
|
-
* Fonction de callback qui renvoit la/les valeurs sélectionnées
|
773
|
-
*
|
774
|
-
* @param {object} event
|
775
|
-
* @param {string || array} value
|
776
|
-
*/
|
777
|
-
onChange: PropTypes.func.isRequired,
|
778
|
-
|
779
|
-
/**
|
780
|
-
* Fonction de callback appelée lorsqu'on ferme le select
|
781
|
-
*/
|
782
|
-
onClose: PropTypes.func,
|
783
|
-
|
784
|
-
/**
|
785
|
-
* Fonction de callback appelée lorsqu'on survole le champs
|
786
|
-
*/
|
787
|
-
onMouseEnter: PropTypes.func,
|
788
|
-
|
789
|
-
/**
|
790
|
-
* Fonction de callback appelée lorsque le curseur quitte le champs
|
791
|
-
*/
|
792
|
-
onMouseLeave: PropTypes.func,
|
793
|
-
|
794
|
-
/**
|
795
|
-
* Fonction de callback appelée lorsqu'on vide le champs
|
796
|
-
*/
|
797
|
-
onReset: PropTypes.func,
|
798
|
-
|
799
|
-
/**
|
800
|
-
* Fonction de callback appelée lorsque le scroll atteint le bas de la liste
|
801
|
-
*/
|
802
|
-
onScrollReachBottom: PropTypes.func,
|
803
|
-
|
804
|
-
/**
|
805
|
-
* Fonction de callback appelée lorsque le champs de recherche est utilisé
|
806
|
-
*/
|
807
|
-
onSearch: PropTypes.func,
|
808
|
-
|
809
|
-
/**
|
810
|
-
* Listes des options du select
|
811
|
-
*/
|
812
|
-
options: PropTypes.array.isRequired,
|
813
|
-
|
814
|
-
/**
|
815
|
-
* Placeholder affiché lorsque l'input est vide
|
816
|
-
*/
|
817
|
-
placeholder: PropTypes.string,
|
818
|
-
|
819
|
-
/**
|
820
|
-
* Affiche un input de recherche permettant de filtrer les options
|
821
|
-
*/
|
822
|
-
searchable: PropTypes.bool,
|
823
|
-
|
824
|
-
/**
|
825
|
-
* Node qui s'ajoute entre la barre de recherche et la liste de résultats
|
826
|
-
*/
|
827
|
-
startAdornment: PropTypes.object,
|
828
|
-
|
829
|
-
/**
|
830
|
-
* Si true, le contenu du select sera dans une div static plutôt que dans une popper absolute
|
831
|
-
*/
|
832
|
-
staticPosition: PropTypes.bool,
|
833
|
-
|
834
|
-
/**
|
835
|
-
* Traductions (par défaut en anglais)
|
836
|
-
*/
|
837
|
-
translations: PropTypes.object,
|
838
|
-
|
839
|
-
/**
|
840
|
-
* Type des éléments du select, définit le rendu d'un élément
|
841
|
-
*/
|
842
|
-
type: PropTypes.oneOf(['icon', 'text', 'image', 'primary-highlight']),
|
843
|
-
|
844
|
-
/**
|
845
|
-
* Value(s) du select
|
846
|
-
*/
|
847
|
-
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.array])
|
848
|
-
} : {};
|
849
|
-
export default withStyles(styles, {
|
850
|
-
hiComponent: true,
|
851
|
-
name: 'HmuiHiSelect'
|
852
|
-
})(HiSelect);
|