diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3013c3b..9e746d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,5 @@ name: CI -on: [push] +on: [push, pull_request] jobs: build: diff --git a/.storybook/main.ts b/.storybook/main.ts index 730dd9d..86b26d9 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,23 +1,16 @@ import type { StorybookConfig } from "@storybook/web-components-vite"; -import { NodePackageImporter } from "sass"; const config: StorybookConfig = { framework: "@storybook/web-components-vite", stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], addons: ["@storybook/addon-essentials"], + staticDirs: ["../static"], docs: { autodocs: true, }, async viteFinal(config) { const { mergeConfig } = await import("vite"); return mergeConfig(config, { - css: { - preprocessorOptions: { - scss: { - pkgImporter: new NodePackageImporter(), - }, - }, - }, optimizeDeps: { exclude: [ "@storybook/blocks", diff --git a/.storybook/preview.ts b/.storybook/preview.ts index 82f8158..1beb696 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -1,15 +1,31 @@ import type { Preview } from "@storybook/web-components"; -import "../src/scss/iati.scss"; +import "../src/js/main.js"; +import "../src/scss/main.scss"; import DocsTemplate from "./DocsTemplate.mdx"; const preview: Preview = { parameters: { options: { storySort: { - order: ["Get Started", "Brand", "Core", "Components", "Layout"], + order: [ + "Get Started", + "Installation", + "Usage", + "Contributing", + "Brand", + "Core", + "Components", + "Layout", + ], }, }, + backgrounds: { + values: [ + { name: "light", value: "#fff" }, + { name: "dark", value: "#155366" }, + ], + }, docs: { page: DocsTemplate, source: { diff --git a/README.md b/README.md index e0677fc..87cab31 100644 --- a/README.md +++ b/README.md @@ -4,50 +4,11 @@ The IATI Design System is a set of reusable styles and components which should be used in IATI web products, along with guidance on how to use them. -## How do I use the IATI Design System? +## Using the IATI Design System -### CDN (Recommended) +Please see the [Storybook site](https://iati.github.io/design-system/) for instructions. -The recommended way to use the design system in an IATI product is by including the CSS from the CDN, using the url below, replacing `` with the version you would like to use: - -```code -https://cdn.jsdelivr.net/npm/iati-design-system@/dist/css/iati.min.css -``` - -This project is versioned using [Semantic Versioning](https://semver.org/). Versions can be specified as a major, minor, or patch version e.g. `1`, `1.2`, or `1.2.3`. The latest version is shown on the [GitHub releases page](https://github.com/IATI/design-system/releases). We recommend fixing to a specific patch version so that upgrades can be checked explicitly before deployment, but as a minimum you should fix to a major version to prevent unexpected breaking changes. - -To include the CSS in a HTML project, add the following code inside the `` of your HTML pages: - -```html - -``` - -Once this link is included, core styles will be applied, and all component and layout CSS classes will be available to apply to HTML elements, for example the `.iati-button` class: - -```html - -``` - -### NPM (Optional) - -It is also possible to include the design system in a [Sass](https://sass-lang.com/) project. - -First install with npm: - -```code -npm install iati-design-system -``` - -Then import the package in your `.scss` file. The [Node.js Package Importer](https://sass-lang.com/documentation/at-rules/use/#node-js-package-importer) is required to use this syntax. - -```css -@use "pkg:iati-design-system"; -``` - -## How do I contribute to the IATI Design System? +## Contributing to the IATI Design System ### Prerequisites diff --git a/eslint.config.js b/eslint.config.js index c4e7fff..713ef2b 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -10,6 +10,7 @@ export default [ languageOptions: { globals: { ...globals.node, + ...globals.browser, }, }, }, diff --git a/package-lock.json b/package-lock.json index 898b9e8..e737cce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@commitlint/config-conventional": "^19.2.2", "@eslint/js": "^9.0.0", "@storybook/addon-essentials": "^8.0.10", + "@storybook/addon-links": "^8.0.10", "@storybook/blocks": "^8.0.10", "@storybook/web-components": "^8.0.10", "@storybook/web-components-vite": "^8.0.10", @@ -28,7 +29,8 @@ "semantic-release": "^23.1.1", "storybook": "^8.0.10", "typescript": "^5.4.5", - "typescript-eslint": "^7.7.0" + "typescript-eslint": "^7.7.0", + "vite": "^5.4.4" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -3756,9 +3758,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.3.tgz", - "integrity": "sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", + "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", "cpu": [ "arm" ], @@ -3766,13 +3768,12 @@ "optional": true, "os": [ "android" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.3.tgz", - "integrity": "sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", + "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", "cpu": [ "arm64" ], @@ -3780,13 +3781,12 @@ "optional": true, "os": [ "android" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.3.tgz", - "integrity": "sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", + "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", "cpu": [ "arm64" ], @@ -3794,13 +3794,12 @@ "optional": true, "os": [ "darwin" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.3.tgz", - "integrity": "sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", + "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", "cpu": [ "x64" ], @@ -3808,13 +3807,12 @@ "optional": true, "os": [ "darwin" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.3.tgz", - "integrity": "sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", + "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", "cpu": [ "arm" ], @@ -3822,13 +3820,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.14.3.tgz", - "integrity": "sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", + "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", "cpu": [ "arm" ], @@ -3836,13 +3833,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.3.tgz", - "integrity": "sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", + "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", "cpu": [ "arm64" ], @@ -3850,13 +3846,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.3.tgz", - "integrity": "sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", + "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", "cpu": [ "arm64" ], @@ -3864,13 +3859,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.3.tgz", - "integrity": "sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", + "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", "cpu": [ "ppc64" ], @@ -3878,13 +3872,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.3.tgz", - "integrity": "sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", + "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", "cpu": [ "riscv64" ], @@ -3892,13 +3885,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.3.tgz", - "integrity": "sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", + "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", "cpu": [ "s390x" ], @@ -3906,13 +3898,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.3.tgz", - "integrity": "sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", + "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", "cpu": [ "x64" ], @@ -3920,13 +3911,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.3.tgz", - "integrity": "sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", + "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", "cpu": [ "x64" ], @@ -3934,13 +3924,12 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.3.tgz", - "integrity": "sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", + "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", "cpu": [ "arm64" ], @@ -3948,13 +3937,12 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.3.tgz", - "integrity": "sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", + "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", "cpu": [ "ia32" ], @@ -3962,13 +3950,12 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.3.tgz", - "integrity": "sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", + "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", "cpu": [ "x64" ], @@ -3976,8 +3963,7 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@sec-ant/readable-stream": { "version": "0.4.1", @@ -4849,6 +4835,29 @@ "url": "https://opencollective.com/storybook" } }, + "node_modules/@storybook/addon-links": { + "version": "8.0.10", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.0.10.tgz", + "integrity": "sha512-+mIyH2UcrgQfAyRM4+ARkB/D0OOY8UMwkZsD8dD23APZ8oru7W/NHX3lXl0WjPfQcOIx/QwWNWI3+DgVZJY3jw==", + "dev": true, + "dependencies": { + "@storybook/csf": "^0.1.4", + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, "node_modules/@storybook/addon-measure": { "version": "8.0.10", "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.0.10.tgz", @@ -5432,6 +5441,15 @@ "url": "https://opencollective.com/storybook" } }, + "node_modules/@storybook/core-server/node_modules/@types/node": { + "version": "18.19.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@storybook/core-server/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -5511,6 +5529,12 @@ "node": ">=8" } }, + "node_modules/@storybook/core-server/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/@storybook/core-server/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -5944,8 +5968,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/express": { "version": "4.17.21", @@ -6017,12 +6040,12 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.19.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.31.tgz", - "integrity": "sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", "dev": true, "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/normalize-package-data": { @@ -12000,7 +12023,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -15477,9 +15499,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -15626,9 +15648,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.45", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", + "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", "dev": true, "funding": [ { @@ -15644,10 +15666,9 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -16461,11 +16482,10 @@ } }, "node_modules/rollup": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.3.tgz", - "integrity": "sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", "dev": true, - "peer": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -16477,22 +16497,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.14.3", - "@rollup/rollup-android-arm64": "4.14.3", - "@rollup/rollup-darwin-arm64": "4.14.3", - "@rollup/rollup-darwin-x64": "4.14.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.14.3", - "@rollup/rollup-linux-arm-musleabihf": "4.14.3", - "@rollup/rollup-linux-arm64-gnu": "4.14.3", - "@rollup/rollup-linux-arm64-musl": "4.14.3", - "@rollup/rollup-linux-powerpc64le-gnu": "4.14.3", - "@rollup/rollup-linux-riscv64-gnu": "4.14.3", - "@rollup/rollup-linux-s390x-gnu": "4.14.3", - "@rollup/rollup-linux-x64-gnu": "4.14.3", - "@rollup/rollup-linux-x64-musl": "4.14.3", - "@rollup/rollup-win32-arm64-msvc": "4.14.3", - "@rollup/rollup-win32-ia32-msvc": "4.14.3", - "@rollup/rollup-win32-x64-msvc": "4.14.3", + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", "fsevents": "~2.3.2" } }, @@ -18060,9 +18080,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -18337,15 +18357,14 @@ } }, "node_modules/vite": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.9.tgz", - "integrity": "sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.4.tgz", + "integrity": "sha512-RHFCkULitycHVTtelJ6jQLd+KSAAzOgEYorV32R2q++M6COBjKJR6BxqClwp5sf0XaBDjVMuJ9wnNfyAJwjMkA==", "dev": true, - "peer": true, "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", - "rollup": "^4.13.0" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -18364,6 +18383,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -18381,6 +18401,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -18392,6 +18415,412 @@ } } }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/watchpack": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", diff --git a/package.json b/package.json index 6275b64..f1f58b1 100644 --- a/package.json +++ b/package.json @@ -9,16 +9,18 @@ "type": "module", "exports": { ".": { - "sass": "./src/scss/iati.scss" + "sass": "./src/scss/main.scss" } }, "files": [ "src/scss/**/*.scss", - "dist/css/**/*.css" + "dist/css/**/*.css", + "dist/js/**/*.js" ], "scripts": { "start": "storybook dev -p 6006", - "build": "sass --pkg-importer=node --no-source-map --style=expanded src/scss:dist/css", + "clean": "rm -rf dist", + "build": "vite build", "build:storybook": "storybook build", "serve:storybook": "npx http-server -o ./storybook-static", "lint": "npm run lint:eslint && npm run lint:prettier", @@ -31,6 +33,7 @@ "@commitlint/config-conventional": "^19.2.2", "@eslint/js": "^9.0.0", "@storybook/addon-essentials": "^8.0.10", + "@storybook/addon-links": "^8.0.10", "@storybook/blocks": "^8.0.10", "@storybook/web-components": "^8.0.10", "@storybook/web-components-vite": "^8.0.10", @@ -44,7 +47,8 @@ "semantic-release": "^23.1.1", "storybook": "^8.0.10", "typescript": "^5.4.5", - "typescript-eslint": "^7.7.0" + "typescript-eslint": "^7.7.0", + "vite": "^5.4.4" }, "dependencies": { "normalize-scss": "^8.0.0" diff --git a/src/assets/svg/icon-globe.svg b/src/assets/svg/icon-globe.svg new file mode 100644 index 0000000..592ebc1 --- /dev/null +++ b/src/assets/svg/icon-globe.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/svg/icon-info.svg b/src/assets/svg/icon-info.svg new file mode 100644 index 0000000..02f6aba --- /dev/null +++ b/src/assets/svg/icon-info.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/svg/icon-search.svg b/src/assets/svg/icon-search.svg new file mode 100644 index 0000000..d7870d5 --- /dev/null +++ b/src/assets/svg/icon-search.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/contributing.mdx b/src/contributing.mdx new file mode 100644 index 0000000..1e30e3a --- /dev/null +++ b/src/contributing.mdx @@ -0,0 +1,7 @@ +import { Meta, Title } from "@storybook/blocks"; + + + +Contributing to the IATI Design System + +To contribute to the IATI Design System, please see the [Github repository](https://github.com/IATI/design-system). diff --git a/src/installation.mdx b/src/installation.mdx new file mode 100644 index 0000000..79933f7 --- /dev/null +++ b/src/installation.mdx @@ -0,0 +1,37 @@ +import { Meta, Title } from "@storybook/blocks"; + + + +Installing the IATI Design System + +## CDN (Recommended) + +The recommended installation method is including the CSS and Javascript files which we are distirbuted using the [jsDelivr](https://www.jsdelivr.com/) CDN. + +Add the following code inside the `` of your HTML pages, replacing `` with the version you want to use, e.g. `1.2.3`. +This project is versioned using [Semantic Versioning](https://semver.org/), and the latest version is shown on the [GitHub releases page](https://github.com/IATI/design-system/releases). +You can [watch the Github repository](https://docs.github.com/en/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository) to be notified when a new version is released. + +```html + + +``` + +## NPM (Optional) + +It is also possible to include the design system in a [Sass](https://sass-lang.com/) project. + +First install with npm: + +```code +npm install iati-design-system +``` + +Then import the package in your `.scss` file. The [Node.js Package Importer](https://sass-lang.com/documentation/at-rules/use/#node-js-package-importer) is required to use this syntax. + +```css +@use "pkg:iati-design-system"; +``` diff --git a/src/js/components/header/header.js b/src/js/components/header/header.js new file mode 100644 index 0000000..be7cb2e --- /dev/null +++ b/src/js/components/header/header.js @@ -0,0 +1,68 @@ +(function () { + /** + * @param {Object} container DOM element, which will be hidden\displayed (required) + * @param {string} options the class to be toggled. + */ + class IatiMobileNav { + constructor(wrapper, openClass) { + this.wrapper = wrapper; + this.openClass = openClass; + const focusableElements = this.wrapper.querySelectorAll("a, button"); + this.firstElement = focusableElements[0]; + this.lastElement = focusableElements[focusableElements.length - 1]; + } + + show = () => { + this.wrapper.removeAttribute("hidden"); + document.addEventListener("keydown", (e) => this.handleKeyDown(e)); + this.wrapper.classList.add(this.openClass); + setTimeout(() => { + this.firstElement.focus(); + }, 500); + }; + + hide = (closeCallBack) => { + this.wrapper.classList.remove(this.openClass); + document.removeEventListener("keydown", (e) => this.handleKeyDown(e)); + setTimeout(() => { + this.wrapper.setAttribute("hidden", "hidden"); + closeCallBack(); + }, 500); + }; + + handleKeyDown(event) { + if (event.key === "Tab") { + if (document.activeElement === this.firstElement && event.shiftKey) { + this.lastElement.focus(); + event.preventDefault(); + } + if (document.activeElement === this.lastElement && !event.shiftKey) { + this.firstElement.focus(); + event.preventDefault(); + } + } + if (event.key == "Escape") { + this.hide(); + } + } + } + + document.addEventListener("DOMContentLoaded", function () { + const iatiMobileNav = new IatiMobileNav( + document.querySelector(".js-iati-mobile-nav"), + "iati-mobile-nav--open", + ); + + const overlay = document.querySelector(".js-iati-mobile-overlay"); + const menuOpenBtn = document.querySelector(".js-iati-menu-toggle-open"); + const menuCloseBtn = document.querySelector(".js-iati-menu-toggle-close"); + const restoreFocus = () => { + menuOpenBtn.focus(); + }; + menuOpenBtn.addEventListener("click", iatiMobileNav.show); + menuCloseBtn.addEventListener("click", () => + iatiMobileNav.hide(restoreFocus), + ); + overlay.addEventListener("click", () => iatiMobileNav.hide(restoreFocus)); + }); +})(); diff --git a/src/js/main.js b/src/js/main.js new file mode 100644 index 0000000..37ca1a0 --- /dev/null +++ b/src/js/main.js @@ -0,0 +1 @@ +import "./components/header/header.js"; diff --git a/src/scss/base/_focus.scss b/src/scss/base/_focus.scss new file mode 100644 index 0000000..8ee9a37 --- /dev/null +++ b/src/scss/base/_focus.scss @@ -0,0 +1,6 @@ +@use "../tokens/color" as *; + +:is(a, button, input, select, textarea, summary):focus-visible { + outline: 2px solid $color-blue-60; + outline-offset: 2px; +} diff --git a/src/scss/base/_index.scss b/src/scss/base/_index.scss index 85802a3..b3714c1 100644 --- a/src/scss/base/_index.scss +++ b/src/scss/base/_index.scss @@ -1,3 +1,4 @@ @forward "normalize"; @forward "reset"; @forward "mixins"; +@forward "focus"; diff --git a/src/scss/base/_mixins.scss b/src/scss/base/_mixins.scss index 9165a69..12353af 100644 --- a/src/scss/base/_mixins.scss +++ b/src/scss/base/_mixins.scss @@ -4,9 +4,9 @@ @mixin page-width-container { width: 100%; max-width: $page-width-max; - margin-left: auto; + margin-inline-start: auto; margin-right: auto; - padding: $padding-block; + padding: 0 $padding-block; } @mixin columns { @@ -30,6 +30,18 @@ } li li { - padding-left: $padding-block; + padding-inline-start: $padding-block; } } + +@mixin sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} diff --git a/src/scss/base/_reset.scss b/src/scss/base/_reset.scss index 4e3dbf1..aaac052 100644 --- a/src/scss/base/_reset.scss +++ b/src/scss/base/_reset.scss @@ -4,7 +4,7 @@ box-sizing: border-box; } -a, +a[href], button { cursor: pointer; } @@ -23,3 +23,7 @@ button, input { font-weight: inherit; } + +input { + border-radius: 0; +} diff --git a/src/scss/components/_index.scss b/src/scss/components/_index.scss index fbea8e9..d696b72 100644 --- a/src/scss/components/_index.scss +++ b/src/scss/components/_index.scss @@ -1,6 +1,17 @@ @forward "button/button"; +@forward "breadcrumb/breadcrumb"; +@forward "brand-background/brand-background"; @forward "callout/callout"; @forward "card/card"; +@forward "country-switcher/country-switcher"; +@forward "piped-list/piped-list"; @forward "icon/icon"; @forward "search-bar/search-bar"; @forward "table/table"; +@forward "tool-nav/tool-nav"; +@forward "menu-toggle/menu-toggle"; +@forward "message/message"; +@forward "mobile-nav/mobile-nav"; +@forward "newsletter-form/newsletter-form"; +@forward "title-bar/title-bar"; +@forward "footer-block/footer-block"; diff --git a/src/scss/components/brand-background/_brand-background.scss b/src/scss/components/brand-background/_brand-background.scss new file mode 100644 index 0000000..26b8154 --- /dev/null +++ b/src/scss/components/brand-background/_brand-background.scss @@ -0,0 +1,25 @@ +@use "../../tokens/color" as *; +@use "../../tokens/screens" as *; + +.iati-brand-background { + $var-background-image: --background-image; + #{$var-background-image}: url("/images/marque-white.svg"); + + background-color: $color-teal-90; + display: grid; + @media (min-width: $screen-md) { + &:after { + content: ""; + grid-area: 1/-1; + background-image: var($var-background-image); + background-repeat: no-repeat; + background-position: right 2rem top; + background-size: 32.3rem auto; + opacity: 0.1; + } + .iati-brand-background__content { + grid-area: 1/-1; + z-index: 1; + } + } +} diff --git a/src/scss/components/brand-background/brand-background.mdx b/src/scss/components/brand-background/brand-background.mdx new file mode 100644 index 0000000..a159bea --- /dev/null +++ b/src/scss/components/brand-background/brand-background.mdx @@ -0,0 +1,27 @@ +import { Meta, Title, Subtitle, Stories } from "@storybook/blocks"; +import LinkTo from "@storybook/addon-links/react"; +import * as ComponentStories from "./brand-background.stories.ts"; + + + +Brand Background + +**This component expects the background image to be served by the app using the design system.** + +To use this component, take the following steps: + +1. Go to Marque White and download the image. + +2. Serve the file from your app. This will depend on the technology your app is written in. + +3. Optionally, use the provided CSS custom property to configure the path to the image. The default is `/images/marque-white.svg`. + + ```css + .iati-brand-background { + --background-image: url("PATH_TO_IMAGE"); + } + ``` + +4. Apply the appropriate classes to your html elements, using the example below. + + diff --git a/src/scss/components/brand-background/brand-background.stories.ts b/src/scss/components/brand-background/brand-background.stories.ts new file mode 100644 index 0000000..1ebec9e --- /dev/null +++ b/src/scss/components/brand-background/brand-background.stories.ts @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from "@storybook/web-components"; + +import { html } from "lit"; + +const meta: Meta = { + title: "Components/Brand Background", +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => + html`
+
+ +
+
+
`, +}; diff --git a/src/scss/components/breadcrumb/_breadcrumb.scss b/src/scss/components/breadcrumb/_breadcrumb.scss new file mode 100644 index 0000000..8f56895 --- /dev/null +++ b/src/scss/components/breadcrumb/_breadcrumb.scss @@ -0,0 +1,54 @@ +@use "../../tokens/color" as *; +@use "../../tokens/spacing" as *; +@use "../../tokens/screens" as *; + +.iati-breadcrumb { + font-weight: 600; +} + +.iati-breadcrumb__list { + list-style-type: none; + padding: 0; + margin: 0; + display: flex; + display: none; + > *:not(:last-child)::after { + content: "/"; + color: $color-teal-90; + font-weight: 600; + display: inline-block; + padding-inline: 0.4em; + } +} + +.iati-breadcrumb-item { + line-height: 1; +} + +.iati-breadcrumb__previous { + display: flex; + align-items: flex-end; + &::before { + content: ""; + display: inline-block; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='currentColor' class='size-5'%3E%3Cpath fill-rule='evenodd' d='M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z' clip-rule='evenodd' /%3E%3C/svg%3E%0A"); + background-size: contain; + background-position: center; + height: 1.2em; + width: 1.2em; + } +} + +.iati-breadcrumb-link { + text-decoration: none; + line-height: 1; +} + +@media (min-width: $screen-sm) { + .iati-breadcrumb__previous { + display: none; + } + .iati-breadcrumb__list { + display: flex; + } +} diff --git a/src/scss/components/breadcrumb/breadcrumb.stories.ts b/src/scss/components/breadcrumb/breadcrumb.stories.ts new file mode 100644 index 0000000..2e47182 --- /dev/null +++ b/src/scss/components/breadcrumb/breadcrumb.stories.ts @@ -0,0 +1,39 @@ +import { html } from "lit"; +import { classMap } from "lit-html/directives/class-map.js"; + +import type { Meta, StoryObj } from "@storybook/web-components"; + +const items = ["Home", "About", "Current page"]; + +const meta: Meta = { + title: "Components/Breadcrumb", +}; + +export default meta; +type Story = StoryObj; + +export const Breadcrumb: Story = { + render: () => html` + + `, +}; diff --git a/src/scss/components/button/_button.scss b/src/scss/components/button/_button.scss index f084647..ca96dca 100644 --- a/src/scss/components/button/_button.scss +++ b/src/scss/components/button/_button.scss @@ -1,14 +1,44 @@ @use "../../tokens/color" as *; +@use "../../tokens/font" as *; @use "../../tokens/spacing" as *; .iati-button { + --display: inline-flex; // Used by .display--* utilities + + display: var(--display); + align-items: center; + justify-content: center; + gap: 0.25em; background-color: $color-teal-90; border: none; color: white; - text-transform: uppercase; - padding: $padding-block; + font-family: $font-stack-heading; + line-height: 1.1; + padding: 0.7em; + font-weight: 600; + transition: all 0.2s ease-in-out; &:hover { background-color: $color-teal-80; } + + &__icon { + width: 1rem; + } + + &--light { + color: $color-grey-90; + background-color: #fff; + &:hover { + background-color: $color-blue-30; + } + } + + &--submit { + color: $color-grey-90; + background-color: $color-green-50; + &:hover { + background-color: $color-green-40; + } + } } diff --git a/src/scss/components/button/button.stories.ts b/src/scss/components/button/button.stories.ts index f2d362a..3ffbf05 100644 --- a/src/scss/components/button/button.stories.ts +++ b/src/scss/components/button/button.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from "@storybook/web-components"; +import iconInfoUrl from "../../../assets/svg/icon-info.svg"; import { html } from "lit"; @@ -9,6 +10,35 @@ const meta: Meta = { export default meta; type Story = StoryObj; -export const Button: Story = { +export const Default: Story = { render: () => html``, }; + +export const Light: Story = { + parameters: { + backgrounds: { + default: "dark", + }, + }, + render: () => + html``, +}; + +export const Submit: Story = { + render: () => + html``, +}; + +export const WithIcon: Story = { + parameters: { + backgrounds: { + default: "dark", + }, + }, + render: () => html` + + `, +}; diff --git a/src/scss/components/callout/_callout.scss b/src/scss/components/callout/_callout.scss index 76a014e..30b10f2 100644 --- a/src/scss/components/callout/_callout.scss +++ b/src/scss/components/callout/_callout.scss @@ -4,7 +4,7 @@ .iati-callout { padding: $padding-block; - border-left: $border-width solid $color-blue-50; + border-inline-start: $border-width solid $color-blue-50; background-color: $color-teal-10; color: $color-teal-90; box-shadow: 0 4px 5px $color-grey-20; diff --git a/src/scss/components/country-switcher/_country-switcher.scss b/src/scss/components/country-switcher/_country-switcher.scss new file mode 100644 index 0000000..08b05d3 --- /dev/null +++ b/src/scss/components/country-switcher/_country-switcher.scss @@ -0,0 +1,40 @@ +@use "../../tokens/color" as *; +@use "../../tokens/font" as *; +@use "../../base/mixins"; + +.iati-country-switcher { + background-color: #fff; + position: relative; + display: inline-block; + color: #121212; + cursor: pointer; + .iati-country-switcher__label { + @include mixins.sr-only; + } + .iati-country-switcher__control { + padding: 0.7em 2.1em 0.7em calc(1em + 1rem); + font-family: $font-stack-heading; + line-height: 1.1; + width: 100%; + height: 100%; + appearance: none; + background-color: #fff; + border: none; + font-family: $font-stack-heading; + color: $color-grey-90; + font-weight: 600; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none'%3E%3Cpath stroke='%23121212' stroke-linecap='square' stroke-width='1.3' d='M10 19c4.9706 0 9-4.0294 9-9 0-4.97056-4.0294-9-9-9-4.97056 0-9 4.02944-9 9 0 4.9706 4.02944 9 9 9Z'/%3E%3Cpath stroke='%23121212' stroke-linecap='round' stroke-linejoin='bevel' stroke-width='1.3' d='M9.99984 18.991C12.3938 16.8114 13.5908 13.8144 13.5908 10c0-3.81433-1.197-6.81133-3.59096-8.99097-2.394 2.17964-3.591 5.17664-3.591 8.99097 0 3.8144 1.197 6.8114 3.591 8.991Z'/%3E%3Cpath stroke='%23121212' stroke-linecap='round' stroke-width='1.3' d='M1.44991 7.29993H18.5499M1.44991 12.6999H18.5499'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: 0.5em center; + } + &::after { + position: absolute; + right: 0.7em; + top: calc(50% - 0.1875em); + content: ""; + width: 0.75em; + height: 0.375em; + background-color: currentColor; + clip-path: polygon(15% 0, 0 0, 50% 100%, 100% 0, 85% 0, 50% 70%); + } +} diff --git a/src/scss/components/country-switcher/country-switcher.stories.ts b/src/scss/components/country-switcher/country-switcher.stories.ts new file mode 100644 index 0000000..5bf6f97 --- /dev/null +++ b/src/scss/components/country-switcher/country-switcher.stories.ts @@ -0,0 +1,28 @@ +import type { Meta, StoryObj } from "@storybook/web-components"; +import { html } from "lit"; + +const meta: Meta = { + title: "Components/Country Switcher", + parameters: { + backgrounds: { + default: "dark", + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const CountrySwitcher: Story = { + render: () => html` +
+ + +
+ `, +}; diff --git a/src/scss/components/footer-block/_footer-block.scss b/src/scss/components/footer-block/_footer-block.scss new file mode 100644 index 0000000..18b719b --- /dev/null +++ b/src/scss/components/footer-block/_footer-block.scss @@ -0,0 +1,50 @@ +@use "../../tokens/screens" as *; +@use "../../tokens/font" as *; +@use "../../tokens/color" as *; +@use "../../base/mixins"; + +.iati-footer-block { + color: #fff; +} + +.iati-footer-block__title { + margin: 0 0 1.5rem; + font-family: $font-stack-heading; + font-size: 1.25rem; + line-height: 1.2; + font-weight: 700; + &--centered { + @media (min-width: $screen-md) { + text-align: center; + } + } +} + +.iati-footer-block__content { + font-weight: 600; + :where(p, li) { + line-height: 1.375; + margin: 0; + } + a { + color: currentColor; + &:hover { + color: $color-blue-30; + } + } + ul { + list-style-type: none; + margin: 0; + padding: 0; + } + > * + * { + margin-block-start: 0.5rem; + } +} + +.iati-footer-block__content--columns { + @media (min-width: $screen-sm) { + columns: 3; + column-gap: 2rem; + } +} diff --git a/src/scss/components/footer-block/footer-block.stories.ts b/src/scss/components/footer-block/footer-block.stories.ts new file mode 100644 index 0000000..7f95918 --- /dev/null +++ b/src/scss/components/footer-block/footer-block.stories.ts @@ -0,0 +1,53 @@ +import type { Meta, StoryObj } from "@storybook/web-components"; + +import { html } from "lit"; + +const meta: Meta = { + title: "Components/Footer/Footer Block", + parameters: { + backgrounds: { + default: "dark", + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const UsefulLinks: Story = { + render: () => + html``, +}; + +export const AdditionInfo: Story = { + render: () => + html``, +}; diff --git a/src/scss/components/menu-toggle/_menu-toggle.scss b/src/scss/components/menu-toggle/_menu-toggle.scss new file mode 100644 index 0000000..46184a5 --- /dev/null +++ b/src/scss/components/menu-toggle/_menu-toggle.scss @@ -0,0 +1,36 @@ +@use "../../tokens/color" as *; +@use "../../tokens/font" as *; +@use "../../tokens/spacing" as *; +@use "../../tokens/screens" as *; + +.iati-menu-toggle { + color: #fff; + border: none; + background-color: transparent; + font-size: 0.9rem; + font-family: $font-stack-heading; + font-weight: 600; + flex-direction: column; + display: inline-flex; + align-items: flex-end; + gap: 0.5em; + padding: 0; + align-self: stretch; + background-repeat: no-repeat; + background-size: contain; + justify-content: flex-end; + min-height: 2.2rem; + &--open { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='white' viewBox='0 0 38 17'%3E%3Cpath d='M0 0h38v3H0ZM0 7h38v3H0ZM0 14h38v3H0Z'/%3E%3C/svg%3E"); + } + &--close { + height: 3.5rem; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 26 26'%3E%3Cpath stroke='white' stroke-miterlimit='10' stroke-width='1.3' d='M13 25c6.6274 0 12-5.3726 12-12 0-6.62742-5.3726-12-12-12C6.37258 1 1 6.37258 1 13c0 6.6274 5.37258 12 12 12ZM18.4163 18.416 7.58386 7.58386M7.58386 18.416 18.4163 7.58386'/%3E%3C/svg%3E"); + } +} + +.iati-menu-toggle__label { + line-height: 1; + position: relative; + top: 0.25em; +} diff --git a/src/scss/components/menu-toggle/menu-toggle.stories.ts b/src/scss/components/menu-toggle/menu-toggle.stories.ts new file mode 100644 index 0000000..036bd18 --- /dev/null +++ b/src/scss/components/menu-toggle/menu-toggle.stories.ts @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from "@storybook/web-components"; +import { html } from "lit"; + +const meta: Meta = { + title: "Components/Menu Toggle", + parameters: { + backgrounds: { + default: "dark", + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Open: Story = { + render: () => html` + + `, +}; + +export const Close: Story = { + render: () => html` + + `, +}; diff --git a/src/scss/components/message/_message.scss b/src/scss/components/message/_message.scss new file mode 100644 index 0000000..0bbdc56 --- /dev/null +++ b/src/scss/components/message/_message.scss @@ -0,0 +1,27 @@ +@use "../../tokens/color" as *; +@use "../../tokens/font" as *; + +.iati-message { + padding: 0.8em 1em; + font-family: $font-stack-heading; + font-size: 1.1rem; + line-height: 1; + margin: 0; + font-weight: 400; + a { + color: currentColor; + text-decoration-color: currentColor; + } +} + +.iati-message-highlight { + font-weight: 600; +} + +.iati-message--notice { + background-color: $color-grey-10; +} + +.iati-message--info { + background-color: $color-green-10; +} diff --git a/src/scss/components/message/message.stories.ts b/src/scss/components/message/message.stories.ts new file mode 100644 index 0000000..294e994 --- /dev/null +++ b/src/scss/components/message/message.stories.ts @@ -0,0 +1,32 @@ +import { html } from "lit"; + +import type { Meta, StoryObj } from "@storybook/web-components"; + +const meta: Meta = { + title: "Components/Message", +}; + +export default meta; +type Story = StoryObj; + +export const Notice: Story = { + render: () => html` +

+ You are viewing + VERSION 2.03 of IATI Standard Reference. View another version. +

+ `, +}; + +export const Info: Story = { + render: () => html` +

+ You are viewing + VERSION 2.03 of IATI Standard Reference. View another version. +

+ `, +}; diff --git a/src/scss/components/mobile-nav/_mobile-nav.scss b/src/scss/components/mobile-nav/_mobile-nav.scss new file mode 100644 index 0000000..2420d4a --- /dev/null +++ b/src/scss/components/mobile-nav/_mobile-nav.scss @@ -0,0 +1,89 @@ +@use "../../tokens/color" as *; +@use "../../tokens/font" as *; +@use "../../tokens/spacing" as *; + +.iati-mobile-nav { + overflow: hidden; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + z-index: -1; + transition: all 0.5s; + &--open { + z-index: 100; + } +} + +.iati-mobile-nav__overlay { + height: 100%; + min-height: 100vh; + width: 100%; + background-color: #000; + opacity: 0; + position: absolute; + top: 0; + left: 0; + visibility: hidden; + transition: all 0.5s; + z-index: -1; + .iati-mobile-nav--open & { + opacity: 0.6; + visibility: visible; + } +} + +.iati-mobile-nav__menu { + background-color: $color-teal-90; + padding: 1rem; + color: #fff; + position: absolute; + z-index: 101; + right: 0; + top: 0; + height: 100%; + width: min(90vw, 400px); + margin: 0; + transform: translateX(400px); + transition: transform 0.5s; + .iati-mobile-nav--open & { + transform: translateX(0); + } + ul { + list-style-type: none; + margin: 0; + padding: 0; + } +} + +.iati-mobile-nav__label { + font-size: 1.375rem; + margin-block-end: 2rem; + margin: 0; +} + +.iati-mobile-nav__header { + display: flex; + justify-content: space-between; + align-items: center; + margin-block-end: 2rem; +} + +.iati-mobile-nav__item { + border-block-start: 1px solid #fff; +} + +.iati-mobile-nav__link { + color: #fff; + text-decoration: none; + font-weight: 800; + font-size: 1.0625rem; + line-height: 1; + padding-block: 0.75em; + display: block; + transition: all 0.2s ease-in-out; + &:hover { + color: $color-blue-30; + } +} diff --git a/src/scss/components/mobile-nav/mobile-nav.stories.ts b/src/scss/components/mobile-nav/mobile-nav.stories.ts new file mode 100644 index 0000000..4d8af8b --- /dev/null +++ b/src/scss/components/mobile-nav/mobile-nav.stories.ts @@ -0,0 +1,68 @@ +import { html } from "lit"; + +import type { Meta, StoryObj } from "@storybook/web-components"; +import { Close as MenuToggle } from "../menu-toggle/menu-toggle.stories"; + +const toolItems = [ + "Tool Home", + "About", + "Data Dashboards", + "Custom Data Download", +]; +const generalItems = ["IATI Home", "News", "Events", "Contact", "Help Docs"]; + +const meta: Meta = { + title: "Components/Mobile Nav", + argTypes: { + open: { + control: { type: "boolean" }, + }, + }, + parameters: { + docs: { + story: { + height: "600px", + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const MobileNav: Story = { + args: { + open: true, + }, + render: (args) => html` +
+
+ +
+ `, +}; diff --git a/src/scss/components/newsletter-form/_newsletter-form.scss b/src/scss/components/newsletter-form/_newsletter-form.scss new file mode 100644 index 0000000..d69a33b --- /dev/null +++ b/src/scss/components/newsletter-form/_newsletter-form.scss @@ -0,0 +1,44 @@ +@use "../../tokens/color" as *; +@use "../../tokens/font" as *; +@use "../../base/mixins"; +@use "../../tokens/screens" as *; + +.iati-newsletter-form { + color: #fff; + display: grid; + gap: 1rem; + min-width: min(31.25rem, calc(100vw - 2rem)); + @media (min-width: $screen-md) { + grid-template-columns: max-content 1fr; + } +} + +.iati-newsletter-form__item { + display: grid; + grid-template-columns: subgrid; + grid-column: 1 / -1; + align-items: end; + gap: 0.2rem; + @media (min-width: $screen-md) { + gap: 1rem; + } +} + +.iati-newsletter-form__label { + font-weight: 600; + grid-column: 1; + @media (min-width: $screen-md) { + text-align: end; + } +} + +.iati-newsletter-form__input { + max-width: 100%; + border: none; + background-color: #fff; + padding: 0.5em 1em; +} + +.iati-newsletter-form__submit { + grid-column: -1 / span 1; +} diff --git a/src/scss/components/newsletter-form/newsletter-form.stories.ts b/src/scss/components/newsletter-form/newsletter-form.stories.ts new file mode 100644 index 0000000..365c7aa --- /dev/null +++ b/src/scss/components/newsletter-form/newsletter-form.stories.ts @@ -0,0 +1,58 @@ +import type { Meta, StoryObj } from "@storybook/web-components"; +import { html } from "lit"; + +const meta: Meta = { + title: "Components/Newsletter Form", + parameters: { + backgrounds: { + default: "dark", + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => html` +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ `, +}; diff --git a/src/scss/components/piped-list/_piped-list.scss b/src/scss/components/piped-list/_piped-list.scss new file mode 100644 index 0000000..c9eab41 --- /dev/null +++ b/src/scss/components/piped-list/_piped-list.scss @@ -0,0 +1,28 @@ +@use "../../tokens/color" as *; +@use "../../tokens/font" as *; + +.iati-piped-list { + display: flex; + flex-wrap: wrap; + gap: 0.5em; + list-style-type: none; + padding: 0; + margin: 0; + & > * { + line-height: 1; + position: relative; + &:not(:last-child) { + &:after { + content: ""; + position: absolute; + right: 1rem; + height: 120%; + width: 1px; + display: block; + background-color: currentColor; + top: -10%; + } + padding-inline-end: 2rem; + } + } +} diff --git a/src/scss/components/piped-list/piped-list.stories.ts b/src/scss/components/piped-list/piped-list.stories.ts new file mode 100644 index 0000000..3c3c5eb --- /dev/null +++ b/src/scss/components/piped-list/piped-list.stories.ts @@ -0,0 +1,20 @@ +import { html } from "lit"; + +import type { Meta, StoryObj } from "@storybook/web-components"; + +const items = ["IATI Home", "News", "Events", "Contacts"]; + +const meta: Meta = { + title: "Components/Piped List", +}; + +export default meta; +type Story = StoryObj; + +export const PipedList: Story = { + render: () => html` +
    + ${items.map((i) => html`
  • ${i}
  • `)} +
+ `, +}; diff --git a/src/scss/components/search-bar/_search-bar.scss b/src/scss/components/search-bar/_search-bar.scss index f8ebc0f..6427e25 100644 --- a/src/scss/components/search-bar/_search-bar.scss +++ b/src/scss/components/search-bar/_search-bar.scss @@ -9,7 +9,7 @@ flex-grow: 1; padding: $padding-block; border: 1px solid $color-grey-20; - border-right: none; + border-inline-end: none; &::placeholder { color: $color-grey-40; diff --git a/src/scss/components/title-bar/_title-bar.scss b/src/scss/components/title-bar/_title-bar.scss new file mode 100644 index 0000000..df6aaff --- /dev/null +++ b/src/scss/components/title-bar/_title-bar.scss @@ -0,0 +1,40 @@ +@use "../../tokens/color" as *; +@use "../../tokens/font" as *; +@use "../../tokens/spacing" as *; +@use "../../tokens/screens" as *; + +.iati-header-title { + display: flex; + flex-direction: column; + gap: 0.8rem; + padding-inline-start: 1rem; + margin-block-end: 1.5rem; + border-inline-start: $border-width solid $color-blue-50; + & > * { + margin: 0; + } +} + +.iati-header-title__eyebrow, +.iati-header-title__heading { + color: white; + font-family: $font-stack-heading; + font-weight: 800; +} + +.iati-header-title__eyebrow { + font-size: 1.1rem; + line-height: 1; + @media (min-width: $screen-sm) { + font-size: 1.5rem; + line-height: 1.2; + } +} + +.iati-header-title__heading { + font-size: 1.625rem; + line-height: 1; + @media (min-width: $screen-sm) { + font-size: 2.5rem; + } +} diff --git a/src/scss/components/title-bar/title-bar.stories.ts b/src/scss/components/title-bar/title-bar.stories.ts new file mode 100644 index 0000000..792c33f --- /dev/null +++ b/src/scss/components/title-bar/title-bar.stories.ts @@ -0,0 +1,23 @@ +import type { Meta, StoryObj } from "@storybook/web-components"; +import { html } from "lit"; + +const meta: Meta = { + title: "Components/Title Bar", + parameters: { + backgrounds: { + default: "dark", + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => html` +
+

IATI Tools

+

Country Development Finance Data

+
+ `, +}; diff --git a/src/scss/components/tool-nav/_tool-nav.scss b/src/scss/components/tool-nav/_tool-nav.scss new file mode 100644 index 0000000..ca08698 --- /dev/null +++ b/src/scss/components/tool-nav/_tool-nav.scss @@ -0,0 +1,26 @@ +@use "../../tokens/color" as *; +@use "../../tokens/font" as *; +@use "../../tokens/spacing" as *; + +.iati-tool-nav { + list-style-type: none; + display: flex; + padding: 0; + margin: 0; +} + +.iati-tool-nav-link { + text-decoration: none; + padding: 1rem; + font-family: $font-stack-heading; + font-weight: 600; + color: #fff; + font-size: 1.0625rem; + line-height: 1.1; + transition: all 0.2s ease-in-out; + display: inline-block; + &:hover { + background-color: $color-blue-30; + color: $color-teal-90; + } +} diff --git a/src/scss/components/tool-nav/tool-nav.stories.ts b/src/scss/components/tool-nav/tool-nav.stories.ts new file mode 100644 index 0000000..efab64d --- /dev/null +++ b/src/scss/components/tool-nav/tool-nav.stories.ts @@ -0,0 +1,29 @@ +import { html } from "lit"; + +import type { Meta, StoryObj } from "@storybook/web-components"; + +const items = ["Tool Home", "About", "Data Dashboards", "Custom Data Download"]; + +const meta: Meta = { + title: "Components/Header/Tool Nav", + parameters: { + backgrounds: { + default: "dark", + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const ToolNav: Story = { + render: () => html` + + `, +}; diff --git a/src/scss/layout/_index.scss b/src/scss/layout/_index.scss index 440ce9a..f127e09 100644 --- a/src/scss/layout/_index.scss +++ b/src/scss/layout/_index.scss @@ -1,4 +1,3 @@ @forward "footer/footer"; @forward "header/header"; -@forward "title-bar/title-bar"; @forward "page/page"; diff --git a/src/scss/layout/footer/_footer.scss b/src/scss/layout/footer/_footer.scss index d0f61dc..3b25788 100644 --- a/src/scss/layout/footer/_footer.scss +++ b/src/scss/layout/footer/_footer.scss @@ -2,47 +2,63 @@ @use "../../tokens/font" as *; @use "../../tokens/spacing" as *; @use "../../base/mixins"; +@use "../../tokens/screens" as *; .iati-footer { - background-color: $color-teal-90; - color: white; + color: #fff; +} - & a { - color: currentColor; - } +.iati-footer__section { + margin-block: 2rem; - & > div { - @include mixins.page-width-container(); - @include mixins.columns(); - flex-wrap: wrap; + &:not(:first-of-type) { + padding-block-start: 2rem; + border-block-start: 1px solid $color-blue-30; } +} - hr { - border: none; - border-top: 1px solid $color-teal-70; - margin: 0; +.iati-footer__section--first .iati-footer__container { + display: flex; + gap: 2rem; + flex-direction: column; + @media (min-width: $screen-md) { + justify-content: space-between; + flex-direction: row; } +} - &__logo { - max-height: 80px; - max-width: 100%; - margin: $padding-block 0; +.iati-footer__section--last .iati-footer__container { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 2rem; + > :first-child { + margin-inline-end: auto; } +} - &__list { - &-title { - text-transform: uppercase; - font-family: $font-stack-heading; - font-weight: $font-weight-heading; - line-height: $line-height-body; - } +.iati-footer__container { + @include mixins.page-width-container(); +} - ul { - @include mixins.unstyled-list(); +.iati-footer__legal-nav { + color: currentColor; + font-weight: 600; + font-size: 1.0625rem; + line-height: 1.1; + a { + font-size: 1.0625rem; + line-height: 1.1; + color: currentColor; + text-decoration: none; + &:visited, + &:hover { + color: $color-blue-30; } } +} - &__social-icons { - @include mixins.columns(); - } +.iati-footer__social { + display: flex; + gap: 0.5rem; } diff --git a/src/scss/layout/footer/footer.stories.ts b/src/scss/layout/footer/footer.stories.ts index 7202c1b..1518366 100644 --- a/src/scss/layout/footer/footer.stories.ts +++ b/src/scss/layout/footer/footer.stories.ts @@ -1,10 +1,25 @@ import type { Meta, StoryObj } from "@storybook/web-components"; import { html } from "lit"; +import { CountrySwitcher } from "../../components/country-switcher/country-switcher.stories"; +import { + AdditionInfo as AdditionalInfoFooterBlock, + UsefulLinks as UsefulLinksFooterBlock, +} from "../../components/footer-block/footer-block.stories"; import { Linkedin, Twitter, Youtube } from "../../components/icon/icon.stories"; +import { Default as NewsletterForm } from "../../components/newsletter-form/newsletter-form.stories"; + +const legalNavItems = [ + html`Privacy`, + html`Data removal`, + html`© Copyright IATI 2024. All rights reserved`, +]; const meta: Meta = { title: "Layout/Footer", + parameters: { + layout: "fullscreen", + }, }; export default meta; @@ -12,42 +27,54 @@ type Story = StoryObj; export const Footer: Story = { render: (args) => html` -