@plone/volto 18.0.0-alpha.32 → 18.0.0-alpha.34

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.
Files changed (101) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/locales/ca/LC_MESSAGES/volto.po +17 -0
  3. package/locales/ca.json +1 -1
  4. package/locales/de/LC_MESSAGES/volto.po +17 -0
  5. package/locales/de.json +1 -1
  6. package/locales/en/LC_MESSAGES/volto.po +17 -0
  7. package/locales/en.json +1 -1
  8. package/locales/es/LC_MESSAGES/volto.po +17 -0
  9. package/locales/es.json +1 -1
  10. package/locales/eu/LC_MESSAGES/volto.po +17 -0
  11. package/locales/eu.json +1 -1
  12. package/locales/fi/LC_MESSAGES/volto.po +17 -0
  13. package/locales/fi.json +1 -1
  14. package/locales/fr/LC_MESSAGES/volto.po +17 -0
  15. package/locales/fr.json +1 -1
  16. package/locales/hi/LC_MESSAGES/volto.po +17 -0
  17. package/locales/hi.json +1 -1
  18. package/locales/it/LC_MESSAGES/volto.po +17 -0
  19. package/locales/it.json +1 -1
  20. package/locales/ja/LC_MESSAGES/volto.po +17 -0
  21. package/locales/ja.json +1 -1
  22. package/locales/nl/LC_MESSAGES/volto.po +17 -0
  23. package/locales/nl.json +1 -1
  24. package/locales/pt/LC_MESSAGES/volto.po +17 -0
  25. package/locales/pt.json +1 -1
  26. package/locales/pt_BR/LC_MESSAGES/volto.po +17 -0
  27. package/locales/pt_BR.json +1 -1
  28. package/locales/ro/LC_MESSAGES/volto.po +17 -0
  29. package/locales/ro.json +1 -1
  30. package/locales/volto.pot +18 -1
  31. package/locales/zh_CN/LC_MESSAGES/volto.po +17 -0
  32. package/locales/zh_CN.json +1 -1
  33. package/package.json +10 -5
  34. package/razzle.config.js +58 -0
  35. package/src/actions/form/form.js +18 -2
  36. package/src/actions/index.js +1 -1
  37. package/src/components/manage/BlockChooser/BlockChooserSearch.jsx +1 -0
  38. package/src/components/manage/Blocks/Block/BlocksForm.jsx +157 -81
  39. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +8 -0
  40. package/src/components/manage/Blocks/Block/Edit.jsx +37 -4
  41. package/src/components/manage/Blocks/Block/Order/Item.jsx +122 -0
  42. package/src/components/manage/Blocks/Block/Order/Order.jsx +367 -0
  43. package/src/components/manage/Blocks/Block/Order/SortableItem.jsx +58 -0
  44. package/src/components/manage/Blocks/Block/Order/utilities.js +113 -0
  45. package/src/components/manage/Blocks/Container/Edit.jsx +1 -0
  46. package/src/components/manage/Blocks/Grid/Edit.jsx +6 -4
  47. package/src/components/manage/Blocks/Image/schema.js +2 -0
  48. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +1 -1
  49. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +1 -1
  50. package/src/components/manage/Form/Form.jsx +159 -151
  51. package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +158 -65
  52. package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +125 -71
  53. package/src/components/manage/Sidebar/Sidebar.jsx +28 -1
  54. package/src/components/manage/Widgets/IdWidget.jsx +138 -203
  55. package/src/components/manage/Widgets/InternalUrlWidget.jsx +10 -14
  56. package/src/components/manage/Widgets/TextWidget.jsx +92 -124
  57. package/src/components/manage/Widgets/TextWidget.stories.jsx +14 -3
  58. package/src/components/theme/App/App.jsx +5 -0
  59. package/src/components/theme/Footer/Footer.jsx +1 -0
  60. package/src/components/theme/FormattedDate/FormattedDate.jsx +13 -1
  61. package/src/components/theme/Icon/Icon.jsx +4 -4
  62. package/src/components/theme/Navigation/Navigation.jsx +1 -1
  63. package/src/components/theme/SlotRenderer/SlotRenderer.tsx +3 -4
  64. package/src/components/theme/View/View.jsx +1 -1
  65. package/src/config/Loadables.jsx +18 -0
  66. package/src/config/server.js +0 -1
  67. package/src/constants/ActionTypes.js +1 -0
  68. package/src/express-middleware/static.js +37 -19
  69. package/src/helpers/Blocks/Blocks.js +182 -1
  70. package/src/helpers/Blocks/Blocks.test.js +136 -0
  71. package/src/helpers/Html/Html.jsx +6 -8
  72. package/src/helpers/Slots/index.tsx +12 -5
  73. package/src/helpers/index.js +4 -0
  74. package/src/reducers/form/form.js +18 -1
  75. package/src/reducers/form/form.test.js +15 -1
  76. package/src/server.jsx +34 -36
  77. package/theme/themes/pastanaga/extras/blocks.less +7 -6
  78. package/theme/themes/pastanaga/extras/objectbrowser-widget.less +83 -0
  79. package/theme/themes/pastanaga/extras/sidebar.less +145 -0
  80. package/theme/themes/pastanaga/extras/widgets.less +19 -0
  81. package/types/actions/form/form.d.ts +8 -1
  82. package/types/actions/index.d.ts +1 -1
  83. package/types/components/manage/Blocks/Block/Order/Item.d.ts +2 -0
  84. package/types/components/manage/Blocks/Block/Order/Order.d.ts +13 -0
  85. package/types/components/manage/Blocks/Block/Order/SortableItem.d.ts +9 -0
  86. package/types/components/manage/Blocks/Block/Order/utilities.d.ts +9 -0
  87. package/types/components/manage/Blocks/Image/schema.d.ts +2 -0
  88. package/types/components/manage/Sidebar/ObjectBrowserNav.d.ts +2 -1
  89. package/types/components/manage/Widgets/IdWidget.d.ts +54 -2
  90. package/types/components/manage/Widgets/TextWidget.d.ts +54 -5
  91. package/types/components/manage/Widgets/TextWidget.stories.d.ts +13 -1
  92. package/types/components/manage/Widgets/index.d.ts +2 -2
  93. package/types/components/theme/Icon/Icon.d.ts +8 -8
  94. package/types/config/Loadables.d.ts +15 -162
  95. package/types/config/Widgets.d.ts +1 -1
  96. package/types/config/server.d.ts +0 -3
  97. package/types/constants/ActionTypes.d.ts +1 -0
  98. package/types/helpers/Blocks/Blocks.d.ts +13 -0
  99. package/types/helpers/Slots/index.d.ts +5 -3
  100. package/types/helpers/index.d.ts +2 -2
  101. package/types/start-client.d.ts +1 -1
@@ -3,14 +3,13 @@
3
3
  * @module components/manage/Widgets/IdWidget
4
4
  */
5
5
 
6
- import React, { Component } from 'react';
6
+ import { useState, useEffect, useRef } from 'react';
7
7
  import PropTypes from 'prop-types';
8
- import { connect } from 'react-redux';
9
- import { compose } from 'redux';
8
+ import { useSelector, useDispatch } from 'react-redux';
10
9
  import { Input } from 'semantic-ui-react';
11
10
  import { compact, concat, keys, map, union, uniq } from 'lodash';
12
11
 
13
- import { defineMessages, injectIntl } from 'react-intl';
12
+ import { defineMessages, useIntl } from 'react-intl';
14
13
  import { Icon } from '@plone/volto/components';
15
14
  import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
16
15
  import config from '@plone/volto/registry';
@@ -28,222 +27,158 @@ const messages = defineMessages({
28
27
  },
29
28
  });
30
29
 
31
- /**
32
- * The id widget.
33
- *
34
- * This is the id widget to handle for example the short name field.
35
- */
36
- class IdWidget extends Component {
37
- /**
38
- * Property types.
39
- * @property {Object} propTypes Property types.
40
- * @static
41
- */
42
- static propTypes = {
43
- id: PropTypes.string.isRequired,
44
- title: PropTypes.string.isRequired,
45
- description: PropTypes.string,
46
- required: PropTypes.bool,
47
- error: PropTypes.arrayOf(PropTypes.string),
48
- value: PropTypes.string,
49
- focus: PropTypes.bool,
50
- onChange: PropTypes.func,
51
- onBlur: PropTypes.func,
52
- onClick: PropTypes.func,
53
- onEdit: PropTypes.func,
54
- onDelete: PropTypes.func,
55
- icon: PropTypes.shape({
56
- xmlns: PropTypes.string,
57
- viewBox: PropTypes.string,
58
- content: PropTypes.string,
59
- }),
60
- iconAction: PropTypes.func,
61
- minLength: PropTypes.number,
62
- maxLength: PropTypes.number,
63
- wrapped: PropTypes.bool,
64
- placeholder: PropTypes.string,
65
- };
66
-
67
- /**
68
- * Default properties.
69
- * @property {Object} defaultProps Default properties.
70
- * @static
71
- */
72
- static defaultProps = {
73
- description: null,
74
- required: false,
75
- error: [],
76
- value: null,
77
- onChange: () => {},
78
- onBlur: () => {},
79
- onClick: () => {},
80
- onEdit: null,
81
- onDelete: null,
82
- focus: false,
83
- icon: null,
84
- iconAction: null,
85
- minLength: null,
86
- maxLength: null,
87
- };
88
-
89
- /**
90
- * Constructor
91
- * @method constructor
92
- * @param {Object} props Component properties
93
- * @constructs Actions
94
- */
95
- constructor(props) {
96
- super(props);
97
- this.state = {
98
- error: [],
99
- reservedIds: compact(
100
- uniq(
101
- union(
102
- config.settings.reservedIds,
103
- map(config.settings.nonContentRoutes, (route) =>
104
- String(route).replace(/[^a-z-]/g, ''),
105
- ),
30
+ const IdWidget = (props) => {
31
+ const {
32
+ id,
33
+ onClick,
34
+ icon,
35
+ iconAction,
36
+ minLength,
37
+ maxLength,
38
+ onBlur,
39
+ value,
40
+ focus,
41
+ isDisabled,
42
+ placeholder,
43
+ onChange,
44
+ } = props;
45
+
46
+ const intl = useIntl();
47
+ const dispatch = useDispatch();
48
+ const ref = useRef();
49
+
50
+ const indexes = useSelector((state) => keys(state.querystring.indexes));
51
+
52
+ const [errors, setError] = useState([]);
53
+ const [reservedIds] = useState(
54
+ compact(
55
+ uniq(
56
+ union(
57
+ config.settings.reservedIds,
58
+ map(config.settings.nonContentRoutes, (route) =>
59
+ String(route).replace(/[^a-z-]/g, ''),
106
60
  ),
107
61
  ),
108
62
  ),
109
- };
110
-
111
- this.handleChange = this.handleChange.bind(this);
112
- this.handleBlur = this.handleBlur.bind(this);
113
- this.fieldValidation = this.fieldValidation.bind(this);
114
- }
115
-
116
- /**
117
- * Component did mount lifecycle method
118
- * @method componentDidMount
119
- * @returns {undefined}
120
- */
121
- componentDidMount() {
122
- if (this.props.focus) {
123
- this.node.focus();
124
- }
125
- this.props.getQuerystring();
126
- this.fieldValidation(this.props.value);
127
- }
128
-
129
- /**
130
- * Field validation.
131
- * @method fieldValidation
132
- * @param {string} value New value
133
- * @returns {undefined}
134
- */
135
- fieldValidation(value) {
63
+ ),
64
+ );
65
+ const fieldValidation = (values) => {
136
66
  const error = [];
137
67
 
138
68
  // Check reserved id's
139
- if (this.state.reservedIds.indexOf(value) !== -1) {
140
- error.push(this.props.intl.formatMessage(messages.reservedId));
69
+ if (reservedIds.indexOf(values) !== -1) {
70
+ error.push(intl.formatMessage(messages.reservedId));
141
71
  }
142
72
 
143
73
  // Check invalid characters
144
74
  if (
145
75
  // eslint-disable-next-line no-control-regex
146
76
  !/^(?!.*\\)(?!\+\+)(?!@@)(?!.*request)(?!.*contributors)(?!aq_)(?!.*__)(?!_)(?!((^|\/)\.\.?($|\/)|^"\s*"$))(?!.*[A-Z])(?:(?![\r\n<>/?&#\x00-\x1F\x7F])['\x00-\x7F\u0080-\uFFFF. _])*$/.test(
147
- value,
77
+ values,
148
78
  )
149
79
  ) {
150
- error.push(this.props.intl.formatMessage(messages.invalidCharacters));
80
+ error.push(intl.formatMessage(messages.invalidCharacters));
151
81
  }
152
82
 
153
83
  // Check indexes
154
- if (this.props.indexes.indexOf(value) !== -1) {
155
- error.push(this.props.intl.formatMessage(messages.reservedId));
84
+ if (indexes.indexOf(values) !== -1) {
85
+ error.push(intl.formatMessage(messages.reservedId));
156
86
  }
157
87
 
158
- this.setState({ error });
159
- }
160
-
161
- /**
162
- * Handle the field change.
163
- * @method handleChange
164
- * @param {Object} event Event object
165
- * @returns {undefined}
166
- */
167
- handleChange({ target }) {
168
- this.fieldValidation(target.value);
169
- this.props.onChange(
170
- this.props.id,
171
- target.value === '' ? undefined : target.value,
172
- );
173
- }
174
-
175
- /**
176
- * Handle the field blur.
177
- * @method handleBlur
178
- * @param {Object} event Event object
179
- * @returns {undefined}
180
- */
181
- handleBlur({ target }) {
182
- this.fieldValidation(target.value);
183
- this.props.onBlur(
184
- this.props.id,
185
- target.value === '' ? undefined : target.value,
186
- );
187
- }
188
-
189
- /**
190
- * Render method.
191
- * @method render
192
- * @returns {string} Markup for the component.
193
- */
194
- render() {
195
- const {
196
- id,
197
- value,
198
- onClick,
199
- icon,
200
- iconAction,
201
- minLength,
202
- maxLength,
203
- placeholder,
204
- } = this.props;
205
-
206
- const props = {
207
- ...this.props,
208
- error: concat(this.props.error, this.state.error),
209
- };
210
-
211
- return (
212
- <FormFieldWrapper {...props} className="text">
213
- <Input
214
- id={`field-${id}`}
215
- name={id}
216
- value={value || ''}
217
- disabled={this.props.isDisabled}
218
- icon={icon || null}
219
- placeholder={placeholder}
220
- onChange={this.handleChange}
221
- onBlur={this.handleBlur}
222
- onClick={() => onClick()}
223
- ref={(node) => {
224
- this.node = node;
225
- }}
226
- minLength={minLength || null}
227
- maxLength={maxLength || null}
228
- />
229
- {icon && iconAction && (
230
- <button className={`field-${id}-action-button`} onClick={iconAction}>
231
- <Icon name={icon} size="18px" />
232
- </button>
233
- )}
234
- </FormFieldWrapper>
235
- );
236
- }
237
- }
238
-
239
- export default compose(
240
- injectIntl,
241
- connect(
242
- (state, props) => ({
243
- indexes: keys(state.querystring.indexes),
244
- }),
245
- {
246
- getQuerystring,
88
+ setError(error);
89
+ };
90
+
91
+ useEffect(
92
+ () => {
93
+ if (focus) ref.current.focus();
94
+
95
+ dispatch(getQuerystring());
96
+ fieldValidation(value);
247
97
  },
248
- ),
249
- )(IdWidget);
98
+ // eslint-disable-next-line react-hooks/exhaustive-deps
99
+ [focus, value, dispatch],
100
+ );
101
+
102
+ const handleChange = ({ target }) => {
103
+ fieldValidation(target.value);
104
+ onChange(id, target.value === '' ? undefined : target.value);
105
+ };
106
+
107
+ const handleBlur = ({ target }) => {
108
+ fieldValidation(target.value);
109
+ onBlur(id, target.value === '' ? undefined : target.value);
110
+ };
111
+
112
+ props = {
113
+ ...props,
114
+ error: concat(props.error, errors),
115
+ };
116
+
117
+ return (
118
+ <FormFieldWrapper {...props} className="text">
119
+ <Input
120
+ id={`field-${id}`}
121
+ name={id}
122
+ value={value || ''}
123
+ disabled={isDisabled}
124
+ icon={icon || null}
125
+ placeholder={placeholder}
126
+ onChange={handleChange}
127
+ onBlur={handleBlur}
128
+ onClick={() => onClick()}
129
+ ref={ref}
130
+ minLength={minLength || null}
131
+ maxLength={maxLength || null}
132
+ />
133
+ {icon && iconAction && (
134
+ <button className={`field-${id}-action-button`} onClick={iconAction}>
135
+ <Icon name={icon} size="18px" />
136
+ </button>
137
+ )}
138
+ </FormFieldWrapper>
139
+ );
140
+ };
141
+
142
+ export default IdWidget;
143
+
144
+ IdWidget.propTypes = {
145
+ id: PropTypes.string.isRequired,
146
+ title: PropTypes.string.isRequired,
147
+ description: PropTypes.string,
148
+ required: PropTypes.bool,
149
+ error: PropTypes.arrayOf(PropTypes.string),
150
+ value: PropTypes.string,
151
+ focus: PropTypes.bool,
152
+ onChange: PropTypes.func,
153
+ onBlur: PropTypes.func,
154
+ onClick: PropTypes.func,
155
+ onEdit: PropTypes.func,
156
+ onDelete: PropTypes.func,
157
+ icon: PropTypes.shape({
158
+ xmlns: PropTypes.string,
159
+ viewBox: PropTypes.string,
160
+ content: PropTypes.string,
161
+ }),
162
+ iconAction: PropTypes.func,
163
+ minLength: PropTypes.number,
164
+ maxLength: PropTypes.number,
165
+ wrapped: PropTypes.bool,
166
+ placeholder: PropTypes.string,
167
+ };
168
+
169
+ IdWidget.defaultProps = {
170
+ description: null,
171
+ required: false,
172
+ error: [],
173
+ value: null,
174
+ onChange: () => {},
175
+ onBlur: () => {},
176
+ onClick: () => {},
177
+ onEdit: null,
178
+ onDelete: null,
179
+ focus: false,
180
+ icon: null,
181
+ iconAction: null,
182
+ minLength: null,
183
+ maxLength: null,
184
+ };
@@ -15,13 +15,13 @@ import navTreeSVG from '@plone/volto/icons/nav.svg';
15
15
 
16
16
  /** Widget to edit urls
17
17
  *
18
- * This is the default widget used for the `remoteUrl` field. You can also use
18
+ * This is a widget used for getting and setting an internal url. You can also use
19
19
  * it by declaring a field like:
20
20
  *
21
21
  * ```jsx
22
22
  * {
23
23
  * title: "URL",
24
- * widget: 'url',
24
+ * widget: 'internal_url',
25
25
  * }
26
26
  * ```
27
27
  */
@@ -35,20 +35,20 @@ export const InternalUrlWidget = (props) => {
35
35
  maxLength,
36
36
  placeholder,
37
37
  isDisabled,
38
+ value,
38
39
  } = props;
39
40
  const inputId = `field-${id}`;
40
41
 
41
- const [value, setValue] = useState(flattenToAppURL(props.value));
42
42
  const [isInvalid, setIsInvalid] = useState(false);
43
+
43
44
  /**
44
45
  * Clear handler
45
46
  * @method clear
46
47
  * @param {Object} value Value
47
- * @returns {undefined}
48
+ * @returns {string} Empty string
48
49
  */
49
50
  const clear = () => {
50
- setValue('');
51
- onChange(id, undefined);
51
+ onChange(id, '');
52
52
  };
53
53
 
54
54
  const onChangeValue = (_value) => {
@@ -63,8 +63,6 @@ export const InternalUrlWidget = (props) => {
63
63
  }
64
64
  }
65
65
 
66
- setValue(newValue);
67
-
68
66
  newValue = isInternalURL(newValue) ? flattenToAppURL(newValue) : newValue;
69
67
 
70
68
  if (!isInternalURL(newValue) && newValue.length > 0) {
@@ -75,7 +73,7 @@ export const InternalUrlWidget = (props) => {
75
73
  }
76
74
  }
77
75
 
78
- onChange(id, newValue === '' ? undefined : newValue);
76
+ onChange(id, newValue);
79
77
  };
80
78
 
81
79
  return (
@@ -89,12 +87,10 @@ export const InternalUrlWidget = (props) => {
89
87
  disabled={isDisabled}
90
88
  placeholder={placeholder}
91
89
  onChange={({ target }) => onChangeValue(target.value)}
92
- onBlur={({ target }) =>
93
- onBlur(id, target.value === '' ? undefined : target.value)
94
- }
90
+ onBlur={({ target }) => onBlur(id, target.value)}
95
91
  onClick={() => onClick()}
96
- minLength={minLength || null}
97
- maxLength={maxLength || null}
92
+ minLength={minLength}
93
+ maxLength={maxLength}
98
94
  error={isInvalid}
99
95
  />
100
96
  {value?.length > 0 ? (
@@ -1,136 +1,104 @@
1
- /**
2
- * TextWidget component.
3
- * @module components/manage/Widgets/TextWidget
4
- */
5
-
6
- import React, { Component } from 'react';
1
+ import { useEffect, useRef } from 'react';
7
2
  import PropTypes from 'prop-types';
8
3
  import { Input } from 'semantic-ui-react';
9
4
 
10
- import { injectIntl } from 'react-intl';
11
5
  import { Icon } from '@plone/volto/components';
12
6
  import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
13
7
 
14
- /**
15
- * The simple text widget.
16
- *
17
- * It is the default fallback widget, so if no other widget is found based on
18
- * passed field properties, it will be used.
19
- */
20
- class TextWidget extends Component {
21
- /**
22
- * Property types.
23
- * @property {Object} propTypes Property types.
24
- * @static
25
- */
26
- static propTypes = {
27
- id: PropTypes.string.isRequired,
28
- title: PropTypes.string.isRequired,
29
- description: PropTypes.string,
30
- required: PropTypes.bool,
31
- error: PropTypes.arrayOf(PropTypes.string),
32
- value: PropTypes.string,
33
- focus: PropTypes.bool,
34
- onChange: PropTypes.func,
35
- onBlur: PropTypes.func,
36
- onClick: PropTypes.func,
37
- onEdit: PropTypes.func,
38
- onDelete: PropTypes.func,
39
- icon: PropTypes.shape({
40
- xmlns: PropTypes.string,
41
- viewBox: PropTypes.string,
42
- content: PropTypes.string,
43
- }),
44
- iconAction: PropTypes.func,
45
- minLength: PropTypes.number,
46
- maxLength: PropTypes.number,
47
- wrapped: PropTypes.bool,
48
- placeholder: PropTypes.string,
49
- };
8
+ const TextWidget = (props) => {
9
+ const {
10
+ id,
11
+ value,
12
+ onChange,
13
+ onBlur,
14
+ onClick,
15
+ icon,
16
+ iconAction,
17
+ minLength,
18
+ maxLength,
19
+ placeholder,
20
+ isDisabled,
21
+ focus,
22
+ } = props;
50
23
 
51
- /**
52
- * Default properties.
53
- * @property {Object} defaultProps Default properties.
54
- * @static
55
- */
56
- static defaultProps = {
57
- description: null,
58
- required: false,
59
- error: [],
60
- value: null,
61
- onChange: () => {},
62
- onBlur: () => {},
63
- onClick: () => {},
64
- onEdit: null,
65
- onDelete: null,
66
- focus: false,
67
- icon: null,
68
- iconAction: null,
69
- minLength: null,
70
- maxLength: null,
71
- };
24
+ const ref = useRef();
72
25
 
73
- /**
74
- * Component did mount lifecycle method
75
- * @method componentDidMount
76
- * @returns {undefined}
77
- */
78
- componentDidMount() {
79
- if (this.props.focus) {
80
- this.node.focus();
26
+ useEffect(() => {
27
+ if (focus) {
28
+ ref.current.focus();
81
29
  }
82
- }
30
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31
+ }, []);
32
+
33
+ return (
34
+ <FormFieldWrapper {...props} className="text">
35
+ <Input
36
+ id={`field-${id}`}
37
+ name={id}
38
+ value={value || ''}
39
+ disabled={isDisabled}
40
+ icon={icon || null}
41
+ placeholder={placeholder}
42
+ onChange={({ target }) =>
43
+ onChange(id, target.value === '' ? undefined : target.value)
44
+ }
45
+ ref={ref}
46
+ onBlur={({ target }) =>
47
+ onBlur(id, target.value === '' ? undefined : target.value)
48
+ }
49
+ onClick={() => onClick()}
50
+ minLength={minLength || null}
51
+ maxLength={maxLength || null}
52
+ />
53
+ {icon && iconAction && (
54
+ <button className={`field-${id}-action-button`} onClick={iconAction}>
55
+ <Icon name={icon} size="18px" />
56
+ </button>
57
+ )}
58
+ </FormFieldWrapper>
59
+ );
60
+ };
83
61
 
84
- /**
85
- * Render method.
86
- * @method render
87
- * @returns {string} Markup for the component.
88
- */
89
- render() {
90
- const {
91
- id,
92
- value,
93
- onChange,
94
- onBlur,
95
- onClick,
96
- icon,
97
- iconAction,
98
- minLength,
99
- maxLength,
100
- placeholder,
101
- isDisabled,
102
- } = this.props;
62
+ export default TextWidget;
103
63
 
104
- return (
105
- <FormFieldWrapper {...this.props} className="text">
106
- <Input
107
- id={`field-${id}`}
108
- name={id}
109
- value={value || ''}
110
- disabled={isDisabled}
111
- icon={icon || null}
112
- placeholder={placeholder}
113
- onChange={({ target }) =>
114
- onChange(id, target.value === '' ? undefined : target.value)
115
- }
116
- ref={(node) => {
117
- this.node = node;
118
- }}
119
- onBlur={({ target }) =>
120
- onBlur(id, target.value === '' ? undefined : target.value)
121
- }
122
- onClick={() => onClick()}
123
- minLength={minLength || null}
124
- maxLength={maxLength || null}
125
- />
126
- {icon && iconAction && (
127
- <button className={`field-${id}-action-button`} onClick={iconAction}>
128
- <Icon name={icon} size="18px" />
129
- </button>
130
- )}
131
- </FormFieldWrapper>
132
- );
133
- }
134
- }
64
+ TextWidget.propTypes = {
65
+ id: PropTypes.string.isRequired,
66
+ title: PropTypes.string.isRequired,
67
+ description: PropTypes.string,
68
+ required: PropTypes.bool,
69
+ error: PropTypes.arrayOf(PropTypes.string),
70
+ value: PropTypes.string,
71
+ focus: PropTypes.bool,
72
+ onChange: PropTypes.func,
73
+ onBlur: PropTypes.func,
74
+ onClick: PropTypes.func,
75
+ onEdit: PropTypes.func,
76
+ onDelete: PropTypes.func,
77
+ icon: PropTypes.shape({
78
+ xmlns: PropTypes.string,
79
+ viewBox: PropTypes.string,
80
+ content: PropTypes.string,
81
+ }),
82
+ iconAction: PropTypes.func,
83
+ minLength: PropTypes.number,
84
+ maxLength: PropTypes.number,
85
+ wrapped: PropTypes.bool,
86
+ placeholder: PropTypes.string,
87
+ };
135
88
 
136
- export default injectIntl(TextWidget);
89
+ TextWidget.defaultProps = {
90
+ description: null,
91
+ required: false,
92
+ error: [],
93
+ value: null,
94
+ onChange: () => {},
95
+ onBlur: () => {},
96
+ onClick: () => {},
97
+ onEdit: null,
98
+ onDelete: null,
99
+ focus: false,
100
+ icon: null,
101
+ iconAction: null,
102
+ minLength: null,
103
+ maxLength: null,
104
+ };