nhsuk-decorated-components 0.0.5 → 0.0.7
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/README.md +38 -28
- package/lib/decorate.js +80 -78
- package/package.json +22 -17
package/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# NHS.UK Decorated Components · [](https://github.com/x-govuk/nhsuk-decorated-components/actions/workflows/test.yml)
|
|
2
2
|
|
|
3
|
-
Form components for the NHS.UK Design System that require less parameters to collect data. [Replace the multiple parameters needed for saving data with a single `decorate` parameter](https://x-govuk.github.io/
|
|
3
|
+
Form components for the NHS.UK Design System that require less parameters to collect data. [Replace the multiple parameters needed for saving data with a single `decorate` parameter](https://x-govuk.github.io/govuk-prototype-rig/using-data/form-components/).
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
|
-
Node.js
|
|
7
|
+
Node.js v20 or later.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
|
-
>
|
|
11
|
+
> [!NOTE]
|
|
12
|
+
> These components are included by default with the [NHS.UK Prototype Rig](https://x-govuk.github.io/nhsuk-prototype-rig/).
|
|
12
13
|
|
|
13
14
|
```shell
|
|
14
15
|
npm install nhsuk-decorated-components --save
|
|
@@ -20,36 +21,45 @@ To add them to the NHS.UK Prototype Kit, follow these steps:
|
|
|
20
21
|
|
|
21
22
|
1. Add `/node_modules/nhsuk-decorated-components` to your application’s views (`appViews`) in `server.js`:
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
```diff
|
|
25
|
+
// Set up App
|
|
26
|
+
var appViews = extensions.getAppViews([
|
|
27
|
+
+ path.join(projectDir, '/node_modules/nhsuk-decorated-components'),
|
|
28
|
+
path.join(projectDir, '/app/views/'),
|
|
29
|
+
path.join(projectDir, '/lib/')
|
|
30
|
+
])
|
|
31
|
+
```
|
|
31
32
|
|
|
32
33
|
2. Add the `decorate` global function to your Nunjucks environment (`nunjucksAppEnv`) in `server.js`:
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
```diff
|
|
36
|
+
var nunjucksAppEnv = nunjucks.configure(appViews, nunjucksConfig)
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// Add Nunjucks Globals
|
|
39
|
+
+ const { decorate } = require('nhsuk-decorated-components')
|
|
40
|
+
+ nunjucksAppEnv.addGlobal('decorate', decorate)
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
// Add Nunjucks filters
|
|
43
|
+
utils.addNunjucksFilters(nunjucksAppEnv)
|
|
44
|
+
```
|
|
44
45
|
|
|
45
46
|
3. Replace imported NHS.UK Frontend macros with those provided by this package:
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
```diff
|
|
49
|
+
+ {% from "x-nhsuk/decorated/button/macro.njk" import button with context %}
|
|
50
|
+
+ {% from "x-nhsuk/decorated/checkboxes/macro.njk" import checkboxes with context %}
|
|
51
|
+
+ {% from "x-nhsuk/decorated/date-input/macro.njk" import dateInput with context %}
|
|
52
|
+
+ {% from "x-nhsuk/decorated/input/macro.njk" import input with context %}
|
|
53
|
+
+ {% from "x-nhsuk/decorated/radios/macro.njk" import radios with context %}
|
|
54
|
+
+ {% from "x-nhsuk/decorated/select/macro.njk" import select with context %}
|
|
55
|
+
+ {% from "x-nhsuk/decorated/textarea/macro.njk" import textarea with context %}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Releasing a new version
|
|
59
|
+
|
|
60
|
+
`npm run release`
|
|
61
|
+
|
|
62
|
+
This command will ask you what version you want to use. It will then publish a new version on NPM, create and push a new git tag and then generate release notes ready for posting on GitHub.
|
|
63
|
+
|
|
64
|
+
> [!NOTE]
|
|
65
|
+
> Releasing a new version requires permission to publish packages to the `@x-govuk` organisation.
|
package/lib/decorate.js
CHANGED
|
@@ -15,22 +15,22 @@ exports.decorate = function (params, keyPath, componentName) {
|
|
|
15
15
|
return params
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
keyPath = _.toPath(keyPath)
|
|
19
|
-
|
|
20
18
|
const { data, errors } = this.ctx
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
19
|
+
|
|
20
|
+
keyPath = _.toPath(keyPath)
|
|
24
21
|
|
|
25
22
|
// Strip data from key path as auto store data middleware adds it
|
|
26
23
|
if (keyPath[0] === 'data') {
|
|
27
24
|
keyPath.shift(1)
|
|
28
25
|
}
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
// Get stored value from session data, else local data
|
|
28
|
+
const storedValue = _.get(data, keyPath) || _.get(this.ctx, keyPath) || ''
|
|
31
29
|
|
|
32
|
-
params.id =
|
|
33
|
-
params.name =
|
|
30
|
+
params.id = params.id ? params.id : keyPath.join('-')
|
|
31
|
+
params.name = params.name
|
|
32
|
+
? params.name
|
|
33
|
+
: keyPath.map((s) => `[${s}]`).join('')
|
|
34
34
|
|
|
35
35
|
// Add field validations to data
|
|
36
36
|
if (params.validate) {
|
|
@@ -48,82 +48,84 @@ exports.decorate = function (params, keyPath, componentName) {
|
|
|
48
48
|
|
|
49
49
|
if (params.items) {
|
|
50
50
|
params.idPrefix = params.id
|
|
51
|
-
params.items = params.items
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// ==============
|
|
59
|
-
// We want to validate a combined date, but validate.js validates
|
|
60
|
-
// individual fields. The custom `date` validator hooks into the year
|
|
61
|
-
// value and gets day and month values via its `attributes` object.
|
|
62
|
-
//
|
|
63
|
-
// 1. Delete `validations` for all date fields
|
|
64
|
-
// 2. Add `validations` for year field
|
|
65
|
-
|
|
66
|
-
if (item.decorate && data.validations) {
|
|
67
|
-
delete data.validations[params.name] // 1.
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Update date input items based on `decorate` value
|
|
71
|
-
switch (item.decorate) {
|
|
72
|
-
case 'day':
|
|
73
|
-
item.classes = item.classes || 'nhsuk-input--width-2'
|
|
74
|
-
item.id = `${params.id}-day`
|
|
75
|
-
item.name = `${params.name}[day]`
|
|
76
|
-
item.label = item.label || 'Day'
|
|
77
|
-
item.value = storedValue?.day
|
|
78
|
-
break
|
|
79
|
-
case 'month':
|
|
80
|
-
item.classes = item.classes || 'nhsuk-input--width-2'
|
|
81
|
-
item.id = `${params.id}-month`
|
|
82
|
-
item.name = `${params.name}[month]`
|
|
83
|
-
item.label = item.label || 'Month'
|
|
84
|
-
item.value = storedValue?.month
|
|
85
|
-
break
|
|
86
|
-
case 'year':
|
|
87
|
-
item.classes = item.classes || 'nhsuk-input--width-4'
|
|
88
|
-
item.id = `${params.id}-year`
|
|
89
|
-
item.name = `${params.name}[year]`
|
|
90
|
-
item.label = item.label || 'Year'
|
|
91
|
-
item.value = storedValue?.year
|
|
92
|
-
|
|
93
|
-
if (params.validate && data.validations) {
|
|
94
|
-
data.validations[item.name] = params.validate // 2.
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
break
|
|
98
|
-
default:
|
|
99
|
-
// Use label text if no value given for option
|
|
100
|
-
if (typeof item.value === 'undefined') {
|
|
101
|
-
item.value = item.text
|
|
102
|
-
}
|
|
103
|
-
}
|
|
51
|
+
params.items = params.items
|
|
52
|
+
.filter((i) => i)
|
|
53
|
+
.map((item) => {
|
|
54
|
+
// Ignore dividers or empty items
|
|
55
|
+
if (item.divider || item === '') {
|
|
56
|
+
return item
|
|
57
|
+
}
|
|
104
58
|
|
|
105
|
-
|
|
106
|
-
|
|
59
|
+
// Validate dates
|
|
60
|
+
// ==============
|
|
61
|
+
// We want to validate a combined date, but validate.js validates
|
|
62
|
+
// individual fields. The custom `date` validator hooks into the year
|
|
63
|
+
// value and gets day and month values via its `attributes` object.
|
|
64
|
+
//
|
|
65
|
+
// 1. Delete `validations` for all date fields
|
|
66
|
+
// 2. Add `validations` for year field
|
|
67
|
+
|
|
68
|
+
if (item.decorate && data.validations) {
|
|
69
|
+
delete data.validations[params.name] // 1.
|
|
70
|
+
}
|
|
107
71
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
72
|
+
// Update date input items based on `decorate` value
|
|
73
|
+
switch (item.decorate) {
|
|
74
|
+
case 'day':
|
|
75
|
+
item.classes = item.classes || 'nhsuk-input--width-2'
|
|
76
|
+
item.id = `${params.id}-day`
|
|
77
|
+
item.name = `${params.name}[day]`
|
|
78
|
+
item.label = item.label || 'Day'
|
|
79
|
+
item.value = storedValue?.day
|
|
80
|
+
break
|
|
81
|
+
case 'month':
|
|
82
|
+
item.classes = item.classes || 'nhsuk-input--width-2'
|
|
83
|
+
item.id = `${params.id}-month`
|
|
84
|
+
item.name = `${params.name}[month]`
|
|
85
|
+
item.label = item.label || 'Month'
|
|
86
|
+
item.value = storedValue?.month
|
|
87
|
+
break
|
|
88
|
+
case 'year':
|
|
89
|
+
item.classes = item.classes || 'nhsuk-input--width-4'
|
|
90
|
+
item.id = `${params.id}-year`
|
|
91
|
+
item.name = `${params.name}[year]`
|
|
92
|
+
item.label = item.label || 'Year'
|
|
93
|
+
item.value = storedValue?.year
|
|
94
|
+
|
|
95
|
+
if (params.validate && data.validations) {
|
|
96
|
+
data.validations[item.name] = params.validate // 2.
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
break
|
|
100
|
+
default:
|
|
101
|
+
// Use label text if no value given for option
|
|
102
|
+
if (typeof item.value === 'undefined') {
|
|
103
|
+
item.value = item.text
|
|
104
|
+
}
|
|
113
105
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
106
|
+
|
|
107
|
+
let checkedValue = ''
|
|
108
|
+
let selectedValue = ''
|
|
109
|
+
|
|
110
|
+
if (Array.isArray(storedValue)) {
|
|
111
|
+
// Stored value is an array, check it exists in the array
|
|
112
|
+
if (storedValue.indexOf(item.value) !== -1) {
|
|
113
|
+
checkedValue = 'checked'
|
|
114
|
+
selectedValue = 'selected'
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
// Stored value is a simple value, check it matches
|
|
118
|
+
if (storedValue === item.value) {
|
|
119
|
+
checkedValue = 'checked'
|
|
120
|
+
selectedValue = 'selected'
|
|
121
|
+
}
|
|
119
122
|
}
|
|
120
|
-
}
|
|
121
123
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
item.checked = checkedValue
|
|
125
|
+
item.selected = selectedValue
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
return item
|
|
128
|
+
})
|
|
127
129
|
} else {
|
|
128
130
|
// Check for undefined because value may exist and be intentionally blank
|
|
129
131
|
if (typeof params.value === 'undefined') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nhsuk-decorated-components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Form components for the NHS.UK Design System that require less parameters to collect data",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nhsuk",
|
|
@@ -23,10 +23,15 @@
|
|
|
23
23
|
"url": "https://github.com/x-govuk/nhsuk-decorated-components.git"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
|
-
"lint": "
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
26
|
+
"lint:prettier": "prettier . --check",
|
|
27
|
+
"lint:prettier:fix": "prettier . --write",
|
|
28
|
+
"lint:js": "eslint '**/*.js'",
|
|
29
|
+
"lint:js:fix": "eslint '**/*.js' --fix",
|
|
30
|
+
"lint": "npm run lint:prettier && npm run lint:js",
|
|
31
|
+
"lint:fix": "npm run lint:prettier:fix && npm run lint:js:fix",
|
|
32
|
+
"test": "NODE_ENV=test node --test",
|
|
33
|
+
"coverage": "NODE_ENV=test node --test --experimental-test-coverage",
|
|
34
|
+
"release": "np"
|
|
30
35
|
},
|
|
31
36
|
"publishConfig": {
|
|
32
37
|
"access": "public"
|
|
@@ -35,19 +40,19 @@
|
|
|
35
40
|
"lodash": "^4.17.21"
|
|
36
41
|
},
|
|
37
42
|
"devDependencies": {
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
+
"eslint": "^8.56.0",
|
|
44
|
+
"eslint-config-prettier": "^9.1.0",
|
|
45
|
+
"eslint-config-standard": "^17.1.0",
|
|
46
|
+
"eslint-plugin-import": "^2.29.1",
|
|
47
|
+
"eslint-plugin-jsdoc": "^48.0.6",
|
|
48
|
+
"eslint-plugin-n": "^16.6.2",
|
|
49
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
50
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
51
|
+
"nhsuk-frontend": "^8.0.0",
|
|
52
|
+
"np": "^9.2.0",
|
|
53
|
+
"nunjucks": "^3.2.3"
|
|
43
54
|
},
|
|
44
55
|
"engines": {
|
|
45
|
-
"node": ">=
|
|
46
|
-
},
|
|
47
|
-
"c8": {
|
|
48
|
-
"reporter": [
|
|
49
|
-
"text",
|
|
50
|
-
"lcovonly"
|
|
51
|
-
]
|
|
56
|
+
"node": ">=20"
|
|
52
57
|
}
|
|
53
58
|
}
|