From a63caaade18a07e0b0d5efba47b48192a2808a12 Mon Sep 17 00:00:00 2001 From: Newton <5769156+iamnewton@users.noreply.github.com> Date: Thu, 17 Oct 2024 10:33:21 -0700 Subject: [PATCH] =?UTF-8?q?chore:=20=E2=99=BB=EF=B8=8F=20=20refactor=20it?= =?UTF-8?q?=20to=20use=20different=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Newton <5769156+iamnewton@users.noreply.github.com> --- .github/workflows/chromatic.yml | 28 + .github/workflows/deploy.yml | 32 + .github/workflows/visual-tests.yml | 113 +++ .storybook/main.js | 26 - .storybook/main.ts | 24 + .storybook/preview.js | 13 - .storybook/preview.ts | 25 + README.md | 4 +- package-lock.json | 684 ++++++++++++++++++- package.json | 18 +- {stories => src}/Configure.mdx | 0 {stories => src}/assets/accessibility.png | Bin {stories => src}/assets/accessibility.svg | 0 {stories => src}/assets/addon-library.png | Bin {stories => src}/assets/assets.png | Bin {stories => src}/assets/avif-test-image.avif | Bin {stories => src}/assets/context.png | Bin {stories => src}/assets/discord.svg | 0 {stories => src}/assets/docs.png | Bin {stories => src}/assets/figma-plugin.png | Bin {stories => src}/assets/github.svg | 0 {stories => src}/assets/share.png | Bin {stories => src}/assets/styling.png | Bin {stories => src}/assets/testing.png | Bin {stories => src}/assets/theming.png | Bin {stories => src}/assets/tutorials.svg | 0 {stories => src}/assets/youtube.svg | 0 {stories => src/button}/button.css | 4 + src/button/button.story.ts | 60 ++ src/button/button.tsx | 39 ++ {stories => src/header}/header.css | 0 src/header/header.story.ts | 34 + src/header/header.tsx | 65 ++ {stories => src/page}/page.css | 0 src/page/page.story.ts | 32 + src/page/page.tsx | 69 ++ stories/Button.jsx | 40 -- stories/Button.stories.js | 56 -- stories/Header.jsx | 60 -- stories/Header.stories.js | 29 - stories/Page.jsx | 69 -- stories/Page.stories.js | 28 - 42 files changed, 1199 insertions(+), 353 deletions(-) create mode 100644 .github/workflows/chromatic.yml create mode 100644 .github/workflows/deploy.yml create mode 100644 .github/workflows/visual-tests.yml delete mode 100644 .storybook/main.js create mode 100644 .storybook/main.ts delete mode 100644 .storybook/preview.js create mode 100644 .storybook/preview.ts rename {stories => src}/Configure.mdx (100%) rename {stories => src}/assets/accessibility.png (100%) rename {stories => src}/assets/accessibility.svg (100%) rename {stories => src}/assets/addon-library.png (100%) rename {stories => src}/assets/assets.png (100%) rename {stories => src}/assets/avif-test-image.avif (100%) rename {stories => src}/assets/context.png (100%) rename {stories => src}/assets/discord.svg (100%) rename {stories => src}/assets/docs.png (100%) rename {stories => src}/assets/figma-plugin.png (100%) rename {stories => src}/assets/github.svg (100%) rename {stories => src}/assets/share.png (100%) rename {stories => src}/assets/styling.png (100%) rename {stories => src}/assets/testing.png (100%) rename {stories => src}/assets/theming.png (100%) rename {stories => src}/assets/tutorials.svg (100%) rename {stories => src}/assets/youtube.svg (100%) rename {stories => src/button}/button.css (90%) create mode 100644 src/button/button.story.ts create mode 100644 src/button/button.tsx rename {stories => src/header}/header.css (100%) create mode 100644 src/header/header.story.ts create mode 100644 src/header/header.tsx rename {stories => src/page}/page.css (100%) create mode 100644 src/page/page.story.ts create mode 100644 src/page/page.tsx delete mode 100644 stories/Button.jsx delete mode 100644 stories/Button.stories.js delete mode 100644 stories/Header.jsx delete mode 100644 stories/Header.stories.js delete mode 100644 stories/Page.jsx delete mode 100644 stories/Page.stories.js diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml new file mode 100644 index 0000000..65333ce --- /dev/null +++ b/.github/workflows/chromatic.yml @@ -0,0 +1,28 @@ +name: "Chromatic Publish" + +on: push + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - name: Install dependencies + - run: npm ci + + #👇 Adds Chromatic as a step in the workflow + - name: Publish to Chromatic + - uses: chromaui/action@v1 + with: + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..dbef968 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,32 @@ +name: Build and Publish Storybook to GitHub Pages + +on: + push: + branches: ["main"] + +jobs: + deploy: + permissions: + contents: read + pages: write + id-token: write + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.build-publish.outputs.page_url }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: "npm" + + - uses: bitovi/github-actions-storybook-to-github-pages@v1.0.3 + with: + install_command: npm ci + build_command: npm run build-storybook + path: storybook-static # default: dist/storybook + checkout: false # code is already checked out above diff --git a/.github/workflows/visual-tests.yml b/.github/workflows/visual-tests.yml new file mode 100644 index 0000000..25a0b98 --- /dev/null +++ b/.github/workflows/visual-tests.yml @@ -0,0 +1,113 @@ +name: "Visual Tests" + +on: push + +jobs: + # Install and cache npm dependencies + install-cache: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache Yarn dependencies and Cypress + uses: actions/cache@v4 + id: yarn-cache + with: + path: | + ~/.cache/Cypress + node_modules + key: ${{ runner.os }}-yarn-v1-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-v1 + + - name: Install dependencies if cache invalid + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn + + # Run interaction and accessibility tests + interaction-and-accessibility: + runs-on: ubuntu-latest + needs: install-cache + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Restore Yarn dependencies + uses: actions/cache@v4 + id: yarn-cache + with: + path: | + ~/.cache/Cypress + node_modules + key: ${{ runner.os }}-yarn-v1-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-v1 + + - name: Install Playwright + run: npx playwright install --with-deps + + - name: Build Storybook + run: yarn build-storybook --quiet + + - name: Serve Storybook and run tests + run: | + npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \ + "npx http-server storybook-static --port 6006 --silent" \ + "npx wait-on tcp:6006 && yarn test-storybook" + + # Run visual and composition tests with Chromatic + visual-and-composition: + runs-on: ubuntu-latest + needs: install-cache + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required to retrieve Git history + + - name: Restore Yarn dependencies + uses: actions/cache@v4 + id: yarn-cache + with: + path: | + ~/.cache/Cypress + node_modules + key: ${{ runner.os }}-yarn-v1-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-v1 + + - name: Publish to Chromatic + uses: chromaui/action@latest + with: + # Grab this from the Chromatic manage page + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + + # Run user flow tests with Cypress + user-flow: + runs-on: ubuntu-latest + needs: install-cache + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Restore Yarn dependencies + uses: actions/cache@v4 + id: yarn-cache + with: + path: | + ~/.cache/Cypress + node_modules + key: ${{ runner.os }}-yarn-v1-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn-v1 + + - name: Cypress run + uses: cypress-io/github-action@v6 + with: + start: npm run dev diff --git a/.storybook/main.js b/.storybook/main.js deleted file mode 100644 index ff2e8d7..0000000 --- a/.storybook/main.js +++ /dev/null @@ -1,26 +0,0 @@ -import { join, dirname } from "path"; - -/** - * This function is used to resolve the absolute path of a package. - * It is needed in projects that use Yarn PnP or are set up within a monorepo. - */ -function getAbsolutePath(value) { - return dirname(require.resolve(join(value, "package.json"))); -} - -/** @type { import('@storybook/react-vite').StorybookConfig } */ -const config = { - stories: ["../stories/**/*.mdx", "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)"], - addons: [ - getAbsolutePath("@storybook/addon-onboarding"), - getAbsolutePath("@storybook/addon-links"), - getAbsolutePath("@storybook/addon-essentials"), - getAbsolutePath("@chromatic-com/storybook"), - getAbsolutePath("@storybook/addon-interactions"), - ], - framework: { - name: getAbsolutePath("@storybook/react-vite"), - options: {}, - }, -}; -export default config; diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000..fbe5c15 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,24 @@ +import { type StorybookConfig } from "@storybook/react-vite"; + +const config: StorybookConfig = { + addons: [ + "@storybook/addon-onboarding", + "@storybook/addon-links", + "@storybook/addon-essentials", + "@chromatic-com/storybook", + "@storybook/addon-interactions", + "@whitespace/storybook-addon-html", + "@storybook/addon-a11y", + "@storybook/addon-links", + ], + framework: { + name: "@storybook/react-vite", + // https://storybook.js.org/docs/api/main-config/main-config-framework + options: {}, + }, + stories: [ + "../src/**/*.mdx", + "../src/**/*.story.@(js|jsx|mjs|ts|tsx)", + ], +}; +export default config; diff --git a/.storybook/preview.js b/.storybook/preview.js deleted file mode 100644 index 318cd66..0000000 --- a/.storybook/preview.js +++ /dev/null @@ -1,13 +0,0 @@ -/** @type { import('@storybook/react').Preview } */ -const preview = { - parameters: { - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, -}; - -export default preview; diff --git a/.storybook/preview.ts b/.storybook/preview.ts new file mode 100644 index 0000000..95185af --- /dev/null +++ b/.storybook/preview.ts @@ -0,0 +1,25 @@ +import { INITIAL_VIEWPORTS } from "@storybook/addon-viewport"; +import { type Preview } from "@storybook/react"; + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + html: { + prettier: { + tabWidth: 4, + useTabs: true, + }, + }, + viewport: { + viewports: INITIAL_VIEWPORTS, + // defaultViewport: 'ipad', + }, + }, +}; + +export default preview; diff --git a/README.md b/README.md index c557e72..9e567d9 100755 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# +# react-template used within the Galaxy. ## Installation ```bash -npm install --save-dev @theholocron/ +npm install --save-dev @theholocron/react-template ``` ## Usage diff --git a/package-lock.json b/package-lock.json index c0dbd9a..d066ece 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,18 @@ { - "name": "@theholocron/", + "name": "@theholocron/react-template", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@theholocron/", + "name": "@theholocron/react-template", "version": "0.1.0", "license": "GPL-3.0", "devDependencies": { "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "^2.27.9", "@chromatic-com/storybook": "^1.9.0", + "@storybook/addon-a11y": "^8.3.5", "@storybook/addon-essentials": "^8.3.5", "@storybook/addon-interactions": "^8.3.5", "@storybook/addon-links": "^8.3.5", @@ -20,17 +21,20 @@ "@storybook/react": "^8.3.5", "@storybook/react-vite": "^8.3.5", "@storybook/test": "^8.3.5", + "@theholocron/bundlewatch-config": "^3.1.0", "@theholocron/commitlint-config": "^3.0.0", "@theholocron/eslint-config": "^3.0.0", "@theholocron/jest-config": "^3.0.0", "@theholocron/lint-staged-config": "^3.0.0", "@theholocron/prettier-config": "^3.0.0", "@theholocron/tsconfig": "^3.0.0", + "@whitespace/storybook-addon-html": "^6.1.1", "chromatic": "^11.12.5", "eslint-plugin-storybook": "^0.9.0", "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-syntax-highlighter": "^15.6.1", "storybook": "^8.3.5", "turbo": "^2.1.3" } @@ -705,6 +709,22 @@ "semver": "^7.5.3" } }, + "node_modules/@changesets/apply-release-plan/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@changesets/assemble-release-plan": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.4.tgz", @@ -949,6 +969,22 @@ "prettier": "^2.7.1" } }, + "node_modules/@changesets/write/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@chromatic-com/storybook": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-1.9.0.tgz", @@ -3394,6 +3430,24 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@storybook/addon-a11y": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-8.3.5.tgz", + "integrity": "sha512-/19UO8IXbyfcYK5K8ejSYF+hC+EK79c0bBPHMNeYSFOHSqQM3KoMo+TLIcLsuhuRClmlM+4Zs+VSIYDwc+d3ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/addon-highlight": "8.3.5", + "axe-core": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.5" + } + }, "node_modules/@storybook/addon-actions": { "version": "8.3.5", "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.3.5.tgz", @@ -4496,6 +4550,16 @@ "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@theholocron/bundlewatch-config": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@theholocron/bundlewatch-config/-/bundlewatch-config-3.1.0.tgz", + "integrity": "sha512-IGdbq+3uAw6oXSZTT61DlnigzqMziHma2Slf9stqFz1+LpMOrJoZ2MZMwBJXWmy9cplLynAsW/arJL/UC4LV9g==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "bundlewatch": "^0.4.0" + } + }, "node_modules/@theholocron/commitlint-config": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@theholocron/commitlint-config/-/commitlint-config-3.1.0.tgz", @@ -4903,22 +4967,6 @@ "prettier": "^3.3.3" } }, - "node_modules/@theholocron/prettier-config/node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/@theholocron/tsconfig": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@theholocron/tsconfig/-/tsconfig-3.1.0.tgz", @@ -5721,6 +5769,17 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@whitespace/storybook-addon-html": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@whitespace/storybook-addon-html/-/storybook-addon-html-6.1.1.tgz", + "integrity": "sha512-sq/9c6s4PXugl//Q5iFwKoHF3tBDTEfJQubb62HWspF+CqBrDLHVEh7VYoEjubm5LjihxdFV3+mjj8Ck6bnoHQ==", + "dev": true, + "license": "AGPL-3.0-or-later", + "peerDependencies": { + "prettier": "^3.0.0", + "react-syntax-highlighter": "^15.0.0" + } + }, "node_modules/abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", @@ -6237,6 +6296,13 @@ "node": ">=4" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -6253,6 +6319,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axe-core": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.1.tgz", + "integrity": "sha512-qPC9o+kD8Tir0lzNGLeghbOrWMr3ZJpaRlCIb6Uobt/7N4FiEDvqUMnxzCHRHmg8vOg14kr5gVNyScRmbMaJ9g==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.1.tgz", + "integrity": "sha512-iUcGA5a7p0mVb4Gm/sy+FSECNkPFT4y7wt6OM/CDpO/OnNCvSs3PoMG8ibrC9jRoGYU0gUK5pXVC4NPXq6lHRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -7275,6 +7363,196 @@ "dev": true, "license": "MIT" }, + "node_modules/bundlewatch": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/bundlewatch/-/bundlewatch-0.4.0.tgz", + "integrity": "sha512-w8w4K8RdrsHMZD9Ss4Ailfsrax/0zSIgh25GCaiudNHg45xXuh/u/xezzjbu+WCQJGjL9O1Fg9k9TEdS/XkZFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^0.28.0", + "bytes": "^3.1.1", + "chalk": "^4.0.0", + "ci-env": "^1.17.0", + "commander": "^5.0.0", + "glob": "^7.1.2", + "gzip-size": "^6.0.0", + "jsonpack": "^1.1.5", + "lodash.merge": "^4.6.1", + "read-pkg-up": "^7.0.1" + }, + "bin": { + "bundlewatch": "lib/bin/index.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/bundlewatch/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, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/bundlewatch/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, + "license": "MIT", + "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/bundlewatch/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/bundlewatch/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundlewatch/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/bundlewatch/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/bundlewatch/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/bundlewatch/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bundlewatch/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bundlewatch/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/bundlewatch/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/bundlewatch/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/bundlewatch/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -7606,6 +7884,13 @@ } } }, + "node_modules/ci-env": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.17.0.tgz", + "integrity": "sha512-NtTjhgSEqv4Aj90TUYHQLxHdnCPXnjdtuGG1X8lTfp/JqeXTdw0FTWl/vUAPuvbWZTF8QVpv6ASe/XacE+7R2A==", + "dev": true, + "license": "MIT" + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -7828,6 +8113,19 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", @@ -8793,6 +9091,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -10878,6 +11186,27 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -10918,6 +11247,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -11562,6 +11906,22 @@ "dev": true, "license": "MIT" }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -11919,6 +12279,23 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/highlightjs-vue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz", + "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/hosted-git-info": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", @@ -14897,6 +15274,12 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpack": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/jsonpack/-/jsonpack-1.1.5.tgz", + "integrity": "sha512-d2vwomK605ks7Q+uCpbwGyoIF5j+UZuJjlYcugISBt3CxM+eBo/W6y63yVPIyIvbYON+pvJYsYZjCYbzqJj/xQ==", + "dev": true + }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -15582,6 +15965,35 @@ "node": ">=0.10.0" } }, + "node_modules/lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lowlight/node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "dev": true, + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lpad-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", @@ -18670,16 +19082,16 @@ } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "license": "MIT", "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -18700,6 +19112,16 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/proc-log": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", @@ -18792,6 +19214,13 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -19158,6 +19587,24 @@ "dev": true, "license": "MIT" }, + "node_modules/react-syntax-highlighter": { + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz", + "integrity": "sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.4.1", + "highlightjs-vue": "^1.0.0", + "lowlight": "^1.17.0", + "prismjs": "^1.27.0", + "refractor": "^3.6.0" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, "node_modules/read-package-json-fast": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", @@ -19481,6 +19928,197 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/refractor": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.27.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/refractor/node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/refractor/node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/refractor/node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", diff --git a/package.json b/package.json index e17ddae..b8e2f7f 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,16 @@ { - "name": "@theholocron/", + "name": "@theholocron/react-template", "description": "", - "homepage": "https://github.com/theholocron/#readme", + "homepage": "https://github.com/theholocron/react-template#readme", "author": "Newton Koumantzelis", "version": "0.1.0", "repository": { "type": "git", - "url": "git+https://github.com/theholocron/.git" + "url": "git+https://github.com/theholocron/react-template.git" }, - "bugs": "https://github.com/theholocron//issues", - "releases": "https://github.com/theholocron//releases", - "wiki": "https://github.com/theholocron//wiki", + "bugs": "https://github.com/theholocron/react-template/issues", + "releases": "https://github.com/theholocron/react-template/releases", + "wiki": "https://github.com/theholocron/react-template/wiki", "license": "GPL-3.0", "packageManager": "npm@9.5.0", "commitlint": { @@ -23,7 +23,7 @@ ] }, "jest": { - "displayName": "", + "displayName": "react-template", "preset": "@theholocron/jest-config" }, "publishConfig": { @@ -43,6 +43,7 @@ "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "^2.27.9", "@chromatic-com/storybook": "^1.9.0", + "@storybook/addon-a11y": "^8.3.5", "@storybook/addon-essentials": "^8.3.5", "@storybook/addon-interactions": "^8.3.5", "@storybook/addon-links": "^8.3.5", @@ -51,17 +52,20 @@ "@storybook/react": "^8.3.5", "@storybook/react-vite": "^8.3.5", "@storybook/test": "^8.3.5", + "@theholocron/bundlewatch-config": "^3.1.0", "@theholocron/commitlint-config": "^3.0.0", "@theholocron/eslint-config": "^3.0.0", "@theholocron/jest-config": "^3.0.0", "@theholocron/lint-staged-config": "^3.0.0", "@theholocron/prettier-config": "^3.0.0", "@theholocron/tsconfig": "^3.0.0", + "@whitespace/storybook-addon-html": "^6.1.1", "chromatic": "^11.12.5", "eslint-plugin-storybook": "^0.9.0", "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-syntax-highlighter": "^15.6.1", "storybook": "^8.3.5", "turbo": "^2.1.3" } diff --git a/stories/Configure.mdx b/src/Configure.mdx similarity index 100% rename from stories/Configure.mdx rename to src/Configure.mdx diff --git a/stories/assets/accessibility.png b/src/assets/accessibility.png similarity index 100% rename from stories/assets/accessibility.png rename to src/assets/accessibility.png diff --git a/stories/assets/accessibility.svg b/src/assets/accessibility.svg similarity index 100% rename from stories/assets/accessibility.svg rename to src/assets/accessibility.svg diff --git a/stories/assets/addon-library.png b/src/assets/addon-library.png similarity index 100% rename from stories/assets/addon-library.png rename to src/assets/addon-library.png diff --git a/stories/assets/assets.png b/src/assets/assets.png similarity index 100% rename from stories/assets/assets.png rename to src/assets/assets.png diff --git a/stories/assets/avif-test-image.avif b/src/assets/avif-test-image.avif similarity index 100% rename from stories/assets/avif-test-image.avif rename to src/assets/avif-test-image.avif diff --git a/stories/assets/context.png b/src/assets/context.png similarity index 100% rename from stories/assets/context.png rename to src/assets/context.png diff --git a/stories/assets/discord.svg b/src/assets/discord.svg similarity index 100% rename from stories/assets/discord.svg rename to src/assets/discord.svg diff --git a/stories/assets/docs.png b/src/assets/docs.png similarity index 100% rename from stories/assets/docs.png rename to src/assets/docs.png diff --git a/stories/assets/figma-plugin.png b/src/assets/figma-plugin.png similarity index 100% rename from stories/assets/figma-plugin.png rename to src/assets/figma-plugin.png diff --git a/stories/assets/github.svg b/src/assets/github.svg similarity index 100% rename from stories/assets/github.svg rename to src/assets/github.svg diff --git a/stories/assets/share.png b/src/assets/share.png similarity index 100% rename from stories/assets/share.png rename to src/assets/share.png diff --git a/stories/assets/styling.png b/src/assets/styling.png similarity index 100% rename from stories/assets/styling.png rename to src/assets/styling.png diff --git a/stories/assets/testing.png b/src/assets/testing.png similarity index 100% rename from stories/assets/testing.png rename to src/assets/testing.png diff --git a/stories/assets/theming.png b/src/assets/theming.png similarity index 100% rename from stories/assets/theming.png rename to src/assets/theming.png diff --git a/stories/assets/tutorials.svg b/src/assets/tutorials.svg similarity index 100% rename from stories/assets/tutorials.svg rename to src/assets/tutorials.svg diff --git a/stories/assets/youtube.svg b/src/assets/youtube.svg similarity index 100% rename from stories/assets/youtube.svg rename to src/assets/youtube.svg diff --git a/stories/button.css b/src/button/button.css similarity index 90% rename from stories/button.css rename to src/button/button.css index 94d674b..dc01b3b 100644 --- a/stories/button.css +++ b/src/button/button.css @@ -28,3 +28,7 @@ padding: 12px 24px; font-size: 16px; } +.storybook-button--xlarge { + padding: 13px 28px; + font-size: 18px; +} diff --git a/src/button/button.story.ts b/src/button/button.story.ts new file mode 100644 index 0000000..8f6c63f --- /dev/null +++ b/src/button/button.story.ts @@ -0,0 +1,60 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { fn } from "@storybook/test"; + +import { Button } from "./button"; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export +const meta: Meta = { + title: "Example/Button", + component: Button, + parameters: { + // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout + layout: "centered", + }, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs + tags: ["autodocs"], + // More on argTypes: https://storybook.js.org/docs/api/argtypes + argTypes: { + backgroundColor: { control: "color" }, + }, + // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args + args: { onClick: fn() }, +}; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Primary: Story = { + args: { + primary: true, + label: "Button", + }, +}; + +export const Secondary: Story = { + args: { + label: "Button", + }, +}; + +export const Large: Story = { + args: { + size: "large", + label: "Button", + }, +}; + +export const Small: Story = { + args: { + size: "small", + label: "Button", + }, +}; + +export const TestButton: Story = { + args: { + primary: false, + label: "Button", + } +}; diff --git a/src/button/button.tsx b/src/button/button.tsx new file mode 100644 index 0000000..589f332 --- /dev/null +++ b/src/button/button.tsx @@ -0,0 +1,39 @@ +import * as React from "react"; + +import "./button.css"; + +interface ButtonProps { + /** Is this the principal call to action on the page? */ + primary?: boolean; + /** What background color to use */ + backgroundColor?: string | null; + /** How large should the button be? */ + size?: "small" | "medium" | "large" | "xlarge"; + /** Button contents */ + label: string; + /** Optional click handler */ + onClick?: () => void; +} + +/** Primary UI component for user interaction */ +export function Button (props: ButtonProps) { + const { + backgroundColor, + label, + primary = false, + size = "medium", + ...rest + } = props; + + const mode = primary ? "storybook-button--primary" : "storybook-button--secondary"; + return ( + + ); +} diff --git a/stories/header.css b/src/header/header.css similarity index 100% rename from stories/header.css rename to src/header/header.css diff --git a/src/header/header.story.ts b/src/header/header.story.ts new file mode 100644 index 0000000..4cfe9b9 --- /dev/null +++ b/src/header/header.story.ts @@ -0,0 +1,34 @@ +import { linkTo } from "@storybook/addon-links"; +import type { Meta, StoryObj } from "@storybook/react"; +import { fn } from "@storybook/test"; + +import { Header } from "./header"; + +const meta: Meta = { + title: "Example/Header", + component: Header, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs + tags: ["autodocs"], + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout + layout: "fullscreen", + }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: linkTo("Example/Button", "Test Button"), + }, +}; + +export default meta; +type Story = StoryObj; + +export const LoggedIn: Story = { + args: { + user: { + name: "Jane Doe", + }, + }, +}; + +export const LoggedOut: Story = {}; diff --git a/src/header/header.tsx b/src/header/header.tsx new file mode 100644 index 0000000..b527e05 --- /dev/null +++ b/src/header/header.tsx @@ -0,0 +1,65 @@ +import * as React from "react"; +import { Button } from "../button/button"; + +import "./header.css"; + +interface User { + name: string; +} + +interface HeaderProps { + user?: User | null; + onLogin: () => void; + onLogout: () => void; + onCreateAccount: () => void; +} + +export function Header (props: HeaderProps) { + const { + user, + onLogin, + onLogout, + onCreateAccount, + } = props; + + return ( +
+
+
+ + + + + + + +

Acme

+
+
+ {user ? ( + + + Welcome, {user.name}! + +
+
+
+ ); +} diff --git a/stories/page.css b/src/page/page.css similarity index 100% rename from stories/page.css rename to src/page/page.css diff --git a/src/page/page.story.ts b/src/page/page.story.ts new file mode 100644 index 0000000..185835a --- /dev/null +++ b/src/page/page.story.ts @@ -0,0 +1,32 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { expect, userEvent, within } from "@storybook/test"; + +import { Page } from "./page"; + +const meta: Meta = { + title: "Example/Page", + component: Page, + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout + layout: "fullscreen", + }, +}; + +export default meta; +type Story = StoryObj; + +export const LoggedOut: Story = {}; + +// More on interaction testing: https://storybook.js.org/docs/writing-tests/interaction-testing +export const LoggedIn: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const loginButton = canvas.getByRole("button", { name: /Log in/i }); + await expect(loginButton).toBeInTheDocument(); + await userEvent.click(loginButton); + await expect(loginButton).not.toBeInTheDocument(); + + const logoutButton = canvas.getByRole("button", { name: /Log out/i }); + await expect(logoutButton).toBeInTheDocument(); + }, +}; diff --git a/src/page/page.tsx b/src/page/page.tsx new file mode 100644 index 0000000..1013a99 --- /dev/null +++ b/src/page/page.tsx @@ -0,0 +1,69 @@ +import * as React from "react"; +import { Header } from "../header/header"; + +import "./page.css"; + +export const Page: React.FC = () => { + const [user, setUser] = React.useState<{ name: string } | undefined>(undefined); + + return ( +
+
setUser({ name: "Jane Doe" })} + onLogout={() => setUser(undefined)} + onCreateAccount={() => setUser({ name: "Jane Doe" })} + /> + +
+

Pages in Storybook

+

+ We recommend building UIs with a{" "} + + component-driven + {" "} + process starting with atomic components and ending with pages. +

+

+ Render pages with mock data. This makes it easy to build and review page states + without needing to navigate to them in your app. Here are some handy patterns + for managing page data in Storybook: +

+
    +
  • + Use a higher-level connected component. Storybook helps you compose such data from the + "args" of child component stories +
  • +
  • + Assemble data in the page component from your services. You can mock these services out + using Storybook. +
  • +
+

+ Get a guided tutorial on component-driven development at{" "} + + Storybook tutorials + + . Read more in the{" "} + + docs + + . +

+
+ Tip Adjust the width of the canvas with the{" "} + + + + + + Viewports addon in the toolbar +
+
+
+ ); +}; diff --git a/stories/Button.jsx b/stories/Button.jsx deleted file mode 100644 index 5b36a63..0000000 --- a/stories/Button.jsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; - -import PropTypes from 'prop-types'; - -import './button.css'; - -/** Primary UI component for user interaction */ -export const Button = ({ primary, backgroundColor, size, label, ...props }) => { - const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary'; - return ( - - ); -}; - -Button.propTypes = { - /** Is this the principal call to action on the page? */ - primary: PropTypes.bool, - /** What background color to use */ - backgroundColor: PropTypes.string, - /** How large should the button be? */ - size: PropTypes.oneOf(['small', 'medium', 'large']), - /** Button contents */ - label: PropTypes.string.isRequired, - /** Optional click handler */ - onClick: PropTypes.func, -}; - -Button.defaultProps = { - backgroundColor: null, - primary: false, - size: 'medium', - onClick: undefined, -}; diff --git a/stories/Button.stories.js b/stories/Button.stories.js deleted file mode 100644 index 0e37e1f..0000000 --- a/stories/Button.stories.js +++ /dev/null @@ -1,56 +0,0 @@ -import { fn } from '@storybook/test'; - -import { Button } from './Button'; - -// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export -export default { - title: 'Example/Button', - component: Button, - parameters: { - // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout - layout: 'centered', - }, - // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs - tags: ['autodocs'], - // More on argTypes: https://storybook.js.org/docs/api/argtypes - argTypes: { - backgroundColor: { control: 'color' }, - }, - // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args - args: { onClick: fn() }, -}; - -// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args -export const Primary = { - args: { - primary: true, - label: 'Button', - }, -}; - -export const Secondary = { - args: { - label: 'Button', - }, -}; - -export const Large = { - args: { - size: 'large', - label: 'Button', - }, -}; - -export const Small = { - args: { - size: 'small', - label: 'Button', - }, -}; - -export const TestButton = { - args: { - primary: false, - label: "Button" - } -}; diff --git a/stories/Header.jsx b/stories/Header.jsx deleted file mode 100644 index 38aa4d8..0000000 --- a/stories/Header.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from 'react'; - -import PropTypes from 'prop-types'; - -import { Button } from './Button'; -import './header.css'; - -export const Header = ({ user, onLogin, onLogout, onCreateAccount }) => ( -
-
-
- - - - - - - -

Acme

-
-
- {user ? ( - <> - - Welcome, {user.name}! - -
-
-
-); - -Header.propTypes = { - user: PropTypes.shape({ - name: PropTypes.string.isRequired, - }), - onLogin: PropTypes.func.isRequired, - onLogout: PropTypes.func.isRequired, - onCreateAccount: PropTypes.func.isRequired, -}; - -Header.defaultProps = { - user: null, -}; diff --git a/stories/Header.stories.js b/stories/Header.stories.js deleted file mode 100644 index 7cb7da7..0000000 --- a/stories/Header.stories.js +++ /dev/null @@ -1,29 +0,0 @@ -import { fn } from '@storybook/test'; - -import { Header } from './Header'; - -export default { - title: 'Example/Header', - component: Header, - // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs - tags: ['autodocs'], - parameters: { - // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout - layout: 'fullscreen', - }, - args: { - onLogin: fn(), - onLogout: fn(), - onCreateAccount: fn(), - }, -}; - -export const LoggedIn = { - args: { - user: { - name: 'Jane Doe', - }, - }, -}; - -export const LoggedOut = {}; diff --git a/stories/Page.jsx b/stories/Page.jsx deleted file mode 100644 index c421401..0000000 --- a/stories/Page.jsx +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react'; - -import { Header } from './Header'; -import './page.css'; - -export const Page = () => { - const [user, setUser] = React.useState(); - - return ( -
-
setUser({ name: 'Jane Doe' })} - onLogout={() => setUser(undefined)} - onCreateAccount={() => setUser({ name: 'Jane Doe' })} - /> - -
-

Pages in Storybook

-

- We recommend building UIs with a{' '} - - component-driven - {' '} - process starting with atomic components and ending with pages. -

-

- Render pages with mock data. This makes it easy to build and review page states without - needing to navigate to them in your app. Here are some handy patterns for managing page - data in Storybook: -

-
    -
  • - Use a higher-level connected component. Storybook helps you compose such data from the - "args" of child component stories -
  • -
  • - Assemble data in the page component from your services. You can mock these services out - using Storybook. -
  • -
-

- Get a guided tutorial on component-driven development at{' '} - - Storybook tutorials - - . Read more in the{' '} - - docs - - . -

-
- Tip Adjust the width of the canvas with the{' '} - - - - - - Viewports addon in the toolbar -
-
-
- ); -}; diff --git a/stories/Page.stories.js b/stories/Page.stories.js deleted file mode 100644 index 383fd1a..0000000 --- a/stories/Page.stories.js +++ /dev/null @@ -1,28 +0,0 @@ -import { expect, userEvent, within } from '@storybook/test'; - -import { Page } from './Page'; - -export default { - title: 'Example/Page', - component: Page, - parameters: { - // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout - layout: 'fullscreen', - }, -}; - -export const LoggedOut = {}; - -// More on interaction testing: https://storybook.js.org/docs/writing-tests/interaction-testing -export const LoggedIn = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - const loginButton = canvas.getByRole('button', { name: /Log in/i }); - await expect(loginButton).toBeInTheDocument(); - await userEvent.click(loginButton); - await expect(loginButton).not.toBeInTheDocument(); - - const logoutButton = canvas.getByRole('button', { name: /Log out/i }); - await expect(logoutButton).toBeInTheDocument(); - }, -};