@ukhomeoffice/cop-react-form-renderer 3.3.4 → 3.5.2-alpha

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.
@@ -496,7 +496,7 @@ describe('components', function () {
496
496
  }, _callee16);
497
497
  })));
498
498
  it('should show page components corrently with interpolated title and cya_label, if label is missing', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee18() {
499
- var _PAGES, _COMPONENTS, T_PAGES, cya, _cya$childNodes5, cyaTitle, cyaChildNode, names, _names$childNodes3, firstName, surname, _firstName$childNodes, label, value;
499
+ var _PAGES, _COMPONENTS, T_PAGES, cya, _cya$childNodes5, cyaTitle, cyaChildNode, names, _names$childNodes3, firstName, surname, _firstName$childNodes, label;
500
500
 
501
501
  return regeneratorRuntime.wrap(function _callee18$(_context18) {
502
502
  while (1) {
@@ -543,7 +543,7 @@ describe('components', function () {
543
543
  expect(names.tagName).toEqual('DL');
544
544
  expect(names.classList).toContain("govuk-!-margin-bottom-".concat(_CheckYourAnswers.DEFAULT_MARGIN_BOTTOM));
545
545
  _names$childNodes3 = _slicedToArray(names.childNodes, 2), firstName = _names$childNodes3[0], surname = _names$childNodes3[1];
546
- _firstName$childNodes = _slicedToArray(firstName.childNodes, 2), label = _firstName$childNodes[0], value = _firstName$childNodes[1];
546
+ _firstName$childNodes = _slicedToArray(firstName.childNodes, 1), label = _firstName$childNodes[0];
547
547
  expect(label.textContent).toEqual('Text Smith');
548
548
  checkRow(surname, 'Last name', 'Smith', false);
549
549
 
@@ -555,7 +555,7 @@ describe('components', function () {
555
555
  }, _callee18);
556
556
  })));
557
557
  it('should show page components corrently with no label, if label and cya_label are missing', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee20() {
558
- var _PAGES, _COMPONENTS, T_PAGES, cya, _cya$childNodes6, cyaChildNode, names, _names$childNodes4, firstName, surname, _firstName$childNodes2, label, value;
558
+ var _PAGES, _COMPONENTS, T_PAGES, cya, _cya$childNodes6, cyaChildNode, names, _names$childNodes4, firstName, surname, _firstName$childNodes2, label;
559
559
 
560
560
  return regeneratorRuntime.wrap(function _callee20$(_context20) {
561
561
  while (1) {
@@ -596,7 +596,7 @@ describe('components', function () {
596
596
  expect(names.tagName).toEqual('DL');
597
597
  expect(names.classList).toContain("govuk-!-margin-bottom-".concat(_CheckYourAnswers.DEFAULT_MARGIN_BOTTOM));
598
598
  _names$childNodes4 = _slicedToArray(names.childNodes, 2), firstName = _names$childNodes4[0], surname = _names$childNodes4[1];
599
- _firstName$childNodes2 = _slicedToArray(firstName.childNodes, 2), label = _firstName$childNodes2[0], value = _firstName$childNodes2[1];
599
+ _firstName$childNodes2 = _slicedToArray(firstName.childNodes, 1), label = _firstName$childNodes2[0];
600
600
  expect(label.textContent).toEqual("");
601
601
  checkRow(surname, 'Last name', 'Smith', false);
602
602
 
@@ -100,7 +100,7 @@ var FormPage = function FormPage(_ref) {
100
100
  key: index,
101
101
  component: component,
102
102
  onChange: onPageChange,
103
- value: page.formData[component.fieldId],
103
+ value: page.formData[component.fieldId] || patch[component.fieldId],
104
104
  formData: page.formData
105
105
  });
106
106
  }), /*#__PURE__*/_react.default.createElement(_PageActions.default, {
@@ -73,7 +73,8 @@ var FormRenderer = function FormRenderer(_ref) {
73
73
  className = _ref.className,
74
74
  hide_title = _ref.hide_title,
75
75
  summaryListClassModifiers = _ref.summaryListClassModifiers,
76
- noChangeAction = _ref.noChangeAction;
76
+ noChangeAction = _ref.noChangeAction,
77
+ newPageId = _ref.newPageId;
77
78
  return /*#__PURE__*/_react.default.createElement(_context.HooksContextProvider, {
78
79
  overrides: hooks
79
80
  }, /*#__PURE__*/_react.default.createElement(_context.ValidationContextProvider, null, /*#__PURE__*/_react.default.createElement(InternalFormRenderer, {
@@ -89,7 +90,8 @@ var FormRenderer = function FormRenderer(_ref) {
89
90
  className: className,
90
91
  hide_title: hide_title,
91
92
  summaryListClassModifiers: summaryListClassModifiers,
92
- noChangeAction: noChangeAction
93
+ noChangeAction: noChangeAction,
94
+ newPageId: newPageId
93
95
  })));
94
96
  };
95
97
 
@@ -109,7 +111,8 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
109
111
  className = _ref2.className,
110
112
  hide_title = _ref2.hide_title,
111
113
  summaryListClassModifiers = _ref2.summaryListClassModifiers,
112
- noChangeAction = _ref2.noChangeAction;
114
+ noChangeAction = _ref2.noChangeAction,
115
+ newPageId = _ref2.newPageId;
113
116
 
114
117
  // Set up the initial states.
115
118
  var _useState = (0, _react.useState)({}),
@@ -177,7 +180,10 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
177
180
 
178
181
  (0, _react.useEffect)(function () {
179
182
  setPages(_utils.default.FormPage.getAll(_pages, components, _objectSpread({}, data)));
180
- }, [components, _pages, data, setPages]); // Setup initial pageId.
183
+ }, [components, _pages, data, setPages]);
184
+ (0, _react.useEffect)(function () {
185
+ if (newPageId !== undefined) onPageChange(newPageId);
186
+ }, [newPageId]); // Setup initial pageId.
181
187
 
182
188
  (0, _react.useEffect)(function () {
183
189
  setPageId(function (prev) {
@@ -244,8 +250,12 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
244
250
 
245
251
 
246
252
  var onPageAction = function onPageAction(action, patch) {
247
- // Check to see whether the action is able to proceed, which in
253
+ // Re-apply the patch to the page's formData.
254
+ // This should normally have no effect but will prevent issues
255
+ // with validation if formData happens to have been wiped.
256
+ formState.page.formData = _objectSpread(_objectSpread({}, formState.page.formData), patch); // Check to see whether the action is able to proceed, which in
248
257
  // in the case of a submission will validate the fields in the page.
258
+
249
259
  if (_helpers.default.canActionProceed(action, formState.page, validate.page)) {
250
260
  patch = _helpers.default.cleanHiddenNestedData(patch, formState.page);
251
261
 
@@ -9,6 +9,7 @@ var TYPE_CHECKBOXES = 'checkboxes';
9
9
  var TYPE_COLLECTION = 'collection';
10
10
  var TYPE_CONTAINER = 'container';
11
11
  var TYPE_DATE = 'date';
12
+ var TYPE_DETAILS = 'details';
12
13
  var TYPE_EMAIL = 'email';
13
14
  var TYPE_FILE = 'file';
14
15
  var TYPE_HEADING = 'heading';
@@ -16,6 +17,7 @@ var TYPE_HTML = 'html';
16
17
  var TYPE_INSET_TEXT = 'inset-text';
17
18
  var TYPE_PHONE_NUMBER = 'phone-number';
18
19
  var TYPE_RADIOS = 'radios';
20
+ var TYPE_SELECT = 'select';
19
21
  var TYPE_TEXT = 'text';
20
22
  var TYPE_TEXT_AREA = 'textarea';
21
23
  var TYPE_TIME = 'time';
@@ -26,6 +28,7 @@ var ComponentTypes = {
26
28
  COLLECTION: TYPE_COLLECTION,
27
29
  CONTAINER: TYPE_CONTAINER,
28
30
  DATE: TYPE_DATE,
31
+ DETAILS: TYPE_DETAILS,
29
32
  EMAIL: TYPE_EMAIL,
30
33
  FILE: TYPE_FILE,
31
34
  HEADING: TYPE_HEADING,
@@ -33,6 +36,7 @@ var ComponentTypes = {
33
36
  INSET_TEXT: TYPE_INSET_TEXT,
34
37
  PHONE_NUMBER: TYPE_PHONE_NUMBER,
35
38
  RADIOS: TYPE_RADIOS,
39
+ SELECT: TYPE_SELECT,
36
40
  TEXT: TYPE_TEXT,
37
41
  TEXT_AREA: TYPE_TEXT_AREA,
38
42
  TIME: TYPE_TIME,
@@ -59,6 +59,12 @@ var getDate = function getDate(config) {
59
59
  return /*#__PURE__*/_react.default.createElement(_copReactComponents.DateInput, attrs);
60
60
  };
61
61
 
62
+ var getDetails = function getDetails(config) {
63
+ var attrs = (0, _cleanAttributes.default)(config);
64
+ var html = getHTML(config);
65
+ return /*#__PURE__*/_react.default.createElement(_copReactComponents.Details, attrs, html);
66
+ };
67
+
62
68
  var getFileUpload = function getFileUpload(config) {
63
69
  var attrs = (0, _cleanAttributes.default)(config);
64
70
  return /*#__PURE__*/_react.default.createElement(_copReactComponents.FileUpload, attrs);
@@ -114,6 +120,19 @@ var getTime = function getTime(config) {
114
120
  return /*#__PURE__*/_react.default.createElement(_copReactComponents.TimeInput, attrs);
115
121
  };
116
122
 
123
+ var getSelect = function getSelect(config) {
124
+ var options = [];
125
+
126
+ _Data.default.getOptions(config, function (val) {
127
+ options = val;
128
+ });
129
+
130
+ var attrs = (0, _cleanAttributes.default)(config);
131
+ return /*#__PURE__*/_react.default.createElement(_copReactComponents.Select, _extends({}, attrs, {
132
+ options: options
133
+ }));
134
+ };
135
+
117
136
  var getWarningText = function getWarningText(config) {
118
137
  var attrs = (0, _cleanAttributes.default)(config);
119
138
  return /*#__PURE__*/_react.default.createElement(_copReactComponents.WarningText, attrs, config.content);
@@ -159,6 +178,12 @@ var getComponentByType = function getComponentByType(config) {
159
178
  case _models.ComponentTypes.WARNING:
160
179
  return getWarningText(config);
161
180
 
181
+ case _models.ComponentTypes.SELECT:
182
+ return getSelect(config);
183
+
184
+ case _models.ComponentTypes.DETAILS:
185
+ return getDetails(config);
186
+
162
187
  default:
163
188
  {
164
189
  return null;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ var _react = require("@testing-library/react");
4
+
5
+ var _models = require("../../../models");
6
+
7
+ var _getComponent = _interopRequireDefault(require("../getComponent"));
8
+
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+
11
+ // Global imports
12
+ // Local imports
13
+ describe('utils.Component.get', function () {
14
+ it('should return a details component containing basic text', function () {
15
+ var ID = 'test-id';
16
+ var CONTENT = 'Details content';
17
+ var SUMMARY = 'Details Summary';
18
+ var COMPONENT = {
19
+ type: _models.ComponentTypes.DETAILS,
20
+ content: CONTENT,
21
+ summary: SUMMARY,
22
+ 'data-testid': ID
23
+ };
24
+
25
+ var _render = (0, _react.render)((0, _getComponent.default)(COMPONENT)),
26
+ container = _render.container;
27
+
28
+ var details = container.querySelector('details');
29
+ expect(details.classList).toContain('hods-details');
30
+ expect(details.childNodes[0].textContent).toEqual(SUMMARY);
31
+ expect(details.childNodes[1].textContent).toEqual(CONTENT);
32
+ });
33
+ it('should return a details component containing multiple html components', function () {
34
+ var ID = 'test-id';
35
+ var CONTENT = '<p>this is the content</p><ol><li>one</li><li>two</li></ol><p>second section of content</p>';
36
+ var SUMMARY = 'Details Summary';
37
+ var COMPONENT = {
38
+ type: _models.ComponentTypes.DETAILS,
39
+ content: CONTENT,
40
+ summary: SUMMARY,
41
+ 'data-testid': ID
42
+ };
43
+
44
+ var _render2 = (0, _react.render)((0, _getComponent.default)(COMPONENT)),
45
+ container = _render2.container;
46
+
47
+ var details = container.querySelector('details');
48
+ expect(details.classList).toContain('hods-details');
49
+ expect(details.childNodes[1].childNodes[0].childNodes[0].textContent).toEqual('this is the content');
50
+ expect(details.childNodes[1].childNodes[0].childNodes[0].tagName).toEqual('P');
51
+ expect(details.childNodes[1].childNodes[0].childNodes[1].childNodes[0].textContent).toEqual('one');
52
+ expect(details.childNodes[1].childNodes[0].childNodes[1].childNodes[1].textContent).toEqual('two');
53
+ expect(details.childNodes[1].childNodes[0].childNodes[1].tagName).toEqual('OL');
54
+ expect(details.childNodes[1].childNodes[0].childNodes[2].textContent).toEqual('second section of content');
55
+ expect(details.childNodes[1].childNodes[0].childNodes[2].tagName).toEqual('P');
56
+ });
57
+ });
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ var _react = require("@testing-library/react");
4
+
5
+ var _models = require("../../../models");
6
+
7
+ var _getComponent = _interopRequireDefault(require("../getComponent"));
8
+
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+
11
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
12
+
13
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
14
+
15
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
16
+
17
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
18
+
19
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
20
+
21
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
22
+
23
+ describe('utils.Component.get', function () {
24
+ it('should return an appropriately rendered select component', function () {
25
+ var ID = 'test-id';
26
+ var FIELD_ID = 'field-id';
27
+ var LABEL = 'label';
28
+ var NEW_VALUE = 'option2';
29
+ var ON_CHANGE_CALLS = [];
30
+
31
+ var ON_CHANGE = function ON_CHANGE(e) {
32
+ ON_CHANGE_CALLS.push(e.target);
33
+ };
34
+
35
+ var COMPONENT = {
36
+ type: _models.ComponentTypes.SELECT,
37
+ id: ID,
38
+ fieldId: FIELD_ID,
39
+ label: LABEL,
40
+ onChange: ON_CHANGE,
41
+ options: [{
42
+ label: 'Option 1',
43
+ value: 'option1'
44
+ }, {
45
+ label: 'Option 2',
46
+ value: NEW_VALUE
47
+ }],
48
+ 'data-testid': ID
49
+ };
50
+
51
+ var _render = (0, _react.render)((0, _getComponent.default)(COMPONENT)),
52
+ container = _render.container;
53
+
54
+ var _getAllByTestId = (0, _react.getAllByTestId)(container, ID),
55
+ _getAllByTestId2 = _slicedToArray(_getAllByTestId, 2),
56
+ formGroup = _getAllByTestId2[0],
57
+ select = _getAllByTestId2[1];
58
+
59
+ expect(formGroup.tagName).toEqual('DIV');
60
+ expect(formGroup.classList).toContain('govuk-form-group');
61
+ var label = undefined;
62
+ formGroup.childNodes.forEach(function (node) {
63
+ // Check if it's an element.
64
+ if (node instanceof Element && node.tagName === 'LABEL') {
65
+ label = node;
66
+ }
67
+ });
68
+ expect(label).toBeDefined();
69
+ expect(label.innerHTML).toContain(LABEL);
70
+ expect(label.getAttribute('for')).toEqual(ID);
71
+ expect(select.tagName).toEqual('SELECT');
72
+ expect(select.classList).toContain('govuk-select');
73
+ expect(select.id).toEqual(ID);
74
+
75
+ _react.fireEvent.change(select, {
76
+ target: {
77
+ name: FIELD_ID,
78
+ value: NEW_VALUE
79
+ }
80
+ });
81
+
82
+ expect(ON_CHANGE_CALLS.length).toEqual(1);
83
+ expect(ON_CHANGE_CALLS[0]).toMatchObject({
84
+ name: FIELD_ID,
85
+ value: NEW_VALUE
86
+ });
87
+ });
88
+ });
@@ -8,7 +8,7 @@ exports.default = exports.EDITABLE_TYPES = void 0;
8
8
  var _models = require("../../models");
9
9
 
10
10
  // Local imports
11
- var EDITABLE_TYPES = [_models.ComponentTypes.AUTOCOMPLETE, _models.ComponentTypes.CHECKBOXES, _models.ComponentTypes.DATE, _models.ComponentTypes.EMAIL, _models.ComponentTypes.FILE, _models.ComponentTypes.PHONE_NUMBER, _models.ComponentTypes.RADIOS, _models.ComponentTypes.TEXT, _models.ComponentTypes.TEXT_AREA, _models.ComponentTypes.TIME];
11
+ var EDITABLE_TYPES = [_models.ComponentTypes.AUTOCOMPLETE, _models.ComponentTypes.CHECKBOXES, _models.ComponentTypes.DATE, _models.ComponentTypes.EMAIL, _models.ComponentTypes.FILE, _models.ComponentTypes.PHONE_NUMBER, _models.ComponentTypes.RADIOS, _models.ComponentTypes.SELECT, _models.ComponentTypes.TEXT, _models.ComponentTypes.TEXT_AREA, _models.ComponentTypes.TIME];
12
12
  exports.EDITABLE_TYPES = EDITABLE_TYPES;
13
13
 
14
14
  var isEditable = function isEditable(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ukhomeoffice/cop-react-form-renderer",
3
- "version": "3.3.4",
3
+ "version": "3.5.2-alpha",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",
@@ -16,7 +16,7 @@
16
16
  "post-compile": "rimraf dist/*.test.* dist/**/*.test.* dist/**/*.stories.* dist/docs dist/assets"
17
17
  },
18
18
  "dependencies": {
19
- "@ukhomeoffice/cop-react-components": "1.8.0",
19
+ "@ukhomeoffice/cop-react-components": "1.9.0",
20
20
  "axios": "^0.21.1",
21
21
  "dayjs": "^1.11.0",
22
22
  "govuk-frontend": "^3.13.0",