@defra/forms-model 3.0.491 → 3.0.492

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 (50) hide show
  1. package/dist/module/form/form-editor/__stubs__/preview.js +6 -7
  2. package/dist/module/form/form-editor/__stubs__/preview.js.map +1 -1
  3. package/dist/module/form/form-editor/preview/component-elements.js +2 -10
  4. package/dist/module/form/form-editor/preview/component-elements.js.map +1 -1
  5. package/dist/module/form/form-editor/preview/content.js +2 -3
  6. package/dist/module/form/form-editor/preview/content.js.map +1 -1
  7. package/dist/module/form/form-editor/preview/controller/page-controller.js +91 -6
  8. package/dist/module/form/form-editor/preview/controller/page-controller.js.map +1 -1
  9. package/dist/module/form/form-editor/preview/helpers.js +5 -6
  10. package/dist/module/form/form-editor/preview/helpers.js.map +1 -1
  11. package/dist/module/form/form-editor/preview/list.js +2 -3
  12. package/dist/module/form/form-editor/preview/list.js.map +1 -1
  13. package/dist/module/form/form-editor/preview/preview.js +3 -8
  14. package/dist/module/form/form-editor/preview/preview.js.map +1 -1
  15. package/dist/module/form/form-editor/preview/question.js +2 -2
  16. package/dist/module/form/form-editor/preview/question.js.map +1 -1
  17. package/dist/module/form/form-editor/preview/types.js.map +1 -1
  18. package/dist/module/stubs.js +3 -0
  19. package/dist/module/stubs.js.map +1 -1
  20. package/dist/types/form/form-editor/__stubs__/preview.d.ts +4 -3
  21. package/dist/types/form/form-editor/__stubs__/preview.d.ts.map +1 -1
  22. package/dist/types/form/form-editor/preview/component-elements.d.ts +1 -7
  23. package/dist/types/form/form-editor/preview/component-elements.d.ts.map +1 -1
  24. package/dist/types/form/form-editor/preview/content.d.ts +1 -2
  25. package/dist/types/form/form-editor/preview/content.d.ts.map +1 -1
  26. package/dist/types/form/form-editor/preview/controller/page-controller.d.ts +27 -0
  27. package/dist/types/form/form-editor/preview/controller/page-controller.d.ts.map +1 -1
  28. package/dist/types/form/form-editor/preview/helpers.d.ts +1 -2
  29. package/dist/types/form/form-editor/preview/helpers.d.ts.map +1 -1
  30. package/dist/types/form/form-editor/preview/list.d.ts +1 -2
  31. package/dist/types/form/form-editor/preview/list.d.ts.map +1 -1
  32. package/dist/types/form/form-editor/preview/preview.d.ts +4 -5
  33. package/dist/types/form/form-editor/preview/preview.d.ts.map +1 -1
  34. package/dist/types/form/form-editor/preview/question.d.ts +1 -1
  35. package/dist/types/form/form-editor/preview/question.d.ts.map +1 -1
  36. package/dist/types/form/form-editor/preview/types.d.ts +13 -4
  37. package/dist/types/form/form-editor/preview/types.d.ts.map +1 -1
  38. package/dist/types/stubs.d.ts +3 -0
  39. package/dist/types/stubs.d.ts.map +1 -1
  40. package/package.json +1 -1
  41. package/src/form/form-editor/__stubs__/preview.js +6 -14
  42. package/src/form/form-editor/preview/component-elements.js +2 -10
  43. package/src/form/form-editor/preview/content.js +2 -3
  44. package/src/form/form-editor/preview/controller/page-controller.js +109 -10
  45. package/src/form/form-editor/preview/helpers.js +5 -10
  46. package/src/form/form-editor/preview/list.js +2 -3
  47. package/src/form/form-editor/preview/preview.js +3 -11
  48. package/src/form/form-editor/preview/question.js +2 -2
  49. package/src/form/form-editor/preview/types.ts +18 -4
  50. package/src/stubs.ts +3 -0
@@ -12,10 +12,9 @@ export class ContentElements extends ComponentElements {
12
12
  _component
13
13
  /**
14
14
  * @param {Exclude<ContentComponentsDef, ListComponent>} component
15
- * @param {boolean} largeTitle
16
15
  */
17
- constructor(component, largeTitle = true) {
18
- super(component, largeTitle)
16
+ constructor(component) {
17
+ super(component)
19
18
  this._component = component
20
19
  }
21
20
 
@@ -26,6 +26,7 @@ export class PagePreviewElements {
26
26
  * @private
27
27
  */
28
28
  _page
29
+
29
30
  /**
30
31
  * @param {Page} page
31
32
  */
@@ -48,6 +49,10 @@ export class PagePreviewElements {
48
49
  ? possibleGuidanceComponent.content
49
50
  : ''
50
51
  }
52
+
53
+ get addHeading() {
54
+ return this._page.title.length > 0
55
+ }
51
56
  }
52
57
 
53
58
  /**
@@ -95,6 +100,11 @@ export class PreviewPageController {
95
100
  * @protected
96
101
  */
97
102
  _guidanceComponent
103
+ /**
104
+ * @type {boolean}
105
+ * @private
106
+ */
107
+ _showTitle = true
98
108
  /**
99
109
  * @param {ComponentDef[]} components
100
110
  * @param {PageOverviewElements} elements
@@ -103,11 +113,7 @@ export class PreviewPageController {
103
113
  */
104
114
  constructor(components, elements, definition, renderer) {
105
115
  const questions = components.map(
106
- mapComponentToPreviewQuestion(
107
- questionRenderer,
108
- definition,
109
- elements.heading.length > 0
110
- )
116
+ mapComponentToPreviewQuestion(questionRenderer, definition)
111
117
  )
112
118
  const firstQuestion = /** @type { Markdown | undefined | Question } */ (
113
119
  questions.shift()
@@ -117,6 +123,7 @@ export class PreviewPageController {
117
123
  PreviewPageController.getOrCreateGuidanceComponent(firstQuestion)
118
124
  this._guidanceText = elements.guidance
119
125
  this._components = this.#constructComponents(firstQuestion, questions)
126
+ this._showTitle = elements.addHeading
120
127
 
121
128
  this.#pageRenderer = renderer
122
129
  this.#title = elements.heading
@@ -156,10 +163,67 @@ export class PreviewPageController {
156
163
  ...this._components
157
164
  ])
158
165
 
159
- return componentsWithGuidance.map((component) => ({
160
- model: component.renderInput,
161
- questionType: component.componentType
162
- }))
166
+ return componentsWithGuidance.map((component) => {
167
+ return {
168
+ model: this._overrideComponentHeading(component),
169
+ questionType: component.componentType
170
+ }
171
+ })
172
+ }
173
+
174
+ /**
175
+ * @returns {boolean}
176
+ */
177
+ get showLargeTitle() {
178
+ const componentsLength =
179
+ this._components.length + this._guidanceComponents.length
180
+
181
+ if (componentsLength > 1 || this._highlighted === 'title') {
182
+ return false
183
+ }
184
+ // |_ one component and title not highlighted
185
+ if (this.#title.trim() === this._components[0].question.trim()) {
186
+ return true
187
+ }
188
+ // titles not the same
189
+
190
+ return !this._showTitle // add page heading deselected?
191
+ }
192
+
193
+ /**
194
+ * @param {PreviewComponent} component
195
+ * @returns {QuestionBaseModel}
196
+ */
197
+ _overrideComponentHeading(component) {
198
+ const largeTitle = this.showLargeTitle
199
+
200
+ const fieldset = component.renderInput.fieldset
201
+ ? {
202
+ fieldset: {
203
+ legend: {
204
+ ...component.renderInput.fieldset.legend,
205
+ classes: largeTitle
206
+ ? 'govuk-fieldset__legend--l'
207
+ : 'govuk-fieldset__legend--m'
208
+ }
209
+ }
210
+ }
211
+ : {}
212
+
213
+ const label = component.renderInput.label
214
+ ? {
215
+ label: {
216
+ ...component.renderInput.label,
217
+ classes: largeTitle ? 'govuk-label--l' : 'govuk-label--m'
218
+ }
219
+ }
220
+ : {}
221
+
222
+ return {
223
+ ...component.renderInput,
224
+ ...fieldset,
225
+ ...label
226
+ }
163
227
  }
164
228
 
165
229
  set guidanceText(text) {
@@ -169,9 +233,25 @@ export class PreviewPageController {
169
233
  }
170
234
 
171
235
  get guidanceText() {
236
+ if (!this._showTitle) {
237
+ return ''
238
+ }
172
239
  return this._guidanceText
173
240
  }
174
241
 
242
+ /**
243
+ *
244
+ * @param {boolean} showTitle
245
+ */
246
+ set showTitle(showTitle) {
247
+ this._showTitle = showTitle
248
+ this.render()
249
+ }
250
+
251
+ get showTitle() {
252
+ return this._showTitle
253
+ }
254
+
175
255
  get guidance() {
176
256
  return {
177
257
  text: this.guidanceText,
@@ -193,11 +273,29 @@ export class PreviewPageController {
193
273
  this.#pageRenderer.render(this._pageTemplate, this)
194
274
  }
195
275
 
276
+ /**
277
+ * @returns {boolean}
278
+ */
279
+ get titleAndFirstTitleSame() {
280
+ return (
281
+ this._components.length > 0 &&
282
+ this.#title.trim() === this._components[0].question.trim() &&
283
+ this.components.length === 1 &&
284
+ this._highlighted !== 'title'
285
+ )
286
+ }
287
+
196
288
  /**
197
289
  * @returns {string}
198
290
  */
199
291
  get title() {
200
- return this.#title
292
+ if (!this._showTitle || this.titleAndFirstTitleSame) {
293
+ return ''
294
+ }
295
+ if (this.#title.length) {
296
+ return this.#title
297
+ }
298
+ return 'Page heading'
201
299
  }
202
300
 
203
301
  /**
@@ -269,6 +367,7 @@ export class PreviewPageController {
269
367
  /**
270
368
  * @import { PageRenderer, PageOverviewElements, QuestionRenderer, QuestionBaseModel } from '~/src/form/form-editor/preview/types.js'
271
369
  * @import { Question } from '~/src/form/form-editor/preview/question.js'
370
+ * @import { PreviewComponent } from '~/src/form/form-editor/preview/preview.js'
272
371
  * @import { FormDefinition, Page } from '~/src/form/form-definition/types.js'
273
372
  * @import { ComponentDef, MarkdownComponent } from '~/src/components/types.js'
274
373
  * @import { PagePreviewComponent, PagePreviewPanelMacro } from '~/src/form/form-editor/macros/types.js'
@@ -55,14 +55,9 @@ const InputFieldComponentDictionary = {
55
55
  /**
56
56
  * @param {QuestionRenderer} questionRenderer
57
57
  * @param {FormDefinition} definition
58
- * @param {boolean} hasTitle
59
58
  * @returns {(component: ComponentDef) => Question}
60
59
  */
61
- export function mapComponentToPreviewQuestion(
62
- questionRenderer,
63
- definition,
64
- hasTitle
65
- ) {
60
+ export function mapComponentToPreviewQuestion(questionRenderer, definition) {
66
61
  return /** @type {(component: ComponentDef) => Question} */ (
67
62
  (component) => {
68
63
  /**
@@ -72,16 +67,16 @@ export function mapComponentToPreviewQuestion(
72
67
 
73
68
  if (hasSelectionFields(component) && hasListField(component)) {
74
69
  const list = findDefinitionListFromComponent(component, definition)
75
- questionElements = new ListComponentElements(component, list, !hasTitle)
70
+ questionElements = new ListComponentElements(component, list)
76
71
  } else if (
77
72
  hasInputField(component) ||
78
73
  component.type === ComponentType.YesNoField
79
74
  ) {
80
- questionElements = new QuestionComponentElements(component, !hasTitle)
75
+ questionElements = new QuestionComponentElements(component)
81
76
  } else if (hasContentField(component)) {
82
- questionElements = new ContentElements(component, !hasTitle)
77
+ questionElements = new ContentElements(component)
83
78
  } else {
84
- questionElements = new ComponentElements(component, !hasTitle)
79
+ questionElements = new ComponentElements(component)
85
80
  }
86
81
 
87
82
  const QuestionConstructor = InputFieldComponentDictionary[component.type]
@@ -61,10 +61,9 @@ export class ListComponentElements extends QuestionComponentElements {
61
61
  /**
62
62
  * @param {SelectionComponentsDef} component
63
63
  * @param {List} list
64
- * @param {boolean} largeTitle
65
64
  */
66
- constructor(component, list, largeTitle = true) {
67
- super(component, largeTitle)
65
+ constructor(component, list) {
66
+ super(component)
68
67
  this._list = list
69
68
  }
70
69
 
@@ -48,14 +48,13 @@ export class PreviewComponent {
48
48
  * @type {boolean}
49
49
  * @protected
50
50
  */
51
- _largeTitle = true
52
51
 
53
52
  /**
54
53
  * @param {QuestionElements} htmlElements
55
54
  * @param {QuestionRenderer} questionRenderer
56
55
  */
57
56
  constructor(htmlElements, questionRenderer) {
58
- const { question, optional, largeTitle } = htmlElements.values
57
+ const { question, optional } = htmlElements.values
59
58
 
60
59
  /**
61
60
  * @type {QuestionElements}
@@ -78,7 +77,6 @@ export class PreviewComponent {
78
77
  * @protected
79
78
  */
80
79
  this._questionRenderer = questionRenderer
81
- this._largeTitle = largeTitle
82
80
  }
83
81
 
84
82
  /**
@@ -100,11 +98,9 @@ export class PreviewComponent {
100
98
  * @type {DefaultComponent}
101
99
  */
102
100
  get label() {
103
- const titleClass = this._largeTitle ? 'govuk-label--l' : 'govuk-label--m'
104
-
105
101
  return {
106
102
  text: this.titleText,
107
- classes: titleClass + this.getHighlight('question')
103
+ classes: 'govuk-label--l' + this.getHighlight('question')
108
104
  }
109
105
  }
110
106
 
@@ -113,14 +109,10 @@ export class PreviewComponent {
113
109
  * @type {GovukFieldset}
114
110
  */
115
111
  get fieldSet() {
116
- const titleClass = this._largeTitle
117
- ? 'govuk-fieldset__legend--l'
118
- : 'govuk-fieldset__legend--m'
119
-
120
112
  return {
121
113
  legend: {
122
114
  text: this.titleText,
123
- classes: titleClass + this.getHighlight('question')
115
+ classes: 'govuk-fieldset__legend--l' + this.getHighlight('question')
124
116
  }
125
117
  }
126
118
  }
@@ -14,8 +14,8 @@ export class QuestionComponentElements extends ComponentElements {
14
14
  /**
15
15
  * @param {FormComponentsDef} component
16
16
  */
17
- constructor(component, largeTitle = true) {
18
- super(component, largeTitle)
17
+ constructor(component) {
18
+ super(component)
19
19
  this._component = component
20
20
  }
21
21
 
@@ -16,7 +16,6 @@ import { type UkAddressQuestion } from '~/src/form/form-editor/preview/uk-addres
16
16
  import { type ListElement } from '~/src/form/form-editor/types.js'
17
17
  export { type QuestionBaseModel } from '~/src/form/form-editor/macros/types.js'
18
18
  export interface BaseSettings {
19
- largeTitle: boolean
20
19
  question: string
21
20
  hintText: string
22
21
  optional: boolean
@@ -41,19 +40,31 @@ export type ListenerRow = [
41
40
  keyof HTMLElementEventMap
42
41
  ]
43
42
 
44
- export interface QuestionElements {
45
- readonly values: BaseSettings
43
+ export interface DomElementsBase {
44
+ readonly values?: BaseSettings
45
+ autocompleteOptions?: string
46
46
  setPreviewHTML(value: string): void
47
47
  setPreviewDOM(element: HTMLElement): void
48
48
  }
49
+
50
+ export interface QuestionElements extends DomElementsBase {
51
+ readonly values: BaseSettings
52
+ }
53
+
49
54
  export interface AutocompleteElements extends QuestionElements {
50
55
  autocompleteOptions: string
51
56
  }
52
57
 
53
- export interface RenderContext {
58
+ export interface QuestionRenderContext {
54
59
  model: QuestionBaseModel
55
60
  }
56
61
 
62
+ export interface PageRenderContext {
63
+ params: PagePreviewPanelMacro
64
+ }
65
+
66
+ export type RenderContext = QuestionRenderContext | PageRenderContext
67
+
57
68
  export interface HTMLBuilder {
58
69
  buildHTML(questionTemplate: string, renderContext: RenderContext): string
59
70
  }
@@ -66,6 +77,8 @@ export interface PageRenderer {
66
77
  render(pageTemplate: string, pagePreview: PagePreviewPanelMacro): void
67
78
  }
68
79
 
80
+ export type Renderer = QuestionRenderer | PageRenderer
81
+
69
82
  export interface ListElements extends QuestionElements {
70
83
  afterInputsHTML: string
71
84
  }
@@ -73,6 +86,7 @@ export interface ListElements extends QuestionElements {
73
86
  export interface PageOverviewElements {
74
87
  heading: string
75
88
  guidance: string
89
+ addHeading: boolean
76
90
  }
77
91
 
78
92
  export type PreviewQuestion =
package/src/stubs.ts CHANGED
@@ -11,3 +11,6 @@ export { buildFileUploadPage } from '~/src/__stubs__/pages.js'
11
11
  export { buildSummaryPage } from '~/src/__stubs__/pages.js'
12
12
  export { buildQuestionPage } from '~/src/__stubs__/pages.js'
13
13
  export { buildMarkdownComponent } from '~/src/__stubs__/components.js'
14
+ export { QuestionRendererStub } from '~/src/form/form-editor/__stubs__/preview.js'
15
+ export { PageRendererStub } from '~/src/form/form-editor/__stubs__/preview.js'
16
+ export { QuestionPreviewElements } from '~/src/form/form-editor/__stubs__/preview.js'