@hipay/hipay-material-ui 2.0.0-beta.50 → 2.0.0-beta.51

Sign up to get free protection for your applications and to get access to all the features.
@@ -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);
@@ -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';
@@ -106,8 +106,7 @@ export const styles = theme => ({
106
106
  textOverflow: 'ellipsis',
107
107
  textAlign: 'right',
108
108
  margin: '4px 12px 4px 8px',
109
- alignSelf: 'center',
110
- width: '100%'
109
+ alignSelf: 'center'
111
110
  }),
112
111
  checkbox: {
113
112
  marginTop: 3
package/index.es.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license HiPay-Material-UI v2.0.0-beta.50
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.
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license HiPay-Material-UI v2.0.0-beta.50
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.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@hipay/hipay-material-ui",
3
3
  "private": false,
4
4
  "author": "HiPay PSYCHE Team",
5
- "version": "2.0.0-beta.50",
5
+ "version": "2.0.0-beta.51",
6
6
  "description": "React components that implement Google's Material Design.",
7
7
  "keywords": [
8
8
  "react",
@@ -1,4 +1,4 @@
1
- /** @license HiPay-Material-UI v2.0.0-beta.50
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
- if (authorizedChar.indexOf(event.target.value.charAt(event.target.value.length - 1)) >= 0 && this.props.onlyNumbers === true || this.props.onlyNumbers !== true) {
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