@x-govuk/nhsuk-eleventy-plugin 1.0.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.
Files changed (68) hide show
  1. package/LICENSE.txt +22 -0
  2. package/README.md +35 -0
  3. package/package.json +102 -0
  4. package/src/application.js +11 -0
  5. package/src/application.scss +2 -0
  6. package/src/components/_index.scss +12 -0
  7. package/src/components/attribution/_index.scss +13 -0
  8. package/src/components/blockquote/_index.scss +22 -0
  9. package/src/components/card-group/macro.njk +3 -0
  10. package/src/components/card-group/template.njk +26 -0
  11. package/src/components/code/_index.scss +153 -0
  12. package/src/components/contents-list/_index.scss +18 -0
  13. package/src/components/document-header/macro.njk +3 -0
  14. package/src/components/document-header/template.njk +10 -0
  15. package/src/components/document-list/macro.njk +3 -0
  16. package/src/components/document-list/template.njk +22 -0
  17. package/src/components/footnotes-list/_index.scss +55 -0
  18. package/src/components/heading/macro.njk +3 -0
  19. package/src/components/heading/template.njk +15 -0
  20. package/src/components/hero/_index.scss +17 -0
  21. package/src/components/hero/macro.njk +3 -0
  22. package/src/components/hero/template.njk +36 -0
  23. package/src/components/image/_index.scss +8 -0
  24. package/src/components/metadata/_index.scss +24 -0
  25. package/src/components/metadata/macro.njk +3 -0
  26. package/src/components/metadata/template.njk +50 -0
  27. package/src/components/prose-scope/_index.scss +72 -0
  28. package/src/components/prose-scope/macro.njk +3 -0
  29. package/src/components/prose-scope/template.njk +4 -0
  30. package/src/components/related/_index.scss +10 -0
  31. package/src/components/related/macro.njk +3 -0
  32. package/src/components/related/template.njk +17 -0
  33. package/src/components/search/_index.scss +120 -0
  34. package/src/components/search/search.js +133 -0
  35. package/src/components/sub-navigation/_index.scss +71 -0
  36. package/src/components/sub-navigation/macro.njk +3 -0
  37. package/src/components/sub-navigation/template.njk +27 -0
  38. package/src/data/eleventy-computed.js +17 -0
  39. package/src/data/options.js +49 -0
  40. package/src/events/generate-nhsuk-assets.js +57 -0
  41. package/src/filters/current-page.js +18 -0
  42. package/src/filters/index.js +21 -0
  43. package/src/filters/items-from-collection.js +73 -0
  44. package/src/filters/markdown.js +20 -0
  45. package/src/index.js +136 -0
  46. package/src/index.scss +5 -0
  47. package/src/layouts/base.njk +81 -0
  48. package/src/layouts/collection.njk +38 -0
  49. package/src/layouts/error.njk +11 -0
  50. package/src/layouts/feed.njk +32 -0
  51. package/src/layouts/hub.njk +31 -0
  52. package/src/layouts/page.njk +31 -0
  53. package/src/layouts/post.njk +47 -0
  54. package/src/layouts/product.njk +32 -0
  55. package/src/layouts/sitemap.njk +25 -0
  56. package/src/layouts/sub-navigation.njk +40 -0
  57. package/src/layouts/tag.njk +14 -0
  58. package/src/layouts/tags.njk +18 -0
  59. package/src/markdown-it/alert.js +36 -0
  60. package/src/markdown-it/deflist.js +16 -0
  61. package/src/markdown-it/figure.js +12 -0
  62. package/src/markdown-it/footnote.js +47 -0
  63. package/src/markdown-it/table.js +18 -0
  64. package/src/markdown-it.js +91 -0
  65. package/src/nunjucks.js +65 -0
  66. package/src/vendor/nhsuk-frontend/_index.scss +2 -0
  67. package/src/vendor/nhsuk-frontend/components/_index.scss +15 -0
  68. package/src/vendor/nhsuk-frontend/core/_index.scss +1 -0
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Render a definition list
3
+ *
4
+ * @param {Function} md - markdown-it instance
5
+ */
6
+ export function defListRules(md) {
7
+ const { rules } = md.renderer
8
+
9
+ rules.dl_open = () => '<dl class="nhsuk-body-m">\n'
10
+
11
+ rules.dt_open = () =>
12
+ '<dt class="nhsuk-u-font-weight-bold nhsuk-u-margin-bottom-2">\n'
13
+
14
+ rules.dd_open = () =>
15
+ '<dd class="nhsuk-u-margin-bottom-2 nhsuk-u-margin-left-4">\n'
16
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Render a figure
3
+ *
4
+ * @param {Function} md - markdown-it instance
5
+ */
6
+ export function figureRules(md) {
7
+ const { rules } = md.renderer
8
+
9
+ rules.figure_open = () => '<figure class="nhsuk-image">\n'
10
+
11
+ rules.figcaption_open = () => '<figcaption class="nhsuk-image__caption">\n'
12
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Render footnotes
3
+ *
4
+ * @param {Function} md - markdown-it instance
5
+ */
6
+ export function footnotesRules(md) {
7
+ const { rules } = md.renderer
8
+
9
+ rules.footnote_ref = (tokens, idx, options, env, self) => {
10
+ let id = self.rules.footnote_anchor_name(tokens, idx, options, env, self)
11
+
12
+ if (tokens[idx].meta.subId > 0) {
13
+ id += `:${tokens[idx].meta.subId}`
14
+ }
15
+
16
+ return `<sup id="fnref:${id}"><a class="nhsuk-link" href="#fn:${id}" aria-describedby="footnotes-label">${id.toString()}</a></sup>`
17
+ }
18
+
19
+ rules.footnote_anchor = (tokens, idx, options, env, self) => {
20
+ let id = self.rules.footnote_anchor_name(tokens, idx, options, env, self)
21
+
22
+ if (tokens[idx].meta.subId > 0) {
23
+ id += `:${tokens[idx].meta.subId}`
24
+ }
25
+
26
+ // ↩ using unicode escape code to prevent display as emoji on iOS
27
+ return ` <a class="nhsuk-link" href="#fnref:${id}" aria-label="Back to content">\u21a9\uFE0E</a>`
28
+ }
29
+
30
+ rules.footnote_block_open = () =>
31
+ `<footer>
32
+ <hr class="nhsuk-section-break nhsuk-section-break--l nhsuk-section-break--visible">\n
33
+ <h2 id="footnotes-label" class="nhsuk-u-visually-hidden">Footnotes</h2>\n
34
+ <ol class="app-footnotes-list">\n`
35
+
36
+ rules.footnote_block_close = () => '</ol>\n</footer>\n'
37
+
38
+ rules.footnote_open = (tokens, idx, options, env, self) => {
39
+ let id = self.rules.footnote_anchor_name(tokens, idx, options, env, self)
40
+
41
+ if (tokens[idx].meta.subId > 0) {
42
+ id += `:${tokens[idx].meta.subId}`
43
+ }
44
+
45
+ return `<li id="fn:${id}">`
46
+ }
47
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Render a table with `tabindex` to enable keyboard scrolling
3
+ *
4
+ * @param {Function} md - markdown-it instance
5
+ */
6
+ export function tableRules(md) {
7
+ const { rules } = md.renderer
8
+ const defaultRenderer =
9
+ rules.table_open ||
10
+ function (tokens, idx, options, env, self) {
11
+ return self.renderToken(tokens, idx, options)
12
+ }
13
+
14
+ rules.table_open = (tokens, idx, options, env, self) => {
15
+ tokens[idx].attrPush(['tabindex', 0])
16
+ return defaultRenderer(tokens, idx, options, env, self)
17
+ }
18
+ }
@@ -0,0 +1,91 @@
1
+ import slugify from '@sindresorhus/slugify'
2
+ import MarkdownIt from 'markdown-it'
3
+ import markdownItAbbr from 'markdown-it-abbr'
4
+ import markdownItAnchor from 'markdown-it-anchor'
5
+ import markdownItAttribution from 'markdown-it-attribution'
6
+ import markdownItAttrs from 'markdown-it-attrs'
7
+ import markdownItDeflist from 'markdown-it-deflist'
8
+ import markdownItFootnote from 'markdown-it-footnote'
9
+ import MarkdownItGitHubAlerts from 'markdown-it-github-alerts'
10
+ import markdownItGovuk from 'markdown-it-govuk'
11
+ import highlight from 'markdown-it-govuk/highlight'
12
+ import markdownItImageFigures from 'markdown-it-image-figures'
13
+ import markdownItIns from 'markdown-it-ins'
14
+ import markdownItMark from 'markdown-it-mark'
15
+ import markdownItSub from 'markdown-it-sub'
16
+ import markdownItSup from 'markdown-it-sup'
17
+ import markdownItTableOfContents from 'markdown-it-table-of-contents'
18
+
19
+ import { alertRules } from './markdown-it/alert.js'
20
+ import { defListRules } from './markdown-it/deflist.js'
21
+ import { figureRules } from './markdown-it/figure.js'
22
+ import { footnotesRules } from './markdown-it/footnote.js'
23
+ import { tableRules } from './markdown-it/table.js'
24
+
25
+ /**
26
+ * Configure markdown-it
27
+ *
28
+ * @see {@link https://markdown-it.github.io/markdown-it/}
29
+ * @param {object} [options] - Plugin options
30
+ * @returns {Function} markdown-it instance
31
+ */
32
+ export function md(options = {}) {
33
+ const opts = {
34
+ breaks: true,
35
+ highlight,
36
+ html: true,
37
+ linkify: false,
38
+ typographer: true
39
+ }
40
+
41
+ const md = new MarkdownIt(opts)
42
+ .use(markdownItGovuk, {
43
+ brand: 'nhsuk',
44
+ calvert: true,
45
+ headingsStartWith: 'xl'
46
+ })
47
+ .use(markdownItAbbr)
48
+ .use(markdownItAnchor, {
49
+ permalink: options.headingPermalinks
50
+ ? markdownItAnchor.permalink.headerLink({
51
+ class: 'app-link--heading',
52
+ safariReaderFix: true
53
+ })
54
+ : false,
55
+ slugify: (string) => slugify(string).replaceAll(/[*+~.()'"!:@]/g, '')
56
+ })
57
+ .use(markdownItAttribution, {
58
+ classNameContainer: 'app-attribution',
59
+ classNameAttribution: 'app-attribution__caption',
60
+ marker: '--'
61
+ })
62
+ .use(markdownItAttrs)
63
+ .use(markdownItDeflist)
64
+ .use(defListRules)
65
+ .use(markdownItFootnote)
66
+ .use(footnotesRules)
67
+ .use(MarkdownItGitHubAlerts)
68
+ .use(alertRules)
69
+ .use(markdownItIns)
70
+ .use(markdownItImageFigures, {
71
+ classes: 'nhsuk-image__img',
72
+ figcaption: true
73
+ })
74
+ .use(figureRules)
75
+ .use(markdownItMark)
76
+ .use(markdownItSub)
77
+ .use(markdownItSup)
78
+ .use(tableRules)
79
+ .use(markdownItTableOfContents, {
80
+ includeLevel: [2, 3],
81
+ listType: 'ol',
82
+ transformContainerOpen: () => {
83
+ return '<nav class="nhsuk-contents-list"><h2 class="nhsuk-u-visually-hidden">Contents</h2>'
84
+ },
85
+ transformContainerClose: () => {
86
+ return '</nav>'
87
+ }
88
+ })
89
+
90
+ return md
91
+ }
@@ -0,0 +1,65 @@
1
+ import path from 'node:path'
2
+
3
+ import Nunjucks from 'nunjucks'
4
+
5
+ /**
6
+ * Gets the value at `path` of `object`. If the resolved value is `undefined`,
7
+ * the `defaultValue` is returned in its place.
8
+ *
9
+ * @param {object} object - Object to query
10
+ * @param {Array|string} keys - Path of the property to get
11
+ * @param {*} defaultValue - Value returned for `undefined` resolved values
12
+ * @returns {*} The resolved value
13
+ */
14
+ function getProp(object, keys, defaultValue) {
15
+ keys = Array.isArray(keys) ? keys : keys.split('.')
16
+ object = object[keys[0]]
17
+ if (object && keys.length > 1) {
18
+ return getProp(object, keys.slice(1))
19
+ }
20
+ return object === undefined ? defaultValue : object
21
+ }
22
+
23
+ /**
24
+ * Configure Nunjucks environment
25
+ *
26
+ * @see {@link https://mozilla.github.io/nunjucks/api.html#environment}
27
+ * @param {object} eleventyConfig - Eleventy config
28
+ * @returns {Function} Nunjucks environment
29
+ */
30
+ export function nunjucksConfig(eleventyConfig) {
31
+ const { includes, input, layouts } = eleventyConfig.dir
32
+
33
+ const searchPaths = [
34
+ ...(includes ? [path.join(input, includes)] : []),
35
+ ...(layouts ? [path.join(input, layouts)] : []),
36
+ input,
37
+ './node_modules/@x-govuk/nhsuk-eleventy-plugin/src',
38
+ './node_modules/nhsuk-frontend/dist'
39
+ ]
40
+
41
+ /**
42
+ * Set default options, but respect `nunjucksEnvironmentOptions`
43
+ *
44
+ * @see {@link https://www.11ty.dev/docs/languages/nunjucks/#optional-use-your-nunjucks-environment-options}
45
+ */
46
+ const options = {
47
+ autoescape: false,
48
+ lstripBlocks: true,
49
+ trimBlocks: true,
50
+ noCache: process.env === 'development',
51
+ watch: process.env === 'development',
52
+ ...eleventyConfig.nunjucksEnvironmentOptions
53
+ }
54
+
55
+ const nunjucks = new Nunjucks.Environment(
56
+ new Nunjucks.FileSystemLoader(searchPaths),
57
+ options
58
+ )
59
+
60
+ nunjucks.addGlobal('getData', function (keyName) {
61
+ return typeof keyName === 'string' ? getProp(this.ctx, keyName) : keyName
62
+ })
63
+
64
+ return nunjucks
65
+ }
@@ -0,0 +1,2 @@
1
+ @forward "core";
2
+ @forward "components";
@@ -0,0 +1,15 @@
1
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/breadcrumb";
2
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/button";
3
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/card";
4
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/contents-list";
5
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/footer";
6
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/header";
7
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/hero";
8
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/images";
9
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/inset-text";
10
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/input";
11
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/pagination";
12
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/skip-link";
13
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/tables";
14
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/tag";
15
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/components/warning-callout";
@@ -0,0 +1 @@
1
+ @forward "pkg:nhsuk-frontend/dist/nhsuk/core";