@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.
- package/.public/stylesheets/application.min.css +1 -1
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/stylesheets/_prose.scss +19 -0
- package/.server/server/forms/simple-form.yaml +19 -0
- package/.server/server/plugins/engine/components/NotificationBanner.d.ts +56 -0
- package/.server/server/plugins/engine/components/NotificationBanner.js +28 -0
- package/.server/server/plugins/engine/components/NotificationBanner.js.map +1 -0
- package/.server/server/plugins/engine/components/helpers/components.d.ts +1 -1
- package/.server/server/plugins/engine/components/helpers/components.js +3 -0
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/index.d.ts +1 -0
- package/.server/server/plugins/engine/components/index.js +1 -0
- package/.server/server/plugins/engine/components/index.js.map +1 -1
- package/.server/server/plugins/engine/views/components/notificationbanner.html +15 -0
- package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
- package/package.json +1 -1
- package/src/client/stylesheets/_prose.scss +19 -0
- package/src/server/forms/simple-form.yaml +19 -0
- package/src/server/plugins/engine/components/NotificationBanner.ts +32 -0
- package/src/server/plugins/engine/components/helpers/components.ts +5 -0
- package/src/server/plugins/engine/components/index.ts +1 -0
- package/src/server/plugins/engine/views/components/notificationbanner.html +15 -0
|
@@ -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
|
@@ -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 %}
|