@nationalarchives/frontend 0.1.20-prerelease → 0.1.21-prerelease

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 (134) hide show
  1. package/README.md +1 -1
  2. package/govuk-prototype-kit.config.json +6 -1
  3. package/nationalarchives/_prototype-kit.scss +16 -0
  4. package/nationalarchives/all.css +3 -3
  5. package/nationalarchives/all.css.map +1 -1
  6. package/nationalarchives/all.js +1 -1
  7. package/nationalarchives/all.js.map +1 -1
  8. package/nationalarchives/all.mjs +17 -10
  9. package/nationalarchives/all.scss +1 -5
  10. package/nationalarchives/assets/images/favicon.ico +0 -0
  11. package/nationalarchives/assets/images/mask-icon.svg +17 -5
  12. package/nationalarchives/assets/images/mstile-150x150.png +0 -0
  13. package/nationalarchives/components/_index.scss +1 -0
  14. package/nationalarchives/components/breadcrumbs/breadcrumbs.css +1 -1
  15. package/nationalarchives/components/breadcrumbs/breadcrumbs.css.map +1 -1
  16. package/nationalarchives/components/breadcrumbs/breadcrumbs.scss +10 -0
  17. package/nationalarchives/components/button/button.css +1 -13
  18. package/nationalarchives/components/button/button.css.map +1 -1
  19. package/nationalarchives/components/button/button.scss +23 -6
  20. package/nationalarchives/components/card/card.css +1 -13
  21. package/nationalarchives/components/card/card.css.map +1 -1
  22. package/nationalarchives/components/card/card.scss +51 -6
  23. package/nationalarchives/components/card/card.stories.js +74 -35
  24. package/nationalarchives/components/card/fixtures.json +39 -15
  25. package/nationalarchives/components/card/macro-options.json +20 -0
  26. package/nationalarchives/components/card/template.njk +38 -26
  27. package/nationalarchives/components/cookie-banner/cookie-banner.css +1 -13
  28. package/nationalarchives/components/cookie-banner/cookie-banner.css.map +1 -1
  29. package/nationalarchives/components/cookie-banner/cookie-banner.js +1 -1
  30. package/nationalarchives/components/cookie-banner/cookie-banner.js.map +1 -1
  31. package/nationalarchives/components/cookie-banner/cookie-banner.mjs +15 -7
  32. package/nationalarchives/components/cookie-banner/cookie-banner.scss +9 -1
  33. package/nationalarchives/components/cookie-banner/cookie-banner.stories.js +23 -10
  34. package/nationalarchives/components/cookie-banner/macro-options.json +1 -1
  35. package/nationalarchives/components/cookie-banner/template.njk +4 -4
  36. package/nationalarchives/components/filters/filters.css +1 -1
  37. package/nationalarchives/components/filters/filters.css.map +1 -1
  38. package/nationalarchives/components/filters/filters.scss +1 -1
  39. package/nationalarchives/components/footer/fixtures.json +1 -1
  40. package/nationalarchives/components/footer/footer.css +1 -13
  41. package/nationalarchives/components/footer/footer.css.map +1 -1
  42. package/nationalarchives/components/footer/footer.scss +2 -8
  43. package/nationalarchives/components/footer/template.njk +8 -7
  44. package/nationalarchives/components/gallery/gallery.css +1 -13
  45. package/nationalarchives/components/gallery/gallery.css.map +1 -1
  46. package/nationalarchives/components/grid/grid.css +1 -1
  47. package/nationalarchives/components/grid/grid.css.map +1 -1
  48. package/nationalarchives/components/grid/grid.scss +15 -11
  49. package/nationalarchives/components/header/header.css +1 -1
  50. package/nationalarchives/components/header/header.css.map +1 -1
  51. package/nationalarchives/components/header/header.scss +10 -24
  52. package/nationalarchives/components/hero/fixtures.json +85 -6
  53. package/nationalarchives/components/hero/hero.css +1 -1
  54. package/nationalarchives/components/hero/hero.css.map +1 -1
  55. package/nationalarchives/components/hero/hero.scss +177 -63
  56. package/nationalarchives/components/hero/hero.stories.js +74 -23
  57. package/nationalarchives/components/hero/macro-options.json +28 -36
  58. package/nationalarchives/components/hero/template.njk +26 -24
  59. package/nationalarchives/components/index-grid/index-grid.css +1 -1
  60. package/nationalarchives/components/index-grid/index-grid.css.map +1 -1
  61. package/nationalarchives/components/index-grid/template.njk +1 -1
  62. package/nationalarchives/components/message/message.css +1 -1
  63. package/nationalarchives/components/message/message.css.map +1 -1
  64. package/nationalarchives/components/pagination/_index.scss +1 -0
  65. package/nationalarchives/components/pagination/fixtures.json +4 -0
  66. package/nationalarchives/components/pagination/macro-options.json +116 -0
  67. package/nationalarchives/components/pagination/macro.njk +3 -0
  68. package/nationalarchives/components/pagination/pagination.css +1 -0
  69. package/nationalarchives/components/pagination/pagination.css.map +1 -0
  70. package/nationalarchives/components/pagination/pagination.scss +79 -0
  71. package/nationalarchives/components/pagination/pagination.stories.js +73 -0
  72. package/nationalarchives/components/pagination/template.njk +38 -0
  73. package/nationalarchives/components/phase-banner/phase-banner.css +1 -1
  74. package/nationalarchives/components/phase-banner/phase-banner.css.map +1 -1
  75. package/nationalarchives/components/picture/picture.css +1 -13
  76. package/nationalarchives/components/picture/picture.css.map +1 -1
  77. package/nationalarchives/components/picture/picture.stories.js +2 -2
  78. package/nationalarchives/components/profile/profile.css +1 -1
  79. package/nationalarchives/components/profile/profile.css.map +1 -1
  80. package/nationalarchives/components/sensitive-image/sensitive-image.css +1 -1
  81. package/nationalarchives/components/sensitive-image/sensitive-image.css.map +1 -1
  82. package/nationalarchives/components/skip-link/fixtures.json +1 -1
  83. package/nationalarchives/components/skip-link/skip-link.css +1 -1
  84. package/nationalarchives/components/skip-link/skip-link.css.map +1 -1
  85. package/nationalarchives/components/skip-link/skip-link.js +2 -0
  86. package/nationalarchives/components/skip-link/skip-link.js.map +1 -0
  87. package/nationalarchives/components/skip-link/skip-link.mjs +40 -0
  88. package/nationalarchives/components/skip-link/skip-link.scss +18 -16
  89. package/nationalarchives/components/skip-link/skip-link.stories.js +48 -6
  90. package/nationalarchives/components/skip-link/template.njk +1 -1
  91. package/nationalarchives/components/tabs/tabs.css +1 -1
  92. package/nationalarchives/components/tabs/tabs.css.map +1 -1
  93. package/nationalarchives/components/tabs/tabs.js +1 -1
  94. package/nationalarchives/components/tabs/tabs.js.map +1 -1
  95. package/nationalarchives/components/tabs/tabs.mjs +6 -2
  96. package/nationalarchives/components/tabs/tabs.scss +16 -1
  97. package/nationalarchives/lib/_font-awesome.scss +3 -2
  98. package/nationalarchives/lib/cookies.mjs +122 -50
  99. package/nationalarchives/stories/development/contributing.mdx +0 -10
  100. package/nationalarchives/stories/development/cookies.mdx +82 -0
  101. package/nationalarchives/stories/development/structure.mdx +88 -0
  102. package/nationalarchives/stories/development/using/compiled.mdx +9 -0
  103. package/nationalarchives/stories/development/using/hosted.mdx +53 -0
  104. package/nationalarchives/stories/development/using/npm.mdx +59 -0
  105. package/nationalarchives/stories/utilities/colour-schemes/colour-schemes.stories.js +284 -29
  106. package/nationalarchives/stories/utilities/typography/headings.stories.js +4 -1
  107. package/nationalarchives/stories/utilities/typography/lists.stories.js +93 -0
  108. package/nationalarchives/stories/utilities/typography/typography.mdx +11 -1
  109. package/nationalarchives/stories/utilities/typography/typography.stories.js +1 -1
  110. package/nationalarchives/templates/homepage.njk +11 -58
  111. package/nationalarchives/templates/layouts/_generic.njk +33 -14
  112. package/nationalarchives/templates/layouts/_prototype-kit.njk +11 -1
  113. package/nationalarchives/templates/search-results.njk +10 -14
  114. package/nationalarchives/templates/topics.njk +18 -22
  115. package/nationalarchives/tools/_colour.scss +42 -18
  116. package/nationalarchives/tools/_media.scss +6 -0
  117. package/nationalarchives/tools/_typography.scss +4 -2
  118. package/nationalarchives/utilities/_a11y.scss +15 -0
  119. package/nationalarchives/utilities/_debug.scss +1 -1
  120. package/nationalarchives/utilities/_global.scss +23 -25
  121. package/nationalarchives/utilities/_typography.scss +204 -27
  122. package/nationalarchives/variables/_assets.scss +2 -1
  123. package/nationalarchives/variables/_colour.scss +94 -73
  124. package/nationalarchives/variables/_features.scss +1 -0
  125. package/nationalarchives/variables/_grid.scss +5 -5
  126. package/nationalarchives/variables/_index.scss +1 -0
  127. package/nationalarchives/variables/_media.scss +29 -29
  128. package/nationalarchives/variables/_typography.scss +15 -12
  129. package/package.json +1 -1
  130. package/nationalarchives/_features.scss +0 -1
  131. package/nationalarchives/assets/images/tna-horizontal-logo-inverted.svg +0 -51
  132. package/nationalarchives/assets/images/tna-horizontal-logo.svg +0 -51
  133. package/nationalarchives/stories/development/relationships.mdx +0 -57
  134. package/nationalarchives/stories/development/using.mdx +0 -75
@@ -1 +1 @@
1
- {"version":3,"file":"components/tabs/tabs.js","mappings":"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","sources":["webpack://TNAFrontend/webpack/universalModuleDefinition","webpack://TNAFrontend/webpack/bootstrap","webpack://TNAFrontend/webpack/runtime/define property getters","webpack://TNAFrontend/webpack/runtime/hasOwnProperty shorthand","webpack://TNAFrontend/webpack/runtime/make namespace object","webpack://TNAFrontend/./src/nationalarchives/components/tabs/tabs.mjs"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"TNAFrontend\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"TNAFrontend\"] = factory();\n\telse\n\t\troot[\"TNAFrontend\"] = factory();\n})(self, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export class Tabs {\n constructor($module) {\n this.$module = $module;\n this.$tabList = $module && $module.querySelector(\".tna-tabs__list\");\n this.$tabListItemLinks =\n $module &&\n this.$tabList &&\n $module.querySelectorAll(\".tna-tabs__list-item-link\");\n this.$tabItems = $module && $module.querySelectorAll(\".tna-tabs__item\");\n }\n\n init() {\n if (\n !this.$module ||\n !this.$tabList ||\n !this.$tabListItemLinks ||\n !this.$tabItems ||\n this.$tabListItemLinks.length !== this.$tabItems.length\n ) {\n return;\n }\n\n this.sticky = this.$module.classList.contains(\"tna-tabs--sticky\");\n\n const startingTarget = window.location.hash.replace(/^#/, \"\");\n\n this.$newTabList = document.createElement(\"div\");\n this.$newTabList.setAttribute(\"role\", \"tablist\");\n this.$newTabList.setAttribute(\"class\", this.$tabList.getAttribute(\"class\"));\n\n this.$tabItems.forEach(($tabItem, index) => {\n $tabItem.setAttribute(\"role\", \"tabpanel\");\n $tabItem.setAttribute(\n \"aria-labelledby\",\n `${$tabItem.getAttribute(\"id\")}-tab`,\n );\n $tabItem.setAttribute(\"tabindex\", \"0\");\n if (\n (startingTarget && $tabItem.getAttribute(\"id\") !== startingTarget) ||\n (!startingTarget && index > 0)\n ) {\n $tabItem.setAttribute(\"hidden\", true);\n }\n });\n\n this.$tabListItemLinks.forEach(($tabListItemLink) => {\n const $replacementButton = document.createElement(\"button\");\n $replacementButton.innerText = $tabListItemLink.innerText;\n $replacementButton.setAttribute(\n \"class\",\n $tabListItemLink.getAttribute(\"class\"),\n );\n $replacementButton.setAttribute(\"role\", \"tab\");\n $replacementButton.setAttribute(\n \"id\",\n $tabListItemLink.getAttribute(\"id\"),\n );\n $replacementButton.setAttribute(\n \"aria-controls\",\n $tabListItemLink.getAttribute(\"href\").replace(/^#/, \"\"),\n );\n $replacementButton.setAttribute(\"tabindex\", \"-1\");\n this.$newTabList.appendChild($replacementButton);\n });\n\n this.$tabList.replaceWith(this.$newTabList);\n\n this.$tabListItemLinks = this.$module.querySelectorAll(\n \".tna-tabs__list-item-link\",\n );\n\n this.$tabListItemLinks.forEach(($tabListItemLink, index) => {\n if (\n (startingTarget &&\n $tabListItemLink.getAttribute(\"aria-controls\") ===\n `${startingTarget}`) ||\n (!startingTarget && index === 0)\n ) {\n $tabListItemLink.classList.add(\"tna-tabs__list-item-link--selected\");\n $tabListItemLink.setAttribute(\"aria-selected\", true);\n $tabListItemLink.setAttribute(\"tabindex\", \"0\");\n } else {\n $tabListItemLink.setAttribute(\"aria-selected\", false);\n }\n\n $tabListItemLink.addEventListener(\n \"keydown\",\n (e) => this.handleItemLinkKeyDown(e),\n true,\n );\n $tabListItemLink.addEventListener(\n \"click\",\n (e) => this.handleItemLinkClick(e),\n true,\n );\n });\n }\n\n handleItemLinkClick(itemLinkClickEvent) {\n itemLinkClickEvent.preventDefault();\n const targetItem =\n itemLinkClickEvent.currentTarget.getAttribute(\"aria-controls\");\n\n this.switchTab(targetItem);\n }\n\n handleItemLinkKeyDown(itemLinkKeyDownEvent) {\n const targetItem = itemLinkKeyDownEvent.currentTarget;\n let overwriteKeyAction = false;\n\n switch (itemLinkKeyDownEvent.key) {\n case \"ArrowLeft\":\n case \"ArrowUp\":\n this.setSelectedToPreviousTab(targetItem);\n overwriteKeyAction = true;\n break;\n\n case \"ArrowRight\":\n case \"ArrowDown\":\n this.setSelectedToNextTab(targetItem);\n overwriteKeyAction = true;\n break;\n\n case \"Home\":\n this.switchTab(this.$tabListItemLinks[0].getAttribute(\"aria-controls\"));\n overwriteKeyAction = true;\n break;\n\n case \"End\":\n this.switchTab(\n this.$tabListItemLinks[\n this.$tabListItemLinks.length - 1\n ].getAttribute(\"aria-controls\"),\n );\n overwriteKeyAction = true;\n break;\n\n default:\n break;\n }\n\n if (overwriteKeyAction) {\n itemLinkKeyDownEvent.stopPropagation();\n itemLinkKeyDownEvent.preventDefault();\n }\n }\n\n setSelectedToNextTab(targetItem) {\n console.log(\"setSelectedToNextTab\", targetItem);\n const currentIndex = [...this.$tabListItemLinks].findIndex(\n ($tabListItemLink) =>\n $tabListItemLink.getAttribute(\"id\") === targetItem.getAttribute(\"id\"),\n );\n let newIndex;\n if (currentIndex < this.$tabListItemLinks.length - 1) {\n newIndex = currentIndex + 1;\n } else {\n newIndex = 0;\n }\n console.log(currentIndex, newIndex);\n this.switchTab(\n this.$tabListItemLinks[newIndex].getAttribute(\"aria-controls\"),\n );\n }\n\n setSelectedToPreviousTab(targetItem) {\n console.log(\"setSelectedToPreviousTab\", targetItem);\n const currentIndex = [...this.$tabListItemLinks].findIndex(\n ($tabListItemLink) =>\n $tabListItemLink.getAttribute(\"id\") === targetItem.getAttribute(\"id\"),\n );\n let newIndex;\n if (currentIndex >= 1) {\n newIndex = currentIndex - 1;\n } else {\n newIndex = this.$tabListItemLinks.length - 1;\n }\n console.log(currentIndex, newIndex);\n this.switchTab(\n this.$tabListItemLinks[newIndex].getAttribute(\"aria-controls\"),\n );\n }\n\n switchTab(targetId) {\n this.$tabListItemLinks.forEach(($tabListItemLink) => {\n if ($tabListItemLink.getAttribute(\"aria-controls\") === targetId) {\n $tabListItemLink.classList.add(\"tna-tabs__list-item-link--selected\");\n $tabListItemLink.setAttribute(\"aria-selected\", true);\n $tabListItemLink.setAttribute(\"tabindex\", \"0\");\n $tabListItemLink.focus();\n } else {\n $tabListItemLink.classList.remove(\"tna-tabs__list-item-link--selected\");\n $tabListItemLink.setAttribute(\"aria-selected\", false);\n $tabListItemLink.setAttribute(\"tabindex\", \"-1\");\n }\n });\n\n this.$tabItems.forEach(($tabItem) => {\n if ($tabItem.getAttribute(\"id\") === targetId) {\n $tabItem.removeAttribute(\"hidden\");\n $tabItem.setAttribute(\"tabindex\", \"0\");\n } else {\n $tabItem.setAttribute(\"hidden\", true);\n $tabItem.setAttribute(\"tabindex\", \"-1\");\n }\n });\n\n if (this.sticky) {\n if (history.replaceState) {\n history.replaceState(null, null, `#${targetId}`);\n } else {\n location.hash = `#${targetId}`;\n }\n }\n }\n}\n"],"names":["root","factory","exports","module","define","amd","self","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","Tabs","$module","_classCallCheck","this","$tabList","querySelector","$tabListItemLinks","querySelectorAll","$tabItems","_this","length","sticky","classList","contains","startingTarget","window","location","hash","replace","$newTabList","document","createElement","setAttribute","getAttribute","forEach","$tabItem","index","concat","$tabListItemLink","$replacementButton","innerText","appendChild","replaceWith","add","addEventListener","e","handleItemLinkKeyDown","handleItemLinkClick","itemLinkClickEvent","preventDefault","targetItem","currentTarget","switchTab","itemLinkKeyDownEvent","overwriteKeyAction","setSelectedToPreviousTab","setSelectedToNextTab","stopPropagation","console","log","newIndex","currentIndex","_toConsumableArray","findIndex","targetId","focus","remove","removeAttribute","history","replaceState"],"sourceRoot":""}
1
+ {"version":3,"file":"components/tabs/tabs.js","mappings":"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","sources":["webpack://TNAFrontend/webpack/universalModuleDefinition","webpack://TNAFrontend/webpack/bootstrap","webpack://TNAFrontend/webpack/runtime/define property getters","webpack://TNAFrontend/webpack/runtime/hasOwnProperty shorthand","webpack://TNAFrontend/webpack/runtime/make namespace object","webpack://TNAFrontend/./src/nationalarchives/components/tabs/tabs.mjs"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"TNAFrontend\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"TNAFrontend\"] = factory();\n\telse\n\t\troot[\"TNAFrontend\"] = factory();\n})(self, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export class Tabs {\n constructor($module) {\n this.$module = $module;\n this.$tabList = $module && $module.querySelector(\".tna-tabs__list\");\n this.$tabListItemLinks =\n $module &&\n this.$tabList &&\n $module.querySelectorAll(\".tna-tabs__list-item-link\");\n this.$tabItems = $module && $module.querySelectorAll(\".tna-tabs__item\");\n }\n\n init() {\n if (\n !this.$module ||\n !this.$tabList ||\n !this.$tabListItemLinks ||\n !this.$tabItems ||\n this.$tabListItemLinks.length !== this.$tabItems.length\n ) {\n return;\n }\n\n this.sticky = this.$module.classList.contains(\"tna-tabs--sticky\");\n\n const startingTarget = window.location.hash.replace(/^#/, \"\");\n const doesStartingTargetExist = [...this.$tabItems].some(\n ($tabItem) => $tabItem.getAttribute(\"id\") === startingTarget,\n );\n\n this.$newTabList = document.createElement(\"div\");\n this.$newTabList.setAttribute(\"role\", \"tablist\");\n this.$newTabList.setAttribute(\"class\", this.$tabList.getAttribute(\"class\"));\n\n this.$tabItems.forEach(($tabItem, index) => {\n $tabItem.setAttribute(\"role\", \"tabpanel\");\n $tabItem.setAttribute(\n \"aria-labelledby\",\n `${$tabItem.getAttribute(\"id\")}-tab`,\n );\n $tabItem.setAttribute(\"tabindex\", \"0\");\n if (\n (doesStartingTargetExist &&\n $tabItem.getAttribute(\"id\") !== startingTarget) ||\n (!doesStartingTargetExist && index > 0)\n ) {\n $tabItem.setAttribute(\"hidden\", true);\n }\n });\n\n this.$tabListItemLinks.forEach(($tabListItemLink) => {\n const $replacementButton = document.createElement(\"button\");\n $replacementButton.innerText = $tabListItemLink.innerText;\n $replacementButton.setAttribute(\n \"class\",\n $tabListItemLink.getAttribute(\"class\"),\n );\n $replacementButton.setAttribute(\"role\", \"tab\");\n $replacementButton.setAttribute(\n \"id\",\n $tabListItemLink.getAttribute(\"id\"),\n );\n $replacementButton.setAttribute(\n \"aria-controls\",\n $tabListItemLink.getAttribute(\"href\").replace(/^#/, \"\"),\n );\n $replacementButton.setAttribute(\"tabindex\", \"-1\");\n this.$newTabList.appendChild($replacementButton);\n });\n\n this.$tabList.replaceWith(this.$newTabList);\n\n this.$tabListItemLinks = this.$module.querySelectorAll(\n \".tna-tabs__list-item-link\",\n );\n\n this.$tabListItemLinks.forEach(($tabListItemLink, index) => {\n if (\n (startingTarget &&\n $tabListItemLink.getAttribute(\"aria-controls\") ===\n `${startingTarget}`) ||\n (!startingTarget && index === 0)\n ) {\n $tabListItemLink.classList.add(\"tna-tabs__list-item-link--selected\");\n $tabListItemLink.setAttribute(\"aria-selected\", true);\n $tabListItemLink.setAttribute(\"tabindex\", \"0\");\n } else {\n $tabListItemLink.setAttribute(\"aria-selected\", false);\n }\n\n $tabListItemLink.addEventListener(\n \"keydown\",\n (e) => this.handleItemLinkKeyDown(e),\n true,\n );\n $tabListItemLink.addEventListener(\n \"click\",\n (e) => this.handleItemLinkClick(e),\n true,\n );\n });\n }\n\n handleItemLinkClick(itemLinkClickEvent) {\n itemLinkClickEvent.preventDefault();\n const targetItem =\n itemLinkClickEvent.currentTarget.getAttribute(\"aria-controls\");\n\n this.switchTab(targetItem);\n }\n\n handleItemLinkKeyDown(itemLinkKeyDownEvent) {\n const targetItem = itemLinkKeyDownEvent.currentTarget;\n let overwriteKeyAction = false;\n\n switch (itemLinkKeyDownEvent.key) {\n case \"ArrowLeft\":\n case \"ArrowUp\":\n this.setSelectedToPreviousTab(targetItem);\n overwriteKeyAction = true;\n break;\n\n case \"ArrowRight\":\n case \"ArrowDown\":\n this.setSelectedToNextTab(targetItem);\n overwriteKeyAction = true;\n break;\n\n case \"Home\":\n this.switchTab(this.$tabListItemLinks[0].getAttribute(\"aria-controls\"));\n overwriteKeyAction = true;\n break;\n\n case \"End\":\n this.switchTab(\n this.$tabListItemLinks[\n this.$tabListItemLinks.length - 1\n ].getAttribute(\"aria-controls\"),\n );\n overwriteKeyAction = true;\n break;\n\n default:\n break;\n }\n\n if (overwriteKeyAction) {\n itemLinkKeyDownEvent.stopPropagation();\n itemLinkKeyDownEvent.preventDefault();\n }\n }\n\n setSelectedToNextTab(targetItem) {\n console.log(\"setSelectedToNextTab\", targetItem);\n const currentIndex = [...this.$tabListItemLinks].findIndex(\n ($tabListItemLink) =>\n $tabListItemLink.getAttribute(\"id\") === targetItem.getAttribute(\"id\"),\n );\n let newIndex;\n if (currentIndex < this.$tabListItemLinks.length - 1) {\n newIndex = currentIndex + 1;\n } else {\n newIndex = 0;\n }\n console.log(currentIndex, newIndex);\n this.switchTab(\n this.$tabListItemLinks[newIndex].getAttribute(\"aria-controls\"),\n );\n }\n\n setSelectedToPreviousTab(targetItem) {\n console.log(\"setSelectedToPreviousTab\", targetItem);\n const currentIndex = [...this.$tabListItemLinks].findIndex(\n ($tabListItemLink) =>\n $tabListItemLink.getAttribute(\"id\") === targetItem.getAttribute(\"id\"),\n );\n let newIndex;\n if (currentIndex >= 1) {\n newIndex = currentIndex - 1;\n } else {\n newIndex = this.$tabListItemLinks.length - 1;\n }\n console.log(currentIndex, newIndex);\n this.switchTab(\n this.$tabListItemLinks[newIndex].getAttribute(\"aria-controls\"),\n );\n }\n\n switchTab(targetId) {\n this.$tabListItemLinks.forEach(($tabListItemLink) => {\n if ($tabListItemLink.getAttribute(\"aria-controls\") === targetId) {\n $tabListItemLink.classList.add(\"tna-tabs__list-item-link--selected\");\n $tabListItemLink.setAttribute(\"aria-selected\", true);\n $tabListItemLink.setAttribute(\"tabindex\", \"0\");\n $tabListItemLink.focus();\n } else {\n $tabListItemLink.classList.remove(\"tna-tabs__list-item-link--selected\");\n $tabListItemLink.setAttribute(\"aria-selected\", false);\n $tabListItemLink.setAttribute(\"tabindex\", \"-1\");\n }\n });\n\n this.$tabItems.forEach(($tabItem) => {\n if ($tabItem.getAttribute(\"id\") === targetId) {\n $tabItem.removeAttribute(\"hidden\");\n $tabItem.setAttribute(\"tabindex\", \"0\");\n } else {\n $tabItem.setAttribute(\"hidden\", true);\n $tabItem.setAttribute(\"tabindex\", \"-1\");\n }\n });\n\n if (this.sticky) {\n if (history.replaceState) {\n history.replaceState(null, null, `#${targetId}`);\n } else {\n location.hash = `#${targetId}`;\n }\n }\n }\n}\n"],"names":["root","factory","exports","module","define","amd","self","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","Tabs","$module","_classCallCheck","this","$tabList","querySelector","$tabListItemLinks","querySelectorAll","$tabItems","_this","length","sticky","classList","contains","startingTarget","window","location","hash","replace","doesStartingTargetExist","_toConsumableArray","some","$tabItem","getAttribute","$newTabList","document","createElement","setAttribute","forEach","index","concat","$tabListItemLink","$replacementButton","innerText","appendChild","replaceWith","add","addEventListener","e","handleItemLinkKeyDown","handleItemLinkClick","itemLinkClickEvent","preventDefault","targetItem","currentTarget","switchTab","itemLinkKeyDownEvent","overwriteKeyAction","setSelectedToPreviousTab","setSelectedToNextTab","stopPropagation","console","log","newIndex","currentIndex","findIndex","targetId","focus","remove","removeAttribute","history","replaceState"],"sourceRoot":""}
@@ -23,6 +23,9 @@ export class Tabs {
23
23
  this.sticky = this.$module.classList.contains("tna-tabs--sticky");
24
24
 
25
25
  const startingTarget = window.location.hash.replace(/^#/, "");
26
+ const doesStartingTargetExist = [...this.$tabItems].some(
27
+ ($tabItem) => $tabItem.getAttribute("id") === startingTarget,
28
+ );
26
29
 
27
30
  this.$newTabList = document.createElement("div");
28
31
  this.$newTabList.setAttribute("role", "tablist");
@@ -36,8 +39,9 @@ export class Tabs {
36
39
  );
37
40
  $tabItem.setAttribute("tabindex", "0");
38
41
  if (
39
- (startingTarget && $tabItem.getAttribute("id") !== startingTarget) ||
40
- (!startingTarget && index > 0)
42
+ (doesStartingTargetExist &&
43
+ $tabItem.getAttribute("id") !== startingTarget) ||
44
+ (!doesStartingTargetExist && index > 0)
41
45
  ) {
42
46
  $tabItem.setAttribute("hidden", true);
43
47
  }
@@ -1,6 +1,7 @@
1
1
  @use "../../tools/colour";
2
- @use "../../tools/typography";
2
+ @use "../../tools/media";
3
3
  @use "../../tools/spacing";
4
+ @use "../../tools/typography";
4
5
  @use "../../utilities";
5
6
 
6
7
  .tna-tabs {
@@ -140,4 +141,18 @@
140
141
  @include colour.colour-border("keyline-dark", 1px);
141
142
  }
142
143
  }
144
+
145
+ @include media.on-print {
146
+ &__list {
147
+ display: none;
148
+ }
149
+
150
+ &__item {
151
+ display: block !important;
152
+
153
+ & + & {
154
+ margin-top: 2rem;
155
+ }
156
+ }
157
+ }
143
158
  }
@@ -1,5 +1,6 @@
1
- @import "../variables/assets";
2
- $fa-font-path: $tna-font-path !default;
1
+ @use "../variables/assets";
2
+
3
+ $fa-font-path: assets.$fa-font-path;
3
4
  @import "font-awesome/fontawesome";
4
5
  @import "font-awesome/solid";
5
6
  @import "font-awesome/brands";
@@ -1,32 +1,43 @@
1
+ /**
2
+ * Class to handle cookies.
3
+ * @class Cookies
4
+ * @constructor
5
+ * @public
6
+ */
1
7
  export default class Cookies {
8
+ /** @protected */
2
9
  #policies = {};
3
10
 
11
+ /**
12
+ * Create a cookie handler.
13
+ * @param {string[]} [policies=usage,settings] - The cookie policies to manage.
14
+ * @param {string} [cookiesPolicyKey=cookies_policy] - The name of the cookie.
15
+ */
4
16
  constructor(
5
- policies = ["analytics", "settings"],
17
+ policies = ["usage", "settings"],
6
18
  cookiesPolicyKey = "cookies_policy",
7
- crossDomain = false,
8
19
  ) {
9
20
  this.cookiesPolicyKey = cookiesPolicyKey;
10
- this.crossDomain = crossDomain;
11
21
  policies.forEach((policy) => {
12
- this.#policies[policy] = false;
22
+ this.#policies[policy.toLowerCase()] = false;
13
23
  });
14
- this.#getPolicies();
24
+ this.#policies.essential = true;
15
25
  }
16
26
 
17
- #getPolicies() {
18
- if (this.exists(this.cookiesPolicyKey)) {
19
- this.#policies = {
20
- ...this.#policies,
21
- ...this.allPolicies,
22
- };
23
- }
27
+ get policies() {
28
+ return this.exists(this.cookiesPolicyKey)
29
+ ? (this.#policies = {
30
+ ...this.#policies,
31
+ ...this.allPolicies,
32
+ })
33
+ : this.#policies;
24
34
  }
25
35
 
26
- get data() {
27
- return this.#deserialise(document.cookie);
36
+ set policies(newPolicyValues) {
37
+ this.#policies = newPolicyValues;
28
38
  }
29
39
 
40
+ /** @protected */
30
41
  #deserialise(cookieString) {
31
42
  const deserialised = {};
32
43
  cookieString.split(";").forEach((cookie) => {
@@ -37,74 +48,135 @@ export default class Cookies {
37
48
  }
38
49
 
39
50
  get all() {
40
- return this.data;
41
- }
42
-
43
- get allPolicies() {
44
- return JSON.parse(this.get(this.cookiesPolicyKey));
51
+ return this.#deserialise(document.cookie);
45
52
  }
46
53
 
54
+ /**
55
+ * Check to see whether a cookie exists or not.
56
+ * @param {string} key - The cookie name.
57
+ * @returns {boolean}
58
+ */
47
59
  exists(key) {
48
- return Object.prototype.hasOwnProperty.call(this.data, key);
60
+ return Object.prototype.hasOwnProperty.call(this.all, key);
49
61
  }
50
62
 
63
+ /**
64
+ * Check to see whether a cookie has a particular value.
65
+ * @param {string} key - The cookie name.
66
+ * @param {string|number|boolean} value - The value to check against.
67
+ * @returns
68
+ */
51
69
  hasValue(key, value) {
52
- return this.get(key) === value;
70
+ return this.get(key) == value;
53
71
  }
54
72
 
73
+ /**
74
+ * Get a cookie.
75
+ * @param {string} key - The cookie name.
76
+ * @returns {string|number|boolean}
77
+ */
55
78
  get(key) {
56
- return decodeURIComponent(this.data[key]);
79
+ return this.exists(key) ? decodeURIComponent(this.all[key]) : null;
80
+ }
81
+
82
+ /**
83
+ * Set a cookie.
84
+ * @param {string} key - The cookie name.
85
+ * @param {string|number|boolean} value - The cookie value.
86
+ * @param {Object} options
87
+ * @param {number} [options.maxAge=31536000] - The maximum age of the cookie in seconds.
88
+ * @param {string} [options.path=/] - The path to register the cookie for.
89
+ * @param {string} [options.sameSite=Lax] - The sameSite attribute.
90
+ */
91
+ set(key, value, options = {}) {
92
+ const {
93
+ maxAge = 60 * 60 * 24 * 365,
94
+ path = "/",
95
+ sameSite = "Lax",
96
+ } = options;
97
+ document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(
98
+ value,
99
+ )}; SameSite=${sameSite}; path=${path}; max-age=${maxAge}; Secure`;
57
100
  }
58
101
 
102
+ /**
103
+ * Delete a cookie.
104
+ * @param {string} key - The cookie name.
105
+ * @param {string} [path=/] - The path to the cookie is registered on.
106
+ */
59
107
  delete(key, path = "/") {
60
108
  this.set(key, "", 0, path);
61
109
  }
62
110
 
111
+ get allPolicies() {
112
+ return JSON.parse(this.get(this.cookiesPolicyKey) || "{}");
113
+ }
114
+
115
+ /**
116
+ * Accept a policy.
117
+ * @param {string} policy - The name of the policy.
118
+ */
63
119
  acceptPolicy(policy) {
64
- this.setPolicy(policy, true);
120
+ this.#setPolicy(policy, true);
121
+ this.savePolicies();
65
122
  }
66
123
 
124
+ /**
125
+ * Reject a policy.
126
+ * @param {string} policy - The name of the policy.
127
+ */
67
128
  rejectPolicy(policy) {
68
- this.setPolicy(policy, false);
129
+ if (policy === "essential") {
130
+ return;
131
+ }
132
+ this.#setPolicy(policy, false);
133
+ this.savePolicies();
69
134
  }
70
135
 
71
- setPolicy(policy, accepted) {
72
- this.#policies = {
73
- ...this.#policies,
136
+ /** @protected */
137
+ #setPolicy(policy, accepted) {
138
+ this.policies = {
139
+ ...this.policies,
74
140
  [policy]: accepted,
141
+ essential: true,
75
142
  };
76
- this.set(this.cookiesPolicyKey, JSON.stringify(this.#policies));
77
143
  }
78
144
 
145
+ /**
146
+ * Commit the policy preferences to the browser.
147
+ */
148
+ savePolicies() {
149
+ this.set(this.cookiesPolicyKey, JSON.stringify(this.policies));
150
+ }
151
+
152
+ /**
153
+ * Accept all the cookie policies.
154
+ */
79
155
  acceptAllPolicies() {
80
- Object.keys(this.#policies)
81
- .filter((policy) => this.#policies[policy] === false)
82
- .forEach((policy) => this.acceptPolicy(policy));
156
+ Object.keys(this.policies).forEach((policy) =>
157
+ this.#setPolicy(policy, true),
158
+ );
159
+ this.savePolicies();
83
160
  }
84
161
 
162
+ /**
163
+ * Reject all the cookie policies.
164
+ */
85
165
  rejectAllPolicies() {
86
- Object.keys(this.#policies)
87
- .filter((policy) => this.#policies[policy] === true)
88
- .forEach((policy) => this.rejectPolicy(policy));
166
+ Object.keys(this.policies).forEach((policy) =>
167
+ this.#setPolicy(policy, false),
168
+ );
169
+ this.savePolicies();
89
170
  }
90
171
 
172
+ /**
173
+ * Get the acceptance status of a policy.
174
+ * @param {string} policy - The name of the policy.
175
+ * @returns {boolean}
176
+ */
91
177
  isPolicyAccepted(policy) {
92
- this.#getPolicies();
93
- return Object.prototype.hasOwnProperty.call(this.#policies, policy)
94
- ? this.#policies[policy] === true
178
+ return Object.prototype.hasOwnProperty.call(this.policies, policy)
179
+ ? this.policies[policy] === true
95
180
  : null;
96
181
  }
97
-
98
- set(key, value, maxAge = 60 * 60 * 24 * 365, path = "/") {
99
- document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(
100
- value,
101
- )}; SameSite=${
102
- this.crossDomain ? "None" : "Lax"
103
- }; path=${path}; max-age=${maxAge}; Secure`;
104
- this.#getPolicies();
105
- }
106
-
107
- policy(policy) {
108
- return this.#policies[policy];
109
- }
110
182
  }
@@ -30,13 +30,3 @@ import { Meta } from "@storybook/blocks";
30
30
  1. Import and initialise your component as part of the `initAll` function in `src/nationalarchives/all.mjs`
31
31
  1. Update the check in `tasks/test-package.js` to add the JavaScript class to check for
32
32
  1. If your component uses JavaScript, ensure you add interaction tests using `@storybook/testing-library`
33
-
34
- ### Best practices
35
-
36
- - [HTML standards](https://nationalarchives.github.io/developer-handbook/technology/html/)
37
- - [JavaScript standards](https://nationalarchives.github.io/developer-handbook/technology/javascript/)
38
- - [CSS standards](https://nationalarchives.github.io/developer-handbook/technology/css/)
39
-
40
- ## Updating a component
41
-
42
- [TODO]
@@ -0,0 +1,82 @@
1
+ import { Meta } from "@storybook/blocks";
2
+ import { Mermaid } from 'mdx-mermaid/Mermaid';
3
+
4
+ <Meta title="Development/Cookies" />
5
+
6
+ # Cookies handling
7
+
8
+ The principles of cookie handling are:
9
+
10
+ - Create cookies on the client side (apart from session cookies)
11
+ - Update cookies on the client side (apart from session cookies)
12
+ - Reject by default (don't assume acceptance and don't add tracking until after they agree)
13
+
14
+ ## Policies
15
+
16
+ As standard we should use at least these three classes of cookies:
17
+
18
+ - `essential` - we don't need to ask permission for these
19
+ - `usage` - analytics, tracking, data gathering
20
+ - `settings` - configured options for the site (e.g. default results view or static light/dark mode)
21
+
22
+ ## Process
23
+
24
+ ### First visit
25
+
26
+ <Mermaid chart={`sequenceDiagram
27
+ User->>Browser: Request page
28
+ Browser->>Server: HTTP request with no cookies
29
+ Server->>Browser: Rendered HTML with cookie banner and no analytics
30
+ Browser->>User: Accept cookies?
31
+ alt Accept
32
+ User->>Browser: Accept cookies
33
+ Browser->>Browser: Create cookie policy with all accepted
34
+ Browser->>Browser: Add analytics code with JavaScript
35
+ else Reject
36
+ User->>Browser: Reject cookies
37
+ Browser->>Browser: Create cookie policy with all rejected
38
+ end
39
+ opt Next request
40
+ User->>Browser: Request page
41
+ Browser->>Server: HTTP request with cookie policy
42
+ Server->>Browser: Rendered HTML with analytics but no cookie banner
43
+ end
44
+ `} />
45
+
46
+ ### Repeat visit
47
+
48
+ <Mermaid chart={`sequenceDiagram
49
+ User->>Browser: Request page
50
+ Browser->>Server: HTTP request with cookie policy
51
+ Server->>Browser: Rendered HTML with analytics but no cookie banner
52
+ `} />
53
+
54
+ ## Cookie library
55
+
56
+ When you load in the tna-frontend JavaScript, it comes with a [cookie library](https://github.com/nationalarchives/tna-frontend/blob/main/src/nationalarchives/lib/cookies.mjs).
57
+
58
+ This is loaded into the `window` object as `TNAFrontend.Cookies`:
59
+
60
+ ```JavaScript
61
+ // Initialise a new Cookie instance
62
+ const cookies = new TNAFrontend.Cookies();
63
+
64
+ // Log all the cookies to the console
65
+ console.log(cookies.all);
66
+ ```
67
+
68
+ ### Functions
69
+
70
+ - `cookies.all` - Returns all the cookies
71
+ - `cookies.exists(key)` - Returns `true` if a cookie exists with the name `key`
72
+ - `cookies.hasValue(key, value)` - Returns `true` if the cookie with the name `key` is equal to `value`
73
+ - `cookies.get(key)` - Returns the cookie with the name `key`
74
+ - `cookies.set(key, value, maxAge, path)` - Set a cookie (max age default is one year, default path is `/`)
75
+ - `cookies.delete(key)` - Deletes the cookie with the name `key`
76
+ - `cookies.allPolicies` - Returns all the cookie policies
77
+ - `cookies.acceptPolicy(policy)` - Accepts the policy with the name `policy`
78
+ - `cookies.rejectPolicy(policy)` - Rejects the policy with the name `policy`
79
+ - `cookies.setPolicy(policy, accepted)` - Accepts or rejects the policy with the name `policy` depending on the value of `accepted`
80
+ - `cookies.acceptAllPolicies()` - Accepts all policies
81
+ - `cookies.rejectAllPolicies()` - Rejects all policies
82
+ - `cookies.isPolicyAccepted(policy)` - Returns `true` or `false` depending on whether the policy has been accepted
@@ -0,0 +1,88 @@
1
+ import { Meta } from "@storybook/blocks";
2
+
3
+ <Meta title="Development/Structure" />
4
+
5
+ # Structure
6
+
7
+ The layers of the TNA frontend SCSS library is built as:
8
+
9
+ 1. [Variables](#variables)
10
+ 1. [Tools](#tools)
11
+ 1. [Libraries](#libraries)/[Utilities](#utilities)
12
+ 1. [Components](#components)
13
+ 1. [Overrides](#overrides)
14
+
15
+ ## Variables
16
+
17
+ TNA frontend variables are defined in `src/nationalarchives/variables`.
18
+
19
+ Lots of variables can be modified but some are fixed, such as our brand colours.
20
+
21
+ An example fixed variable is `$relative-1rem-px` where we set the value of `1rem` to `16px` which makes it easier to define widths as a function of `1rem` as we mostly work on a 4px grid:
22
+
23
+ | Pixels | REM |
24
+ | ------ | ----------- |
25
+ | `1px` | `0.0625rem` |
26
+ | `2px` | `0.125rem` |
27
+ | `4px` | `0.25rem` |
28
+ | `8px` | `0.5rem` |
29
+ | `16px` | `1rem` |
30
+ | `32px` | `2rem` |
31
+ | `64px` | `4rem` |
32
+
33
+ An example of a variable that can be modified is `$body-font-size-px` which we set to `18px` by default. This font size might not be right for all services so we have allowed it to be modified.
34
+
35
+ ## Tools
36
+
37
+ The tools provided are reusable `@mixin` and `@function` blocks to make writing styles easier. They are defined in `src/nationalarchives/tools`.
38
+
39
+ Tools rely directly on variables and can be used throughout the frontend library.
40
+
41
+ As an exmaple, `colour-font()` will apply a font colour in a way that should work for all browsers and takes into consideration the light/dark theme used.
42
+
43
+ ## Libraries
44
+
45
+ The libraries in `src/nationalarchives/lib` are a mix of third party libraries as well as some TNA ones.
46
+
47
+ They can join up tools to make larger, more useful elements.
48
+
49
+ ## Utilities
50
+
51
+ The utilities in `src/nationalarchives/utilities` are some global styles that aren't associated with a specific component.
52
+
53
+ This layer is where we define some general purpose elements such as:
54
+
55
+ - The `tna-template` and `tna-template__body` elements
56
+ - Headings
57
+ - Lists
58
+ - Chips
59
+ - `<p>` elements
60
+ - General media elements like `<img>`, `<svg>`, `<picture>`, `<video>` and `<canvas>`
61
+ - Columns
62
+ - General form elements
63
+
64
+ These elements all still adhere to the [BEM methodology](https://getbem.com/).
65
+
66
+ Utilities should not implement any `!important` rules.
67
+
68
+ ## Components
69
+
70
+ The most prominent layer of styling, the components in `src/nationalarchives/components` should use the tools already defined.
71
+
72
+ Components shouldn't use variables directly. They shouldn't use static values for colour unless the colour of that component will never change, for example the message component which is always yellow.
73
+
74
+ Some components may use utilities such as headings. Where these styles have already been defined, they should not be redefined. The heading in a cookie banner should use the existing `tna-heading` and `tna-heading--m` styles that already exist rather than implimenting its own.
75
+
76
+ Components should not implement any `!important` rules. There are exceptions such as the skip link that needs to be visually hidden in a way that it is still available for someone navigating a site with a keyboard.
77
+
78
+ Components should not care about the context or layout within which they are used. As an example, a breadcrumb *could* be placed within a card or a footer element although in reality we wouldn't allow this.
79
+
80
+ ## Overrides
81
+
82
+ Overrides start with `tna-!--` and can only be used in HTML classes. They have `!important` rules.
83
+
84
+ Examples of overrides are:
85
+
86
+ - Spacing (margin, padding etc.)
87
+ - No focus style (`.tna-!--no-focus-style`) for items such as the target element of a skip link
88
+ - Visibly hidden content (used to add extra descriptions which appear for screenreaders only)
@@ -0,0 +1,9 @@
1
+ import { Meta } from "@storybook/blocks";
2
+
3
+ <Meta title="Development/Using/Compiled" />
4
+
5
+ # Using the compiled files
6
+
7
+ Each release (as of `v0.1.21-prerelease`) should contain a ZIP of the package.
8
+
9
+ Find the release you want on the `tna-frontend` [releases page](https://github.com/nationalarchives/tna-frontend/releases) and download the package from the "Assets" dropdown.
@@ -0,0 +1,53 @@
1
+ import { Meta } from "@storybook/blocks";
2
+
3
+ <Meta title="Development/Using/Hosted" />
4
+
5
+ # Using with a hosted solution
6
+
7
+ The `@nationalarchives/frontend` package is available on [jsdelivr.com](https://www.jsdelivr.com/package/npm/@nationalarchives/frontend).
8
+
9
+ While you can use the CSS and JavaScript from there, the font files which includes the icon font will have to be hosted from your web application.
10
+
11
+ As a result, **using a hosted solution is not the preferred method for using the `tna-frontend` library**.
12
+
13
+ ## All components and styles
14
+
15
+ Include the CSS in the `<head>` element of your page:
16
+
17
+ ```html
18
+ <link href="https://cdn.jsdelivr.net/npm/@nationalarchives/frontend@0.1.18-prerelease/nationalarchives/all.css" rel="stylesheet" integrity="sha384-6Egfw6aX1Jrwuf+APn+BMPswroudkIQ6StU095OPkNCKLEzj7ksWGmYxjend8P7g" crossorigin="anonymous">
19
+ ```
20
+
21
+ ### JavaScript
22
+
23
+ Add the JavaScript to the end of your page just before your closing `</body>` tag:
24
+
25
+ ```html
26
+ <script src="https://cdn.jsdelivr.net/npm/@nationalarchives/frontend@0.1.18-prerelease/nationalarchives/all.js" integrity="sha384-sBkiMlxl9svXopGxNSMVAdALjzyvh6sQHp+21PE3LGfTxAEbG4EIpK" crossorigin="anonymous"></script>
27
+ <script>
28
+ // Initialise all TNA components
29
+ window.TNAFrontend.initAll();
30
+ </script>
31
+ ```
32
+
33
+ ...or use the module syntax:
34
+
35
+ ```
36
+ <script type="module">
37
+ import { initAll } from "https://cdn.jsdelivr.net/npm/@nationalarchives/frontend@0.1.18-prerelease/nationalarchives/all.js";
38
+ initAll();
39
+ </script>
40
+ ```
41
+
42
+ ## Specific components
43
+
44
+ ```html
45
+ <link href="https://cdn.jsdelivr.net/npm/@nationalarchives/frontend@0.1.18-prerelease/nationalarchives/components/tabs.css" rel="stylesheet" integrity="sha384-hkx4svJn1A7pWYlzaDRMmtIBBijZdEop+M1Y/H4Hdg8aAqZRJHG56RokLk/eqJYl" crossorigin="anonymous">
46
+ ```
47
+
48
+ ### JavaScript
49
+
50
+ ```html
51
+ <!-- JavaScript for a single component -->
52
+ <script src="https://cdn.jsdelivr.net/npm/@nationalarchives/frontend@0.1.18-prerelease/nationalarchives/components/tabs.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
53
+ ```