@hipay/hipay-material-ui 1.0.0-beta.19 → 1.0.0-beta.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. package/HiChip/HiChip.js +12 -2
  2. package/HiDatePicker/HiDateRangePicker.js +1 -1
  3. package/HiDatePicker/HiDateRangeSelector.js +5 -4
  4. package/HiDatePicker/stylesheet.js +4 -0
  5. package/HiForm/HiAddressField.js +32 -49
  6. package/HiForm/HiInput.js +11 -6
  7. package/HiForm/HiUpload.js +280 -0
  8. package/HiForm/HiUploadField.js +456 -0
  9. package/HiForm/index.js +18 -0
  10. package/HiMap/HiMap.js +367 -0
  11. package/HiMap/HiMapExpand.js +217 -0
  12. package/HiMap/index.js +25 -0
  13. package/HiSelect/HiSelect.js +1 -1
  14. package/HiTable/BodyCellBuilder.js +1 -1
  15. package/HiTable/BodyCells/CellCountry.js +1 -1
  16. package/HiTable/BodyCells/CellImage.js +6 -6
  17. package/HiTable/BodyCells/CellLayout.js +1 -1
  18. package/HiTable/HeaderCell.js +5 -4
  19. package/HiTable/HiTableFooter.js +2 -1
  20. package/HiTopBar/HiTopBar.js +6 -4
  21. package/es/HiChip/HiChip.js +11 -2
  22. package/es/HiDatePicker/HiDateRangePicker.js +1 -1
  23. package/es/HiDatePicker/HiDateRangeSelector.js +5 -4
  24. package/es/HiDatePicker/stylesheet.js +4 -0
  25. package/es/HiForm/HiAddressField.js +30 -45
  26. package/es/HiForm/HiInput.js +10 -5
  27. package/es/HiForm/HiUpload.js +194 -0
  28. package/es/HiForm/HiUploadField.js +368 -0
  29. package/es/HiForm/index.js +2 -0
  30. package/es/HiMap/HiMap.js +285 -0
  31. package/es/HiMap/HiMapExpand.js +145 -0
  32. package/es/HiMap/index.js +2 -0
  33. package/es/HiSelect/HiSelect.js +1 -1
  34. package/es/HiTable/BodyCellBuilder.js +1 -1
  35. package/es/HiTable/BodyCells/CellCountry.js +1 -1
  36. package/es/HiTable/BodyCells/CellImage.js +6 -6
  37. package/es/HiTable/BodyCells/CellLayout.js +1 -1
  38. package/es/HiTable/HeaderCell.js +5 -3
  39. package/es/HiTable/HiTableFooter.js +2 -1
  40. package/es/HiTopBar/HiTopBar.js +6 -4
  41. package/es/styles/createHiMuiTheme.js +2 -0
  42. package/hmu/images/map_marker.svg +8 -0
  43. package/index.es.js +1 -1
  44. package/index.js +1 -1
  45. package/package.json +44 -42
  46. package/styles/createHiMuiTheme.js +2 -0
  47. package/umd/hipay-material-ui.development.js +58049 -14511
  48. package/umd/hipay-material-ui.production.min.js +5 -5
@@ -226,8 +226,7 @@ var HeaderCell = function (_React$PureComponent) {
226
226
  filterSource = _props.filterSource,
227
227
  view = _props.view,
228
228
  dense = _props.dense,
229
- _props$width = _props.width,
230
- width = _props$width === undefined ? cst.DEFAULT_WIDTHS[type][view] : _props$width,
229
+ width = _props.width,
231
230
  fixedColumnWidth = _props.fixedColumnWidth,
232
231
  _props$align = _props.align,
233
232
  align = _props$align === undefined ? cst.ALIGN_RIGHT_TYPES.includes(type) ? 'right' : 'left' : _props$align,
@@ -243,7 +242,7 @@ var HeaderCell = function (_React$PureComponent) {
243
242
  var offset = selectable ? dense ? 32 : 40 : padding;
244
243
 
245
244
  // Inclue le padding et/ou la checkbox dans la largeur de la cellule
246
- var _width = width + offset + padding;
245
+ var _width = (width || cst.DEFAULT_WIDTHS[type][view]) + offset + padding;
247
246
  // N'affiche pas le tri si il est désactivé.
248
247
  var _sorted = sortable && sorted;
249
248
  // N'active pas le filtre si il n'y a pas de jeu de donnée sur lesquelles filtrées.
@@ -275,6 +274,8 @@ var HeaderCell = function (_React$PureComponent) {
275
274
  cellStyle.maxWidth = _width;
276
275
  cellStyle.minWidth = _width;
277
276
  cellStyle.width = _width;
277
+ } else if (width) {
278
+ cellStyle.width = width;
278
279
  }
279
280
 
280
281
  return _react2.default.createElement(
@@ -446,7 +447,7 @@ HeaderCell.propTypes = process.env.NODE_ENV !== "production" ? {
446
447
  /**
447
448
  * Largeur de la cellule (hors padding), est déduit de view par défaut
448
449
  */
449
- width: _propTypes2.default.number,
450
+ width: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.string]),
450
451
  /**
451
452
  * La largeur de la cellule est fixé (toutes les colonnes sauf une)
452
453
  */
@@ -52,7 +52,8 @@ var styles = exports.styles = function styles(theme) {
52
52
  },
53
53
  tfootCell: {
54
54
  borderTop: '1px solid',
55
- borderTopColor: theme.palette.line.stepper
55
+ borderTopColor: theme.palette.line.stepper,
56
+ padding: 0
56
57
  },
57
58
  patchDiv: {
58
59
  position: 'relative',
@@ -285,7 +285,8 @@ var HiTopBar = function (_React$Component) {
285
285
  _AppBar2.default,
286
286
  {
287
287
  classes: { root: classes.root, colorPrimary: colorPrimaryClass },
288
- position: this.props.position
288
+ position: this.props.position,
289
+ id: 'top-bar'
289
290
  },
290
291
  _react2.default.createElement(
291
292
  _Hidden2.default,
@@ -304,7 +305,7 @@ var HiTopBar = function (_React$Component) {
304
305
  { className: classes.toolbar },
305
306
  _react2.default.createElement(
306
307
  'div',
307
- { ref: refButtons },
308
+ { ref: refButtons, id: 'menu-button-container' },
308
309
  searchFocus ? _react2.default.createElement(
309
310
  _HiButton2.default,
310
311
  {
@@ -335,7 +336,7 @@ var HiTopBar = function (_React$Component) {
335
336
  ),
336
337
  _react2.default.createElement(
337
338
  'div',
338
- { className: classes.flex },
339
+ { id: 'quick-search-input', className: classes.flex },
339
340
  searchInput
340
341
  ),
341
342
  notificationButton,
@@ -347,7 +348,8 @@ var HiTopBar = function (_React$Component) {
347
348
  classes: {
348
349
  label: classes.accountSelectorButtonLabel
349
350
  },
350
- onClick: this.props.onClickAccountSelector
351
+ onClick: this.props.onClickAccountSelector,
352
+ id: 'account-selector-button'
351
353
  },
352
354
  accountSelectorContent
353
355
  ),
@@ -50,9 +50,12 @@ export const styles = theme => ({
50
50
  whiteSpace: 'nowrap',
51
51
  color: theme.palette.neutral.dark,
52
52
  overflow: 'hidden',
53
- width: '100%',
54
53
  textOverflow: 'ellipsis'
55
54
  },
55
+ prefix: {
56
+ color: theme.palette.neutral.dark,
57
+ paddingRight: 4
58
+ },
56
59
  navigate: {
57
60
  // Remove grey highlight
58
61
  WebkitTapHighlightColor: 'transparent',
@@ -75,7 +78,7 @@ export const styles = theme => ({
75
78
  });
76
79
 
77
80
  function HiChip(props) {
78
- const { label, classes, icon, img, onPrevious, onNext, onDelete } = props;
81
+ const { label, classes, icon, img, onPrevious, onNext, onDelete, prefix } = props;
79
82
 
80
83
  return React.createElement(
81
84
  'div',
@@ -86,6 +89,12 @@ function HiChip(props) {
86
89
  [classes.deletable]: onDelete
87
90
  })
88
91
  },
92
+ prefix && React.createElement(
93
+ 'span',
94
+ { className: classes.prefix },
95
+ prefix,
96
+ ' : '
97
+ ),
89
98
  img && React.createElement('img', { className: classes.badge, src: img, alt: img }),
90
99
  icon && React.createElement(HiIconBuilder, { className: classes.icon, icon: icon, size: 16 }),
91
100
  onPrevious && React.createElement(HiIconBuilder, {
@@ -452,7 +452,7 @@ class HiDateRangePicker extends React.Component {
452
452
 
453
453
  return React.createElement(
454
454
  'div',
455
- { className: classes.root },
455
+ { className: classNames(classes.root, classes.rangePickerContainer) },
456
456
  React.createElement(
457
457
  'div',
458
458
  {
@@ -28,9 +28,9 @@ export function buildDateRangeOptionByKey(key, t, format) {
28
28
  break;
29
29
  case 'cd':
30
30
  label = t.today;
31
- from = moment().subtract(1, 'day');
32
- to = moment();
33
- info = `${from.calendar()} ${t.to_now}`;
31
+ from = moment().startOf('day');
32
+ to = moment().endOf('day');
33
+ info = `${from.format(format)}`;
34
34
  break;
35
35
  case 'pd':
36
36
  label = t.yesterday;
@@ -97,7 +97,8 @@ export function buildDateRangeOptionByKey(key, t, format) {
97
97
  export const styles = theme => ({
98
98
  root: {
99
99
  maxWidth: 500,
100
- marginLeft: -4
100
+ marginLeft: -4,
101
+ alignItems: 'flex-start'
101
102
  },
102
103
  dateSelect: {
103
104
  paddingTop: 1,
@@ -26,6 +26,10 @@ export default (theme => ({
26
26
  top: -337,
27
27
  width: 'calc(100% - 4px)'
28
28
  },
29
+ rangePickerContainer: {
30
+ display: 'flex',
31
+ alignItems: 'flex-start'
32
+ },
29
33
  // The container element
30
34
  container: {
31
35
  width: '100%',
@@ -12,31 +12,27 @@ import HiSuggestSelectField from '../HiSelect/HiSuggestSelectField';
12
12
  class HiAddressField extends React.Component {
13
13
  constructor(props) {
14
14
  super(props);
15
- this.autocompleteService = null;
16
15
 
17
- this.displaySuggestions = (predictions, status) => {
18
- if (status !== 'OK') {
19
- // Si l'API renvoie un statut différent de 'OK'
20
- // (par exemple ZERO_RESULTS), pas de prédictions
21
- } else {
22
- // Sinon je mets à jour les options du champ avec les prédictions de GMaps
23
- const options = [];
24
- let isExact = false;
25
- predictions.forEach(prediction => {
26
- // Si le texte saisi est identique à une des propositions de GMaps,
27
- // on estime que la valeur de l'adresse est exacte,
28
- // même sans clic sur une proposition
29
- isExact = prediction.description === this.value ? true : isExact;
30
- options.push({
31
- id: prediction.id,
32
- label: prediction.description,
33
- labelHighlight: prediction.description.replace(new RegExp(this.value, 'gi'), '<strong>$&</strong>'),
34
- icon: prediction.types.indexOf('establishment') >= 0 ? 'domain' : 'map_marker',
35
- type: 'icon'
36
- });
37
- }, this);
38
- this.setState({ options, isExact });
39
- }
16
+ this.displaySuggestions = predictions => {
17
+ // Sinon je mets à jour les options du champ avec les prédictions de GMaps
18
+ const options = [];
19
+ let isExact = false;
20
+ predictions.forEach(prediction => {
21
+ // Si le texte saisi est identique à une des propositions,
22
+ // on estime que la valeur de l'adresse est exacte,
23
+ // même sans clic sur une proposition
24
+ isExact = prediction.display_name === this.value ? true : isExact;
25
+ // liste des types d'adresse : https://github.com/openstreetmap/Nominatim/blob/80df4d3b560f5b1fd550dcf8cdc09a992b69fee0/settings/partitionedtags.def
26
+ options.push({
27
+ id: prediction.place_id,
28
+ label: prediction.display_name,
29
+ labelHighlight: prediction.display_name.replace(new RegExp(this.value, 'gi'), '<strong>$&</strong>'),
30
+ icon: ['amenity', 'building'].includes(prediction.category) ? 'domain' : 'map_marker',
31
+ type: 'icon',
32
+ key: prediction.id
33
+ });
34
+ }, this);
35
+ this.setState({ options, isExact });
40
36
  };
41
37
 
42
38
  this.state = {
@@ -50,13 +46,6 @@ class HiAddressField extends React.Component {
50
46
  this.displaySuggestions = this.displaySuggestions.bind(this);
51
47
  }
52
48
 
53
- /**
54
- * Au chargement du composant, je définis mon service autocomplete GMaps
55
- */
56
- componentDidMount() {
57
- this.autocompleteService = new google.maps.places.AutocompleteService();
58
- }
59
-
60
49
  handleReset() {
61
50
  this.props.onReset();
62
51
  this.setState({
@@ -68,23 +57,19 @@ class HiAddressField extends React.Component {
68
57
  handleSearch(event) {
69
58
  // Je vérifie que le champ n'est pas vide car l'API lève une exception en cas d'input vide
70
59
  if (event.target.value) {
71
- // Liste des types à rechercher. Voir https://developers.google.com/places/web-service/autocomplete?hl=fr#place_types (ex : ['establishement', 'address']
72
- const types = [];
73
- // Liste des codes ISO Alpha-2 des pays où il faut rechercher (ex : ['fr', 'us'])
74
- const countries = [];
75
60
  // À chaque changement, la méthode getPlacesPredictions appelle la méthode
76
61
  // displaySuggestions en lui fournissant un tableau de 5 prédictions
77
62
  this.value = event.target.value;
78
- if (this.autocompleteService) {
79
- this.autocompleteService.getPlacePredictions({
80
- input: event.target.value,
81
- types,
82
- componentRestrictions: { country: countries }
83
- }, this.displaySuggestions);
84
- } else {
85
- // Dans le cas où le service ne peut pas se charger (mode test par exemple).
86
- this.displaySuggestions([], 'EMPTY_RESULT');
87
- }
63
+ const xhr = new XMLHttpRequest();
64
+ xhr.onreadystatechange = () => {
65
+ if (xhr.readyState === XMLHttpRequest.DONE) {
66
+ const response = JSON.parse(xhr.responseText);
67
+ this.displaySuggestions(response, 'OK');
68
+ }
69
+ };
70
+ xhr.open('GET', `https://nominatim.openstreetmap.org/search?q=${event.target.value}&format=jsonv2&limit=5&bounded=1&dedupe=1&namedetails=1`, true);
71
+ xhr.setRequestHeader('Content-type', 'application/json');
72
+ xhr.send();
88
73
  }
89
74
  this.props.onSearch(event);
90
75
  // Mise à jour du texte dans l'input
@@ -65,7 +65,6 @@ export const styles = theme => ({
65
65
  color: theme.palette.neutral.light
66
66
  },
67
67
  rightIcon: {
68
- margin: '0 8px',
69
68
  width: 18,
70
69
  height: 39,
71
70
  color: theme.palette.neutral.normal
@@ -78,7 +77,7 @@ export const styles = theme => ({
78
77
  },
79
78
  rightIconError: {
80
79
  // Ajout d'1px pour ne pas avoir de décalage en mode error avec le border right
81
- marginRight: 10
80
+ marginRight: '-1px'
82
81
  },
83
82
  input: _extends({}, theme.typography.body1, {
84
83
  fontWeight: theme.typography.fontWeightRegular,
@@ -179,7 +178,6 @@ class HiInput extends React.PureComponent {
179
178
  if (this.props.onFocus) {
180
179
  this.props.onFocus(event);
181
180
  }
182
- this.inputElement.focus();
183
181
  }
184
182
  }
185
183
 
@@ -256,6 +254,8 @@ class HiInput extends React.PureComponent {
256
254
  if (startAdornment) {
257
255
  leftIcon = React.createElement(HiIconBuilder, {
258
256
  icon: startAdornment,
257
+ size: 36,
258
+ style: { padding: '8px' },
259
259
  onClick: this.props.onLeftIconClick,
260
260
  className: classNames(classes.startAdornment, {
261
261
  [classes.startAdornmentFocus]: focused,
@@ -272,13 +272,15 @@ class HiInput extends React.PureComponent {
272
272
  onClick: this.handleReset,
273
273
  onBlur: this.handleBlur
274
274
  },
275
- React.createElement(HiIconBuilder, { icon: 'close', size: 18, color: theme.palette.neutral.normal })
275
+ React.createElement(HiIconBuilder, { icon: 'close', size: 36, color: theme.palette.neutral.normal, style: { padding: '8px' } })
276
276
  );
277
277
 
278
278
  let endAdornment = endAdornmentProps;
279
279
  if (typeof endAdornmentProps === 'string' && endAdornmentProps !== '') {
280
280
  endAdornment = React.createElement(HiIconBuilder, {
281
281
  icon: endAdornmentProps,
282
+ size: 36,
283
+ style: { padding: '8px' },
282
284
  onClick: this.props.onRightIconClick,
283
285
  className: classNames(classes.rightIcon, {
284
286
  [classes.rightIconFocus]: focused,
@@ -314,7 +316,10 @@ class HiInput extends React.PureComponent {
314
316
  startAdornment: leftIcon,
315
317
  endAdornment: React.createElement(
316
318
  'div',
317
- { className: classes.endAdornment, ref: el => this.endAdornmentNode = el },
319
+ {
320
+ className: classes.endAdornment,
321
+ ref: el => this.endAdornmentNode = el
322
+ },
318
323
  eraseIcon,
319
324
  endAdornment
320
325
  ),
@@ -0,0 +1,194 @@
1
+ import _extends from 'babel-runtime/helpers/extends';
2
+ import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
3
+ // @inheritedComponent HiUploadField
4
+
5
+ import React from 'react';
6
+ import PropTypes from 'prop-types';
7
+ import classNames from 'classnames';
8
+ import withStyles from '../styles/withStyles';
9
+ import withTheme from '../styles/withTheme';
10
+ import HiFormControl from './HiFormControl';
11
+ import HiUploadField from './HiUploadField';
12
+ import HiIconBuilder from '../utils/HiIconBuilder';
13
+
14
+ export const styles = theme => ({
15
+ flexContainer: {
16
+ display: ' flex',
17
+ alignItems: 'center'
18
+ },
19
+ statusIcon: {
20
+ color: theme.palette.text.icon,
21
+ marginRight: '8px',
22
+ padding: '24px',
23
+ borderRadius: '2px',
24
+ border: `1px solid ${theme.palette.input.bottomLine}`,
25
+ backgroundColor: theme.palette.local.background2,
26
+ '&:not($empty)': {
27
+ border: `1px solid ${theme.palette.middle.normal}`,
28
+ color: `${theme.palette.middle.normal}`
29
+ },
30
+ '&$complete': {
31
+ border: `1px solid ${theme.palette.positive.normal}`,
32
+ color: `${theme.palette.positive.normal}`
33
+ },
34
+ '&$error': {
35
+ border: `1px solid ${theme.palette.negative.normal}`,
36
+ color: `${theme.palette.negative.normal}`
37
+ }
38
+ },
39
+ inputContainer: {
40
+ flex: '1'
41
+ },
42
+ empty: {},
43
+ complete: {},
44
+ error: {}
45
+ });
46
+
47
+ class HiUpload extends React.PureComponent {
48
+
49
+ constructor(props) {
50
+ super(props);
51
+ this.state = {
52
+ params: new Array(this.props.inputs.length)
53
+ };
54
+
55
+ this.handleChange = this.handleChange.bind(this);
56
+ this.handleClear = this.handleClear.bind(this);
57
+ this.handleSeeFile = this.handleSeeFile.bind(this);
58
+ }
59
+
60
+ handleChange(param, index) {
61
+ this.setState(prevState => {
62
+ const oldParams = [...prevState.params];
63
+ oldParams.splice(index, 1, param);
64
+ return {
65
+ params: oldParams
66
+ };
67
+ });
68
+ }
69
+
70
+ handleClear(index) {
71
+ this.setState(prevState => {
72
+ const oldParams = [...prevState.params];
73
+ oldParams.splice(index, 1, undefined);
74
+ return {
75
+ params: oldParams
76
+ };
77
+ });
78
+ }
79
+
80
+ handleSeeFile(file) {
81
+ this.props.onSeeFile(file);
82
+ }
83
+
84
+ render() {
85
+ const _props = this.props,
86
+ { inputs, className, classes, label, helperIcon, helperText } = _props,
87
+ others = _objectWithoutProperties(_props, ['inputs', 'className', 'classes', 'label', 'helperIcon', 'helperText']);
88
+
89
+ const { params } = this.state;
90
+
91
+ let complete = true;
92
+ let empty = true;
93
+ let error = false;
94
+ let errorText = '';
95
+
96
+ for (let i = 0, len = params.length; i < len; i += 1) {
97
+ const param = params[i];
98
+ if (param !== undefined) {
99
+ complete = param.value === null || param.error ? false : complete;
100
+ empty = param.value !== null && !param.error ? false : empty;
101
+ error = param.error || error;
102
+ errorText = errorText || param.errorMessage;
103
+ } else {
104
+ complete = false;
105
+ }
106
+ }
107
+
108
+ const statusClass = classNames(classes.statusIcon, {
109
+ [classes.empty]: empty,
110
+ [classes.complete]: complete,
111
+ [classes.error]: error
112
+ });
113
+
114
+ let icon;
115
+
116
+ if (error) {
117
+ icon = 'alert';
118
+ } else if (complete) {
119
+ icon = 'check_circle';
120
+ } else {
121
+ icon = 'upload';
122
+ }
123
+
124
+ return React.createElement(
125
+ HiFormControl,
126
+ {
127
+ label: label,
128
+ className: className,
129
+ errorText: errorText,
130
+ error: error,
131
+ helperIcon: helperIcon,
132
+ helperText: helperText
133
+ },
134
+ React.createElement(
135
+ 'div',
136
+ { className: classes.flexContainer },
137
+ React.createElement(HiIconBuilder, { className: statusClass, size: 80, icon: icon }),
138
+ React.createElement(
139
+ 'div',
140
+ { className: classes.inputContainer },
141
+ inputs.map((item, index) => React.createElement(HiUploadField, _extends({
142
+ maxSize: item.maxSize,
143
+ acceptedTypes: item.acceptedTypes,
144
+ placeholder: item.placeholder,
145
+ value: params[index] ? params[index].value : null,
146
+ error: params[index] ? params[index].error : null,
147
+ errorMessage: params[index] ? params[index].errorMessage : null,
148
+ onSeeFile: this.handleSeeFile,
149
+ onClear: this.handleClear,
150
+ onChange: this.handleChange,
151
+ index: index,
152
+ key: item.id
153
+ }, others)))
154
+ )
155
+ )
156
+ );
157
+ }
158
+ }
159
+
160
+ HiUpload.defaultProps = {
161
+ helperText: '',
162
+ helperIcon: false
163
+ };
164
+ HiUpload.propTypes = process.env.NODE_ENV !== "production" ? {
165
+ /**
166
+ * Useful to extend the style applied to components.
167
+ */
168
+ classes: PropTypes.object,
169
+ /**
170
+ * Classes CSS appliquées.
171
+ */
172
+ className: PropTypes.string,
173
+ /**
174
+ * Si "true", le texte d'aide s'affichera seulement au clic sur l'icône "Information"
175
+ */
176
+ helperIcon: PropTypes.bool,
177
+ /**
178
+ * Texte de l'aide
179
+ */
180
+ helperText: PropTypes.string,
181
+ /**
182
+ * Array containing each of the inputs the component has to show (represented by an object).
183
+ */
184
+ inputs: PropTypes.array.isRequired,
185
+ /**
186
+ * The label of the global input.
187
+ */
188
+ label: PropTypes.string,
189
+ /**
190
+ * The method given to see the file.
191
+ */
192
+ onSeeFile: PropTypes.func
193
+ } : {};
194
+ export default withStyles(styles, { name: 'HmuiHiUpload', withTheme: true })(HiUpload);