From a8ba53fce4867e4f9ed1ece801e22e4240f1434d Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Tue, 14 Nov 2023 18:43:24 +0000 Subject: [PATCH] Tweaks from 0.1.24 (#51) * Move TypeKit CSS to prototype kit config * GOV.UK prototype kit fixes * Remove transitions * Fixed width icons * Spelling mistake * More colour examples * Add styling for tables * Fix card supertitle * Allow column alignment * Change header layout to flexbox * Adjust hero caption width * Add color to tint and light accent backgrounds * Add plain supertitle heading story * Updates to card component * Change grid alignment classes * Lint * Remove margin and padding from all elements * Updates and fixes to cookie banner * Spelling mistake * Update CHANGELOG.md * Fix linting and test errors * Use TNAFrontend from window if available * Update README.md * Omit some stories from Chromatic snapshots * Omit more stories from Chromatic snapshots * Fix spelling mistake in published assets * Update README.md * Rework Cookie class * More immutability in Cookies class, lint * Change focus outline colour on dark theme * Pagination option with no numbers, nested lists * Update list of cards markup * Add table wrapper * Change table to use space-above * Make smaller tables full width * Update Cookies library * Add more linting and unit tests --- .babelrc.json | 9 +- .eslintrc.js | 36 +- .github/workflows/npm-publish.yml | 6 +- .storybook/preview.js | 16 +- CHANGELOG.md | 28 + README.md | 22 + govuk-prototype-kit.config.json | 16 +- jest.config.js | 6 + package-lock.json | 874 +++++++++++------- package.json | 9 +- .../breadcrumbs/breadcrumbs.stories.js | 2 +- .../components/button/button.scss | 16 +- .../components/button/template.njk | 4 +- .../components/card/card.scss | 8 +- .../components/card/card.stories.js | 84 +- .../components/card/fixtures.json | 34 +- .../components/card/macro-options.json | 58 +- .../components/card/template.njk | 91 +- .../cookie-banner/cookie-banner.mjs | 33 +- .../cookie-banner/cookie-banner.stories.js | 135 ++- .../components/cookie-banner/fixtures.json | 43 +- .../cookie-banner/macro-options.json | 8 +- .../components/cookie-banner/template.njk | 2 +- .../components/filters/filters.scss | 12 +- .../components/filters/template.njk | 2 +- .../components/footer/footer.stories.js | 2 +- .../components/footer/template.njk | 6 +- .../components/gallery/gallery.stories.js | 4 +- .../components/grid/grid.scss | 12 + .../components/grid/grid.stories.js | 12 + .../components/header/header.scss | 32 +- .../components/header/template.njk | 4 +- .../components/hero/hero.scss | 4 +- .../components/hero/hero.stories.js | 6 + .../index-grid/index-grid.stories.js | 4 +- .../components/pagination/macro-options.json | 6 + .../components/pagination/pagination.scss | 4 + .../pagination/pagination.stories.js | 65 +- .../components/pagination/template.njk | 11 +- .../sensitive-image.stories.js | 3 + .../components/skip-link/skip-link.stories.js | 5 +- .../components/tabs/tabs.stories.js | 9 +- src/nationalarchives/lib/cookies.mjs | 206 +++-- src/nationalarchives/prototype-kit.scss | 6 +- .../colour-schemes/colour-schemes.stories.js | 218 +++-- .../utilities/overrides/overrides.stories.js | 1 + .../stories/utilities/tables/tables.mdx | 8 + .../utilities/tables/tables.stories.js | 45 + .../typography/heading-groups.stories.js | 78 +- .../templates/layouts/_prototype-kit.njk | 2 + src/nationalarchives/tests/cookies.test.js | 9 + src/nationalarchives/tools/_colour.scss | 2 + src/nationalarchives/utilities/_index.scss | 1 + src/nationalarchives/utilities/_lists.scss | 5 + src/nationalarchives/utilities/_tables.scss | 86 ++ .../utilities/_typography.scss | 25 +- src/nationalarchives/variables/_colour.scss | 1 + webpack.config.js | 1 - 58 files changed, 1630 insertions(+), 807 deletions(-) create mode 100644 jest.config.js create mode 100644 src/nationalarchives/stories/utilities/tables/tables.mdx create mode 100644 src/nationalarchives/stories/utilities/tables/tables.stories.js create mode 100644 src/nationalarchives/tests/cookies.test.js create mode 100644 src/nationalarchives/utilities/_tables.scss diff --git a/.babelrc.json b/.babelrc.json index ced787a4..fbaf389e 100644 --- a/.babelrc.json +++ b/.babelrc.json @@ -10,5 +10,10 @@ } ] ], - "plugins": [] -} \ No newline at end of file + "plugins": [], + "env": { + "test": { + "plugins": ["@babel/plugin-transform-modules-commonjs"] + } + } +} diff --git a/.eslintrc.js b/.eslintrc.js index 2baca9da..cc41cc02 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,21 +1,23 @@ module.exports = { - "env": { - "browser": true, - "es2021": true + env: { + browser: true, + es2021: true, }, - "extends": ["eslint:recommended", "plugin:storybook/recommended"], - "overrides": [{ - "env": { - "node": true + extends: ["eslint:recommended", "plugin:storybook/recommended"], + overrides: [ + { + env: { + node: true, + }, + files: [".eslintrc.{js,cjs}"], + parserOptions: { + sourceType: "script", + }, }, - "files": [".eslintrc.{js,cjs}"], - "parserOptions": { - "sourceType": "script" - } - }], - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" + ], + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", }, - "rules": {} -}; \ No newline at end of file + rules: {}, +}; diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index fdf0779e..0cdacec0 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -82,11 +82,11 @@ jobs: - name: Publish to npm run: cd package && npm publish - name: Rename package directory - run: mv package "nationalarhives-frontend-${{ needs.check.outputs.version }}" + run: mv package "tna-frontend-${{ needs.check.outputs.version }}" - name: Compress package - run: zip -r "nationalarhives-frontend-${{ needs.check.outputs.version }}.zip" "nationalarhives-frontend-${{ needs.check.outputs.version }}" + run: zip -r "tna-frontend-${{ needs.check.outputs.version }}.zip" "tna-frontend-${{ needs.check.outputs.version }}" - name: Upload the package to the GitHub release - run: gh release upload "v${{ needs.check.outputs.version }}" "nationalarhives-frontend-${{ needs.check.outputs.version }}.zip" + run: gh release upload "v${{ needs.check.outputs.version }}" "tna-frontend-${{ needs.check.outputs.version }}.zip" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.storybook/preview.js b/.storybook/preview.js index c7661716..7d217d41 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,6 +1,7 @@ import "../src/nationalarchives/all.scss"; import { a11yConfig } from "./storybook-config"; import { customViewports } from "./viewports"; +import Cookies from "../src/nationalarchives/lib/cookies.mjs"; // import isChromatic from "chromatic/isChromatic"; document.documentElement.classList.add( @@ -14,7 +15,7 @@ document.body.classList.add("tna-template__body"); export const parameters = { actions: { - disable: true, + // disable: true, }, viewport: { viewports: customViewports }, options: { showPanel: true }, @@ -33,6 +34,19 @@ export const parameters = { }, }; +export const decorators = [ + (Story, ctx) => { + window.dataLayer = []; + window.TNAFrontend = { + Cookies, + }; + const cookies = new Cookies(); + cookies.deleteAll(); + cookies.destroy(); + return Story(); + }, +]; + // const fontLoader = async () => ({ // fonts: await Promise.all([ // document.fonts.load("normal 1em Open Sans"), diff --git a/CHANGELOG.md b/CHANGELOG.md index 6547543c..06bd205f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/nationalarchives/tna-frontend/compare/v0.1.24-prerelease...HEAD) ### Added + +- Grid columns can be aligned along the cross axis with classes `tna-column--align-top`, `tna-column--align-bottom` and `tna-column--align-centre` +- Actions and items using the `href` attribute on cards can now have custom classes and attributes +- Events can now be added when cookie preferences change +- Table styles added +- Pagination component has the option to have no numbers +- Table wrapper for tables wider than the current viewport + ### Changed + +- Change many instances of Font Awesome icons to a fixed width +- Adjusted the width of the hero caption +- Removed margin and padding from all elements by default +- The standard cookie policies are always `essential`, `usage` and `settings` - other custom policies can be added +- Focus outline on dark themes has changed from blue to orange to avoid colour conflict with links + ### Deprecated ### Removed + +- Removed CSS to counter conflicting GOV.UK paragraph styling +- Transitions removed from most elements +- `loadScriptsOnAccept` option for cookie banner removed in favour of callback events + ### Fixed + +- Assets path fixed for GOV.UK prototype kit +- Colour fixed for plain card supertitles in accented style +- Header navigation uses flexbox for layout of tabs and top navigation stacks on mobile +- Explicitly declare font colour for tinted and light accent backgrounds +- Accepting or declining individual cookie policies now works +- Removed extra space from nested links + ### Security ## [0.1.24-prerelease](https://github.com/nationalarchives/tna-frontend/compare/v0.1.23-prerelease...v0.1.24-prerelease) - 2023-11-06 diff --git a/README.md b/README.md index 23282d6d..5ea3f6cd 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,25 @@ npm install # Start Storybook npm start ``` + +## Useful links + +- [TNA Frontend Storybook](https://nationalarchives.github.io/tna-frontend/) +- [TNA Frontend wiki](https://github.com/nationalarchives/tna-frontend/wiki) +- [National Archives Design System](https://nationalarchives.github.io/design-system/) + +## Accessibility + +The National Archives Digital Services team works hard to ensure that TNA Frontend is accessible. + +Using Frontend will help your service meet [level AA of WCAG 2.2](https://www.gov.uk/service-manual/helping-people-to-use-your-service/understanding-wcag). But you must still [check that your service meets accessibility requirements](https://www.gov.uk/service-manual/helping-people-to-use-your-service/making-your-service-accessible-an-introduction), especially if you extend or modify components. + +You should also use: + +- [the JavaScript from TNA Frontend](https://github.com/nationalarchives/tna-frontend/wiki/Using-TNA-Frontend#javascript) + +You can also read the [accessibility statement for the National Archives Design System](https://nationalarchives.github.io/design-system/accessibility/). + +### Accessibility warnings + +If you get a warning from a linter or accessibility checker, check our list of [issues you should not need to fix](https://github.com/nationalarchives/tna-frontend/wiki/Accessibility-issues-you-should-not-need-to-fix). diff --git a/govuk-prototype-kit.config.json b/govuk-prototype-kit.config.json index 8900c09c..3c8932fc 100644 --- a/govuk-prototype-kit.config.json +++ b/govuk-prototype-kit.config.json @@ -1,16 +1,8 @@ { - "nunjucksPaths": [ - "/" - ], - "scripts": [ - "/nationalarchives/all.js" - ], - "assets": [ - "/nationalarchives/assets" - ], - "stylesheets": [ - "/nationalarchives/prototype-kit.css" - ], + "nunjucksPaths": ["/"], + "scripts": ["/nationalarchives/all.js"], + "assets": ["/nationalarchives/assets"], + "stylesheets": ["/nationalarchives/prototype-kit.css"], "templates": [ { "name": "Homepage", diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..e857e0a3 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,6 @@ +module.exports = { + testEnvironment: "jsdom", + transform: { + "\\.m?js$": "babel-jest", + }, +}; diff --git a/package-lock.json b/package-lock.json index 8efb8ff6..6c30c414 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "@storybook/test-runner": "^0.13.0", "@storybook/testing-library": "^0.2.2", "axe-playwright": "^1.2.3", + "babel-jest": "^29.7.0", "babel-loader": "^9.0.1", "chromatic": "^7.5.0", "copy-webpack-plugin": "^11.0.0", @@ -33,7 +34,7 @@ "eslint": "^8.52.0", "eslint-plugin-storybook": "^0.6.15", "glob": "^10.3.10", - "jest-image-snapshot": "^6.2.0", + "jest-environment-jsdom": "^29.7.0", "jsdom": "^22.1.0", "mdx-mermaid": "^2.0.0", "node-self": "^1.0.2", @@ -333,9 +334,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", - "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -1284,12 +1285,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", - "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -7969,6 +7970,41 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "node_modules/@types/jsdom/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@types/jsdom/node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/@types/json-schema": { "version": "7.0.14", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", @@ -8152,6 +8188,12 @@ "integrity": "sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==", "dev": true }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true + }, "node_modules/@types/unist": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.9.tgz", @@ -8724,6 +8766,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "node_modules/acorn-import-assertions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", @@ -8742,6 +8794,15 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/address": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", @@ -9157,87 +9218,26 @@ } }, "node_modules/babel-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", - "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "dependencies": { - "@jest/transform": "^28.1.3", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.1.3", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.8.0" } }, - "node_modules/babel-jest/node_modules/@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/babel-jest/node_modules/@jest/transform": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", - "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^28.1.3", - "@jridgewell/trace-mapping": "^0.3.13", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.3", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/babel-jest/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/babel-jest/node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", - "dev": true - }, "node_modules/babel-jest/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -9269,12 +9269,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/babel-jest/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, "node_modules/babel-jest/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -9284,57 +9278,6 @@ "node": ">=8" } }, - "node_modules/babel-jest/node_modules/jest-haste-map": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", - "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.3", - "jest-worker": "^28.1.3", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/babel-jest/node_modules/jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/babel-jest/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, "node_modules/babel-jest/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9494,9 +9437,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", - "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -9505,7 +9448,7 @@ "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/babel-plugin-named-exports-order": { @@ -9577,16 +9520,16 @@ } }, "node_modules/babel-preset-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", - "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^28.1.3", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -10979,6 +10922,12 @@ "node": ">=4" } }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, "node_modules/cssstyle": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", @@ -12441,6 +12390,27 @@ "node": ">=0.8.0" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, "node_modules/eslint": { "version": "8.52.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", @@ -13984,15 +13954,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-stdin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", - "integrity": "sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -14204,12 +14165,6 @@ "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true }, - "node_modules/glur": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/glur/-/glur-1.1.2.tgz", - "integrity": "sha512-l+8esYHTKOx2G/Aao4lEQ0bnHWg4fWtJbVoZZT9Knxi01pB8C80BR85nONLFwkkQoFRCmXY+BUcGZN3yZ2QsRA==", - "dev": true - }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -16256,6 +16211,32 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/jest-config/node_modules/@jest/transform": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, "node_modules/jest-config/node_modules/@jest/types": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", @@ -16294,30 +16275,88 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-config/node_modules/babel-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/transform": "^28.1.3", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.1.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/jest-config/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-config/node_modules/babel-preset-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^28.1.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/jest-config/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", @@ -16339,6 +16378,31 @@ "node": ">=8" } }, + "node_modules/jest-config/node_modules/jest-haste-map": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, "node_modules/jest-config/node_modules/jest-regex-util": { "version": "28.0.2", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", @@ -16693,6 +16757,327 @@ "node": ">=8" } }, + "node_modules/jest-environment-jsdom": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz", + "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0", + "jsdom": "^20.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/jest-environment-node": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", @@ -16900,117 +17285,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest-image-snapshot": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jest-image-snapshot/-/jest-image-snapshot-6.2.0.tgz", - "integrity": "sha512-9mTHBKiiSIZ26csbLmjKyN+SrVypM93S5y+jULCvn6YItgepvcrJIKGNeSyt9d2EZiutOroLs/UjtrWiBzpHbA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "get-stdin": "^5.0.1", - "glur": "^1.1.2", - "lodash": "^4.17.4", - "pixelmatch": "^5.1.0", - "pngjs": "^3.4.0", - "rimraf": "^2.6.2", - "ssim.js": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "jest": ">=20 <=29" - }, - "peerDependenciesMeta": { - "jest": { - "optional": true - } - } - }, - "node_modules/jest-image-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-image-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-image-snapshot/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-image-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-image-snapshot/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/jest-image-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-junit": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-14.0.1.tgz", @@ -22583,27 +22857,6 @@ "node": ">= 6" } }, - "node_modules/pixelmatch": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz", - "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==", - "dev": true, - "dependencies": { - "pngjs": "^6.0.0" - }, - "bin": { - "pixelmatch": "bin/pixelmatch" - } - }, - "node_modules/pixelmatch/node_modules/pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", - "dev": true, - "engines": { - "node": ">=12.13.0" - } - }, "node_modules/pkg-dir": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", @@ -22669,15 +22922,6 @@ "node": ">=4" } }, - "node_modules/pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/polished": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/polished/-/polished-4.2.2.tgz", @@ -24777,12 +25021,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/ssim.js": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ssim.js/-/ssim.js-3.5.0.tgz", - "integrity": "sha512-Aj6Jl2z6oDmgYFFbQqK7fght19bXdOxY7Tj03nF+03M9gCBAjeIiO8/PlEGMfKDwYpw4q6iBqVq2YuREorGg/g==", - "dev": true - }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", diff --git a/package.json b/package.json index 48255c71..868e23ea 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "scripts": { "start": "storybook dev -p 6006", "build": "storybook build -o storybook --webpack-stats-json", - "test": "node tasks/test-fixtures.js && test-storybook --verbose --stories-json", - "lint": "prettier --check '{src,.storybook,tasks}/**/*.{js,mjs,scss,json,html}' && stylelint 'src/**/*.scss' && eslint 'src/**/*.mjs'", - "lint:fix": "prettier --write '{src,.storybook,tasks}/**/*.{js,mjs,scss,json,html}' && stylelint --fix 'src/**/*.scss' && eslint --fix 'src/**/*.mjs'", + "test": "node tasks/test-fixtures.js && test-storybook --verbose && jest", + "lint": "prettier --check '{src,.storybook,tasks,.}/**/*.{js,mjs,scss,json,html}' && stylelint 'src/**/*.scss' && eslint 'src/**/*.{js,mjs}'", + "lint:fix": "prettier --write '{src,.storybook,tasks,.}/**/*.{js,mjs,scss,json,html}' && stylelint --fix 'src/**/*.scss' && eslint --fix 'src/**/*.{js,mjs}'", "package:sass": "sass --style=compressed --embed-sources src/nationalarchives:package/nationalarchives", "package:scripts": "webpack" }, @@ -55,6 +55,7 @@ "@storybook/test-runner": "^0.13.0", "@storybook/testing-library": "^0.2.2", "axe-playwright": "^1.2.3", + "babel-jest": "^29.7.0", "babel-loader": "^9.0.1", "chromatic": "^7.5.0", "copy-webpack-plugin": "^11.0.0", @@ -63,7 +64,7 @@ "eslint": "^8.52.0", "eslint-plugin-storybook": "^0.6.15", "glob": "^10.3.10", - "jest-image-snapshot": "^6.2.0", + "jest-environment-jsdom": "^29.7.0", "jsdom": "^22.1.0", "mdx-mermaid": "^2.0.0", "node-self": "^1.0.2", diff --git a/src/nationalarchives/components/breadcrumbs/breadcrumbs.stories.js b/src/nationalarchives/components/breadcrumbs/breadcrumbs.stories.js index fc842707..44d08df7 100644 --- a/src/nationalarchives/components/breadcrumbs/breadcrumbs.stories.js +++ b/src/nationalarchives/components/breadcrumbs/breadcrumbs.stories.js @@ -98,7 +98,7 @@ MobileExpanded.parameters = { MobileExpanded.args = { ...Standard.args, }; -MobileExpanded.play = async ({ args, canvasElement, step }) => { +MobileExpanded.play = async ({ args, canvasElement }) => { const canvas = within(canvasElement); const $module = document.querySelector('[data-module="tna-breadcrumbs"]'); diff --git a/src/nationalarchives/components/button/button.scss b/src/nationalarchives/components/button/button.scss index b4f1de77..a57d530c 100644 --- a/src/nationalarchives/components/button/button.scss +++ b/src/nationalarchives/components/button/button.scss @@ -21,10 +21,10 @@ @include colour.colour-border("button-background", 0.25rem); - transition: - color 200ms, - background-color 200ms, - border-color 200ms; + // transition: + // color 200ms, + // background-color 200ms, + // border-color 200ms; cursor: pointer; @@ -40,10 +40,10 @@ background: transparent; - transition: - color 50ms, - background-color 50ms, - border-color 50ms; + // transition: + // color 50ms, + // background-color 50ms, + // border-color 50ms; } &--plain { diff --git a/src/nationalarchives/components/button/template.njk b/src/nationalarchives/components/button/template.njk index a0e2f7bd..2992ce3d 100644 --- a/src/nationalarchives/components/button/template.njk +++ b/src/nationalarchives/components/button/template.njk @@ -10,9 +10,9 @@ {%- endif -%} <{{ 'button' if params.buttonElement else 'a' }}{%- if not params.buttonElement %} href="{{ params.href }}"{%- endif %} class="tna-button {{ buttonClasses | join(' ') }}"{%- if not params.buttonElement %} role="button"{%- endif -%}{%- if params.title %} title="{{ params.title }}"{% endif %} {%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}"{% endfor %}> {%- if params.brandIcon -%} - + {%- elseif params.icon -%} - + {%- endif -%} {{ params.text }} diff --git a/src/nationalarchives/components/card/card.scss b/src/nationalarchives/components/card/card.scss index c7a89409..9db39262 100644 --- a/src/nationalarchives/components/card/card.scss +++ b/src/nationalarchives/components/card/card.scss @@ -61,7 +61,7 @@ } &__meta { - margin-bottom: 1rem; + margin: 0; padding: 0; display: flex; @@ -85,6 +85,10 @@ @include colour.colour-font("icon-light"); } } + + + p { + margin-top: 1rem; + } } &__actions { @@ -123,7 +127,7 @@ &--accent { @include colour.accent; - .tna-hgroup__supertitle { + .tna-hgroup__supertitle:not(.tna-hgroup__supertitle--plain) { @include colour.contrast; @include colour.colour-border("contrast-background"); diff --git a/src/nationalarchives/components/card/card.stories.js b/src/nationalarchives/components/card/card.stories.js index 1d170dbf..1cb5b805 100644 --- a/src/nationalarchives/components/card/card.stories.js +++ b/src/nationalarchives/components/card/card.stories.js @@ -7,6 +7,8 @@ const argTypes = { headingLevel: { control: { type: "number", min: 1, max: 6 } }, headingSize: { control: "inline-radio", options: ["s", "m", "l"] }, href: { control: "text" }, + hrefClasses: { control: "text" }, + hrefAttributes: { control: "object" }, imageSrc: { control: { type: "file", accept: ".jpg" } }, imageAlt: { control: "text" }, imageWidth: { control: { type: "number", min: 1 } }, @@ -45,6 +47,8 @@ const Template = ({ headingLevel, headingSize, href, + hrefClasses, + hrefAttributes, imageSrc, imageAlt, imageWidth, @@ -70,6 +74,8 @@ const Template = ({ headingLevel, headingSize, href, + hrefClasses, + hrefAttributes, imageSrc, imageAlt, imageWidth, @@ -302,81 +308,3 @@ Sources.args = { htmlElement: "article", classes: "tna-card--demo", }; - -export const WithoutImage = Template.bind({}); -WithoutImage.args = { - supertitle: "Card supertitle", - title: "Card title", - headingLevel: 3, - headingSize: "s", - body: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel tincidunt velit, a molestie turpis.

", - htmlElement: "article", - classes: "tna-card--demo", -}; - -const GridTemplate = ({ - title, - supertitle, - headingLevel, - headingSize, - href, - imageSrc, - imageAlt, - imageWidth, - imageHeight, - imageSources, - label, - body, - text, - actions, - horizontal, - htmlElement, - classes, - attributes, -}) => - `
- ${Array(12) - .fill( - `
- ${Card({ - params: { - title, - supertitle, - headingLevel, - headingSize, - href, - imageSrc, - imageAlt, - imageWidth, - imageHeight, - imageSources, - label, - body, - text, - actions, - horizontal, - htmlElement, - classes, - attributes, - }, - })} -
`, - ) - .join("")} -
`; - -export const Grid = GridTemplate.bind({}); -Grid.args = { - title: "Card title", - headingLevel: 3, - headingSize: "s", - href: "#", - imageSrc: - "https://www.nationalarchives.gov.uk/wp-content/uploads/sites/24/2023/07/tna-building-compress.jpg", - imageAlt: "The National Archives office", - imageWidth: 499, - imageHeight: 333, - body: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vel tincidunt velit, a molestie turpis.

", - htmlElement: "article", - classes: "tna-card--demo", -}; diff --git a/src/nationalarchives/components/card/fixtures.json b/src/nationalarchives/components/card/fixtures.json index 24874ce2..1c4aa0fc 100644 --- a/src/nationalarchives/components/card/fixtures.json +++ b/src/nationalarchives/components/card/fixtures.json @@ -8,7 +8,7 @@ "headingLevel": 3, "body": "

Card body

" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -19,7 +19,7 @@ "headingLevel": 3, "body": "

Card body

" }, - "html": "

Card supertitleCard title

Card body

", + "html": "

Card supertitleCard title

Card body

", "hidden": false }, { @@ -30,7 +30,7 @@ "headingSize": "xl", "body": "

Card body

" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -40,7 +40,7 @@ "headingLevel": 1, "body": "

Card body

" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -51,7 +51,7 @@ "href": "#", "body": "

Card body

" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -75,7 +75,7 @@ ], "body": "

Card body

" }, - "html": "

Card title

  • 24th September 2023
  • From £16
  • Online

Card body

", + "html": "

Card title

  • 24th September 2023
  • From £16
  • Online

Card body

", "hidden": false }, { @@ -85,7 +85,7 @@ "headingLevel": 3, "text": "Card body" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -99,7 +99,7 @@ "imageHeight": 360, "body": "

Card body

" }, - "html": "

Card title

\"A

Card body

", + "html": "

Card title

\"A

Card body

", "hidden": false }, { @@ -119,7 +119,7 @@ ], "body": "

Card body

" }, - "html": "

Card title

\"A

Card body

", + "html": "

Card title

\"A

Card body

", "hidden": false }, { @@ -134,7 +134,7 @@ "href": "#", "body": "

Card body

" }, - "html": "

Card title

\"A

Card body

", + "html": "

Card title

\"A

Card body

", "hidden": false }, { @@ -151,7 +151,7 @@ } ] }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -162,7 +162,7 @@ "label": "New", "body": "

Card body

" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -173,7 +173,7 @@ "body": "

Card body

", "style": "boxed" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -184,7 +184,7 @@ "body": "

Card body

", "style": "accent" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -195,7 +195,7 @@ "body": "

Card body

", "style": "foobar" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -206,7 +206,7 @@ "body": "

Card body

", "classes": "card__test-class" }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false }, { @@ -219,7 +219,7 @@ "data-testattribute": "foobar" } }, - "html": "

Card title

Card body

", + "html": "

Card title

Card body

", "hidden": false } ] diff --git a/src/nationalarchives/components/card/macro-options.json b/src/nationalarchives/components/card/macro-options.json index 2236b274..41ff75fb 100644 --- a/src/nationalarchives/components/card/macro-options.json +++ b/src/nationalarchives/components/card/macro-options.json @@ -28,13 +28,25 @@ "name": "href", "type": "string", "required": false, - "description": "A URL to use as a link in the card's heading and image (if one is declared)." + "description": "A URL to use as a link in the card's heading and image." + }, + { + "name": "hrefClasses", + "type": "string", + "required": false, + "description": "Classes to add to the elements of the card that use `href`." + }, + { + "name": "hrefAttributes", + "type": "object", + "required": false, + "description": "HTML attributes (for example data attributes) to add to the elements of the card that use `href`." }, { "name": "imageSrc", "type": "string", "required": false, - "description": "A JPG file to use as the card's image." + "description": "The location of the card's image." }, { "name": "imageAlt", @@ -58,43 +70,43 @@ "name": "imageType", "type": "string", "required": false, - "description": "" + "description": "The mime type of the image. Defaults to `image/jpeg`. Only required when using `imageSources`." }, { "name": "imageSources", "type": "array", - "required": true, - "description": "Alternative sources of the image which can include WebP files.", + "required": false, + "description": "Alternative sources of the image.", "params": [ { "name": "src", "type": "string", "required": true, - "description": "" + "description": "The location of the image." }, { "name": "type", "type": "string", "required": true, - "description": "" + "description": "The mime type of the image." }, { "name": "media", "type": "string", "required": false, - "description": "" + "description": "A media condition for the image." }, { "name": "width", "type": "number", "required": false, - "description": "" + "description": "The width of the image in pixels." }, { "name": "height", "type": "number", "required": false, - "description": "" + "description": "The height of the image in pixels." } ] }, @@ -120,14 +132,14 @@ "name": "icon", "type": "string", "required": false, - "description": "The name of a font-awesome icon, without the prefixed `fa-`." + "description": "The name of a Font Awesome icon, without the prefixed `fa-`." } ] }, { "name": "body", "type": "string", - "required": true, + "required": false, "description": "The HTML for the main body of the card. Not displayed if `text` is set." }, { @@ -146,31 +158,43 @@ "name": "text", "type": "string", "required": true, - "description": "" + "description": "The text for the action." }, { "name": "href", "type": "string", "required": true, - "description": "" + "description": "The URL of the action." }, { "name": "title", "type": "string", "required": false, - "description": "" + "description": "An optional title for the action." }, { "name": "icon", "type": "string", "required": false, - "description": "" + "description": "The name of a Font Awesome icon, without the prefixed `fa-`." }, { "name": "brandIcon", "type": "string", "required": false, - "description": "" + "description": "The name of a Font Awesome brand icon, without the prefixed `fa-`." + }, + { + "name": "classes", + "type": "string", + "required": false, + "description": "Classes to add to the card action." + }, + { + "name": "attributes", + "type": "object", + "required": false, + "description": "HTML attributes (for example data attributes) to add to the card action." } ] }, diff --git a/src/nationalarchives/components/card/template.njk b/src/nationalarchives/components/card/template.njk index 6eedaca5..2284b24e 100644 --- a/src/nationalarchives/components/card/template.njk +++ b/src/nationalarchives/components/card/template.njk @@ -8,86 +8,87 @@ {%- elseif params.style == "accent" -%} {%- set containerClasses = containerClasses.concat('tna-card--accent') -%} {%- endif -%} -<{{ htmlElement }} class="tna-card {{ containerClasses | join(' ') }}" data-module="tna-card" {%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}"{% endfor %}> +{%- set classes = containerClasses | join(' ') -%} +<{{ htmlElement }} class="tna-card{% if classes %} {{ classes }}{% endif %}" {%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}"{% endfor %}>
- {%- if params.supertitle -%} + {%- if params.supertitle %}
{{ params.supertitle }} - {%- if params.href -%} - {{ params.title }} - {%- else -%} + {%- if params.href %} + {{ params.title }} + {%- else %} {{ params.title }} - {%- endif -%} + {%- endif %}
- {%- else -%} + {%- else %} - {%- if params.href -%} - {{ params.title }} - {%- else -%} + {%- if params.href %} + {{ params.title }} + {%- else %} {{ params.title }} - {%- endif -%} + {%- endif %} - {%- endif -%} - {%- if params.imageSrc -%} - {%- if params.href -%} - - {%- else -%} + {%- endif %} + {%- if params.imageSrc %} + {%- if params.href %} + + {%- else %} - {%- endif -%} - {%- endif -%} + {%- endif %} + {%- endif %}
- {%- if params.meta -%} + {%- if params.meta %}
    - {%- for item in params.meta -%} + {%- for item in params.meta %}
  • - {%- if item.icon -%} - - {%- endif -%} + {%- if item.icon %} + + {%- endif %} {{ item.text }}
  • - {%- endfor -%} + {%- endfor %}
- {%- endif -%} - {%- if params.text -%} + {%- endif %} + {%- if params.text %}

{{ params.text }}

- {%- else -%} + {%- else %} {{ params.body | safe }} - {%- endif -%} + {%- endif %}
- {%- if params.actions -%} + {%- if params.actions %} - {%- endif -%} + {%- endif %}
diff --git a/src/nationalarchives/components/cookie-banner/cookie-banner.mjs b/src/nationalarchives/components/cookie-banner/cookie-banner.mjs index 98e546f6..c237933a 100644 --- a/src/nationalarchives/components/cookie-banner/cookie-banner.mjs +++ b/src/nationalarchives/components/cookie-banner/cookie-banner.mjs @@ -27,19 +27,27 @@ export class CookieBanner { return; } - const policies = this.$module.getAttribute("data-policies"); - if (!policies) { - return; - } - this.cookies = new Cookies( - policies.split(",").map((policy) => policy.trim()), - ); + const policies = this.$module.getAttribute("data-policies") || ""; + const domain = this.$module.getAttribute("data-domain") || undefined; + const secure = this.$module.getAttribute("data-secure") || undefined; + const policiesKey = + this.$module.getAttribute("data-policies-key") || undefined; - this.loadScriptsOnAccept = this.$module.getAttribute("data-acceptscripts"); + this.cookies = new (window.TNAFrontend?.Cookies || Cookies)( + policies + .split(",") + .filter((x) => x) + .map((policy) => policy.trim()), + { + domain, + secure, + policiesKey, + }, + ); this.cookiePreferencesSet = this.$module.getAttribute("data-preferenceskey") || - "cookies_preferences_set"; + "cookie_preferences_set"; const cookiePreferencesSet = this.cookies.hasValue( this.cookiePreferencesSet, "true", @@ -60,13 +68,6 @@ export class CookieBanner { this.$acceptedMessage.focus(); this.$acceptedMessage.setAttribute("tabindex", "-1"); this.cookies.acceptAllPolicies(); - if (this.loadScriptsOnAccept) { - this.loadScriptsOnAccept.split(",").forEach((script) => { - const $script = document.createElement("script"); - $script.src = script; - document.head.appendChild($script); - }); - } } reject() { diff --git a/src/nationalarchives/components/cookie-banner/cookie-banner.stories.js b/src/nationalarchives/components/cookie-banner/cookie-banner.stories.js index bbba5adc..406110aa 100644 --- a/src/nationalarchives/components/cookie-banner/cookie-banner.stories.js +++ b/src/nationalarchives/components/cookie-banner/cookie-banner.stories.js @@ -7,8 +7,10 @@ import Cookies from "../../lib/cookies.mjs"; const argTypes = { cookiesUrl: { control: "text" }, policies: { control: "text" }, - cookiesPreferencesSetKey: { control: "text" }, - loadScriptsOnAccept: { control: "text" }, + policiesKey: { control: "text" }, + preferencesSetKey: { control: "text" }, + cookiesDomain: { control: "text" }, + allowInsecure: { control: "boolean" }, classes: { control: "text" }, attributes: { control: "object" }, }; @@ -27,8 +29,10 @@ export default { const Template = ({ cookiesUrl, policies, - cookiesPreferencesSetKey, - loadScriptsOnAccept, + policiesKey, + preferencesSetKey, + cookiesDomain, + allowInsecure, classes, attributes, }) => @@ -36,8 +40,10 @@ const Template = ({ params: { cookiesUrl, policies, - cookiesPreferencesSetKey, - loadScriptsOnAccept, + policiesKey, + preferencesSetKey, + cookiesDomain, + allowInsecure, classes, attributes, }, @@ -49,23 +55,19 @@ Standard.args = { classes: "tna-cookie-banner--demo", }; -const deleteAllCookies = (cookies) => { - Object.keys(cookies.all).forEach((cookie) => cookies.delete(cookie)); -}; - export const Accept = Template.bind({}); Accept.args = { cookiesUrl: "#", + allowInsecure: true, classes: "tna-cookie-banner--demo", }; Accept.play = async ({ canvasElement }) => { - const cookies = new Cookies(); - deleteAllCookies(cookies); - + const cookies = new window.TNAFrontend.Cookies(); await expect(cookies.isPolicyAccepted("essential")).toEqual(true); await expect(cookies.isPolicyAccepted("usage")).toEqual(false); await expect(cookies.isPolicyAccepted("settings")).toEqual(false); await expect(cookies.isPolicyAccepted("unknown")).toEqual(null); + await expect(cookies.exists("cookie_preferences_set")).toEqual(false); const canvas = within(canvasElement); const acceptButton = canvas.getByText("Accept cookies"); @@ -78,6 +80,11 @@ Accept.play = async ({ canvasElement }) => { await expect(cookies.isPolicyAccepted("usage")).toEqual(true); await expect(cookies.isPolicyAccepted("settings")).toEqual(true); await expect(cookies.isPolicyAccepted("unknown")).toEqual(null); + await expect(cookies.exists("cookie_preferences_set")).toEqual(true); + await expect(cookies.get("cookie_preferences_set")).toEqual("true"); + await expect(cookies.hasValue("cookie_preferences_set", "true")).toEqual( + true, + ); await expect(acceptButton).not.toBeVisible(); await expect(rejectButton).not.toBeVisible(); @@ -86,8 +93,6 @@ Accept.play = async ({ canvasElement }) => { // await userEvent.click(closeButton); // await expect(closeButton).not.toBeVisible(); - - deleteAllCookies(cookies); }; export const Reject = Template.bind({}); @@ -97,12 +102,11 @@ Reject.args = { }; Reject.play = async ({ canvasElement }) => { const cookies = new Cookies(); - deleteAllCookies(cookies); - await expect(cookies.isPolicyAccepted("essential")).toEqual(true); await expect(cookies.isPolicyAccepted("usage")).toEqual(false); await expect(cookies.isPolicyAccepted("settings")).toEqual(false); await expect(cookies.isPolicyAccepted("unknown")).toEqual(null); + await expect(cookies.exists("cookie_preferences_set")).toEqual(false); const canvas = within(canvasElement); const acceptButton = canvas.getByText("Accept cookies"); @@ -115,10 +119,15 @@ Reject.play = async ({ canvasElement }) => { await expect(cookies.isPolicyAccepted("usage")).toEqual(false); await expect(cookies.isPolicyAccepted("settings")).toEqual(false); await expect(cookies.isPolicyAccepted("unknown")).toEqual(null); + await expect(cookies.exists("cookie_preferences_set")).toEqual(true); + await expect(cookies.get("cookie_preferences_set")).toEqual("true"); + await expect(cookies.hasValue("cookie_preferences_set", "true")).toEqual( + true, + ); await expect(acceptButton).not.toBeVisible(); await expect(rejectButton).not.toBeVisible(); - deleteAllCookies(cookies); + await cookies.deleteAll(); }; export const CustomPolicies = Template.bind({}); @@ -127,51 +136,93 @@ CustomPolicies.args = { policies: "custom", classes: "tna-cookie-banner--demo", }; +CustomPolicies.parameters = { + chromatic: { disableSnapshot: true }, +}; CustomPolicies.play = async ({ args, canvasElement }) => { const cookies = new Cookies(args.policies.split(",")); - deleteAllCookies(cookies); - await expect(cookies.isPolicyAccepted("essential")).toEqual(true); - await expect(cookies.isPolicyAccepted("usage")).toEqual(null); - await expect(cookies.isPolicyAccepted("settings")).toEqual(null); + await expect(cookies.isPolicyAccepted("usage")).toEqual(false); + await expect(cookies.isPolicyAccepted("settings")).toEqual(false); await expect(cookies.isPolicyAccepted("custom")).toEqual(false); + await expect(cookies.exists("cookie_preferences_set")).toEqual(false); const canvas = within(canvasElement); const acceptButton = canvas.getByText("Accept cookies"); await userEvent.click(acceptButton); await expect(cookies.isPolicyAccepted("essential")).toEqual(true); - await expect(cookies.isPolicyAccepted("usage")).toEqual(null); - await expect(cookies.isPolicyAccepted("settings")).toEqual(null); + await expect(cookies.isPolicyAccepted("usage")).toEqual(true); + await expect(cookies.isPolicyAccepted("settings")).toEqual(true); await expect(cookies.isPolicyAccepted("custom")).toEqual(true); + await expect(cookies.exists("cookie_preferences_set")).toEqual(true); + await expect(cookies.get("cookie_preferences_set")).toEqual("true"); + await expect(cookies.hasValue("cookie_preferences_set", "true")).toEqual( + true, + ); - deleteAllCookies(cookies); + await cookies.deleteAll(); }; -export const AddScriptsOnAccept = Template.bind({}); -AddScriptsOnAccept.args = { +export const Existing = Template.bind({}); +Existing.args = { cookiesUrl: "#", - loadScriptsOnAccept: "my-usage-script.js", + allowInsecure: true, classes: "tna-cookie-banner--demo", }; -AddScriptsOnAccept.play = async ({ args, canvasElement }) => { +Existing.decorators = [ + (Story) => { + const cookies = new Cookies(); + cookies.set("cookie_preferences_set", true); + cookies.destroy(); + return Story(); + }, +]; +Existing.play = async ({ canvasElement }) => { const cookies = new Cookies(); - deleteAllCookies(cookies); - - const noScript = document.querySelector( - `script[src="${args.loadScriptsOnAccept}"]`, + await expect(cookies.isPolicyAccepted("essential")).toEqual(true); + await expect(cookies.isPolicyAccepted("usage")).toEqual(false); + await expect(cookies.isPolicyAccepted("settings")).toEqual(false); + await expect(cookies.isPolicyAccepted("unknown")).toEqual(null); + await expect(cookies.exists("cookie_preferences_set")).toEqual(true); + await expect(cookies.get("cookie_preferences_set")).toEqual("true"); + await expect(cookies.hasValue("cookie_preferences_set", "true")).toEqual( + true, ); - await expect(noScript).toEqual(null); const canvas = within(canvasElement); const acceptButton = canvas.getByText("Accept cookies"); - await userEvent.click(acceptButton); - - const script = document.querySelector( - `script[src="${args.loadScriptsOnAccept}"]`, - ); - await expect(script).toBeTruthy(); + const rejectButton = canvas.getByText("Reject cookies"); + await expect(acceptButton).not.toBeVisible(); + await expect(rejectButton).not.toBeVisible(); - deleteAllCookies(cookies); - script.remove(); + await cookies.deleteAll(); }; + +// export const EventHandling = Template.bind({}); +// EventHandling.args = { +// cookiesUrl: "#", +// policies: "custom", +// classes: "tna-cookie-banner--demo", +// }; +// EventHandling.play = async ({ args, canvasElement }) => { +// deleteAllCookies(); + +// const cookies = new Cookies(); + +// const onChangePolicy = jest.fn(data => { +// console.log(data) +// }) +// cookies.on("changePolicy", onChangePolicy) + +// const canvas = within(canvasElement); +// const acceptButton = canvas.getByText("Accept cookies"); +// await userEvent.click(acceptButton); + +// await expect(onChangePolicy.mock).toHaveBeenCalledTimes(1); +// await expect(onChangePolicy.mock.calls).toHaveLength(1); +// await expect(onChangePolicy.mock.results[0].value).toHaveProperty("custom"); +// await expect(onChangePolicy.mock.results[0].value.custom).toEqual(true); + +// deleteAllCookies(); +// }; diff --git a/src/nationalarchives/components/cookie-banner/fixtures.json b/src/nationalarchives/components/cookie-banner/fixtures.json index 1a164ea6..a1d0c388 100644 --- a/src/nationalarchives/components/cookie-banner/fixtures.json +++ b/src/nationalarchives/components/cookie-banner/fixtures.json @@ -6,7 +6,7 @@ "options": { "cookiesUrl": "/cookies" }, - "html": "", + "html": "", "hidden": false }, { @@ -15,7 +15,7 @@ "cookiesUrl": "/cookies", "cookiesPreferencesSetKey": "custom" }, - "html": "", + "html": "", "hidden": false }, { @@ -24,16 +24,43 @@ "cookiesUrl": "/cookies", "policies": "custom" }, - "html": "", + "html": "", "hidden": false }, { - "name": "add scripts on accept", + "name": "custom policies key", "options": { "cookiesUrl": "/cookies", - "loadScriptsOnAccept": "my-usage-script.js" + "policiesKey": "custom_key" }, - "html": "", + "html": "", + "hidden": false + }, + { + "name": "with domain", + "options": { + "cookiesUrl": "/cookies", + "cookiesDomain": "nationalarchives.gov.uk" + }, + "html": "", + "hidden": false + }, + { + "name": "with preferences set key", + "options": { + "cookiesUrl": "/cookies", + "preferencesSetKey": "custom_preferences_set_key" + }, + "html": "", + "hidden": false + }, + { + "name": "insecure", + "options": { + "cookiesUrl": "/cookies", + "allowInsecure": true + }, + "html": "", "hidden": false }, { @@ -42,7 +69,7 @@ "cookiesUrl": "/cookies", "classes": "tna-cookie-banner--fixture" }, - "html": "", + "html": "", "hidden": false }, { @@ -53,7 +80,7 @@ "data-fixturetest": "pass" } }, - "html": "", + "html": "", "hidden": false } ] diff --git a/src/nationalarchives/components/cookie-banner/macro-options.json b/src/nationalarchives/components/cookie-banner/macro-options.json index 757b43f5..8ef747e9 100644 --- a/src/nationalarchives/components/cookie-banner/macro-options.json +++ b/src/nationalarchives/components/cookie-banner/macro-options.json @@ -18,11 +18,17 @@ "description": "" }, { - "name": "loadScriptsOnAccept", + "name": "cookiesDomain", "type": "string", "required": false, "description": "" }, + { + "name": "allowInsecure", + "type": "boolean", + "required": false, + "description": "" + }, { "name": "classes", "type": "string", diff --git a/src/nationalarchives/components/cookie-banner/template.njk b/src/nationalarchives/components/cookie-banner/template.njk index f2a20b15..48aeff1e 100644 --- a/src/nationalarchives/components/cookie-banner/template.njk +++ b/src/nationalarchives/components/cookie-banner/template.njk @@ -1,7 +1,7 @@ {% from "nationalarchives/components/button/macro.njk" import tnaButton %} {%- set containerClasses = [params.classes] if params.classes else [] -%} -