@defra/forms-engine-plugin 4.15.0 → 4.16.0

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.
@@ -54,3 +54,22 @@
54
54
  @extend %govuk-section-break--xl;
55
55
  }
56
56
  }
57
+
58
+ .govuk-notification-banner__content {
59
+ .app-prose-scope > :last-child {
60
+ margin-bottom: 0;
61
+ }
62
+ }
63
+
64
+ // GOV.UK Frontend does not expose placeholder selectors for these — class selectors are the only option.
65
+ .app-prose-notification-banner-scope {
66
+ p {
67
+ // stylelint-disable-next-line scss/at-extend-no-missing-placeholder
68
+ @extend .govuk-notification-banner__heading;
69
+ }
70
+
71
+ a {
72
+ // stylelint-disable-next-line scss/at-extend-no-missing-placeholder
73
+ @extend .govuk-notification-banner__link;
74
+ }
75
+ }
@@ -78,6 +78,25 @@ pages:
78
78
  id: '00738799-3489-4ab2-a57b-542eecb31bfa'
79
79
  next: []
80
80
  id: da0fbdb4-a2de-4650-be16-9ba552af135f
81
+ - title: ''
82
+ path: '/notification-demo'
83
+ components:
84
+ - type: NotificationBanner
85
+ title: Important
86
+ name: notificationImportant
87
+ content: 'Contact us if you need [help with your application](https://www.defra.gov.uk).'
88
+ options:
89
+ heading: There may be a delay in processing your application.
90
+ id: ca6b6590-1608-49f4-82f9-9d92e38e66ea
91
+ - type: NotificationBanner
92
+ title: Success
93
+ name: notificationSuccess
94
+ content: 'Your application has been submitted.'
95
+ options:
96
+ type: success
97
+ id: b6960f4b-d771-4956-9c9b-17da5c603062
98
+ next: []
99
+ id: be4b4b86-514c-43bb-8cdc-f9aed6155924
81
100
  - id: 449a45f6-4541-4a46-91bd-8b8931b07b50
82
101
  title: ''
83
102
  path: '/summary'
@@ -0,0 +1,56 @@
1
+ import { type NotificationBannerComponent } from '@defra/forms-model';
2
+ import { ComponentBase } from '../../../../server/plugins/engine/components/ComponentBase.js';
3
+ export declare class NotificationBanner extends ComponentBase {
4
+ options: NotificationBannerComponent['options'];
5
+ content: NotificationBannerComponent['content'];
6
+ constructor(def: NotificationBannerComponent, props: ConstructorParameters<typeof ComponentBase>[1]);
7
+ getViewModel(): {
8
+ titleHtml: string;
9
+ content: string;
10
+ heading: string | undefined;
11
+ type: "success" | undefined;
12
+ label?: import("./types.js").Label;
13
+ id?: string;
14
+ name?: string;
15
+ value?: import("../types.js").FormValue;
16
+ hint?: {
17
+ id?: string;
18
+ text: string;
19
+ };
20
+ prefix?: import("./types.js").ComponentText;
21
+ suffix?: import("./types.js").ComponentText;
22
+ classes?: string;
23
+ condition?: string;
24
+ errors?: import("../types.js").FormSubmissionError[];
25
+ errorMessage?: {
26
+ text: string;
27
+ };
28
+ summaryHtml?: string;
29
+ html?: string;
30
+ attributes: {
31
+ autocomplete?: string;
32
+ maxlength?: number;
33
+ multiple?: string;
34
+ accept?: string;
35
+ inputmode?: string;
36
+ };
37
+ maxlength?: number;
38
+ maxwords?: number;
39
+ rows?: number;
40
+ items?: import("./types.js").ListItem[] | import("./types.js").DateInputItem[];
41
+ fieldset?: {
42
+ attributes?: string | Record<string, string>;
43
+ legend?: import("./types.js").Label;
44
+ };
45
+ formGroup?: {
46
+ classes?: string;
47
+ attributes?: string | Record<string, string>;
48
+ };
49
+ showFieldsetError?: boolean;
50
+ components?: import("./types.js").ComponentViewModel[];
51
+ upload?: {
52
+ count: number;
53
+ summaryList: import("../types.js").SummaryList;
54
+ };
55
+ };
56
+ }
@@ -0,0 +1,28 @@
1
+ import { ComponentBase } from "./ComponentBase.js";
2
+ export class NotificationBanner extends ComponentBase {
3
+ content;
4
+ constructor(def, props) {
5
+ super(def, props);
6
+ const {
7
+ content,
8
+ options
9
+ } = def;
10
+ this.content = content;
11
+ this.options = options;
12
+ }
13
+ getViewModel() {
14
+ const {
15
+ content,
16
+ title,
17
+ viewModel
18
+ } = this;
19
+ return {
20
+ ...viewModel,
21
+ titleHtml: title,
22
+ content,
23
+ heading: this.options.heading,
24
+ type: this.options.type
25
+ };
26
+ }
27
+ }
28
+ //# sourceMappingURL=NotificationBanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationBanner.js","names":["ComponentBase","NotificationBanner","content","constructor","def","props","options","getViewModel","title","viewModel","titleHtml","heading","type"],"sources":["../../../../../src/server/plugins/engine/components/NotificationBanner.ts"],"sourcesContent":["import { type NotificationBannerComponent } from '@defra/forms-model'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\n\nexport class NotificationBanner extends ComponentBase {\n declare options: NotificationBannerComponent['options']\n content: NotificationBannerComponent['content']\n\n constructor(\n def: NotificationBannerComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { content, options } = def\n\n this.content = content\n this.options = options\n }\n\n getViewModel() {\n const { content, title, viewModel } = this\n\n return {\n ...viewModel,\n titleHtml: title,\n content,\n heading: this.options.heading,\n type: this.options.type\n }\n }\n}\n"],"mappings":"AAEA,SAASA,aAAa;AAEtB,OAAO,MAAMC,kBAAkB,SAASD,aAAa,CAAC;EAEpDE,OAAO;EAEPC,WAAWA,CACTC,GAAgC,EAChCC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEH,OAAO;MAAEI;IAAQ,CAAC,GAAGF,GAAG;IAEhC,IAAI,CAACF,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACI,OAAO,GAAGA,OAAO;EACxB;EAEAC,YAAYA,CAAA,EAAG;IACb,MAAM;MAAEL,OAAO;MAAEM,KAAK;MAAEC;IAAU,CAAC,GAAG,IAAI;IAE1C,OAAO;MACL,GAAGA,SAAS;MACZC,SAAS,EAAEF,KAAK;MAChBN,OAAO;MACPS,OAAO,EAAE,IAAI,CAACL,OAAO,CAACK,OAAO;MAC7BC,IAAI,EAAE,IAAI,CAACN,OAAO,CAACM;IACrB,CAAC;EACH;AACF","ignoreList":[]}
@@ -5,7 +5,7 @@ import * as Components from '../../../../../server/plugins/engine/components/ind
5
5
  import { type FormState } from '../../../../../server/plugins/engine/types.js';
6
6
  export type Component = InstanceType<(typeof Components)[keyof typeof Components]>;
7
7
  export type Field = InstanceType<typeof Components.AutocompleteField | typeof Components.RadiosField | typeof Components.YesNoField | typeof Components.CheckboxesField | typeof Components.DatePartsField | typeof Components.DeclarationField | typeof Components.EastingNorthingField | typeof Components.EmailAddressField | typeof Components.LatLongField | typeof Components.MonthYearField | typeof Components.MultilineTextField | typeof Components.NationalGridFieldNumberField | typeof Components.NumberField | typeof Components.OsGridRefField | typeof Components.SelectField | typeof Components.TelephoneNumberField | typeof Components.TextField | typeof Components.UkAddressField | typeof Components.FileUploadField | typeof Components.HiddenField | typeof Components.PaymentField | typeof Components.GeospatialField>;
8
- export type Guidance = InstanceType<typeof Components.Details> | InstanceType<typeof Components.Html> | InstanceType<typeof Components.Markdown> | InstanceType<typeof Components.InsetText> | InstanceType<typeof Components.List>;
8
+ export type Guidance = InstanceType<typeof Components.Details> | InstanceType<typeof Components.Html> | InstanceType<typeof Components.Markdown> | InstanceType<typeof Components.InsetText> | InstanceType<typeof Components.List> | InstanceType<typeof Components.NotificationBanner>;
9
9
  export type ListField = InstanceType<typeof Components.AutocompleteField | typeof Components.CheckboxesField | typeof Components.RadiosField | typeof Components.SelectField | typeof Components.YesNoField>;
10
10
  export declare const designerUrl: string;
11
11
  export { markdown } from '../../../../../server/plugins/engine/components/markdownParser.js';
@@ -65,6 +65,9 @@ export function createComponent(def, options) {
65
65
  case ComponentType.Markdown:
66
66
  component = new Components.Markdown(def, options);
67
67
  break;
68
+ case ComponentType.NotificationBanner:
69
+ component = new Components.NotificationBanner(def, options);
70
+ break;
68
71
  case ComponentType.MultilineTextField:
69
72
  component = new Components.MultilineTextField(def, options);
70
73
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","names":["ComponentType","config","ListFormComponent","escapeMarkdown","Components","markdown","designerUrl","get","hasListFormField","field","type","undefined","isListFieldType","allowedTypes","AutocompleteField","CheckboxesField","RadiosField","SelectField","YesNoField","includes","createComponent","def","options","component","DatePartsField","DeclarationField","Details","EmailAddressField","Html","InsetText","List","Markdown","MultilineTextField","NumberField","TelephoneNumberField","TextField","UkAddressField","MonthYearField","FileUploadField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField","Error","getAnswer","state","format","getAnswerMarkdown","context","getContextValueFromState","toString","parse","async","trim","getDisplayStringFromState","answer","answerEscaped","files","getFormValueFromState","length","map","status","file","form","filename","fileId","join","values","flat","items","filter","value","item","label","text","line","toLowerCase","split","concat","contextValue","features","getDisplayStringFromFormValue"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/components.ts"],"sourcesContent":["import { ComponentType, type ComponentDef } from '@defra/forms-model'\n\nimport { config } from '~/src/config/index.js'\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport * as Components from '~/src/server/plugins/engine/components/index.js'\nimport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\nimport { type FormState } from '~/src/server/plugins/engine/types.js'\n\n// All component instances\nexport type Component = InstanceType<\n (typeof Components)[keyof typeof Components]\n>\n\n// Field component instances only\nexport type Field = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.RadiosField\n | typeof Components.YesNoField\n | typeof Components.CheckboxesField\n | typeof Components.DatePartsField\n | typeof Components.DeclarationField\n | typeof Components.EastingNorthingField\n | typeof Components.EmailAddressField\n | typeof Components.LatLongField\n | typeof Components.MonthYearField\n | typeof Components.MultilineTextField\n | typeof Components.NationalGridFieldNumberField\n | typeof Components.NumberField\n | typeof Components.OsGridRefField\n | typeof Components.SelectField\n | typeof Components.TelephoneNumberField\n | typeof Components.TextField\n | typeof Components.UkAddressField\n | typeof Components.FileUploadField\n | typeof Components.HiddenField\n | typeof Components.PaymentField\n | typeof Components.GeospatialField\n>\n\n// Guidance component instances only\nexport type Guidance =\n | InstanceType<typeof Components.Details>\n | InstanceType<typeof Components.Html>\n | InstanceType<typeof Components.Markdown>\n | InstanceType<typeof Components.InsetText>\n | InstanceType<typeof Components.List>\n\n// List component instances only\nexport type ListField = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.CheckboxesField\n | typeof Components.RadiosField\n | typeof Components.SelectField\n | typeof Components.YesNoField\n>\n\nexport const designerUrl = config.get('designerUrl')\n\n// Re-export markdown from its own module to avoid circular dependencies\nexport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\n\n/**\n * Filter known components with lists\n */\nexport function hasListFormField(\n field?: Partial<Component>\n): field is ListFormComponent {\n return !!field && field.type !== undefined && isListFieldType(field.type)\n}\n\nexport function isListFieldType(\n type?: ComponentType\n): type is ListField['type'] {\n const allowedTypes = [\n ComponentType.AutocompleteField,\n ComponentType.CheckboxesField,\n ComponentType.RadiosField,\n ComponentType.SelectField,\n ComponentType.YesNoField\n ]\n\n return !!type && allowedTypes.includes(type)\n}\n\n/**\n * Create field instance for each {@link ComponentDef} type\n */\nexport function createComponent(\n def: ComponentDef,\n options: ConstructorParameters<typeof ComponentBase>[1]\n): Component {\n let component: Component | undefined\n\n switch (def.type) {\n case ComponentType.AutocompleteField:\n component = new Components.AutocompleteField(def, options)\n break\n\n case ComponentType.CheckboxesField:\n component = new Components.CheckboxesField(def, options)\n break\n\n case ComponentType.DatePartsField:\n component = new Components.DatePartsField(def, options)\n break\n\n case ComponentType.DeclarationField:\n component = new Components.DeclarationField(def, options)\n break\n\n case ComponentType.Details:\n component = new Components.Details(def, options)\n break\n\n case ComponentType.EmailAddressField:\n component = new Components.EmailAddressField(def, options)\n break\n\n case ComponentType.Html:\n component = new Components.Html(def, options)\n break\n\n case ComponentType.InsetText:\n component = new Components.InsetText(def, options)\n break\n\n case ComponentType.List:\n component = new Components.List(def, options)\n break\n\n case ComponentType.Markdown:\n component = new Components.Markdown(def, options)\n break\n\n case ComponentType.MultilineTextField:\n component = new Components.MultilineTextField(def, options)\n break\n\n case ComponentType.NumberField:\n component = new Components.NumberField(def, options)\n break\n\n case ComponentType.RadiosField:\n component = new Components.RadiosField(def, options)\n break\n\n case ComponentType.SelectField:\n component = new Components.SelectField(def, options)\n break\n\n case ComponentType.TelephoneNumberField:\n component = new Components.TelephoneNumberField(def, options)\n break\n\n case ComponentType.TextField:\n component = new Components.TextField(def, options)\n break\n\n case ComponentType.UkAddressField:\n component = new Components.UkAddressField(def, options)\n break\n\n case ComponentType.YesNoField:\n component = new Components.YesNoField(def, options)\n break\n\n case ComponentType.MonthYearField:\n component = new Components.MonthYearField(def, options)\n break\n\n case ComponentType.FileUploadField:\n component = new Components.FileUploadField(def, options)\n break\n\n case ComponentType.EastingNorthingField:\n component = new Components.EastingNorthingField(def, options)\n break\n\n case ComponentType.OsGridRefField:\n component = new Components.OsGridRefField(def, options)\n break\n\n case ComponentType.NationalGridFieldNumberField:\n component = new Components.NationalGridFieldNumberField(def, options)\n break\n\n case ComponentType.LatLongField:\n component = new Components.LatLongField(def, options)\n break\n\n case ComponentType.HiddenField:\n component = new Components.HiddenField(def, options)\n break\n\n case ComponentType.PaymentField:\n component = new Components.PaymentField(def, options)\n break\n\n case ComponentType.GeospatialField:\n component = new Components.GeospatialField(def, options)\n break\n }\n\n if (typeof component === 'undefined') {\n throw new Error(`Component type ${def.type} does not exist`)\n }\n\n return component\n}\n\n/**\n * Get formatted answer for a field\n */\nexport function getAnswer(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'data' // Submission data\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n // Use escaped display text for GOV.UK Notify emails\n if (options.format === 'email') {\n return getAnswerMarkdown(field, state, { format: 'email' })\n }\n\n // Use context value for submission data\n if (options.format === 'data') {\n const context = field.getContextValueFromState(state)\n return context?.toString() ?? ''\n }\n\n // Use display HTML for check answers summary (multi line)\n if (\n field instanceof ListFormComponent ||\n field instanceof Components.MultilineTextField ||\n field instanceof Components.UkAddressField ||\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n return markdown\n .parse(getAnswerMarkdown(field, state), { async: false })\n .trim()\n }\n\n // Use display text for check answers summary (single line)\n return field.getDisplayStringFromState(state)\n}\n\n/**\n * Get formatted answer for a field (Markdown only)\n */\nexport function getAnswerMarkdown(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n const answer = field.getDisplayStringFromState(state)\n\n // Use escaped display text\n let answerEscaped = `${escapeMarkdown(answer)}\\n`\n\n if (field instanceof Components.FileUploadField) {\n const files = field.getFormValueFromState(state)\n\n // Skip empty files\n if (!files?.length) {\n return answerEscaped\n }\n\n answerEscaped = `${escapeMarkdown(answer)}:\\n\\n`\n\n // Append bullet points\n answerEscaped += files\n .map(({ status }) => {\n const { file } = status.form\n const filename = escapeMarkdown(file.filename)\n return `* [${filename}](${designerUrl}/file-download/${file.fileId})\\n`\n })\n .join('')\n } else if (field instanceof ListFormComponent) {\n const values = [field.getContextValueFromState(state)].flat()\n const items = field.items.filter(({ value }) => values.includes(value))\n\n // Skip empty values\n if (!items.length) {\n return answerEscaped\n }\n\n answerEscaped = ''\n\n // Append bullet points\n answerEscaped += items\n .map((item) => {\n const label = escapeMarkdown(item.text)\n const value = escapeMarkdown(`(${item.value})`)\n\n let line = label\n\n // Prepend bullet points for checkboxes only\n if (field instanceof Components.CheckboxesField) {\n line = `* ${line}`\n }\n\n // Append raw values in parentheses\n // e.g. `* None of the above (false)`\n return options.format === 'email' &&\n `${item.value}`.toLowerCase() !== item.text.toLowerCase()\n ? `${line} ${value}\\n`\n : `${line}\\n`\n })\n .join('')\n } else if (field instanceof Components.MultilineTextField) {\n // Preserve Multiline text new lines\n answerEscaped = answer\n .split(/(?:\\r?\\n)+/)\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (field instanceof Components.UkAddressField) {\n // Format UK addresses into new lines\n answerEscaped = (field.getContextValueFromState(state) ?? [])\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n const contextValue = field.getContextValueFromState(state)\n answerEscaped = contextValue ? `${contextValue}\\n` : ''\n } else if (field instanceof Components.GeospatialField) {\n const features = field.getFormValueFromState(state)\n const value = field.getDisplayStringFromFormValue(features)\n\n answerEscaped = value ? `${value}\\n` : ''\n }\n\n return answerEscaped\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"components.js","names":["ComponentType","config","ListFormComponent","escapeMarkdown","Components","markdown","designerUrl","get","hasListFormField","field","type","undefined","isListFieldType","allowedTypes","AutocompleteField","CheckboxesField","RadiosField","SelectField","YesNoField","includes","createComponent","def","options","component","DatePartsField","DeclarationField","Details","EmailAddressField","Html","InsetText","List","Markdown","NotificationBanner","MultilineTextField","NumberField","TelephoneNumberField","TextField","UkAddressField","MonthYearField","FileUploadField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField","Error","getAnswer","state","format","getAnswerMarkdown","context","getContextValueFromState","toString","parse","async","trim","getDisplayStringFromState","answer","answerEscaped","files","getFormValueFromState","length","map","status","file","form","filename","fileId","join","values","flat","items","filter","value","item","label","text","line","toLowerCase","split","concat","contextValue","features","getDisplayStringFromFormValue"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/components.ts"],"sourcesContent":["import { ComponentType, type ComponentDef } from '@defra/forms-model'\n\nimport { config } from '~/src/config/index.js'\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport * as Components from '~/src/server/plugins/engine/components/index.js'\nimport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\nimport { type FormState } from '~/src/server/plugins/engine/types.js'\n\n// All component instances\nexport type Component = InstanceType<\n (typeof Components)[keyof typeof Components]\n>\n\n// Field component instances only\nexport type Field = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.RadiosField\n | typeof Components.YesNoField\n | typeof Components.CheckboxesField\n | typeof Components.DatePartsField\n | typeof Components.DeclarationField\n | typeof Components.EastingNorthingField\n | typeof Components.EmailAddressField\n | typeof Components.LatLongField\n | typeof Components.MonthYearField\n | typeof Components.MultilineTextField\n | typeof Components.NationalGridFieldNumberField\n | typeof Components.NumberField\n | typeof Components.OsGridRefField\n | typeof Components.SelectField\n | typeof Components.TelephoneNumberField\n | typeof Components.TextField\n | typeof Components.UkAddressField\n | typeof Components.FileUploadField\n | typeof Components.HiddenField\n | typeof Components.PaymentField\n | typeof Components.GeospatialField\n>\n\n// Guidance component instances only\nexport type Guidance =\n | InstanceType<typeof Components.Details>\n | InstanceType<typeof Components.Html>\n | InstanceType<typeof Components.Markdown>\n | InstanceType<typeof Components.InsetText>\n | InstanceType<typeof Components.List>\n | InstanceType<typeof Components.NotificationBanner>\n\n// List component instances only\nexport type ListField = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.CheckboxesField\n | typeof Components.RadiosField\n | typeof Components.SelectField\n | typeof Components.YesNoField\n>\n\nexport const designerUrl = config.get('designerUrl')\n\n// Re-export markdown from its own module to avoid circular dependencies\nexport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\n\n/**\n * Filter known components with lists\n */\nexport function hasListFormField(\n field?: Partial<Component>\n): field is ListFormComponent {\n return !!field && field.type !== undefined && isListFieldType(field.type)\n}\n\nexport function isListFieldType(\n type?: ComponentType\n): type is ListField['type'] {\n const allowedTypes = [\n ComponentType.AutocompleteField,\n ComponentType.CheckboxesField,\n ComponentType.RadiosField,\n ComponentType.SelectField,\n ComponentType.YesNoField\n ]\n\n return !!type && allowedTypes.includes(type)\n}\n\n/**\n * Create field instance for each {@link ComponentDef} type\n */\nexport function createComponent(\n def: ComponentDef,\n options: ConstructorParameters<typeof ComponentBase>[1]\n): Component {\n let component: Component | undefined\n\n switch (def.type) {\n case ComponentType.AutocompleteField:\n component = new Components.AutocompleteField(def, options)\n break\n\n case ComponentType.CheckboxesField:\n component = new Components.CheckboxesField(def, options)\n break\n\n case ComponentType.DatePartsField:\n component = new Components.DatePartsField(def, options)\n break\n\n case ComponentType.DeclarationField:\n component = new Components.DeclarationField(def, options)\n break\n\n case ComponentType.Details:\n component = new Components.Details(def, options)\n break\n\n case ComponentType.EmailAddressField:\n component = new Components.EmailAddressField(def, options)\n break\n\n case ComponentType.Html:\n component = new Components.Html(def, options)\n break\n\n case ComponentType.InsetText:\n component = new Components.InsetText(def, options)\n break\n\n case ComponentType.List:\n component = new Components.List(def, options)\n break\n\n case ComponentType.Markdown:\n component = new Components.Markdown(def, options)\n break\n\n case ComponentType.NotificationBanner:\n component = new Components.NotificationBanner(def, options)\n break\n\n case ComponentType.MultilineTextField:\n component = new Components.MultilineTextField(def, options)\n break\n\n case ComponentType.NumberField:\n component = new Components.NumberField(def, options)\n break\n\n case ComponentType.RadiosField:\n component = new Components.RadiosField(def, options)\n break\n\n case ComponentType.SelectField:\n component = new Components.SelectField(def, options)\n break\n\n case ComponentType.TelephoneNumberField:\n component = new Components.TelephoneNumberField(def, options)\n break\n\n case ComponentType.TextField:\n component = new Components.TextField(def, options)\n break\n\n case ComponentType.UkAddressField:\n component = new Components.UkAddressField(def, options)\n break\n\n case ComponentType.YesNoField:\n component = new Components.YesNoField(def, options)\n break\n\n case ComponentType.MonthYearField:\n component = new Components.MonthYearField(def, options)\n break\n\n case ComponentType.FileUploadField:\n component = new Components.FileUploadField(def, options)\n break\n\n case ComponentType.EastingNorthingField:\n component = new Components.EastingNorthingField(def, options)\n break\n\n case ComponentType.OsGridRefField:\n component = new Components.OsGridRefField(def, options)\n break\n\n case ComponentType.NationalGridFieldNumberField:\n component = new Components.NationalGridFieldNumberField(def, options)\n break\n\n case ComponentType.LatLongField:\n component = new Components.LatLongField(def, options)\n break\n\n case ComponentType.HiddenField:\n component = new Components.HiddenField(def, options)\n break\n\n case ComponentType.PaymentField:\n component = new Components.PaymentField(def, options)\n break\n\n case ComponentType.GeospatialField:\n component = new Components.GeospatialField(def, options)\n break\n }\n\n if (typeof component === 'undefined') {\n throw new Error(`Component type ${def.type} does not exist`)\n }\n\n return component\n}\n\n/**\n * Get formatted answer for a field\n */\nexport function getAnswer(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'data' // Submission data\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n // Use escaped display text for GOV.UK Notify emails\n if (options.format === 'email') {\n return getAnswerMarkdown(field, state, { format: 'email' })\n }\n\n // Use context value for submission data\n if (options.format === 'data') {\n const context = field.getContextValueFromState(state)\n return context?.toString() ?? ''\n }\n\n // Use display HTML for check answers summary (multi line)\n if (\n field instanceof ListFormComponent ||\n field instanceof Components.MultilineTextField ||\n field instanceof Components.UkAddressField ||\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n return markdown\n .parse(getAnswerMarkdown(field, state), { async: false })\n .trim()\n }\n\n // Use display text for check answers summary (single line)\n return field.getDisplayStringFromState(state)\n}\n\n/**\n * Get formatted answer for a field (Markdown only)\n */\nexport function getAnswerMarkdown(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n const answer = field.getDisplayStringFromState(state)\n\n // Use escaped display text\n let answerEscaped = `${escapeMarkdown(answer)}\\n`\n\n if (field instanceof Components.FileUploadField) {\n const files = field.getFormValueFromState(state)\n\n // Skip empty files\n if (!files?.length) {\n return answerEscaped\n }\n\n answerEscaped = `${escapeMarkdown(answer)}:\\n\\n`\n\n // Append bullet points\n answerEscaped += files\n .map(({ status }) => {\n const { file } = status.form\n const filename = escapeMarkdown(file.filename)\n return `* [${filename}](${designerUrl}/file-download/${file.fileId})\\n`\n })\n .join('')\n } else if (field instanceof ListFormComponent) {\n const values = [field.getContextValueFromState(state)].flat()\n const items = field.items.filter(({ value }) => values.includes(value))\n\n // Skip empty values\n if (!items.length) {\n return answerEscaped\n }\n\n answerEscaped = ''\n\n // Append bullet points\n answerEscaped += items\n .map((item) => {\n const label = escapeMarkdown(item.text)\n const value = escapeMarkdown(`(${item.value})`)\n\n let line = label\n\n // Prepend bullet points for checkboxes only\n if (field instanceof Components.CheckboxesField) {\n line = `* ${line}`\n }\n\n // Append raw values in parentheses\n // e.g. `* None of the above (false)`\n return options.format === 'email' &&\n `${item.value}`.toLowerCase() !== item.text.toLowerCase()\n ? `${line} ${value}\\n`\n : `${line}\\n`\n })\n .join('')\n } else if (field instanceof Components.MultilineTextField) {\n // Preserve Multiline text new lines\n answerEscaped = answer\n .split(/(?:\\r?\\n)+/)\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (field instanceof Components.UkAddressField) {\n // Format UK addresses into new lines\n answerEscaped = (field.getContextValueFromState(state) ?? [])\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n const contextValue = field.getContextValueFromState(state)\n answerEscaped = contextValue ? `${contextValue}\\n` : ''\n } else if (field instanceof Components.GeospatialField) {\n const features = field.getFormValueFromState(state)\n const value = field.getDisplayStringFromFormValue(features)\n\n answerEscaped = value ? `${value}\\n` : ''\n }\n\n return answerEscaped\n}\n"],"mappings":"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","ignoreList":[]}
@@ -14,6 +14,7 @@ export { Html } from '../../../../server/plugins/engine/components/Html.js';
14
14
  export { InsetText } from '../../../../server/plugins/engine/components/InsetText.js';
15
15
  export { List } from '../../../../server/plugins/engine/components/List.js';
16
16
  export { Markdown } from '../../../../server/plugins/engine/components/Markdown.js';
17
+ export { NotificationBanner } from '../../../../server/plugins/engine/components/NotificationBanner.js';
17
18
  export { MonthYearField } from '../../../../server/plugins/engine/components/MonthYearField.js';
18
19
  export { MultilineTextField } from '../../../../server/plugins/engine/components/MultilineTextField.js';
19
20
  export { NumberField } from '../../../../server/plugins/engine/components/NumberField.js';
@@ -15,6 +15,7 @@ export { Html } from "./Html.js";
15
15
  export { InsetText } from "./InsetText.js";
16
16
  export { List } from "./List.js";
17
17
  export { Markdown } from "./Markdown.js";
18
+ export { NotificationBanner } from "./NotificationBanner.js";
18
19
  export { MonthYearField } from "./MonthYearField.js";
19
20
  export { MultilineTextField } from "./MultilineTextField.js";
20
21
  export { NumberField } from "./NumberField.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","DeclarationField","Details","EmailAddressField","FileUploadField","Html","InsetText","List","Markdown","MonthYearField","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField"],"sources":["../../../../../src/server/plugins/engine/components/index.ts"],"sourcesContent":["/**\n * IMPORTANT: Exported Components must follow the naming convention implemented in {@link @defra/forms-model#ComponentType}\n * In the Form JSON, components have a type property which is the name of the components, e.g. DatePartsField.\n * Components are loaded in the ComponentsCollection constructor.\n */\n\nexport { AutocompleteField } from '~/src/server/plugins/engine/components/AutocompleteField.js'\nexport { CheckboxesField } from '~/src/server/plugins/engine/components/CheckboxesField.js'\nexport { DatePartsField } from '~/src/server/plugins/engine/components/DatePartsField.js'\nexport { DeclarationField } from '~/src/server/plugins/engine/components/DeclarationField.js'\nexport { Details } from '~/src/server/plugins/engine/components/Details.js'\nexport { EmailAddressField } from '~/src/server/plugins/engine/components/EmailAddressField.js'\nexport { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'\nexport { Html } from '~/src/server/plugins/engine/components/Html.js'\nexport { InsetText } from '~/src/server/plugins/engine/components/InsetText.js'\nexport { List } from '~/src/server/plugins/engine/components/List.js'\nexport { Markdown } from '~/src/server/plugins/engine/components/Markdown.js'\nexport { MonthYearField } from '~/src/server/plugins/engine/components/MonthYearField.js'\nexport { MultilineTextField } from '~/src/server/plugins/engine/components/MultilineTextField.js'\nexport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nexport { RadiosField } from '~/src/server/plugins/engine/components/RadiosField.js'\nexport { SelectField } from '~/src/server/plugins/engine/components/SelectField.js'\nexport { TelephoneNumberField } from '~/src/server/plugins/engine/components/TelephoneNumberField.js'\nexport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nexport { UkAddressField } from '~/src/server/plugins/engine/components/UkAddressField.js'\nexport { YesNoField } from '~/src/server/plugins/engine/components/YesNoField.js'\nexport { EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js'\nexport { OsGridRefField } from '~/src/server/plugins/engine/components/OsGridRefField.js'\nexport { NationalGridFieldNumberField } from '~/src/server/plugins/engine/components/NationalGridFieldNumberField.js'\nexport { LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\nexport { HiddenField } from '~/src/server/plugins/engine/components/HiddenField.js'\nexport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nexport { GeospatialField } from '~/src/server/plugins/engine/components/GeospatialField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,gBAAgB;AACzB,SAASC,OAAO;AAChB,SAASC,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,IAAI;AACb,SAASC,SAAS;AAClB,SAASC,IAAI;AACb,SAASC,QAAQ;AACjB,SAASC,cAAc;AACvB,SAASC,kBAAkB;AAC3B,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,oBAAoB;AAC7B,SAASC,SAAS;AAClB,SAASC,cAAc;AACvB,SAASC,UAAU;AACnB,SAASC,oBAAoB;AAC7B,SAASC,cAAc;AACvB,SAASC,4BAA4B;AACrC,SAASC,YAAY;AACrB,SAASC,WAAW;AACpB,SAASC,YAAY;AACrB,SAASC,eAAe","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","DeclarationField","Details","EmailAddressField","FileUploadField","Html","InsetText","List","Markdown","NotificationBanner","MonthYearField","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField"],"sources":["../../../../../src/server/plugins/engine/components/index.ts"],"sourcesContent":["/**\n * IMPORTANT: Exported Components must follow the naming convention implemented in {@link @defra/forms-model#ComponentType}\n * In the Form JSON, components have a type property which is the name of the components, e.g. DatePartsField.\n * Components are loaded in the ComponentsCollection constructor.\n */\n\nexport { AutocompleteField } from '~/src/server/plugins/engine/components/AutocompleteField.js'\nexport { CheckboxesField } from '~/src/server/plugins/engine/components/CheckboxesField.js'\nexport { DatePartsField } from '~/src/server/plugins/engine/components/DatePartsField.js'\nexport { DeclarationField } from '~/src/server/plugins/engine/components/DeclarationField.js'\nexport { Details } from '~/src/server/plugins/engine/components/Details.js'\nexport { EmailAddressField } from '~/src/server/plugins/engine/components/EmailAddressField.js'\nexport { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'\nexport { Html } from '~/src/server/plugins/engine/components/Html.js'\nexport { InsetText } from '~/src/server/plugins/engine/components/InsetText.js'\nexport { List } from '~/src/server/plugins/engine/components/List.js'\nexport { Markdown } from '~/src/server/plugins/engine/components/Markdown.js'\nexport { NotificationBanner } from '~/src/server/plugins/engine/components/NotificationBanner.js'\nexport { MonthYearField } from '~/src/server/plugins/engine/components/MonthYearField.js'\nexport { MultilineTextField } from '~/src/server/plugins/engine/components/MultilineTextField.js'\nexport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nexport { RadiosField } from '~/src/server/plugins/engine/components/RadiosField.js'\nexport { SelectField } from '~/src/server/plugins/engine/components/SelectField.js'\nexport { TelephoneNumberField } from '~/src/server/plugins/engine/components/TelephoneNumberField.js'\nexport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nexport { UkAddressField } from '~/src/server/plugins/engine/components/UkAddressField.js'\nexport { YesNoField } from '~/src/server/plugins/engine/components/YesNoField.js'\nexport { EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js'\nexport { OsGridRefField } from '~/src/server/plugins/engine/components/OsGridRefField.js'\nexport { NationalGridFieldNumberField } from '~/src/server/plugins/engine/components/NationalGridFieldNumberField.js'\nexport { LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\nexport { HiddenField } from '~/src/server/plugins/engine/components/HiddenField.js'\nexport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nexport { GeospatialField } from '~/src/server/plugins/engine/components/GeospatialField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,gBAAgB;AACzB,SAASC,OAAO;AAChB,SAASC,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,IAAI;AACb,SAASC,SAAS;AAClB,SAASC,IAAI;AACb,SAASC,QAAQ;AACjB,SAASC,kBAAkB;AAC3B,SAASC,cAAc;AACvB,SAASC,kBAAkB;AAC3B,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,oBAAoB;AAC7B,SAASC,SAAS;AAClB,SAASC,cAAc;AACvB,SAASC,UAAU;AACnB,SAASC,oBAAoB;AAC7B,SAASC,cAAc;AACvB,SAASC,4BAA4B;AACrC,SAASC,YAAY;AACrB,SAASC,WAAW;AACpB,SAASC,YAAY;AACrB,SAASC,eAAe","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ {% from "govuk/components/notification-banner/macro.njk" import govukNotificationBanner %}
2
+
3
+ {% macro NotificationBanner(component) %}
4
+ {%- set bannerHtml -%}
5
+ {%- if component.model.heading -%}
6
+ <div class="app-prose-notification-banner-scope">{{ component.model.heading | markdown | safe }}</div>
7
+ {%- endif -%}
8
+ <div class="app-prose-scope">{{ component.model.content | markdown | safe }}</div>
9
+ {%- endset -%}
10
+ {{ govukNotificationBanner({
11
+ titleHtml: component.model.titleHtml,
12
+ html: bannerHtml,
13
+ type: component.model.type
14
+ }) }}
15
+ {% endmacro %}
@@ -3,5 +3,5 @@
3
3
  * @this {NunjucksContext}
4
4
  * @param {string} name - The name of the component
5
5
  */
6
- export function field(this: NunjucksContext, name: string): import("../../engine/components/TextField.js").TextField | import("../../engine/components/SelectField.js").SelectField | import("../../engine/components/RadiosField.js").RadiosField | import("../../engine/components/YesNoField.js").YesNoField | import("../../engine/components/CheckboxesField.js").CheckboxesField | import("../../engine/components/DatePartsField.js").DatePartsField | import("../../engine/components/DeclarationField.js").DeclarationField | import("../../engine/components/EastingNorthingField.js").EastingNorthingField | import("../../engine/components/EmailAddressField.js").EmailAddressField | import("../../engine/components/LatLongField.js").LatLongField | import("../../engine/components/MonthYearField.js").MonthYearField | import("../../engine/components/MultilineTextField.js").MultilineTextField | import("../../engine/components/NationalGridFieldNumberField.js").NationalGridFieldNumberField | import("../../engine/components/NumberField.js").NumberField | import("../../engine/components/OsGridRefField.js").OsGridRefField | import("../../engine/components/TelephoneNumberField.js").TelephoneNumberField | import("../../engine/components/UkAddressField.js").UkAddressField | import("../../engine/components/FileUploadField.js").FileUploadField | import("../../engine/components/HiddenField.js").HiddenField | import("../../engine/components/PaymentField.js").PaymentField | import("../../engine/components/GeospatialField.js").GeospatialField | import("../../engine/components/Details.js").Details | import("../../engine/components/Html.js").Html | import("../../engine/components/InsetText.js").InsetText | import("../../engine/components/List.js").List | import("../../engine/components/Markdown.js").Markdown | undefined;
6
+ export function field(this: NunjucksContext, name: string): import("../../engine/components/TextField.js").TextField | import("../../engine/components/SelectField.js").SelectField | import("../../engine/components/RadiosField.js").RadiosField | import("../../engine/components/YesNoField.js").YesNoField | import("../../engine/components/CheckboxesField.js").CheckboxesField | import("../../engine/components/DatePartsField.js").DatePartsField | import("../../engine/components/DeclarationField.js").DeclarationField | import("../../engine/components/EastingNorthingField.js").EastingNorthingField | import("../../engine/components/EmailAddressField.js").EmailAddressField | import("../../engine/components/LatLongField.js").LatLongField | import("../../engine/components/MonthYearField.js").MonthYearField | import("../../engine/components/MultilineTextField.js").MultilineTextField | import("../../engine/components/NationalGridFieldNumberField.js").NationalGridFieldNumberField | import("../../engine/components/NumberField.js").NumberField | import("../../engine/components/OsGridRefField.js").OsGridRefField | import("../../engine/components/TelephoneNumberField.js").TelephoneNumberField | import("../../engine/components/UkAddressField.js").UkAddressField | import("../../engine/components/FileUploadField.js").FileUploadField | import("../../engine/components/HiddenField.js").HiddenField | import("../../engine/components/PaymentField.js").PaymentField | import("../../engine/components/GeospatialField.js").GeospatialField | import("../../engine/components/Details.js").Details | import("../../engine/components/Html.js").Html | import("../../engine/components/InsetText.js").InsetText | import("../../engine/components/List.js").List | import("../../engine/components/Markdown.js").Markdown | import("../../engine/components/NotificationBanner.js").NotificationBanner | undefined;
7
7
  import type { NunjucksContext } from '../../../../server/plugins/nunjucks/types.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defra/forms-engine-plugin",
3
- "version": "4.15.0",
3
+ "version": "4.16.0",
4
4
  "description": "Defra forms engine",
5
5
  "type": "module",
6
6
  "files": [
@@ -54,3 +54,22 @@
54
54
  @extend %govuk-section-break--xl;
55
55
  }
56
56
  }
57
+
58
+ .govuk-notification-banner__content {
59
+ .app-prose-scope > :last-child {
60
+ margin-bottom: 0;
61
+ }
62
+ }
63
+
64
+ // GOV.UK Frontend does not expose placeholder selectors for these — class selectors are the only option.
65
+ .app-prose-notification-banner-scope {
66
+ p {
67
+ // stylelint-disable-next-line scss/at-extend-no-missing-placeholder
68
+ @extend .govuk-notification-banner__heading;
69
+ }
70
+
71
+ a {
72
+ // stylelint-disable-next-line scss/at-extend-no-missing-placeholder
73
+ @extend .govuk-notification-banner__link;
74
+ }
75
+ }
@@ -78,6 +78,25 @@ pages:
78
78
  id: '00738799-3489-4ab2-a57b-542eecb31bfa'
79
79
  next: []
80
80
  id: da0fbdb4-a2de-4650-be16-9ba552af135f
81
+ - title: ''
82
+ path: '/notification-demo'
83
+ components:
84
+ - type: NotificationBanner
85
+ title: Important
86
+ name: notificationImportant
87
+ content: 'Contact us if you need [help with your application](https://www.defra.gov.uk).'
88
+ options:
89
+ heading: There may be a delay in processing your application.
90
+ id: ca6b6590-1608-49f4-82f9-9d92e38e66ea
91
+ - type: NotificationBanner
92
+ title: Success
93
+ name: notificationSuccess
94
+ content: 'Your application has been submitted.'
95
+ options:
96
+ type: success
97
+ id: b6960f4b-d771-4956-9c9b-17da5c603062
98
+ next: []
99
+ id: be4b4b86-514c-43bb-8cdc-f9aed6155924
81
100
  - id: 449a45f6-4541-4a46-91bd-8b8931b07b50
82
101
  title: ''
83
102
  path: '/summary'
@@ -0,0 +1,32 @@
1
+ import { type NotificationBannerComponent } from '@defra/forms-model'
2
+
3
+ import { ComponentBase } from './ComponentBase.js'
4
+
5
+ export class NotificationBanner extends ComponentBase {
6
+ declare options: NotificationBannerComponent['options']
7
+ content: NotificationBannerComponent['content']
8
+
9
+ constructor(
10
+ def: NotificationBannerComponent,
11
+ props: ConstructorParameters<typeof ComponentBase>[1]
12
+ ) {
13
+ super(def, props)
14
+
15
+ const { content, options } = def
16
+
17
+ this.content = content
18
+ this.options = options
19
+ }
20
+
21
+ getViewModel() {
22
+ const { content, title, viewModel } = this
23
+
24
+ return {
25
+ ...viewModel,
26
+ titleHtml: title,
27
+ content,
28
+ heading: this.options.heading,
29
+ type: this.options.type
30
+ }
31
+ }
32
+ }
@@ -46,6 +46,7 @@ export type Guidance =
46
46
  | InstanceType<typeof Components.Markdown>
47
47
  | InstanceType<typeof Components.InsetText>
48
48
  | InstanceType<typeof Components.List>
49
+ | InstanceType<typeof Components.NotificationBanner>
49
50
 
50
51
  // List component instances only
51
52
  export type ListField = InstanceType<
@@ -134,6 +135,10 @@ export function createComponent(
134
135
  component = new Components.Markdown(def, options)
135
136
  break
136
137
 
138
+ case ComponentType.NotificationBanner:
139
+ component = new Components.NotificationBanner(def, options)
140
+ break
141
+
137
142
  case ComponentType.MultilineTextField:
138
143
  component = new Components.MultilineTextField(def, options)
139
144
  break
@@ -15,6 +15,7 @@ export { Html } from './Html.js'
15
15
  export { InsetText } from './InsetText.js'
16
16
  export { List } from './List.js'
17
17
  export { Markdown } from './Markdown.js'
18
+ export { NotificationBanner } from './NotificationBanner.js'
18
19
  export { MonthYearField } from './MonthYearField.js'
19
20
  export { MultilineTextField } from './MultilineTextField.js'
20
21
  export { NumberField } from './NumberField.js'
@@ -0,0 +1,15 @@
1
+ {% from "govuk/components/notification-banner/macro.njk" import govukNotificationBanner %}
2
+
3
+ {% macro NotificationBanner(component) %}
4
+ {%- set bannerHtml -%}
5
+ {%- if component.model.heading -%}
6
+ <div class="app-prose-notification-banner-scope">{{ component.model.heading | markdown | safe }}</div>
7
+ {%- endif -%}
8
+ <div class="app-prose-scope">{{ component.model.content | markdown | safe }}</div>
9
+ {%- endset -%}
10
+ {{ govukNotificationBanner({
11
+ titleHtml: component.model.titleHtml,
12
+ html: bannerHtml,
13
+ type: component.model.type
14
+ }) }}
15
+ {% endmacro %}