@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.
@@ -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