@defra/forms-model 3.0.491 → 3.0.493

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 (70) 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/macros/types.js.map +1 -1
  4. package/dist/module/form/form-editor/preview/autocomplete.js +3 -0
  5. package/dist/module/form/form-editor/preview/autocomplete.js.map +1 -1
  6. package/dist/module/form/form-editor/preview/component-elements.js +2 -10
  7. package/dist/module/form/form-editor/preview/component-elements.js.map +1 -1
  8. package/dist/module/form/form-editor/preview/content.js +2 -3
  9. package/dist/module/form/form-editor/preview/content.js.map +1 -1
  10. package/dist/module/form/form-editor/preview/controller/page-controller.js +91 -6
  11. package/dist/module/form/form-editor/preview/controller/page-controller.js.map +1 -1
  12. package/dist/module/form/form-editor/preview/helpers.js +10 -8
  13. package/dist/module/form/form-editor/preview/helpers.js.map +1 -1
  14. package/dist/module/form/form-editor/preview/list.js +60 -8
  15. package/dist/module/form/form-editor/preview/list.js.map +1 -1
  16. package/dist/module/form/form-editor/preview/preview.js +3 -8
  17. package/dist/module/form/form-editor/preview/preview.js.map +1 -1
  18. package/dist/module/form/form-editor/preview/question.js +2 -2
  19. package/dist/module/form/form-editor/preview/question.js.map +1 -1
  20. package/dist/module/form/form-editor/preview/select-sortable.js +5 -1
  21. package/dist/module/form/form-editor/preview/select-sortable.js.map +1 -1
  22. package/dist/module/form/form-editor/preview/select.js +32 -0
  23. package/dist/module/form/form-editor/preview/select.js.map +1 -1
  24. package/dist/module/form/form-editor/preview/types.js.map +1 -1
  25. package/dist/module/stubs.js +3 -0
  26. package/dist/module/stubs.js.map +1 -1
  27. package/dist/types/form/form-editor/__stubs__/preview.d.ts +4 -3
  28. package/dist/types/form/form-editor/__stubs__/preview.d.ts.map +1 -1
  29. package/dist/types/form/form-editor/macros/types.d.ts +13 -5
  30. package/dist/types/form/form-editor/macros/types.d.ts.map +1 -1
  31. package/dist/types/form/form-editor/preview/autocomplete.d.ts.map +1 -1
  32. package/dist/types/form/form-editor/preview/component-elements.d.ts +1 -7
  33. package/dist/types/form/form-editor/preview/component-elements.d.ts.map +1 -1
  34. package/dist/types/form/form-editor/preview/content.d.ts +1 -2
  35. package/dist/types/form/form-editor/preview/content.d.ts.map +1 -1
  36. package/dist/types/form/form-editor/preview/controller/page-controller.d.ts +27 -0
  37. package/dist/types/form/form-editor/preview/controller/page-controller.d.ts.map +1 -1
  38. package/dist/types/form/form-editor/preview/fieldset-question.d.ts +2 -5
  39. package/dist/types/form/form-editor/preview/fieldset-question.d.ts.map +1 -1
  40. package/dist/types/form/form-editor/preview/helpers.d.ts +1 -2
  41. package/dist/types/form/form-editor/preview/helpers.d.ts.map +1 -1
  42. package/dist/types/form/form-editor/preview/list.d.ts +33 -8
  43. package/dist/types/form/form-editor/preview/list.d.ts.map +1 -1
  44. package/dist/types/form/form-editor/preview/preview.d.ts +4 -5
  45. package/dist/types/form/form-editor/preview/preview.d.ts.map +1 -1
  46. package/dist/types/form/form-editor/preview/question.d.ts +1 -1
  47. package/dist/types/form/form-editor/preview/question.d.ts.map +1 -1
  48. package/dist/types/form/form-editor/preview/select-sortable.d.ts +1 -1
  49. package/dist/types/form/form-editor/preview/select-sortable.d.ts.map +1 -1
  50. package/dist/types/form/form-editor/preview/select.d.ts +14 -0
  51. package/dist/types/form/form-editor/preview/select.d.ts.map +1 -1
  52. package/dist/types/form/form-editor/preview/types.d.ts +17 -4
  53. package/dist/types/form/form-editor/preview/types.d.ts.map +1 -1
  54. package/dist/types/stubs.d.ts +3 -0
  55. package/dist/types/stubs.d.ts.map +1 -1
  56. package/package.json +1 -1
  57. package/src/form/form-editor/__stubs__/preview.js +6 -14
  58. package/src/form/form-editor/macros/types.ts +12 -1
  59. package/src/form/form-editor/preview/autocomplete.js +1 -0
  60. package/src/form/form-editor/preview/component-elements.js +2 -10
  61. package/src/form/form-editor/preview/content.js +2 -3
  62. package/src/form/form-editor/preview/controller/page-controller.js +109 -10
  63. package/src/form/form-editor/preview/helpers.js +16 -12
  64. package/src/form/form-editor/preview/list.js +73 -17
  65. package/src/form/form-editor/preview/preview.js +3 -11
  66. package/src/form/form-editor/preview/question.js +2 -2
  67. package/src/form/form-editor/preview/select-sortable.js +5 -1
  68. package/src/form/form-editor/preview/select.js +38 -0
  69. package/src/form/form-editor/preview/types.ts +23 -4
  70. package/src/stubs.ts +3 -0
@@ -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'
@@ -5,7 +5,10 @@ import { ComponentElements } from '~/src/form/form-editor/preview/component-elem
5
5
  import { ContentElements } from '~/src/form/form-editor/preview/content.js'
6
6
  import { DateInputQuestion } from '~/src/form/form-editor/preview/date-input.js'
7
7
  import { EmailAddressQuestion } from '~/src/form/form-editor/preview/email-address.js'
8
- import { ListQuestion } from '~/src/form/form-editor/preview/list.js'
8
+ import {
9
+ ListQuestion,
10
+ SelectComponentElements
11
+ } from '~/src/form/form-editor/preview/list.js'
9
12
  import { LongAnswerQuestion } from '~/src/form/form-editor/preview/long-answer.js'
10
13
  import { Markdown } from '~/src/form/form-editor/preview/markdown.js'
11
14
  import { MonthYearQuestion } from '~/src/form/form-editor/preview/month-year.js'
@@ -55,14 +58,9 @@ const InputFieldComponentDictionary = {
55
58
  /**
56
59
  * @param {QuestionRenderer} questionRenderer
57
60
  * @param {FormDefinition} definition
58
- * @param {boolean} hasTitle
59
61
  * @returns {(component: ComponentDef) => Question}
60
62
  */
61
- export function mapComponentToPreviewQuestion(
62
- questionRenderer,
63
- definition,
64
- hasTitle
65
- ) {
63
+ export function mapComponentToPreviewQuestion(questionRenderer, definition) {
66
64
  return /** @type {(component: ComponentDef) => Question} */ (
67
65
  (component) => {
68
66
  /**
@@ -70,18 +68,24 @@ export function mapComponentToPreviewQuestion(
70
68
  */
71
69
  let questionElements
72
70
 
73
- if (hasSelectionFields(component) && hasListField(component)) {
71
+ if (
72
+ component.type === ComponentType.AutocompleteField ||
73
+ component.type === ComponentType.SelectField
74
+ ) {
75
+ const list = findDefinitionListFromComponent(component, definition)
76
+ questionElements = new SelectComponentElements(component, list)
77
+ } else if (hasSelectionFields(component) && hasListField(component)) {
74
78
  const list = findDefinitionListFromComponent(component, definition)
75
- questionElements = new ListComponentElements(component, list, !hasTitle)
79
+ questionElements = new ListComponentElements(component, list)
76
80
  } else if (
77
81
  hasInputField(component) ||
78
82
  component.type === ComponentType.YesNoField
79
83
  ) {
80
- questionElements = new QuestionComponentElements(component, !hasTitle)
84
+ questionElements = new QuestionComponentElements(component)
81
85
  } else if (hasContentField(component)) {
82
- questionElements = new ContentElements(component, !hasTitle)
86
+ questionElements = new ContentElements(component)
83
87
  } else {
84
- questionElements = new ComponentElements(component, !hasTitle)
88
+ questionElements = new ComponentElements(component)
85
89
  }
86
90
 
87
91
  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
 
@@ -80,6 +79,31 @@ export class ListComponentElements extends QuestionComponentElements {
80
79
  }
81
80
  }
82
81
 
82
+ /**
83
+ * @implements {QuestionElements}
84
+ */
85
+ export class SelectComponentElements extends ListComponentElements {
86
+ /**
87
+ * @returns {BaseSettings}
88
+ * @protected
89
+ */
90
+ _getValues() {
91
+ const emptyItem = /** @type {ListElement} */ ({
92
+ id: 'da310b6e-2513-4d14-a7a1-63a93231891d',
93
+ text: '',
94
+ value: ''
95
+ })
96
+ const items = /** @type {ListElement[]} */ ([
97
+ emptyItem,
98
+ ...super._getValues().items
99
+ ])
100
+ return {
101
+ ...super._getValues(),
102
+ items
103
+ }
104
+ }
105
+ }
106
+
83
107
  export class ListQuestion extends Question {
84
108
  /**
85
109
  * @type {ComponentType}
@@ -114,8 +138,9 @@ export class ListQuestion extends Question {
114
138
  }
115
139
 
116
140
  /**
141
+ * @protected
117
142
  * @returns {{
118
- * formGroup?: {afterInputs: {html: string}};
143
+ * formGroup?: FormGroupAfterInput;
119
144
  * hint: DefaultComponent;
120
145
  * name: string;
121
146
  * fieldset?: GovukFieldset;
@@ -123,19 +148,18 @@ export class ListQuestion extends Question {
123
148
  * items: ListItemReadonly[]
124
149
  * }}
125
150
  */
126
- get renderInput() {
127
- const afterInputs =
128
- /** @type {{ formGroup?: { afterInputs: { html: string } } }} */ (
129
- this.list.length
130
- ? {}
131
- : {
132
- formGroup: {
133
- afterInputs: {
134
- html: this._listElements.afterInputsHTML
135
- }
151
+ _renderInput() {
152
+ const afterInputs = /** @type {{ formGroup?: FormGroupAfterInput }} */ (
153
+ this.list.length
154
+ ? {}
155
+ : {
156
+ formGroup: {
157
+ afterInputs: {
158
+ html: this._listElements.afterInputsHTML
136
159
  }
137
160
  }
138
- )
161
+ }
162
+ )
139
163
 
140
164
  return {
141
165
  id: this.listRenderId,
@@ -147,6 +171,20 @@ export class ListQuestion extends Question {
147
171
  }
148
172
  }
149
173
 
174
+ /**
175
+ * @returns {{
176
+ * formGroup?: FormGroupAfterInput;
177
+ * hint: DefaultComponent;
178
+ * name: string;
179
+ * fieldset?: GovukFieldset;
180
+ * id: string;
181
+ * items: ListItemReadonly[]
182
+ * }}
183
+ */
184
+ get renderInput() {
185
+ return this._renderInput()
186
+ }
187
+
150
188
  /**
151
189
  *
152
190
  * @param {ListElement} listElement
@@ -174,9 +212,10 @@ export class ListQuestion extends Question {
174
212
  }
175
213
 
176
214
  /**
215
+ * @protected
177
216
  * @returns {ListItemReadonly[]}
178
217
  */
179
- get list() {
218
+ _getList() {
180
219
  const iterator = /** @type {MapIterator<ListElement>} */ (
181
220
  this._list.values()
182
221
  )
@@ -195,7 +234,7 @@ export class ListQuestion extends Question {
195
234
  : undefined
196
235
  }
197
236
 
198
- const text = listItem.text.length ? listItem.text : 'Item text'
237
+ const text = listItem.text
199
238
 
200
239
  return {
201
240
  ...listItem,
@@ -209,6 +248,22 @@ export class ListQuestion extends Question {
209
248
  })
210
249
  }
211
250
 
251
+ /**
252
+ * @returns {ListItemReadonly[]}
253
+ */
254
+ get list() {
255
+ const list = this._getList()
256
+
257
+ return list.map((listItem) => {
258
+ const text = listItem.text.length ? listItem.text : 'Item text'
259
+
260
+ return {
261
+ ...listItem,
262
+ text
263
+ }
264
+ })
265
+ }
266
+
212
267
  /**
213
268
  *
214
269
  * @param {string | undefined} id
@@ -267,5 +322,6 @@ export class ListQuestion extends Question {
267
322
  * @import { ListElement, ListItemReadonly } from '~/src/form/form-editor/types.js'
268
323
  * @import { SelectionComponentsDef, ListComponentsDef } from '~/src/components/types.js'
269
324
  * @import { List, Item } from '~/src/form/form-definition/types.js'
325
+ * @import { FormGroupAfterInput } from '~/src/form/form-editor/macros/types.js'
270
326
  * @import { ListElements, QuestionRenderer, DefaultComponent, GovukFieldset, BaseSettings, QuestionElements } from '~/src/form/form-editor/preview/types.js'
271
327
  */
@@ -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
 
@@ -18,7 +18,7 @@ export class SelectSortableQuestion extends ListSortableQuestion {
18
18
 
19
19
  get renderInput() {
20
20
  const afterInput =
21
- /** @type {{ formGroup?: { afterInputs: { html: string } } }} */ (
21
+ /** @type {{ formGroup?: { afterInput: { html: string }} }} */ (
22
22
  this.list.length
23
23
  ? {}
24
24
  : {
@@ -41,3 +41,7 @@ export class SelectSortableQuestion extends ListSortableQuestion {
41
41
  }
42
42
  }
43
43
  }
44
+
45
+ /**
46
+ * @import { FormGroupAfterInput } from '~/src/form/form-editor/macros/types.js'
47
+ */
@@ -4,8 +4,46 @@ import { PreviewComponent } from '~/src/form/form-editor/preview/preview.js'
4
4
 
5
5
  export class SelectQuestion extends ListQuestion {
6
6
  _questionTemplate = PreviewComponent.PATH + 'selectfield.njk'
7
+ _fieldName = 'selectInput'
7
8
  /**
8
9
  * @type {ComponentType}
9
10
  */
10
11
  componentType = ComponentType.SelectField
12
+
13
+ /**
14
+ * @returns {ListItemReadonly[]}
15
+ */
16
+ get list() {
17
+ return this._getList()
18
+ }
19
+
20
+ get renderInput() {
21
+ const afterInput =
22
+ /** @type {{ formGroup?: { afterInput: { html: string }} }} */ (
23
+ this.list.length
24
+ ? {}
25
+ : {
26
+ formGroup: {
27
+ afterInput: {
28
+ html: this._listElements.afterInputsHTML
29
+ }
30
+ }
31
+ }
32
+ )
33
+
34
+ return {
35
+ id: this._fieldName,
36
+ name: this._fieldName,
37
+ hint: this.hint,
38
+ label: this.label,
39
+ items: this.list,
40
+ classes: this.list.length ? '' : 'govuk-visually-hidden',
41
+ ...afterInput
42
+ }
43
+ }
11
44
  }
45
+
46
+ /**
47
+ * @import { ListItemReadonly } from '~/src/form/form-editor/types.js'
48
+ * @import { FormGroupAfterInput } from '~/src/form/form-editor/macros/types.js'
49
+ */
@@ -16,13 +16,13 @@ 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
23
22
  shortDesc: string
24
23
  items: ListElement[]
25
24
  content: string
25
+ attributes?: Record<string, string>
26
26
  }
27
27
 
28
28
  export interface DefaultComponent {
@@ -41,19 +41,35 @@ export type ListenerRow = [
41
41
  keyof HTMLElementEventMap
42
42
  ]
43
43
 
44
- export interface QuestionElements {
45
- readonly values: BaseSettings
44
+ export interface DomElementsBase {
45
+ readonly values?: BaseSettings
46
+ autocompleteOptions?: string
46
47
  setPreviewHTML(value: string): void
47
48
  setPreviewDOM(element: HTMLElement): void
48
49
  }
50
+
51
+ export interface QuestionElements extends DomElementsBase {
52
+ readonly values: BaseSettings
53
+ }
54
+
49
55
  export interface AutocompleteElements extends QuestionElements {
50
56
  autocompleteOptions: string
51
57
  }
52
58
 
53
- export interface RenderContext {
59
+ export interface RenderBase {
60
+ render(questionTemplate: string, renderContext: RenderContext): void
61
+ }
62
+
63
+ export interface QuestionRenderContext {
54
64
  model: QuestionBaseModel
55
65
  }
56
66
 
67
+ export interface PageRenderContext {
68
+ params: PagePreviewPanelMacro
69
+ }
70
+
71
+ export type RenderContext = QuestionRenderContext | PageRenderContext
72
+
57
73
  export interface HTMLBuilder {
58
74
  buildHTML(questionTemplate: string, renderContext: RenderContext): string
59
75
  }
@@ -66,6 +82,8 @@ export interface PageRenderer {
66
82
  render(pageTemplate: string, pagePreview: PagePreviewPanelMacro): void
67
83
  }
68
84
 
85
+ export type Renderer = QuestionRenderer | PageRenderer
86
+
69
87
  export interface ListElements extends QuestionElements {
70
88
  afterInputsHTML: string
71
89
  }
@@ -73,6 +91,7 @@ export interface ListElements extends QuestionElements {
73
91
  export interface PageOverviewElements {
74
92
  heading: string
75
93
  guidance: string
94
+ addHeading: boolean
76
95
  }
77
96
 
78
97
  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'