@ukhomeoffice/cop-react-form-renderer 6.6.1 → 6.11.1

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 (45) hide show
  1. package/dist/components/CheckYourAnswers/Answer.js +11 -5
  2. package/dist/components/CheckYourAnswers/Answer.test.js +67 -14
  3. package/dist/components/CheckYourAnswers/CheckYourAnswers.js +9 -5
  4. package/dist/components/CheckYourAnswers/CheckYourAnswers.test.js +156 -64
  5. package/dist/components/CollectionSummary/CollectionSummary.js +20 -3
  6. package/dist/components/CollectionSummary/CollectionSummary.test.js +66 -20
  7. package/dist/components/CollectionSummary/RenderListView.js +2 -2
  8. package/dist/components/CollectionSummary/SummaryCard.js +17 -6
  9. package/dist/components/CollectionSummary/SummaryCard.test.js +94 -37
  10. package/dist/components/CollectionSummary/SummaryCardDetails.js +78 -34
  11. package/dist/components/CollectionSummary/SummaryCardDetails.scss +9 -0
  12. package/dist/components/CollectionSummary/SummaryCardDetails.test.js +206 -10
  13. package/dist/components/FormComponent/Container.js +2 -1
  14. package/dist/components/FormComponent/Container.test.js +69 -0
  15. package/dist/components/FormComponent/helpers/getComponentFieldSet.js +1 -1
  16. package/dist/components/FormRenderer/FormRenderer.js +1 -0
  17. package/dist/components/SummaryList/SummaryList.js +8 -0
  18. package/dist/components/SummaryList/SummaryList.scss +15 -0
  19. package/dist/components/SummaryList/SummaryList.test.js +67 -7
  20. package/dist/components/SummaryList/SummaryListHeadingRowWithAction.js +53 -0
  21. package/dist/components/SummaryList/SummaryListHeadingRowWithAction.scss +38 -0
  22. package/dist/components/TaskList/TaskList.js +22 -5
  23. package/dist/components/TaskList/TaskList.scss +24 -0
  24. package/dist/components/TaskList/TaskList.test.js +160 -16
  25. package/dist/utils/CheckYourAnswers/getCYARowsForCollectionPage.js +27 -12
  26. package/dist/utils/CheckYourAnswers/getCYARowsForCollectionPage.test.js +145 -0
  27. package/dist/utils/CheckYourAnswers/{getComponentRowForCYA.js → getSummaryListRowForDetails.js} +10 -5
  28. package/dist/utils/CheckYourAnswers/getSummaryListRowForDetails.test.js +56 -0
  29. package/dist/utils/CollectionPage/getQuickEditPage.js +2 -1
  30. package/dist/utils/CollectionPage/getQuickEditPage.test.js +8 -0
  31. package/dist/utils/CollectionPage/mergeCollectionPages.js +10 -1
  32. package/dist/utils/CollectionPage/mergeCollectionPages.test.js +6 -6
  33. package/dist/utils/Component/elevateNestedComponents.js +2 -1
  34. package/dist/utils/Component/elevateNestedComponents.test.js +38 -0
  35. package/dist/utils/Component/optionIsSelected.js +5 -0
  36. package/dist/utils/Component/optionIsSelected.test.js +26 -0
  37. package/dist/utils/Operate/getLength.js +50 -0
  38. package/dist/utils/Operate/getLength.test.js +89 -0
  39. package/dist/utils/Operate/runPageOperations.js +2 -0
  40. package/dist/utils/Validate/validateComponent.js +7 -2
  41. package/dist/utils/Validate/validateComponent.test.js +31 -0
  42. package/dist/utils/Validate/validateTime.js +8 -0
  43. package/dist/utils/Validate/validateTime.test.js +46 -0
  44. package/package.json +1 -1
  45. package/dist/utils/CheckYourAnswers/getComponentRowForCYA.test.js +0 -41
@@ -156,6 +156,94 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
156
156
  expect(section1Content.textContent).toContain('subThreeLabel');
157
157
  expect(section1Content.textContent).toContain('charlie');
158
158
  });
159
+ it('should render sections containing collections with dynamic titles based on summaryLayout config', function () {
160
+ var FORM_DATA = {
161
+ dummyTitleContent: "Kellogg's"
162
+ };
163
+ var CHILD_PAGES = [{
164
+ summaryLayout: {
165
+ sections: [{
166
+ // eslint-disable-next-line no-template-curly-in-string
167
+ title: 'Section 1 - ${dummyTitleContent}',
168
+ columns: [{
169
+ fields: ['collectionComponent']
170
+ }]
171
+ }]
172
+ },
173
+ formData: FORM_DATA,
174
+ components: [{
175
+ fieldId: 'collectionComponent',
176
+ id: 'collectionComponent',
177
+ type: 'collection',
178
+ label: 'Collection',
179
+ labels: {
180
+ item: 'north'
181
+ },
182
+ item: [{
183
+ id: 'north',
184
+ fieldId: 'north',
185
+ type: 'text',
186
+ label: 'North',
187
+ required: true
188
+ }, {
189
+ id: 'east',
190
+ fieldId: 'east',
191
+ type: 'text',
192
+ label: 'East',
193
+ required: true
194
+ }, {
195
+ id: 'south',
196
+ fieldId: 'south',
197
+ type: 'text',
198
+ label: 'South',
199
+ required: true
200
+ }, {
201
+ id: 'west',
202
+ fieldId: 'west',
203
+ type: 'text',
204
+ label: 'West',
205
+ required: true
206
+ }]
207
+ }]
208
+ }];
209
+ var COLLECTION_ENTRY = {
210
+ summaryText: 'Full details',
211
+ collectionComponent: [{
212
+ north: 'Never',
213
+ east: 'Eat',
214
+ south: 'Shredded',
215
+ west: 'Wheat'
216
+ }]
217
+ };
218
+ var MASTER_PAGE = {
219
+ childPages: CHILD_PAGES
220
+ };
221
+ var _renderWithValidation3 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
222
+ masterPage: MASTER_PAGE,
223
+ childMasterPages: [],
224
+ formData: {},
225
+ entryData: COLLECTION_ENTRY
226
+ })),
227
+ container = _renderWithValidation3.container;
228
+
229
+ // Check for section title
230
+ var section1Title = container.querySelector(".".concat(classes('section-title')));
231
+ expect(section1Title).not.toBeUndefined();
232
+
233
+ // Check for embedded variables in title
234
+ expect(section1Title.textContent).toEqual("Section 1 - Kellogg's");
235
+
236
+ // All four subcomponents from the container should have labels and values displayed
237
+ var section1Content = section1Title.parentNode.querySelector(".".concat(classes('section-content')));
238
+ expect(section1Content.textContent).toContain('North');
239
+ expect(section1Content.textContent).toContain('Never');
240
+ expect(section1Content.textContent).toContain('East');
241
+ expect(section1Content.textContent).toContain('Eat');
242
+ expect(section1Content.textContent).toContain('South');
243
+ expect(section1Content.textContent).toContain('Shredded');
244
+ expect(section1Content.textContent).toContain('West');
245
+ expect(section1Content.textContent).toContain('Wheat');
246
+ });
159
247
  it('should render sections if they have show_when checks and pass them', function () {
160
248
  var CHILD_PAGES = [{
161
249
  summaryLayout: {
@@ -192,13 +280,13 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
192
280
  var CUSTOM_ENTRY = _objectSpread(_objectSpread({}, ENTRY), {}, {
193
281
  showSection1: true
194
282
  });
195
- var _renderWithValidation3 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
283
+ var _renderWithValidation4 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
196
284
  masterPage: MASTER_PAGE,
197
285
  childMasterPages: [],
198
286
  formData: {},
199
287
  entryData: CUSTOM_ENTRY
200
288
  })),
201
- container = _renderWithValidation3.container;
289
+ container = _renderWithValidation4.container;
202
290
 
203
291
  // Function to find an element by its text content
204
292
  function getByTextContent(parent, text) {
@@ -253,13 +341,13 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
253
341
  var CUSTOM_ENTRY = _objectSpread(_objectSpread({}, ENTRY), {}, {
254
342
  showSection1: false
255
343
  });
256
- var _renderWithValidation4 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
344
+ var _renderWithValidation5 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
257
345
  masterPage: MASTER_PAGE,
258
346
  childMasterPages: [],
259
347
  formData: {},
260
348
  entryData: CUSTOM_ENTRY
261
349
  })),
262
- container = _renderWithValidation4.container;
350
+ container = _renderWithValidation5.container;
263
351
 
264
352
  // Function to find an element by its text content
265
353
  function getByTextContent(parent, text) {
@@ -309,13 +397,13 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
309
397
  var MASTER_PAGE = {
310
398
  childPages: CHILD_PAGES
311
399
  };
312
- var _renderWithValidation5 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
400
+ var _renderWithValidation6 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
313
401
  masterPage: MASTER_PAGE,
314
402
  childMasterPages: [],
315
403
  formData: {},
316
404
  entryData: ENTRY
317
405
  })),
318
- container = _renderWithValidation5.container;
406
+ container = _renderWithValidation6.container;
319
407
 
320
408
  // Function to find an element by its text content
321
409
  function getByTextContent(parent, text) {
@@ -376,7 +464,7 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
376
464
  var CUSTOM_ENTRY = _objectSpread(_objectSpread({}, ENTRY), {}, {
377
465
  showSection1: false
378
466
  });
379
- var _renderWithValidation6 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
467
+ var _renderWithValidation7 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
380
468
  masterPage: MASTER_PAGE,
381
469
  childMasterPages: [],
382
470
  formData: {
@@ -384,7 +472,7 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
384
472
  },
385
473
  entryData: CUSTOM_ENTRY
386
474
  })),
387
- container = _renderWithValidation6.container;
475
+ container = _renderWithValidation7.container;
388
476
 
389
477
  // Function to find an element by its text content
390
478
  function getByTextContent(parent, text) {
@@ -399,6 +487,57 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
399
487
  expect(section1Title).toBeUndefined();
400
488
  expect(section2Title).toBeUndefined();
401
489
  });
490
+ it('should not render columns that fail show_when checks', function () {
491
+ var CHILD_PAGES = [{
492
+ summaryLayout: {
493
+ sections: [{
494
+ title: 'Section 1',
495
+ columns: [{
496
+ fields: ['fieldA'],
497
+ show_when: [{
498
+ field: 'showSection1',
499
+ op: '=',
500
+ value: true
501
+ }]
502
+ }, {
503
+ fields: ['fieldB']
504
+ }]
505
+ }]
506
+ },
507
+ components: [{
508
+ fieldId: 'fieldA',
509
+ label: 'fieldA'
510
+ }, {
511
+ fieldId: 'fieldB',
512
+ label: 'fieldB'
513
+ }]
514
+ }];
515
+ var MASTER_PAGE = {
516
+ childPages: CHILD_PAGES
517
+ };
518
+ var _renderWithValidation8 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
519
+ masterPage: MASTER_PAGE,
520
+ childMasterPages: [],
521
+ formData: {
522
+ testField: false
523
+ },
524
+ entryData: ENTRY
525
+ })),
526
+ container = _renderWithValidation8.container;
527
+
528
+ // Function to find an element by its text content
529
+ function getByTextContent(parent, text) {
530
+ return Array.from(parent.getElementsByClassName(classes('section-title'))).find(function (el) {
531
+ return el.textContent === text;
532
+ });
533
+ }
534
+
535
+ // Check for section titles
536
+ var section1Title = getByTextContent(container, 'Section 1');
537
+ expect(section1Title).toBeDefined();
538
+ var section1Content = section1Title.parentNode.querySelector(".".concat(classes('section-content')));
539
+ expect(section1Content.querySelectorAll(".".concat(classes('field'))).length).toEqual(1);
540
+ });
402
541
  it('should render child collections', function () {
403
542
  var CHILD_MASTER_PAGES = [{
404
543
  collection: {
@@ -442,13 +581,13 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
442
581
  childPages: [].concat(CHILD_PAGES, CHILD_MASTER_PAGES)
443
582
  };
444
583
  var CHILD_COLLECTIONS = ['childCollection'];
445
- var _renderWithValidation7 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
584
+ var _renderWithValidation9 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
446
585
  masterPage: MASTER_PAGE,
447
586
  childCollections: CHILD_COLLECTIONS,
448
587
  formData: {},
449
588
  entryData: ENTRY
450
589
  })),
451
- container = _renderWithValidation7.container;
590
+ container = _renderWithValidation9.container;
452
591
 
453
592
  // Function to find an element by its text content
454
593
  function getByTextContent(parent, text) {
@@ -464,4 +603,61 @@ describe('components.CollectionSummary.SummaryCardDetails', function () {
464
603
  var childFields = container.querySelectorAll(".".concat(classes('section')));
465
604
  expect(childFields.length).toEqual(2); // One for each entry in the child collection.
466
605
  });
606
+
607
+ it('should render components if a component with the same ID has already failed a show_when', function () {
608
+ var CHILD_PAGES = [{
609
+ summaryLayout: {
610
+ sections: [{
611
+ title: 'Section 1',
612
+ columns: [{
613
+ fields: ['fieldA']
614
+ }, {
615
+ fields: ['fieldB']
616
+ }]
617
+ }]
618
+ },
619
+ components: [{
620
+ fieldId: 'fieldA'
621
+ }, {
622
+ fieldId: 'fieldB',
623
+ label: 'first',
624
+ show_when: [{
625
+ field: 'fieldA',
626
+ op: '=',
627
+ value: 'notTheRightValue'
628
+ }]
629
+ }, {
630
+ fieldId: 'fieldB',
631
+ label: 'second',
632
+ show_when: [{
633
+ field: 'fieldA',
634
+ op: '!=',
635
+ value: 'notTheRightValue'
636
+ }]
637
+ }]
638
+ }];
639
+ var MASTER_PAGE = {
640
+ childPages: CHILD_PAGES
641
+ };
642
+ var _renderWithValidation10 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react.default.createElement(_SummaryCardDetails.default, {
643
+ masterPage: MASTER_PAGE,
644
+ childMasterPages: [],
645
+ formData: {},
646
+ entryData: _objectSpread(_objectSpread({}, ENTRY), {}, {
647
+ fieldA: 'notTheRightValue'
648
+ })
649
+ })),
650
+ container = _renderWithValidation10.container;
651
+
652
+ // Function to find an element by its text content
653
+ function getByTextContent(parent, text) {
654
+ return Array.from(parent.getElementsByClassName(classes('section-title'))).find(function (el) {
655
+ return el.textContent === text;
656
+ });
657
+ }
658
+ var section1Title = getByTextContent(container, 'Section 1');
659
+ expect(section1Title).not.toBeUndefined();
660
+ var section1Content = section1Title.parentNode.querySelector(".".concat(classes('section-content')));
661
+ expect(section1Content.querySelectorAll(".".concat(classes('field'))).length).toEqual(2);
662
+ });
467
663
  });
@@ -11,6 +11,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
  var _models = require("../../models");
12
12
  var _utils = _interopRequireDefault(require("../../utils"));
13
13
  var _FormComponent = _interopRequireDefault(require("./FormComponent"));
14
+ var _getSourceData = _interopRequireDefault(require("../../utils/Data/getSourceData"));
14
15
  var _excluded = ["container", "value", "formData", "onChange", "wrap", "onTopLevelChange"]; // Global imports
15
16
  // Local imports
16
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -58,7 +59,7 @@ var Container = function Container(_ref) {
58
59
  }
59
60
  return _utils.default.Component.show(_objectSpread(_objectSpread({}, options), {}, {
60
61
  full_path: fullPath
61
- }), formData);
62
+ }), _objectSpread(_objectSpread({}, formData), (0, _getSourceData.default)(formData, container.full_path)));
62
63
  };
63
64
  var classes = _utils.default.classBuilder(DEFAULT_CLASS, [], container.className);
64
65
  var cleanedAttrs = _copReactComponents.Utils.cleanHtmlAttributes(attrs);
@@ -368,4 +368,73 @@ describe('components.FormComponent.Container', function () {
368
368
  }
369
369
  }, _callee7);
370
370
  })));
371
+ it('should render a container component appropriately with show_whens referencing other components in the container', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8() {
372
+ var _ID2;
373
+ var TEXT_COMPONENT_CONDITIONAL, FORM_DATA_CONDITIONAL, CONTAINER, _renderWithValidation8, container, c, formGroup, label, input, formGroup2, label2, input2;
374
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
375
+ while (1) switch (_context8.prev = _context8.next) {
376
+ case 0:
377
+ TEXT_COMPONENT_CONDITIONAL = {
378
+ id: 'textTwo',
379
+ fieldId: 'textTwo',
380
+ type: _models.ComponentTypes.TEXT,
381
+ label: 'Text component 2',
382
+ show_when: {
383
+ field: TEXT_ID,
384
+ op: '=',
385
+ value: 'other'
386
+ }
387
+ };
388
+ FORM_DATA_CONDITIONAL = _defineProperty({}, ID, (_ID2 = {}, _defineProperty(_ID2, TEXT_ID, 'other'), _defineProperty(_ID2, "textTwo", 'blue'), _ID2));
389
+ CONTAINER = {
390
+ id: ID,
391
+ fieldId: ID,
392
+ type: _models.ComponentTypes.CONTAINER,
393
+ components: [TEXT_COMPONENT, TEXT_COMPONENT_CONDITIONAL],
394
+ full_path: ID
395
+ };
396
+ _renderWithValidation8 = (0, _setupTests.renderWithValidation)( /*#__PURE__*/_react2.default.createElement(_FormComponent.default, {
397
+ component: CONTAINER,
398
+ value: FORM_DATA_CONDITIONAL[ID],
399
+ formData: FORM_DATA_CONDITIONAL
400
+ })), container = _renderWithValidation8.container; // Check the container itself.
401
+ c = container.childNodes[0];
402
+ expect(c.tagName).toEqual('DIV');
403
+ expect(c.classList).toContain(_Container.DEFAULT_CLASS);
404
+
405
+ // And now check the first text component within it.
406
+ formGroup = c.childNodes[0];
407
+ expect(formGroup.tagName).toEqual('DIV');
408
+ expect(formGroup.classList).toContain('govuk-form-group');
409
+ label = formGroup.childNodes[0];
410
+ expect(label.tagName).toEqual('LABEL');
411
+ expect(label.classList).toContain('govuk-label');
412
+ expect(label.textContent).toEqual("".concat(TEXT_COMPONENT.label, " (optional)"));
413
+ expect(label.getAttribute('for')).toEqual("".concat(ID, ".").concat(TEXT_ID));
414
+ input = formGroup.childNodes[2];
415
+ expect(input.tagName).toEqual('INPUT');
416
+ expect(input.classList).toContain('govuk-input');
417
+ expect(input.id).toEqual("".concat(ID, ".").concat(TEXT_ID));
418
+ expect(input.value).toEqual('other');
419
+
420
+ // And now check the second text component within it that should have passed the show_when
421
+ formGroup2 = c.childNodes[1];
422
+ expect(formGroup2.tagName).toEqual('DIV');
423
+ expect(formGroup2.classList).toContain('govuk-form-group');
424
+ label2 = formGroup2.childNodes[0];
425
+ expect(label2.tagName).toEqual('LABEL');
426
+ expect(label2.classList).toContain('govuk-label');
427
+ expect(label2.textContent).toEqual("".concat(TEXT_COMPONENT.label, " 2 (optional)"));
428
+ expect(label2.getAttribute('for')).toEqual("".concat(ID, ".").concat(TEXT_ID, "Two"));
429
+ input2 = formGroup2.childNodes[2];
430
+ expect(input2.tagName).toEqual('INPUT');
431
+ expect(input2.classList).toContain('govuk-input');
432
+ expect(input2.id).toEqual("".concat(ID, ".").concat(TEXT_ID, "Two"));
433
+ expect(input2.value).toEqual('blue');
434
+ case 33:
435
+ case "end":
436
+ return _context8.stop();
437
+ }
438
+ }, _callee8);
439
+ })));
371
440
  });
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _models = require("../../../models");
8
- var SHOULD_HAVE_FIELDSET = [_models.ComponentTypes.RADIOS, _models.ComponentTypes.CHECKBOXES, _models.ComponentTypes.DATE];
8
+ var SHOULD_HAVE_FIELDSET = [_models.ComponentTypes.RADIOS, _models.ComponentTypes.CHECKBOXES, _models.ComponentTypes.DATE, _models.ComponentTypes.TIME];
9
9
  var _default = exports.default = function _default(component) {
10
10
  return component.fieldset || SHOULD_HAVE_FIELDSET.includes(component.type);
11
11
  };
@@ -352,6 +352,7 @@ var InternalFormRenderer = function InternalFormRenderer(_ref2) {
352
352
  onTaskAction: function onTaskAction(task) {
353
353
  (0, _onTaskAction2.default)(task, pages, setCurrentTask, hubDetails, data, onPageChange);
354
354
  },
355
+ annotations: (hubDetails === null || hubDetails === void 0 ? void 0 : hubDetails.taskListAnnotations) || [],
355
356
  formData: data
356
357
  })), formState.page && !formState.cya && !formState.page.collection && /*#__PURE__*/_react.default.createElement(_FormPage.default, {
357
358
  page: formState.page,
@@ -10,6 +10,7 @@ var _react = _interopRequireDefault(require("react"));
10
10
  var _GroupAction = _interopRequireDefault(require("./GroupAction"));
11
11
  var _SummaryListRow = _interopRequireDefault(require("./SummaryListRow"));
12
12
  var _SummaryListHeadingRow = _interopRequireDefault(require("./SummaryListHeadingRow"));
13
+ var _SummaryListHeadingRowWithAction = _interopRequireDefault(require("./SummaryListHeadingRowWithAction"));
13
14
  var _SummaryListTitleRow = _interopRequireDefault(require("./SummaryListTitleRow"));
14
15
  require("./SummaryList.scss");
15
16
  var _excluded = ["rows", "noChangeAction", "noGroupAction", "isGroup", "classBlock", "classModifiers", "className"]; // Global imports
@@ -59,6 +60,13 @@ var SummaryList = function SummaryList(_ref) {
59
60
  classes: classes
60
61
  });
61
62
  }
63
+ if (row.type === 'headingWithAction') {
64
+ return /*#__PURE__*/_react.default.createElement(_SummaryListHeadingRowWithAction.default, {
65
+ row: row,
66
+ classes: classes,
67
+ noChangeAction: noChangeAction
68
+ });
69
+ }
62
70
  if (row.type === 'action') {
63
71
  return noChangeAction ? null : /*#__PURE__*/_react.default.createElement("div", {
64
72
  key: "".concat(key, "-actions")
@@ -33,6 +33,21 @@
33
33
  }
34
34
  }
35
35
 
36
+ .govuk-summary-list__headingWithAction {
37
+ display: table-row;
38
+ width: 100%;
39
+ white-space: nowrap;
40
+ .heading-text, .heading-action {
41
+ padding-bottom: 10px;
42
+ }
43
+
44
+ &:not(:first-child) {
45
+ .heading-text, .heading-action {
46
+ padding-top: 20px;
47
+ }
48
+ }
49
+ }
50
+
36
51
  .changeRow {
37
52
  .govuk-link {
38
53
  float: right;
@@ -56,13 +56,26 @@ describe('components', function () {
56
56
  expect(actions.classList).toContain("".concat(_SummaryList.DEFAULT_CLASS, "__actions"));
57
57
  return [key, value, actions];
58
58
  };
59
- var checkRowNoChangeActions = function checkRowNoChangeActions(summaryList, index) {
59
+ var checkHeadingRowWithAction = function checkHeadingRowWithAction(summaryList, index) {
60
60
  var row = summaryList.childNodes[index];
61
61
  expect(row.tagName).toEqual('DIV');
62
- expect(row.classList).toContain("".concat(_SummaryList.DEFAULT_CLASS, "__row"));
62
+ expect(row.classList).toContain("".concat(_SummaryList.DEFAULT_CLASS, "__headingWithAction"));
63
63
  var _row$childNodes3 = _slicedToArray(row.childNodes, 2),
64
64
  key = _row$childNodes3[0],
65
- value = _row$childNodes3[1];
65
+ action = _row$childNodes3[1];
66
+ expect(key.tagName).toEqual('TD');
67
+ expect(key.classList).toContain('heading-text');
68
+ expect(action.tagName).toEqual('TD');
69
+ expect(action.classList).toContain('heading-action');
70
+ return [key, action];
71
+ };
72
+ var checkRowNoChangeActions = function checkRowNoChangeActions(summaryList, index) {
73
+ var row = summaryList.childNodes[index];
74
+ expect(row.tagName).toEqual('DIV');
75
+ expect(row.classList).toContain("".concat(_SummaryList.DEFAULT_CLASS, "__row"));
76
+ var _row$childNodes4 = _slicedToArray(row.childNodes, 2),
77
+ key = _row$childNodes4[0],
78
+ value = _row$childNodes4[1];
66
79
  expect(key.tagName).toEqual('DT');
67
80
  expect(key.classList).toContain("".concat(_SummaryList.DEFAULT_CLASS, "__key"));
68
81
  expect(value.tagName).toEqual('DD');
@@ -320,6 +333,53 @@ describe('components', function () {
320
333
  expect(ON_ACTION_CALLS[index]).toEqual(row);
321
334
  });
322
335
  });
336
+ it('should handle heading rows with actions', function () {
337
+ var ID = 'test-id';
338
+ var ON_ACTION_CALLS = [];
339
+ var ON_ACTION = function ON_ACTION(row) {
340
+ ON_ACTION_CALLS.push(row);
341
+ };
342
+ var ROWS = [{
343
+ key: 'a',
344
+ pageId: 'p1',
345
+ type: 'headingWithAction',
346
+ size: 'm',
347
+ action: {
348
+ label: 'Change A',
349
+ onAction: ON_ACTION
350
+ }
351
+ }, {
352
+ key: 'b',
353
+ pageId: 'p2',
354
+ type: 'headingWithAction',
355
+ size: 'm',
356
+ action: {
357
+ label: 'Change B',
358
+ onAction: ON_ACTION
359
+ }
360
+ }];
361
+ var _render8 = (0, _react.render)( /*#__PURE__*/_react2.default.createElement(_SummaryList.default, {
362
+ "data-testid": ID,
363
+ rows: ROWS
364
+ })),
365
+ container = _render8.container;
366
+ var summaryList = checkSummaryList(container, ID);
367
+ expect(summaryList.childNodes.length).toEqual(ROWS.length);
368
+ ROWS.forEach(function (row, index) {
369
+ var _checkHeadingRowWithA = checkHeadingRowWithAction(summaryList, index),
370
+ _checkHeadingRowWithA2 = _slicedToArray(_checkHeadingRowWithA, 2),
371
+ key = _checkHeadingRowWithA2[0],
372
+ actions = _checkHeadingRowWithA2[1];
373
+ expect(key.textContent).toEqual("".concat(row.key));
374
+ var a = actions.childNodes[0];
375
+ expect(a.textContent).toEqual(row.action.label);
376
+ _react.fireEvent.click(a, {});
377
+ expect(ON_ACTION_CALLS.length).toEqual(index + 1);
378
+ expect(ON_ACTION_CALLS[index]).toEqual({
379
+ action: row.action
380
+ });
381
+ });
382
+ });
323
383
  it('should handle rows with component values and actions set to hidden', function () {
324
384
  var ID = 'test-id';
325
385
  var VALUES = ['Alpha component value', 'Bravo component value'];
@@ -334,12 +394,12 @@ describe('components', function () {
334
394
  fieldId: 'b',
335
395
  value: /*#__PURE__*/_react2.default.createElement("div", null, VALUES[1])
336
396
  }];
337
- var _render8 = (0, _react.render)( /*#__PURE__*/_react2.default.createElement(_SummaryList.default, {
397
+ var _render9 = (0, _react.render)( /*#__PURE__*/_react2.default.createElement(_SummaryList.default, {
338
398
  "data-testid": ID,
339
399
  rows: ROWS,
340
400
  noChangeAction: true
341
401
  })),
342
- container = _render8.container;
402
+ container = _render9.container;
343
403
  var summaryList = checkSummaryList(container, ID);
344
404
  expect(summaryList.childNodes.length).toEqual(ROWS.length);
345
405
  ROWS.forEach(function (row, index) {
@@ -377,12 +437,12 @@ describe('components', function () {
377
437
  fieldId: 'c',
378
438
  value: /*#__PURE__*/_react2.default.createElement("div", null, VALUES[2])
379
439
  }];
380
- var _render9 = (0, _react.render)( /*#__PURE__*/_react2.default.createElement(_SummaryList.default, {
440
+ var _render10 = (0, _react.render)( /*#__PURE__*/_react2.default.createElement(_SummaryList.default, {
381
441
  "data-testid": ID,
382
442
  rows: ROWS,
383
443
  isGroup: ISGROUP
384
444
  })),
385
- container = _render9.container;
445
+ container = _render10.container;
386
446
  var summaryList = checkSummaryList(container, ID);
387
447
  expect(summaryList.childNodes.length).toEqual(ROWS.length + 1);
388
448
  ROWS.forEach(function (row, index) {
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _copReactComponents = require("@ukhomeoffice/cop-react-components");
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _RowAction = _interopRequireDefault(require("./RowAction"));
11
+ require("./SummaryListHeadingRowWithAction.scss");
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+ // Global imports
14
+
15
+ // Local imports
16
+
17
+ // Styles
18
+
19
+ var SummaryListHeadingRowWithAction = function SummaryListHeadingRowWithAction(_ref) {
20
+ var row = _ref.row,
21
+ classes = _ref.classes,
22
+ noChangeAction = _ref.noChangeAction;
23
+ return /*#__PURE__*/_react.default.createElement("div", {
24
+ className: classes('headingWithAction')
25
+ }, /*#__PURE__*/_react.default.createElement("td", {
26
+ className: "heading-text",
27
+ colSpan: "2"
28
+ }, row.size === 's' && /*#__PURE__*/_react.default.createElement(_copReactComponents.SmallHeading, null, row.key), row.size === 'm' && /*#__PURE__*/_react.default.createElement(_copReactComponents.MediumHeading, null, row.key)), /*#__PURE__*/_react.default.createElement("td", {
29
+ className: "heading-action"
30
+ }, !noChangeAction && /*#__PURE__*/_react.default.createElement(_RowAction.default, {
31
+ row: {
32
+ action: row.action
33
+ }
34
+ })));
35
+ };
36
+ SummaryListHeadingRowWithAction.propTypes = {
37
+ classes: _propTypes.default.func.isRequired,
38
+ row: _propTypes.default.shape({
39
+ key: _propTypes.default.string.isRequired,
40
+ size: _propTypes.default.string,
41
+ action: _propTypes.default.shape({
42
+ page: _propTypes.default.string,
43
+ label: _propTypes.default.string,
44
+ aria_suffix: _propTypes.default.string,
45
+ onAction: _propTypes.default.func
46
+ })
47
+ }).isRequired,
48
+ noChangeAction: _propTypes.default.bool
49
+ };
50
+ SummaryListHeadingRowWithAction.defaultProps = {
51
+ noChangeAction: false
52
+ };
53
+ var _default = exports.default = SummaryListHeadingRowWithAction;
@@ -0,0 +1,38 @@
1
+ .heading-with-action {
2
+ flex-direction: row;
3
+ width: 100%;
4
+ }
5
+
6
+ .heading-text {
7
+ display: table-cell;
8
+ column-span: 2;
9
+ width: 80%;
10
+
11
+ .govuk-heading-m, .govuk-heading-s {
12
+ margin-bottom: 0;
13
+ }
14
+ }
15
+
16
+ .heading-action {
17
+ display: table-cell;
18
+ width: 20%;
19
+ text-align: right;
20
+ }
21
+
22
+ @media screen and (max-width: 640px) {
23
+ .heading-with-action {
24
+ display: flex;
25
+ flex-direction: column;
26
+ width: 100%;
27
+ }
28
+
29
+ .heading-text {
30
+ width: 100%
31
+ }
32
+
33
+ .heading-action {
34
+ margin-bottom: govuk-spacing(3);
35
+ width: 20%;
36
+ text-align: left;
37
+ }
38
+ }