You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: docs/contributing/coding-standards/component-options.md
+64-9
Original file line number
Diff line number
Diff line change
@@ -30,9 +30,11 @@ Next, use the `mergeConfigs` helper to combine the default config and the config
30
30
31
31
The order in which variables are written defines their priority, with objects passed sooner being overwritten by those passed later. As we want the user's configuration to take precedence over our defaults, we list our default configuration object first.
32
32
33
-
There is no guarantee `config` will have any value at all, so it'll be `undefined`. We use an OR operator (`||`) as a safety check. If the value is `undefined`, we use an empty object instead.
33
+
There is no guarantee `config` will have any value at all, so we set the default to an empty object (`{}`) in the constructor parameters.
@@ -66,7 +68,7 @@ It's now possible to individually initialise the component with configuration op
66
68
67
69
## Allowing options to be passed through the `initAll` function
68
70
69
-
Usually, teams will not be individually initialising components. Instead, GOV.UK Frontend ships with an `initAll` function, which searches the page for instances of components and automatically initialises them.
71
+
Often, teams will not be individually initialising components. Instead, GOV.UK Frontend ships with an `initAll` function, which searches the page for instances of components and automatically initialises them.
70
72
71
73
In `src/govuk/all.mjs`, update the component's `new` class to pass through a nested configuration object. The nested object should use the component's name converted to camelCase (for example, the 'Character Count' component becomes `characterCount`).
72
74
@@ -95,25 +97,30 @@ It's now possible to pass configuration options for your component, as well as m
95
97
96
98
For convenience, we also allow for configuration options to be passed through HTML `data-*` attributes.
97
99
98
-
You can find `data-*` attributes in JavaScript by looking at an element's `dataset` property. Browsers will convert the attribute names from HTML's kebab-case to more JavaScript-friendly camelCase when working with `dataset`. See ['Naming configuration options'](#naming-configuration-options) for exceptions.
100
+
You can find `data-*` attributes in JavaScript by looking at an element's `dataset` property. Browsers will convert the attribute names from HTML's kebab-case to more JavaScript-friendly camelCase when working with `dataset`.
101
+
102
+
See ['Naming configuration options'](#naming-configuration-options) for exceptions to how names are transformed.
99
103
100
104
As we expect configuration-related `data-*` attributes to always be on the component's root element (the same element with the `data-module` attribute), we can access them all using `$module.dataset`.
101
105
102
106
Using the `mergeConfigs` call discussed earlier in this document, update it to include `$module.dataset` as the highest priority.
Here, we pass the value of `$module.dataset` through our `normaliseDataset` function. This is because attribute values in dataset are always interpreted as strings. `normaliseDataset`runs a few simple checks to convert values back to numbers or booleans where appropriate.
123
+
Here, we pass the value of `$module.dataset` through our `normaliseDataset` function. This is because attribute values in dataset are always interpreted as strings. `normaliseDataset`looks at the component's configuration schema and converts values into numbers or booleans where needed.
117
124
118
125
Now, in our HTML, we could pass configuration options by using the kebab-case version of the option's name.
119
126
@@ -128,6 +135,51 @@ Now, in our HTML, we could pass configuration options by using the kebab-case ve
128
135
129
136
However, this only works for developers who are writing raw HTML. We include Nunjucks macros for each component with GOV.UK Frontend to make development easier and faster, but this also makes it harder for developers to manually alter the raw HTML. We'll add a new parameter to Nunjucks to help them out.
130
137
138
+
### Adding a configuration schema
139
+
140
+
Components that accept configuration using `data-*` attributes also require a schema. This schema documents what parameters a configuration object may contain and what types of value they're expected to be.
141
+
142
+
Having a schema is required for the `normaliseDataset` function to work. A schema is also needed to use the `validateConfig` and `extractConfigByNamespace` functions we'll cover later on.
143
+
144
+
```mjs
145
+
exportclassAccordion {
146
+
static schema =Object.freeze({
147
+
properties: {
148
+
i18n: { type:'object' },
149
+
rememberExpanded: { type:'boolean' }
150
+
}
151
+
})
152
+
}
153
+
```
154
+
155
+
### Validating a provided configuration against the schema
156
+
157
+
You can use the `validateConfig` function to ensure that a configuration object matches the schema format.
Most, but not all, components support adding arbitrary attributes and values through the `attributes` parameter. This method is also more verbose compared to having a dedicated Nunjucks parameter.
@@ -177,30 +229,33 @@ In our example, `rememberExpanded` becomes `data-remember-expanded`.
177
229
178
230
Unlike the `data-*` attribute in HTML and our use of `dataset` in JavaScript, there is no intrinsic link between the Nunjucks parameter name and the names used elsewhere. The Nunjucks parameter can therefore be named differently, if convenient.
179
231
180
-
A common case is specifying whether a parameter accepts HTML or only plain text. For example, if a configuration option's value is inserted into the page using `innerText`, you might want to name the Nunjucks parameter something like `sectionLabelText` to indicate that HTML will not be rendered.
232
+
A common case is specifying whether a parameter accepts HTML or only plain text. For example, if a configuration option's value is inserted into the page using `innerText`, you might want to name the Nunjucks parameter something like `sectionLabelText` to indicate that HTML will not be parsed if provided.
181
233
182
234
There is more guidance on naming Nunjucks parameters in [the Nunjucks API documentation](https://github.com/alphagov/govuk-frontend/blob/main/docs/contributing/coding-standards/nunjucks-api.md#naming-options).
183
235
184
236
## Namespacing configuration options
185
237
186
238
You can group configuration options in JavaScript and HTML together by using namespaces; period-separated strings that prefix the configuration option name. Namespaces follow the same formats as other option names, being camelCase in JavaScript and kebab-case in HTML.
187
239
188
-
These are most commonly used for translation strings, which are usually namespaced under `i18n` (for 'internationalisation').
240
+
These are most commonly used for translation strings, which are usually namespaced under `i18n` (short for 'internationalisation').
189
241
190
242
For example, we could namespace our `rememberExpanded` option under the `stateInfo` namespace. Our `data-*` attribute would now be named `data-state-info.remember-expanded` and accessed in the component's JavaScript using `this.config.stateInfo.rememberExpanded`.
191
243
192
244
The `extractConfigByNamespace` JavaScript helper can be used to create an object containing _only_ the configuration options that belong to a certain namespace.
0 commit comments