From 5e07bc0c6a7838de1ed4bbd1b3c5d582b260bf8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Sun, 29 Jun 2025 21:05:48 +0300 Subject: [PATCH 01/38] feat: add components --- .github/workflows/main.yml | 42 +- .storybook/main.ts | 4 + package-lock.json | 1514 ++++++++++++----- package.json | 6 +- src/app/App.css | 38 - src/app/App.scss | 13 + src/app/App.tsx | 2 +- src/components/ProductType.ts | 7 + .../common/HeaderComponent/Header.scss | 7 + .../common/HeaderComponent/Header.stories.ts | 11 + .../common/HeaderComponent/Header.tsx | 11 + .../common/LayoutComponent/Layout.scss | 4 + .../common/LayoutComponent/Layout.stories.ts | 11 + .../common/LayoutComponent/Layout.tsx | 14 + src/components/common/Logo.stories.ts | 11 + src/components/common/Logo.tsx | 12 + .../common/ModalComponent/Modal.scss | 80 + .../common/ModalComponent/Modal.stories.tsx | 36 + .../common/ModalComponent/Modal.tsx | 32 + src/components/common/MyLogo.svg | 10 + .../BasketButtonComponent/BasketButon.scss | 24 + .../BasketButton.stories.ts | 25 + .../BasketButtonComponent/BasketButton.tsx | 29 + .../OperationFullComponent/OperationFull.scss | 3 + .../OperationFull.stories.ts | 32 + .../OperationFullComponent/OperationFull.tsx | 23 + .../ProductBasketComponent/ProductBasket.scss | 13 + .../ProductBasket.stories.ts | 31 + .../ProductBasketComponent/ProductBasket.tsx | 28 + .../ProductPreview.scss | 3 + .../ProductPreview.stories.ts | 31 + .../ProductPreview.tsx | 22 + .../TransactionFull.scss | 7 + .../TransactionFull.stories.ts | 19 + .../TransactionFull.tsx | 27 + .../TransactionPreview.scss | 3 + .../TransactionPreview.stories.ts | 18 + .../TransactionPreview.tsx | 22 + 38 files changed, 1775 insertions(+), 450 deletions(-) delete mode 100644 src/app/App.css create mode 100644 src/app/App.scss create mode 100644 src/components/ProductType.ts create mode 100644 src/components/common/HeaderComponent/Header.scss create mode 100644 src/components/common/HeaderComponent/Header.stories.ts create mode 100644 src/components/common/HeaderComponent/Header.tsx create mode 100644 src/components/common/LayoutComponent/Layout.scss create mode 100644 src/components/common/LayoutComponent/Layout.stories.ts create mode 100644 src/components/common/LayoutComponent/Layout.tsx create mode 100644 src/components/common/Logo.stories.ts create mode 100644 src/components/common/Logo.tsx create mode 100644 src/components/common/ModalComponent/Modal.scss create mode 100644 src/components/common/ModalComponent/Modal.stories.tsx create mode 100644 src/components/common/ModalComponent/Modal.tsx create mode 100644 src/components/common/MyLogo.svg create mode 100644 src/components/market/BasketButtonComponent/BasketButon.scss create mode 100644 src/components/market/BasketButtonComponent/BasketButton.stories.ts create mode 100644 src/components/market/BasketButtonComponent/BasketButton.tsx create mode 100644 src/components/market/OperationFullComponent/OperationFull.scss create mode 100644 src/components/market/OperationFullComponent/OperationFull.stories.ts create mode 100644 src/components/market/OperationFullComponent/OperationFull.tsx create mode 100644 src/components/market/ProductBasketComponent/ProductBasket.scss create mode 100644 src/components/market/ProductBasketComponent/ProductBasket.stories.ts create mode 100644 src/components/market/ProductBasketComponent/ProductBasket.tsx create mode 100644 src/components/market/ProductPreviewComponent/ProductPreview.scss create mode 100644 src/components/market/ProductPreviewComponent/ProductPreview.stories.ts create mode 100644 src/components/market/ProductPreviewComponent/ProductPreview.tsx create mode 100644 src/components/operations/TransactionFullComponent/TransactionFull.scss create mode 100644 src/components/operations/TransactionFullComponent/TransactionFull.stories.ts create mode 100644 src/components/operations/TransactionFullComponent/TransactionFull.tsx create mode 100644 src/components/operations/TransactionPreviewComponent/TransactionPreview.scss create mode 100644 src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts create mode 100644 src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0f5ba90b0..e909e847c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,27 +35,27 @@ jobs: run: npm run lint && npm test # Собираем приложение - - name: Build Application - run: npm run build - - # Публикуем приложение на Github Pages - - name: Deploy to Github Pages - uses: JamesIves/github-pages-deploy-action@4.2.1 - with: - branch: gh-pages - folder: dist - - # # Собираем Storybook - # - name: Build Storybook - # run: npm run build-storybook - # - # # Публикуем Storybook на Github Pages - # - name: Deploy Storybook to Github Pages - # uses: JamesIves/github-pages-deploy-action@4.2.1 - # with: - # branch: gh-pages - # folder: storybook-static - # commit-message: "Automatically publish Storybook" + # - name: Build Application + # run: npm run build + + # # Публикуем приложение на Github Pages + # - name: Deploy to Github Pages + # uses: JamesIves/github-pages-deploy-action@4.2.1 + # with: + # branch: gh-pages + # folder: dist + + # Собираем Storybook + - name: Build Storybook + run: npm run build-storybook + + # Публикуем Storybook на Github Pages + - name: Deploy Storybook to Github Pages + uses: JamesIves/github-pages-deploy-action@4.2.1 + with: + branch: gh-pages + folder: storybook-static + commit-message: "Automatically publish Storybook" # Останавливаем выполнение строго при неудачных тестах - name: Fail on failed tests diff --git a/.storybook/main.ts b/.storybook/main.ts index 3d1c9b2d5..fcacdda83 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -14,5 +14,9 @@ const config = { docs: { autodocs: "tag", }, + webpack: (config, options) => { + options.cache.set = () => Promise.resolve(); + return config; + } }; export default config; diff --git a/package-lock.json b/package-lock.json index 5b1dfa392..317474c45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,14 +53,14 @@ "less-loader": "^11.1.2", "mini-css-extract-plugin": "^2.7.6", "prettier": "2.8.8", - "sass": "^1.71.1", + "sass": "^1.89.2", "sass-loader": "^13.3.1", "storybook": "^7.6.17", "style-loader": "^3.3.3", "ts-jest": "^29.1.0", "typescript": "^5.1.3", - "webpack": "^5.85.0", - "webpack-cli": "^5.1.3", + "webpack": "^5.99.9", + "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.0" } }, @@ -3504,21 +3504,16 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@juggle/resize-observer": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", @@ -3594,6 +3589,316 @@ "node": ">= 8" } }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -7569,20 +7874,22 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.40.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.1.tgz", - "integrity": "sha512-vRb792M4mF1FBT+eoLecmkpLXwxsBHvWWRGJjzbYANBM6DtiJc6yETyv4rqDA6QNjF1pkj1U7LMA6dGb3VYlHw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -7736,10 +8043,11 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", @@ -8268,148 +8576,163 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -8461,13 +8784,15 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@yarnpkg/esbuild-plugin-pnp": { "version": "3.0.0-rc.15", @@ -9498,9 +9823,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "dev": true, "funding": [ { @@ -9516,11 +9841,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -9640,9 +9966,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001554", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001554.tgz", - "integrity": "sha512-A2E3U//MBwbJVzebddm1YfNp7Nud5Ip+IPn4BozBmn4KqVX7AvluoIDFWjsv5OkGnKUXQVmMSoMKLa3ScCblcQ==", + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", "dev": true, "funding": [ { @@ -9657,7 +9983,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -10711,6 +11038,20 @@ "node": ">=8" } }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -11016,10 +11357,11 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.567", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.567.tgz", - "integrity": "sha512-8KR114CAYQ4/r5EIEsOmOMqQ9j0MRbJZR3aXD/KFA8RuKzyoUB4XrUCg+l8RUGqTVQgKNIgTpjaG8YHRPAbX2w==", - "dev": true + "version": "1.5.177", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz", + "integrity": "sha512-7EH2G59nLsEMj97fpDuvVcYi6lwTcM1xuWw3PssD8xzboAW7zj7iB3COEEEATUfjLHrs5uKBLQT03V/8URx06g==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", @@ -11078,10 +11420,11 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", - "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -11316,10 +11659,11 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -12405,6 +12749,23 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -13794,10 +14155,11 @@ } }, "node_modules/immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", - "dev": true + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "dev": true, + "license": "MIT" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -18466,6 +18828,14 @@ "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", "dev": true }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", @@ -18542,10 +18912,11 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "2.5.0", @@ -19293,10 +19664,11 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -19823,6 +20195,7 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -20569,13 +20942,14 @@ "dev": true }, "node_modules/sass": { - "version": "1.71.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", - "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", + "version": "1.89.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", + "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", "dev": true, + "license": "MIT", "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", + "chokidar": "^4.0.0", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -20583,6 +20957,9 @@ }, "engines": { "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, "node_modules/sass-loader": { @@ -20623,6 +21000,36 @@ } } }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -20742,10 +21149,11 @@ "dev": true }, "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -21662,13 +22070,14 @@ } }, "node_modules/terser": { - "version": "5.17.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", - "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.14.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -21680,16 +22089,17 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -21713,6 +22123,36 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, "node_modules/terser-webpack-plugin/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -21736,6 +22176,33 @@ "node": ">= 10.13.0" } }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -21752,10 +22219,11 @@ } }, "node_modules/terser/node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -22440,9 +22908,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -22458,9 +22926,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -22725,10 +23194,11 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -22765,34 +23235,35 @@ } }, "node_modules/webpack": { - "version": "5.86.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", - "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", + "version": "5.99.9", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", + "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.1", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", + "schema-utils": "^4.3.2", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -22816,6 +23287,7 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, + "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -23158,16 +23630,18 @@ "dev": true }, "node_modules/webpack/node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -23175,13 +23649,61 @@ "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/webpack/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, "peerDependencies": { - "acorn": "^8" + "ajv": "^8.8.2" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/websocket-driver": { @@ -25910,21 +26432,13 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - } + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@juggle/resize-observer": { @@ -25986,6 +26500,123 @@ "fastq": "^1.6.0" } }, + "@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "optional": true, + "requires": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1", + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + } + }, + "@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "dev": true, + "optional": true + }, + "@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "dev": true, + "optional": true + }, + "@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "dev": true, + "optional": true + }, "@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -28801,9 +29432,9 @@ "dev": true }, "@types/eslint": { - "version": "8.40.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.1.tgz", - "integrity": "sha512-vRb792M4mF1FBT+eoLecmkpLXwxsBHvWWRGJjzbYANBM6DtiJc6yETyv4rqDA6QNjF1pkj1U7LMA6dGb3VYlHw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, "requires": { "@types/estree": "*", @@ -28811,9 +29442,9 @@ } }, "@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "requires": { "@types/eslint": "*", @@ -28961,9 +29592,9 @@ } }, "@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "@types/json5": { @@ -29383,148 +30014,148 @@ } }, "@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -30362,15 +30993,15 @@ } }, "browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" } }, "bs-logger": { @@ -30452,9 +31083,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001554", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001554.tgz", - "integrity": "sha512-A2E3U//MBwbJVzebddm1YfNp7Nud5Ip+IPn4BozBmn4KqVX7AvluoIDFWjsv5OkGnKUXQVmMSoMKLa3ScCblcQ==", + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", "dev": true }, "case-sensitive-paths-webpack-plugin": { @@ -31263,6 +31894,13 @@ "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -31508,9 +32146,9 @@ } }, "electron-to-chromium": { - "version": "1.4.567", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.567.tgz", - "integrity": "sha512-8KR114CAYQ4/r5EIEsOmOMqQ9j0MRbJZR3aXD/KFA8RuKzyoUB4XrUCg+l8RUGqTVQgKNIgTpjaG8YHRPAbX2w==", + "version": "1.5.177", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz", + "integrity": "sha512-7EH2G59nLsEMj97fpDuvVcYi6lwTcM1xuWw3PssD8xzboAW7zj7iB3COEEEATUfjLHrs5uKBLQT03V/8URx06g==", "dev": true }, "emittery": { @@ -31558,9 +32196,9 @@ } }, "enhanced-resolve": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", - "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -31750,9 +32388,9 @@ } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-html": { @@ -32549,6 +33187,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true + }, "fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -33573,9 +34217,9 @@ "peer": true }, "immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", "dev": true }, "import-fresh": { @@ -36904,6 +37548,13 @@ "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", "dev": true }, + "node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, "node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", @@ -36965,9 +37616,9 @@ "dev": true }, "node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "normalize-package-data": { @@ -37508,9 +38159,9 @@ "dev": true }, "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.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "picomatch": { @@ -38427,14 +39078,32 @@ "dev": true }, "sass": { - "version": "1.71.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", - "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", + "version": "1.89.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", + "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", "dev": true, "requires": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", + "@parcel/watcher": "^2.4.1", + "chokidar": "^4.0.0", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" + }, + "dependencies": { + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "requires": { + "readdirp": "^4.0.1" + } + }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true + } } }, "sass-loader": { @@ -38551,9 +39220,9 @@ } }, "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -39275,21 +39944,21 @@ } }, "terser": { - "version": "5.17.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", - "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.14.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "dependencies": { "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true }, "commander": { @@ -39317,18 +39986,39 @@ } }, "terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.17", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "dependencies": { + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -39346,6 +40036,24 @@ "supports-color": "^8.0.0" } }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -39850,13 +40558,13 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" } }, "uri-js": { @@ -40055,9 +40763,9 @@ } }, "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -40089,55 +40797,87 @@ "dev": true }, "webpack": { - "version": "5.86.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", - "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", + "version": "5.99.9", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", + "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.1", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", + "schema-utils": "^4.3.2", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "dependencies": { "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true }, - "acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "requires": {} + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } } } }, diff --git a/package.json b/package.json index 492664d1f..059c7997a 100644 --- a/package.json +++ b/package.json @@ -53,14 +53,14 @@ "less-loader": "^11.1.2", "mini-css-extract-plugin": "^2.7.6", "prettier": "2.8.8", - "sass": "^1.71.1", + "sass": "^1.89.2", "sass-loader": "^13.3.1", "storybook": "^7.6.17", "style-loader": "^3.3.3", "ts-jest": "^29.1.0", "typescript": "^5.1.3", - "webpack": "^5.85.0", - "webpack-cli": "^5.1.3", + "webpack": "^5.99.9", + "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.0" }, "dependencies": { diff --git a/src/app/App.css b/src/app/App.css deleted file mode 100644 index 78b8850cf..000000000 --- a/src/app/App.css +++ /dev/null @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/src/app/App.scss b/src/app/App.scss new file mode 100644 index 000000000..ce2b1b896 --- /dev/null +++ b/src/app/App.scss @@ -0,0 +1,13 @@ +button{ + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 700; + border: 0; + border-radius: 1em; + cursor: pointer; + display: inline-block; + line-height: 1; + color: black; + background-color: #fcd800; + font-size: 12px; + padding: 10px 16px; +} \ No newline at end of file diff --git a/src/app/App.tsx b/src/app/App.tsx index dcc0ff8ad..e54f7a526 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,6 +1,6 @@ import React from 'react'; import logo from './logo.svg'; -import './App.css'; +import './App.scss'; function App() { return ( diff --git a/src/components/ProductType.ts b/src/components/ProductType.ts new file mode 100644 index 000000000..dd937f043 --- /dev/null +++ b/src/components/ProductType.ts @@ -0,0 +1,7 @@ +export type Product = { + name: string, + price: number, + categoryName: string, + image?: string, + description?: string, +} \ No newline at end of file diff --git a/src/components/common/HeaderComponent/Header.scss b/src/components/common/HeaderComponent/Header.scss new file mode 100644 index 000000000..321b300d5 --- /dev/null +++ b/src/components/common/HeaderComponent/Header.scss @@ -0,0 +1,7 @@ +.header-div{ + padding: 0.5em; + position: sticky; + top:0; + border-bottom: 1px solid #dbdbdb; + background-color: #fcd200; +} \ No newline at end of file diff --git a/src/components/common/HeaderComponent/Header.stories.ts b/src/components/common/HeaderComponent/Header.stories.ts new file mode 100644 index 000000000..358ba0744 --- /dev/null +++ b/src/components/common/HeaderComponent/Header.stories.ts @@ -0,0 +1,11 @@ +import type { Meta } from '@storybook/react'; +import { Header } from './Header'; + +const meta: Meta = { + title: "components/Header", + component: Header, +} + +export default meta; + +export const Primary = {} diff --git a/src/components/common/HeaderComponent/Header.tsx b/src/components/common/HeaderComponent/Header.tsx new file mode 100644 index 000000000..0febd2dcc --- /dev/null +++ b/src/components/common/HeaderComponent/Header.tsx @@ -0,0 +1,11 @@ +import React from "react" +import { Logo } from "../Logo" +import "./Header.scss" + +export const Header: React.FC = () => { + return( +
+ +
+ ) +} \ No newline at end of file diff --git a/src/components/common/LayoutComponent/Layout.scss b/src/components/common/LayoutComponent/Layout.scss new file mode 100644 index 000000000..3431665ad --- /dev/null +++ b/src/components/common/LayoutComponent/Layout.scss @@ -0,0 +1,4 @@ +.layout-div{ + height:100em; + background-color: #ffe86f; +} \ No newline at end of file diff --git a/src/components/common/LayoutComponent/Layout.stories.ts b/src/components/common/LayoutComponent/Layout.stories.ts new file mode 100644 index 000000000..5d9f6d3f9 --- /dev/null +++ b/src/components/common/LayoutComponent/Layout.stories.ts @@ -0,0 +1,11 @@ +import type { Meta } from '@storybook/react'; +import { Layout } from './Layout'; + +const meta: Meta = { + title: "components/Layout", + component: Layout, +} + +export default meta; + +export const Primary = {} diff --git a/src/components/common/LayoutComponent/Layout.tsx b/src/components/common/LayoutComponent/Layout.tsx new file mode 100644 index 000000000..966f2f935 --- /dev/null +++ b/src/components/common/LayoutComponent/Layout.tsx @@ -0,0 +1,14 @@ +import React from "react" +import { Header } from "../HeaderComponent/Header" +import "./Layout.scss" + + +export const Layout: React.FC = () => { + return ( + <> +
+
+
+ + ) +} \ No newline at end of file diff --git a/src/components/common/Logo.stories.ts b/src/components/common/Logo.stories.ts new file mode 100644 index 000000000..910e5d31a --- /dev/null +++ b/src/components/common/Logo.stories.ts @@ -0,0 +1,11 @@ +import type { Meta } from '@storybook/react'; +import { Logo } from './Logo'; + +const meta: Meta = { + title: "components/Logo", + component: Logo, +} + +export default meta; + +export const Primary = {} diff --git a/src/components/common/Logo.tsx b/src/components/common/Logo.tsx new file mode 100644 index 000000000..5aa48b593 --- /dev/null +++ b/src/components/common/Logo.tsx @@ -0,0 +1,12 @@ +import React from 'react' +import imageFile from './MyLogo.svg' + + + +export const Logo: React.FC = () => { + return( + <> + + + ) +} \ No newline at end of file diff --git a/src/components/common/ModalComponent/Modal.scss b/src/components/common/ModalComponent/Modal.scss new file mode 100644 index 000000000..8c930b134 --- /dev/null +++ b/src/components/common/ModalComponent/Modal.scss @@ -0,0 +1,80 @@ +.modal { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 100%; + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(0, 0, 0, 0.781); + animation-name: appear; + animation-duration: 300ms; +} + +.modal-dialog { + width: 100%; + max-width: 550px; + background: white; + position: relative; + margin: 0 20px; + max-height: calc(100vh - 40px); + text-align: left; + display: flex; + flex-direction: column; + overflow: hidden; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + -webkit-animation-name: animatetop; + -webkit-animation-duration: 0.4s; + animation-name: slide-in; + animation-duration: 0.5s; +} + +.modal-header, +.modal-footer { + display: flex; + align-items: center; + padding: 1rem; +} +.modal-header { + border-bottom: 1px solid #dbdbdb; + justify-content: space-between; +} +.modal-footer { + border-top: 1px solid #dbdbdb; + justify-content: flex-end; +} +.modal-close { + cursor: pointer; + padding: 1rem; + margin: -1rem -1rem -1rem auto; +} +.modal-body { + overflow: auto; +} +.modal-content { + padding: 1rem; +} + +.modal-title { + margin: 0; +} + +@keyframes appear { + from { + opacity: 0; + } + to { + opacity: 1; + } +} +@keyframes slide-in { + from { + transform: translateY(-150px); + } + to { + transform: translateY(0); + } +} \ No newline at end of file diff --git a/src/components/common/ModalComponent/Modal.stories.tsx b/src/components/common/ModalComponent/Modal.stories.tsx new file mode 100644 index 000000000..7bb89ad05 --- /dev/null +++ b/src/components/common/ModalComponent/Modal.stories.tsx @@ -0,0 +1,36 @@ +import type { Story,Meta } from '@storybook/react'; +import { Modal, ModalProps } from './Modal'; +import React from 'react'; + +const meta: Meta = { + title: "components/Modal", + component: Modal, + args:{ + visible:true + } +} + +export default meta; + + + +export const WithP = { + args:{ + visible: true, + children:

Первый элемент

+ } +} + +export const WithInput = { + args:{ + visible: true, + children:
+ } +} +export const WithButton = { + args:{ + visible: true, + children:
+ } +} + diff --git a/src/components/common/ModalComponent/Modal.tsx b/src/components/common/ModalComponent/Modal.tsx new file mode 100644 index 000000000..241371dc3 --- /dev/null +++ b/src/components/common/ModalComponent/Modal.tsx @@ -0,0 +1,32 @@ +import React, { ReactNode } from "react" +import "./Modal.scss" +import "../../../app/App.scss" + +export interface ModalProps { + visible: boolean, + children: ReactNode, +} + +export const Modal: React.FC = (props) => { + if (!props.visible) return null + return( + <> +
+
+
+

Подтвердите действие

+ + × + +
+
+
{props.children}
+
+
+ +
+
+
+ + ) +} \ No newline at end of file diff --git a/src/components/common/MyLogo.svg b/src/components/common/MyLogo.svg new file mode 100644 index 000000000..b8406f14a --- /dev/null +++ b/src/components/common/MyLogo.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/components/market/BasketButtonComponent/BasketButon.scss b/src/components/market/BasketButtonComponent/BasketButon.scss new file mode 100644 index 000000000..227bc0172 --- /dev/null +++ b/src/components/market/BasketButtonComponent/BasketButon.scss @@ -0,0 +1,24 @@ +.basket-add-button-div{ + display: flex; + justify-content: flex-end; + padding-right: 0.75em; +} +.basket-button{ + border-radius: 0.5em; + padding: 8px 14px; +} +.basket-input{ + width: 100px; + margin: 0; + padding: 0rem 0.5rem; + font-family: inherit; + font-size: 1rem; + font-weight: 400; + line-height: 1.6; + color: #212529; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #bdbdbd; + border-radius: 0.25rem; + padding-bottom: 2px; +} \ No newline at end of file diff --git a/src/components/market/BasketButtonComponent/BasketButton.stories.ts b/src/components/market/BasketButtonComponent/BasketButton.stories.ts new file mode 100644 index 000000000..7134708df --- /dev/null +++ b/src/components/market/BasketButtonComponent/BasketButton.stories.ts @@ -0,0 +1,25 @@ +import type { Meta } from '@storybook/react'; +import { BasketButton, BasketButtonProps } from './BasketButton'; + +const meta: Meta = { + // render: (args: BasketButtonProps) => , + title: "market/BasketButton", + component: BasketButton, + args: { + counter: 0 + } +} + +export default meta; + +export const Primary = { + args:{ + counter: 0 + } +} + +export const WithCounter = { + args:{ + counter: 5 + } +} diff --git a/src/components/market/BasketButtonComponent/BasketButton.tsx b/src/components/market/BasketButtonComponent/BasketButton.tsx new file mode 100644 index 000000000..bedb9311c --- /dev/null +++ b/src/components/market/BasketButtonComponent/BasketButton.tsx @@ -0,0 +1,29 @@ +import "./BasketButon.scss" +import "../../../app/App.scss" + +import React from "react" + +export interface BasketButtonProps { + counter: number +} + +export const BasketButton: React.FC = ({counter}) => { + if(counter===0){ + return( +
+ +
+ ) + } + else + return( + <> +
+ + + +
+ + + ) +} \ No newline at end of file diff --git a/src/components/market/OperationFullComponent/OperationFull.scss b/src/components/market/OperationFullComponent/OperationFull.scss new file mode 100644 index 000000000..483909557 --- /dev/null +++ b/src/components/market/OperationFullComponent/OperationFull.scss @@ -0,0 +1,3 @@ +.operation-div { + width: 200px; +} \ No newline at end of file diff --git a/src/components/market/OperationFullComponent/OperationFull.stories.ts b/src/components/market/OperationFullComponent/OperationFull.stories.ts new file mode 100644 index 000000000..4777c2bfb --- /dev/null +++ b/src/components/market/OperationFullComponent/OperationFull.stories.ts @@ -0,0 +1,32 @@ +import type { Meta } from '@storybook/react'; +import { OperationFull } from './OperationFull'; + +const meta: Meta = { + title: "market/OperationFull", + component: OperationFull, + + +} + +export default meta; + +export const NoCounter = { + args: { + name:"Мороженое", + categoryName:"Еда", + description:"Краткое описание", + image:"", + price:200, + counter:0 + } +} +export const WithCounter = { + args: { + name:"Мороженое", + categoryName:"Еда", + description:"Краткое описание", + image:"", + price:200, + counter:10 + } +} diff --git a/src/components/market/OperationFullComponent/OperationFull.tsx b/src/components/market/OperationFullComponent/OperationFull.tsx new file mode 100644 index 000000000..603c745a9 --- /dev/null +++ b/src/components/market/OperationFullComponent/OperationFull.tsx @@ -0,0 +1,23 @@ +import React from "react" +import { BasketButton } from "../BasketButtonComponent/BasketButton" +import { Product } from "../../ProductType" +import "./OperationFull.scss" + +export interface OperationFullProps extends Product{ + counter: number +}; + +export const OperationFull: React.FC = (props) => { + return( + <> +
+

{props.name}

+

Цена: {props.price}

+

Категория: {props.categoryName}

+

{props.image}

+

{props.description}

+ +
+ + ) +} \ No newline at end of file diff --git a/src/components/market/ProductBasketComponent/ProductBasket.scss b/src/components/market/ProductBasketComponent/ProductBasket.scss new file mode 100644 index 000000000..4e6e8c728 --- /dev/null +++ b/src/components/market/ProductBasketComponent/ProductBasket.scss @@ -0,0 +1,13 @@ +.productBasket-div{ + width: 200px; +} +.delete-button-div{ + padding-top: 0.5em; + padding-right: 0.75em; + display:flex; + justify-content: flex-end; +} +.delete-button{ + width:91.9px; + color:rgb(145, 6, 6); +} \ No newline at end of file diff --git a/src/components/market/ProductBasketComponent/ProductBasket.stories.ts b/src/components/market/ProductBasketComponent/ProductBasket.stories.ts new file mode 100644 index 000000000..03ee7c60f --- /dev/null +++ b/src/components/market/ProductBasketComponent/ProductBasket.stories.ts @@ -0,0 +1,31 @@ +import type { Meta } from '@storybook/react'; +import { ProductBasket } from './ProductBasket'; + +const meta: Meta = { + title: "market/ProductBasket", + component: ProductBasket, +} + +export default meta; + +export const NoCounter = { + args: { + name:"Мороженое", + categoryName:"Еда", + description:"Краткое описание", + image:"", + price:200, + counter:0 + } +} + +export const WithCounter = { + args: { + name:"Мороженое", + categoryName:"Еда", + description:"Краткое описание", + image:"", + price:200, + counter:10 + } +} \ No newline at end of file diff --git a/src/components/market/ProductBasketComponent/ProductBasket.tsx b/src/components/market/ProductBasketComponent/ProductBasket.tsx new file mode 100644 index 000000000..aabb98d75 --- /dev/null +++ b/src/components/market/ProductBasketComponent/ProductBasket.tsx @@ -0,0 +1,28 @@ +import React from "react" +import { ProductPreview } from "../ProductPreviewComponent/ProductPreview" +import { Product } from "../../ProductType" +import "./ProductBasket.scss" + +export interface ProductBasketProps extends Product { + counter: number +} + +export const ProductBasket: React.FC = (props) => { + return ( + <> +
+ +
+ +
+
+ + ) +} \ No newline at end of file diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.scss b/src/components/market/ProductPreviewComponent/ProductPreview.scss new file mode 100644 index 000000000..7bb83bfe6 --- /dev/null +++ b/src/components/market/ProductPreviewComponent/ProductPreview.scss @@ -0,0 +1,3 @@ +.preview-div{ + width: 200px; +} \ No newline at end of file diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts b/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts new file mode 100644 index 000000000..5fd38462f --- /dev/null +++ b/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts @@ -0,0 +1,31 @@ +import type { Meta } from '@storybook/react'; +import { ProductPreview } from './ProductPreview'; + +const meta: Meta = { + title: "market/ProductPreview", + component: ProductPreview, +} + +export default meta; + +export const NoCounter = { + args: { + name:"Мороженое", + categoryName:"Еда", + description:"Краткое описание", + image:"", + price:200, + counter:0 + } +} + +export const WithCounter = { + args: { + name:"Мороженое", + categoryName:"Еда", + description:"Краткое описание", + image:"", + price:200, + counter:10 + } +} \ No newline at end of file diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.tsx b/src/components/market/ProductPreviewComponent/ProductPreview.tsx new file mode 100644 index 000000000..42be30949 --- /dev/null +++ b/src/components/market/ProductPreviewComponent/ProductPreview.tsx @@ -0,0 +1,22 @@ +import React from "react" +import { BasketButton } from "../BasketButtonComponent/BasketButton" +import { Product } from "../../ProductType" +import "./ProductPreview.scss" + +export interface ProductPreviewProps extends Product{ + counter: number +} + +export const ProductPreview: React.FC = (props) => { + return( + <> +
+

{props.name}

+

Price: {props.price}

+

{props.image}

+

{props.description}

+ +
+ + ) +} \ No newline at end of file diff --git a/src/components/operations/TransactionFullComponent/TransactionFull.scss b/src/components/operations/TransactionFullComponent/TransactionFull.scss new file mode 100644 index 000000000..c7c645c42 --- /dev/null +++ b/src/components/operations/TransactionFullComponent/TransactionFull.scss @@ -0,0 +1,7 @@ +.full-div{ + width: 300px; +} +.full-div-button{ + display: flex; + justify-content: flex-end; +} \ No newline at end of file diff --git a/src/components/operations/TransactionFullComponent/TransactionFull.stories.ts b/src/components/operations/TransactionFullComponent/TransactionFull.stories.ts new file mode 100644 index 000000000..50e08d3f6 --- /dev/null +++ b/src/components/operations/TransactionFullComponent/TransactionFull.stories.ts @@ -0,0 +1,19 @@ +import type { Meta } from '@storybook/react'; +import { TransactionFull } from './TransactionFull'; + +const meta: Meta = { + title: "operations/TransactionFull", + component: TransactionFull, +} + +export default meta; + +export const Primary = { + args:{ + title: "Перевод на другой счет", + date: "29.06.2025", + amount: "100р", + category: "Перевод", + description: "Описание операции" + } +} \ No newline at end of file diff --git a/src/components/operations/TransactionFullComponent/TransactionFull.tsx b/src/components/operations/TransactionFullComponent/TransactionFull.tsx new file mode 100644 index 000000000..477f84b24 --- /dev/null +++ b/src/components/operations/TransactionFullComponent/TransactionFull.tsx @@ -0,0 +1,27 @@ +import React from "react" +import "./TransactionFull.scss" + +export interface TransactionFullProps { + title: string, + date: string, + amount: number, + category: string, + description: string +} + +export const TransactionFull: React.FC=(props)=>{ + return( + <> +
+

{props.title}

+

Дата: {props.date}

+

Сумма операции: {props.amount}

+

Категория: {props.category}

+

{props.description}

+
+ +
+
+ + ) +} \ No newline at end of file diff --git a/src/components/operations/TransactionPreviewComponent/TransactionPreview.scss b/src/components/operations/TransactionPreviewComponent/TransactionPreview.scss new file mode 100644 index 000000000..340505358 --- /dev/null +++ b/src/components/operations/TransactionPreviewComponent/TransactionPreview.scss @@ -0,0 +1,3 @@ +.transaction-preview-div{ + width: 300px; +} diff --git a/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts b/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts new file mode 100644 index 000000000..af041c3d5 --- /dev/null +++ b/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts @@ -0,0 +1,18 @@ +import type { Meta } from '@storybook/react'; +import { TransactionPreview } from './TransactionPreview'; + +const meta: Meta = { + title: "operations/TransactionPreview", + component: TransactionPreview, +} + +export default meta; + +export const Primary = { + args:{ + title: "Перевод на другой счет", + amount: "100р", + category: "Перевод", + description: "Описание операции" + } +} \ No newline at end of file diff --git a/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx b/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx new file mode 100644 index 000000000..a110dc15b --- /dev/null +++ b/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx @@ -0,0 +1,22 @@ +import React from "react" +import "./TransactionPreview.scss" + +export interface TransactionPreviewProps { + title: string, + date: string, + amount: number, + category: string, + description: string +} + + +export const TransactionPreview: React.FC = (props) => { + return( +
+

{props.title}

+

Сумма операции: {props.amount}

+

Категория: {props.category}

+

{props.description}

+
+ ) +} \ No newline at end of file From 2cc868c9841274ff94a33fd700f1043553f63b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Sun, 29 Jun 2025 21:25:36 +0300 Subject: [PATCH 02/38] feat: update main.yml --- .github/workflows/main.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e909e847c..a0ea19626 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,17 +45,17 @@ jobs: # branch: gh-pages # folder: dist - # Собираем Storybook - - name: Build Storybook - run: npm run build-storybook + # Собираем Storybook + - name: Build Storybook + run: npm run build-storybook - # Публикуем Storybook на Github Pages - - name: Deploy Storybook to Github Pages - uses: JamesIves/github-pages-deploy-action@4.2.1 - with: - branch: gh-pages - folder: storybook-static - commit-message: "Automatically publish Storybook" + # Публикуем Storybook на Github Pages + - name: Deploy Storybook to Github Pages + uses: JamesIves/github-pages-deploy-action@4.2.1 + with: + branch: gh-pages + folder: storybook-static + commit-message: "Automatically publish Storybook" # Останавливаем выполнение строго при неудачных тестах - name: Fail on failed tests From 8b07f0a39b680e3a3d645e9ddfd0e3e5799cd66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Sun, 29 Jun 2025 21:42:36 +0300 Subject: [PATCH 03/38] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a0ea19626..0c61c2f02 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ permissions: jobs: build-and-deploy: - runs-on: ubuntu-latest + runs-on: ubuntu-latest strategy: matrix: From 41f95d5d325b568f970d54b27a4ddb28ca4fdee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 11:47:42 +0300 Subject: [PATCH 04/38] trigger From 9ad40774b9eacd612e5d27f3b6c0c5efd2e6b656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 12:13:48 +0300 Subject: [PATCH 05/38] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0c61c2f02..6ebdc11ce 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: Test, Lint, Build and Deploy on Github Pages on: push: - branches: ["master", "main"] + branches: ["main"] # Позволяет запустить этот рабочий процесс вручную на вкладке Actions workflow_dispatch: From 3af0435a78cb522b710304d4214b4f77fbb189c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 12:22:48 +0300 Subject: [PATCH 06/38] Update main.yml --- .github/workflows/main.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e909e847c..af2659c46 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,17 +45,17 @@ jobs: # branch: gh-pages # folder: dist - # Собираем Storybook - - name: Build Storybook - run: npm run build-storybook - - # Публикуем Storybook на Github Pages - - name: Deploy Storybook to Github Pages - uses: JamesIves/github-pages-deploy-action@4.2.1 - with: - branch: gh-pages - folder: storybook-static - commit-message: "Automatically publish Storybook" + # Собираем Storybook + - name: Build Storybook + run: npm run build-storybook + + # Публикуем Storybook на Github Pages + - name: Deploy Storybook to Github Pages + uses: JamesIves/github-pages-deploy-action@4.2.1 + with: + branch: gh-pages + folder: storybook-static + commit-message: "Automatically publish Storybook" # Останавливаем выполнение строго при неудачных тестах - name: Fail on failed tests From aa94b05a18364fb1b2829e80ed9ff786e4c0258f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 12:40:53 +0300 Subject: [PATCH 07/38] Update main.yml --- .github/workflows/main.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6ebdc11ce..f90927721 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,17 +34,6 @@ jobs: - name: Run tests and linter run: npm run lint && npm test - # Собираем приложение - # - name: Build Application - # run: npm run build - - # # Публикуем приложение на Github Pages - # - name: Deploy to Github Pages - # uses: JamesIves/github-pages-deploy-action@4.2.1 - # with: - # branch: gh-pages - # folder: dist - # Собираем Storybook - name: Build Storybook run: npm run build-storybook From 8bc0123e7364633db8c7914376b52817f2a2a027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 12:41:51 +0300 Subject: [PATCH 08/38] Update main.ts --- .storybook/main.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index fcacdda83..19b17a0cc 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -13,10 +13,6 @@ const config = { }, docs: { autodocs: "tag", - }, - webpack: (config, options) => { - options.cache.set = () => Promise.resolve(); - return config; } }; export default config; From 7235beb9f9ade310a2542fc5de6729021fecc65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 12:47:07 +0300 Subject: [PATCH 09/38] Update main.yml --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f90927721..4bc940a28 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: Test, Lint, Build and Deploy on Github Pages on: push: - branches: ["main"] + branches: ["master", "main"] # Позволяет запустить этот рабочий процесс вручную на вкладке Actions workflow_dispatch: @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [18.x] + node-version: [22.x] steps: - uses: actions/checkout@v3 From c14d94fa48eeabe479ef133770131956827bccb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 13:07:18 +0300 Subject: [PATCH 10/38] feat: update files --- .github/workflows/main.yml | 2 +- .storybook/main.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4bc940a28..f1c9fab02 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [22.x] + node-version: [18.x] steps: - uses: actions/checkout@v3 diff --git a/.storybook/main.ts b/.storybook/main.ts index 19b17a0cc..fcacdda83 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -13,6 +13,10 @@ const config = { }, docs: { autodocs: "tag", + }, + webpack: (config, options) => { + options.cache.set = () => Promise.resolve(); + return config; } }; export default config; From 4d9dcb68e9265f313f41d135ba2f0839359b6155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 14:33:27 +0300 Subject: [PATCH 11/38] feat: add small description --- .../ProductPreview.stories.ts | 15 +++++++++++++-- .../ProductPreviewComponent/ProductPreview.tsx | 4 +++- .../TransactionPreview.stories.ts | 15 ++++++++++++--- .../TransactionPreview.tsx | 4 +++- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts b/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts index 5fd38462f..102131442 100644 --- a/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts +++ b/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts @@ -12,7 +12,7 @@ export const NoCounter = { args: { name:"Мороженое", categoryName:"Еда", - description:"Краткое описание", + description:"Описание", image:"", price:200, counter:0 @@ -23,7 +23,18 @@ export const WithCounter = { args: { name:"Мороженое", categoryName:"Еда", - description:"Краткое описание", + description:"Описание", + image:"", + price:200, + counter:10 + } +} + +export const LongDescription = { + args: { + name:"Мороженое", + categoryName:"Еда", + description:"Длинное описание, которое будет обрезано", image:"", price:200, counter:10 diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.tsx b/src/components/market/ProductPreviewComponent/ProductPreview.tsx index 42be30949..e5a887f75 100644 --- a/src/components/market/ProductPreviewComponent/ProductPreview.tsx +++ b/src/components/market/ProductPreviewComponent/ProductPreview.tsx @@ -8,13 +8,15 @@ export interface ProductPreviewProps extends Product{ } export const ProductPreview: React.FC = (props) => { + const description = props.description; + const descSmall = description.length>20?description.substring(0,20)+"...":description; return( <>

{props.name}

Price: {props.price}

{props.image}

-

{props.description}

+

{descSmall}

diff --git a/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts b/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts index af041c3d5..eb8f1994e 100644 --- a/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts +++ b/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts @@ -8,11 +8,20 @@ const meta: Meta = { export default meta; -export const Primary = { +export const LongDescription = { args:{ title: "Перевод на другой счет", amount: "100р", category: "Перевод", - description: "Описание операции" + description: "Динное описание, которое будет обрезано" } -} \ No newline at end of file +} + +export const SmallDescription = { + args:{ + title: "Перевод на другой счет", + amount: "100р", + category: "Перевод", + description: "Короткое описание" + } +} diff --git a/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx b/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx index a110dc15b..1758c7a41 100644 --- a/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx +++ b/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx @@ -11,12 +11,14 @@ export interface TransactionPreviewProps { export const TransactionPreview: React.FC = (props) => { + const description = props.description; + const descSmall = description.length>20?description.substring(0,20)+"...":description; return(

{props.title}

Сумма операции: {props.amount}

Категория: {props.category}

-

{props.description}

+

{descSmall}

) } \ No newline at end of file From f8503f028b629a49502bfa89070a2bd8f3c4c081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 16:51:04 +0300 Subject: [PATCH 12/38] feat: update main.yml --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f1c9fab02..abcbca6f6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,8 @@ name: Test, Lint, Build and Deploy on Github Pages on: push: - branches: ["master", "main"] + branches: + - main # Позволяет запустить этот рабочий процесс вручную на вкладке Actions workflow_dispatch: From 98eee5458cc59ada1ee9918a882cb62cc1668d6e Mon Sep 17 00:00:00 2001 From: stepnaya91 Date: Mon, 30 Jun 2025 17:18:12 +0300 Subject: [PATCH 13/38] Create main_test.yml --- .github/workflows/main_test.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/workflows/main_test.yml diff --git a/.github/workflows/main_test.yml b/.github/workflows/main_test.yml new file mode 100644 index 000000000..f24ce69dd --- /dev/null +++ b/.github/workflows/main_test.yml @@ -0,0 +1,10 @@ +name: Print workflow #Название workflow +on: workflow_dispatch #Триггер, который будет вызывать workflow + +jobs: #Начало секции джобов + + print_hello: #Начало секции первой джобы + runs-on: ubuntu-latest #Среда выполнения джоба + steps: #Начало секции шагов + - name: Print hello #Название шага + run: echo "Hello world!" #Команда, которая будет выполнена в терминале From eca754e9daadf551f7120940bfd295a8210bf661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Mon, 30 Jun 2025 17:38:36 +0300 Subject: [PATCH 14/38] feat: small description --- .../ProductPreview.stories.ts | 15 +++++++++++++-- .../ProductPreviewComponent/ProductPreview.tsx | 4 +++- .../TransactionPreview.stories.ts | 15 ++++++++++++--- .../TransactionPreview.tsx | 4 +++- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts b/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts index 5fd38462f..102131442 100644 --- a/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts +++ b/src/components/market/ProductPreviewComponent/ProductPreview.stories.ts @@ -12,7 +12,7 @@ export const NoCounter = { args: { name:"Мороженое", categoryName:"Еда", - description:"Краткое описание", + description:"Описание", image:"", price:200, counter:0 @@ -23,7 +23,18 @@ export const WithCounter = { args: { name:"Мороженое", categoryName:"Еда", - description:"Краткое описание", + description:"Описание", + image:"", + price:200, + counter:10 + } +} + +export const LongDescription = { + args: { + name:"Мороженое", + categoryName:"Еда", + description:"Длинное описание, которое будет обрезано", image:"", price:200, counter:10 diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.tsx b/src/components/market/ProductPreviewComponent/ProductPreview.tsx index 42be30949..e5a887f75 100644 --- a/src/components/market/ProductPreviewComponent/ProductPreview.tsx +++ b/src/components/market/ProductPreviewComponent/ProductPreview.tsx @@ -8,13 +8,15 @@ export interface ProductPreviewProps extends Product{ } export const ProductPreview: React.FC = (props) => { + const description = props.description; + const descSmall = description.length>20?description.substring(0,20)+"...":description; return( <>

{props.name}

Price: {props.price}

{props.image}

-

{props.description}

+

{descSmall}

diff --git a/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts b/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts index af041c3d5..eb8f1994e 100644 --- a/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts +++ b/src/components/operations/TransactionPreviewComponent/TransactionPreview.stories.ts @@ -8,11 +8,20 @@ const meta: Meta = { export default meta; -export const Primary = { +export const LongDescription = { args:{ title: "Перевод на другой счет", amount: "100р", category: "Перевод", - description: "Описание операции" + description: "Динное описание, которое будет обрезано" } -} \ No newline at end of file +} + +export const SmallDescription = { + args:{ + title: "Перевод на другой счет", + amount: "100р", + category: "Перевод", + description: "Короткое описание" + } +} diff --git a/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx b/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx index a110dc15b..1758c7a41 100644 --- a/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx +++ b/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx @@ -11,12 +11,14 @@ export interface TransactionPreviewProps { export const TransactionPreview: React.FC = (props) => { + const description = props.description; + const descSmall = description.length>20?description.substring(0,20)+"...":description; return(

{props.title}

Сумма операции: {props.amount}

Категория: {props.category}

-

{props.description}

+

{descSmall}

) } \ No newline at end of file From 589bedf447f739d09051dde6982a5e9712f893b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Thu, 3 Jul 2025 14:03:38 +0300 Subject: [PATCH 15/38] fix: props to destructuring --- .../common/ModalComponent/Modal.stories.tsx | 7 +++++-- src/components/common/ModalComponent/Modal.tsx | 6 +++--- .../BasketButtonComponent/BasketButton.stories.ts | 1 - .../OperationFull.stories.ts | 2 -- .../OperationFullComponent/OperationFull.tsx | 14 +++++++------- .../ProductBasketComponent/ProductBasket.tsx | 14 +++++++------- .../ProductPreviewComponent/ProductPreview.tsx | 11 +++++------ .../TransactionFullComponent/TransactionFull.tsx | 12 ++++++------ .../TransactionPreview.tsx | 9 ++++----- 9 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/components/common/ModalComponent/Modal.stories.tsx b/src/components/common/ModalComponent/Modal.stories.tsx index 7bb89ad05..5fd812d2f 100644 --- a/src/components/common/ModalComponent/Modal.stories.tsx +++ b/src/components/common/ModalComponent/Modal.stories.tsx @@ -12,8 +12,6 @@ const meta: Meta = { export default meta; - - export const WithP = { args:{ visible: true, @@ -33,4 +31,9 @@ export const WithButton = { children:
} } +export const Unvisible = { + args:{ + visible: false + } +} diff --git a/src/components/common/ModalComponent/Modal.tsx b/src/components/common/ModalComponent/Modal.tsx index 241371dc3..ae67f7472 100644 --- a/src/components/common/ModalComponent/Modal.tsx +++ b/src/components/common/ModalComponent/Modal.tsx @@ -7,8 +7,8 @@ export interface ModalProps { children: ReactNode, } -export const Modal: React.FC = (props) => { - if (!props.visible) return null +export const Modal: React.FC = ({children, visible}) => { + if (!visible) return null return( <>
@@ -20,7 +20,7 @@ export const Modal: React.FC = (props) => {
-
{props.children}
+
{children}
diff --git a/src/components/market/BasketButtonComponent/BasketButton.stories.ts b/src/components/market/BasketButtonComponent/BasketButton.stories.ts index 7134708df..55bf97de8 100644 --- a/src/components/market/BasketButtonComponent/BasketButton.stories.ts +++ b/src/components/market/BasketButtonComponent/BasketButton.stories.ts @@ -2,7 +2,6 @@ import type { Meta } from '@storybook/react'; import { BasketButton, BasketButtonProps } from './BasketButton'; const meta: Meta = { - // render: (args: BasketButtonProps) => , title: "market/BasketButton", component: BasketButton, args: { diff --git a/src/components/market/OperationFullComponent/OperationFull.stories.ts b/src/components/market/OperationFullComponent/OperationFull.stories.ts index 4777c2bfb..87ddeabbf 100644 --- a/src/components/market/OperationFullComponent/OperationFull.stories.ts +++ b/src/components/market/OperationFullComponent/OperationFull.stories.ts @@ -4,8 +4,6 @@ import { OperationFull } from './OperationFull'; const meta: Meta = { title: "market/OperationFull", component: OperationFull, - - } export default meta; diff --git a/src/components/market/OperationFullComponent/OperationFull.tsx b/src/components/market/OperationFullComponent/OperationFull.tsx index 603c745a9..a38bf4f79 100644 --- a/src/components/market/OperationFullComponent/OperationFull.tsx +++ b/src/components/market/OperationFullComponent/OperationFull.tsx @@ -7,16 +7,16 @@ export interface OperationFullProps extends Product{ counter: number }; -export const OperationFull: React.FC = (props) => { +export const OperationFull: React.FC = ({name, price, categoryName, image,description, counter}) => { return( <>
-

{props.name}

-

Цена: {props.price}

-

Категория: {props.categoryName}

-

{props.image}

-

{props.description}

- +

{name}

+

Цена: {price}

+

Категория: {categoryName}

+

{image}

+

{description}

+
) diff --git a/src/components/market/ProductBasketComponent/ProductBasket.tsx b/src/components/market/ProductBasketComponent/ProductBasket.tsx index aabb98d75..a08d0b9dc 100644 --- a/src/components/market/ProductBasketComponent/ProductBasket.tsx +++ b/src/components/market/ProductBasketComponent/ProductBasket.tsx @@ -7,17 +7,17 @@ export interface ProductBasketProps extends Product { counter: number } -export const ProductBasket: React.FC = (props) => { +export const ProductBasket: React.FC = ({name, categoryName,price, description, image, counter}) => { return ( <>
diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.tsx b/src/components/market/ProductPreviewComponent/ProductPreview.tsx index e5a887f75..d97a45f0a 100644 --- a/src/components/market/ProductPreviewComponent/ProductPreview.tsx +++ b/src/components/market/ProductPreviewComponent/ProductPreview.tsx @@ -7,17 +7,16 @@ export interface ProductPreviewProps extends Product{ counter: number } -export const ProductPreview: React.FC = (props) => { - const description = props.description; +export const ProductPreview: React.FC = ({name, counter,price,description,image}) => { const descSmall = description.length>20?description.substring(0,20)+"...":description; return( <>
-

{props.name}

-

Price: {props.price}

-

{props.image}

+

{name}

+

Price: {price}

+

{image}

{descSmall}

- +
) diff --git a/src/components/operations/TransactionFullComponent/TransactionFull.tsx b/src/components/operations/TransactionFullComponent/TransactionFull.tsx index 477f84b24..847ef78f9 100644 --- a/src/components/operations/TransactionFullComponent/TransactionFull.tsx +++ b/src/components/operations/TransactionFullComponent/TransactionFull.tsx @@ -9,15 +9,15 @@ export interface TransactionFullProps { description: string } -export const TransactionFull: React.FC=(props)=>{ +export const TransactionFull: React.FC=({amount,category,date,description,title})=>{ return( <>
-

{props.title}

-

Дата: {props.date}

-

Сумма операции: {props.amount}

-

Категория: {props.category}

-

{props.description}

+

{title}

+

Дата: {date}

+

Сумма операции: {amount}

+

Категория: {category}

+

{description}

diff --git a/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx b/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx index 1758c7a41..56a64589d 100644 --- a/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx +++ b/src/components/operations/TransactionPreviewComponent/TransactionPreview.tsx @@ -10,14 +10,13 @@ export interface TransactionPreviewProps { } -export const TransactionPreview: React.FC = (props) => { - const description = props.description; +export const TransactionPreview: React.FC = ({amount,category,description,title}) => { const descSmall = description.length>20?description.substring(0,20)+"...":description; return(
-

{props.title}

-

Сумма операции: {props.amount}

-

Категория: {props.category}

+

{title}

+

Сумма операции: {amount}

+

Категория: {category}

{descSmall}

) From 1c935ac0af304c54dd3048b78176ff56362d173f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Tue, 15 Jul 2025 21:25:48 +0300 Subject: [PATCH 16/38] feat: add hooks --- .github/workflows/main.yml | 7 +- .storybook/{main.ts => main.tsx} | 0 .storybook/preview.ts | 15 -- .storybook/preview.tsx | 25 +++ package-lock.json | 164 ++++++++++++++---- package.json | 5 +- src/app/App.scss | 54 +++++- src/app/App.tsx | 23 ++- src/app/Variables.scss | 4 + src/components/LanguageProvider.tsx | 38 ++++ src/components/ThemeProvider.tsx | 35 ++++ .../ChangeLanguage.tsx | 27 +++ .../FillInputModal.stories.ts | 11 ++ .../FillInputModal.tsx | 29 ++++ .../common/HeaderComponent/Header.scss | 25 ++- .../common/HeaderComponent/Header.tsx | 25 ++- .../common/LayoutComponent/Layout.scss | 11 +- .../common/LayoutComponent/Layout.tsx | 8 +- .../common/ModalComponent/Modal.stories.tsx | 4 +- .../ToggleThemeComponent/ToggleTheme.tsx | 16 ++ src/i18n/i18next.ts | 33 ++++ 21 files changed, 488 insertions(+), 71 deletions(-) rename .storybook/{main.ts => main.tsx} (100%) delete mode 100644 .storybook/preview.ts create mode 100644 .storybook/preview.tsx create mode 100644 src/app/Variables.scss create mode 100644 src/components/LanguageProvider.tsx create mode 100644 src/components/ThemeProvider.tsx create mode 100644 src/components/common/ChangeLanguageComponent/ChangeLanguage.tsx create mode 100644 src/components/common/FillInputModalComponent/FillInputModal.stories.ts create mode 100644 src/components/common/FillInputModalComponent/FillInputModal.tsx create mode 100644 src/components/common/ToggleThemeComponent/ToggleTheme.tsx create mode 100644 src/i18n/i18next.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index af2659c46..88b116948 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,8 @@ name: Test, Lint, Build and Deploy on Github Pages on: push: - branches: ["master", "main"] + branches: + - storybook # Позволяет запустить этот рабочий процесс вручную на вкладке Actions workflow_dispatch: @@ -34,7 +35,7 @@ jobs: - name: Run tests and linter run: npm run lint && npm test - # Собираем приложение + # # Собираем приложение # - name: Build Application # run: npm run build @@ -48,7 +49,7 @@ jobs: # Собираем Storybook - name: Build Storybook run: npm run build-storybook - + # Публикуем Storybook на Github Pages - name: Deploy Storybook to Github Pages uses: JamesIves/github-pages-deploy-action@4.2.1 diff --git a/.storybook/main.ts b/.storybook/main.tsx similarity index 100% rename from .storybook/main.ts rename to .storybook/main.tsx diff --git a/.storybook/preview.ts b/.storybook/preview.ts deleted file mode 100644 index 1c372b694..000000000 --- a/.storybook/preview.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { Preview } from "@storybook/react"; - -const preview: Preview = { - parameters: { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, - }, - }, - }, -}; - -export default preview; diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 000000000..dbcec2fef --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,25 @@ +import { type Preview } from "@storybook/react"; +import { ThemeProvider } from "../src/components/ThemeProvider" +import { LanguageProvider } from "../src/components/LanguageProvider" + +const preview: Preview = { + parameters: { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + }, + decorators: [ + (Story) => ( + + + + + + )] +}; + +export default preview; diff --git a/package-lock.json b/package-lock.json index 317474c45..89e900a70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,11 @@ "license": "MIT", "dependencies": { "clsx": "^1.2.1", + "i18next": "^25.3.2", + "i18next-browser-languagedetector": "^8.2.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-i18next": "^15.6.0" }, "devDependencies": { "@babel/core": "^7.22.1", @@ -2032,13 +2035,10 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -13907,6 +13907,15 @@ "node": ">=12" } }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, "node_modules/html-tags": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", @@ -14087,6 +14096,46 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/i18next": { + "version": "25.3.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.3.2.tgz", + "integrity": "sha512-JSnbZDxRVbphc5jiptxr3o2zocy5dEqpVm9qCGdJwRNO+9saUJS0/u4LnM/13C23fUEWxAylPqKU/NpMV/IjqA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz", + "integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -20314,6 +20363,32 @@ "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", "dev": true }, + "node_modules/react-i18next": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.6.0.tgz", + "integrity": "sha512-W135dB0rDfiFmbMipC17nOhGdttO5mzH8BivY+2ybsQBbXvxWIwl3cmeH3T9d+YPBSJu/ouyJKFJTtkK7rJofw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -20570,12 +20645,6 @@ "node": ">=4" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", @@ -22666,7 +22735,7 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -23172,6 +23241,15 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -25430,13 +25508,9 @@ "dev": true }, "@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.11" - } + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==" }, "@babel/template": { "version": "7.22.15", @@ -34059,6 +34133,14 @@ "terser": "^5.10.0" } }, + "html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "requires": { + "void-elements": "3.1.0" + } + }, "html-tags": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", @@ -34180,6 +34262,22 @@ "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true }, + "i18next": { + "version": "25.3.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.3.2.tgz", + "integrity": "sha512-JSnbZDxRVbphc5jiptxr3o2zocy5dEqpVm9qCGdJwRNO+9saUJS0/u4LnM/13C23fUEWxAylPqKU/NpMV/IjqA==", + "requires": { + "@babel/runtime": "^7.27.6" + } + }, + "i18next-browser-languagedetector": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz", + "integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==", + "requires": { + "@babel/runtime": "^7.23.2" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -38637,6 +38735,15 @@ } } }, + "react-i18next": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.6.0.tgz", + "integrity": "sha512-W135dB0rDfiFmbMipC17nOhGdttO5mzH8BivY+2ybsQBbXvxWIwl3cmeH3T9d+YPBSJu/ouyJKFJTtkK7rJofw==", + "requires": { + "@babel/runtime": "^7.27.6", + "html-parse-stringify": "^3.0.1" + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -38815,12 +38922,6 @@ "regenerate": "^1.4.2" } }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, "regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", @@ -40384,7 +40485,7 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", - "dev": true + "devOptional": true }, "ufo": { "version": "1.4.0", @@ -40744,6 +40845,11 @@ "unist-util-stringify-position": "^3.0.0" } }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==" + }, "w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/package.json b/package.json index 059c7997a..83d16ee18 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,10 @@ }, "dependencies": { "clsx": "^1.2.1", + "i18next": "^25.3.2", + "i18next-browser-languagedetector": "^8.2.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-i18next": "^15.6.0" } } diff --git a/src/app/App.scss b/src/app/App.scss index ce2b1b896..dd6340284 100644 --- a/src/app/App.scss +++ b/src/app/App.scss @@ -1,13 +1,61 @@ +@import "Variables.scss"; + button{ font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-weight: 700; - border: 0; - border-radius: 1em; + border: 0.01em solid black; cursor: pointer; display: inline-block; line-height: 1; color: black; - background-color: #fcd800; + background-color: $yellow; font-size: 12px; padding: 10px 16px; +} +.button-light, .button-dark{ + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 700; + cursor: pointer; + display: inline-block; + line-height: 1; + font-size: 12px; + padding: 10px 16px; +} +.button-light{ + border: 0.01em solid black; + color: black; + background-color: $yellow; +} +.button-dark{ + border: 0.01em solid $brown; + color: white; + background-color: $darkColor; +} + +.select-light, .select-dark{ + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 700; + cursor: pointer; + display: inline-block; + line-height: 1; + font-size: 12px; + padding: 7.2px 10px; +} + +.select-light{ + border: 0.01em solid black; + color: black; + background-color: $yellow;; +} +.select-dark{ + border: 0.01em solid $brown; + color: white; + background-color: $darkColor; +} + +.h1-light, .p-light { + color: black +} +.h1-dark, .p-dark { + color: white } \ No newline at end of file diff --git a/src/app/App.tsx b/src/app/App.tsx index e54f7a526..a6ad6ce34 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,17 +1,24 @@ import React from 'react'; import logo from './logo.svg'; import './App.scss'; +import { ThemeProvider } from '../components/ThemeProvider'; +import { LanguageProvider } from '../components/LanguageProvider'; + function App() { return ( -
-
- logo -

- Текст писать тут -

-
-
+ + +
+
+ logo +

+ Текст писать тут +

+
+
+
+
); } diff --git a/src/app/Variables.scss b/src/app/Variables.scss new file mode 100644 index 000000000..dc3d5b182 --- /dev/null +++ b/src/app/Variables.scss @@ -0,0 +1,4 @@ +$grey: #C2C8DA; +$brown: #D5621D; +$darkColor: #210E09; +$yellow: #E6C744; \ No newline at end of file diff --git a/src/components/LanguageProvider.tsx b/src/components/LanguageProvider.tsx new file mode 100644 index 000000000..a47e92173 --- /dev/null +++ b/src/components/LanguageProvider.tsx @@ -0,0 +1,38 @@ +import i18next from "../i18n/i18next"; +import React, { createContext, ReactNode, useContext, useState } from "react" + +interface LanguageContextType { + language: string; + changeLanguage: (lang: string) => void; + t: (key: string, options?: any) => string; +} + +const LanguageContext = createContext({ + language: "ru", + changeLanguage: () => { }, + t: (key: string) => key, +}) + +type LanguageProviderProps = { + children: ReactNode +} + +export const useLanguage = () => { + return useContext(LanguageContext); +} + +export const LanguageProvider = ({children}: LanguageProviderProps) => { + const [language, setLanguage] = useState(i18next.language); + + + const changeLanguage = (lang : string) => { + setLanguage(lang); + i18next.changeLanguage(lang); + } + + return ( + + {children} + + ) +} \ No newline at end of file diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx new file mode 100644 index 000000000..02536b498 --- /dev/null +++ b/src/components/ThemeProvider.tsx @@ -0,0 +1,35 @@ +import React, { createContext, ReactNode, useContext, useState } from "react" + +type Theme = "light"|"dark" + +interface ThemeContextType { + theme: Theme; + toggleTheme: () => void; +} + +const ThemeContext = createContext({ + theme: "light", + toggleTheme: () => {} +}) + +type ThemeProviderProps = { + children: ReactNode +} + +export const useTheme = () => { + return useContext(ThemeContext); +} + +export const ThemeProvider = ({children}: ThemeProviderProps) => { + const [theme, setTheme] = useState("light"); + + const toggleTheme = () => { + setTheme((prevTheme) => (prevTheme==="light"?"dark":"light")); + } + + return ( + + {children} + + ) +} \ No newline at end of file diff --git a/src/components/common/ChangeLanguageComponent/ChangeLanguage.tsx b/src/components/common/ChangeLanguageComponent/ChangeLanguage.tsx new file mode 100644 index 000000000..74802456d --- /dev/null +++ b/src/components/common/ChangeLanguageComponent/ChangeLanguage.tsx @@ -0,0 +1,27 @@ +import React, { useState } from "react"; +import "../../../app/App.scss"; +import { useTheme } from "../../ThemeProvider"; +import { useLanguage } from "../../LanguageProvider"; + + +export const ChangeLanguage: React.FC = () => { + const [selectedValue,setSelectedValue] = useState('ru'); + const {changeLanguage} = useLanguage(); + const {theme} = useTheme(); + const className = "select-"+theme; + + const handleChange = (event: React.ChangeEvent) => { + const lang=event.target.value; + setSelectedValue(lang); + changeLanguage(lang); + }; + + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/common/FillInputModalComponent/FillInputModal.stories.ts b/src/components/common/FillInputModalComponent/FillInputModal.stories.ts new file mode 100644 index 000000000..17bab4640 --- /dev/null +++ b/src/components/common/FillInputModalComponent/FillInputModal.stories.ts @@ -0,0 +1,11 @@ +import type { Meta } from '@storybook/react'; +import { FillInputModal } from './FillInputModal'; + +const meta: Meta = { + title: "market/FillInputModal", + component: FillInputModal, +} + +export default meta; + +export const Primary = {} diff --git a/src/components/common/FillInputModalComponent/FillInputModal.tsx b/src/components/common/FillInputModalComponent/FillInputModal.tsx new file mode 100644 index 000000000..7acd78a8c --- /dev/null +++ b/src/components/common/FillInputModalComponent/FillInputModal.tsx @@ -0,0 +1,29 @@ +import "../../../app/App.scss" +import React, { ReactNode, useState } from "react" +import { Modal } from "../ModalComponent/Modal" + + + +export const FillInputModal: React.FC = ()=>{ + const [visible,setVisible]=useState(false); + const [childrenNode,setChildrenNode] = useState(null); + const [text,setText] =useState(""); + const ShowModal=()=>{ + setVisible(!visible); + setChildrenNode(()=>{return( + + )}); + } + + const ChangeInput=(text:string)=>{ + setText(text); + } + + return( + <> + + ChangeInput(e.target.value)} value={text}> + + + ) +} \ No newline at end of file diff --git a/src/components/common/HeaderComponent/Header.scss b/src/components/common/HeaderComponent/Header.scss index 321b300d5..5fce094ba 100644 --- a/src/components/common/HeaderComponent/Header.scss +++ b/src/components/common/HeaderComponent/Header.scss @@ -1,7 +1,24 @@ -.header-div{ +@import "../../../app/Variables.scss"; + +.header-div-light, .header-div-dark{ padding: 0.5em; position: sticky; + display: flex; + justify-content: flex-end; top:0; - border-bottom: 1px solid #dbdbdb; - background-color: #fcd200; -} \ No newline at end of file +} +.header-div-light{ + border-bottom: 1px solid $grey; + background-color: $yellow; +} +.header-div-dark{ + border-bottom: 1px solid $brown; + background-color: $darkColor; +} +.header-div-logo{ + flex-grow: 1; +} +.header-div-right{ + display: flex; + align-items: flex-start; +} diff --git a/src/components/common/HeaderComponent/Header.tsx b/src/components/common/HeaderComponent/Header.tsx index 0febd2dcc..21049aa85 100644 --- a/src/components/common/HeaderComponent/Header.tsx +++ b/src/components/common/HeaderComponent/Header.tsx @@ -1,11 +1,30 @@ import React from "react" import { Logo } from "../Logo" +import { ToggleTheme } from "../ToggleThemeComponent/ToggleTheme"; +import { useTheme } from "../../ThemeProvider"; +import { ChangeLanguage } from "../ChangeLanguageComponent/ChangeLanguage"; +import { useLanguage } from "../../LanguageProvider"; import "./Header.scss" export const Header: React.FC = () => { - return( -
- + const {theme} = useTheme(); + const {language} = useLanguage(); + + const className="header-div-"+theme; + console.log(language); + return( +
+
+ +
+
+
+ +
+
+ +
+
) } \ No newline at end of file diff --git a/src/components/common/LayoutComponent/Layout.scss b/src/components/common/LayoutComponent/Layout.scss index 3431665ad..32f3784ad 100644 --- a/src/components/common/LayoutComponent/Layout.scss +++ b/src/components/common/LayoutComponent/Layout.scss @@ -1,4 +1,11 @@ -.layout-div{ +@import "../../../app/Variables.scss"; + +.layout-div-light{ height:100em; - background-color: #ffe86f; + background-color: #FFF5BF; +} + +.layout-div-dark{ + height:100em; + background-color: $brown; } \ No newline at end of file diff --git a/src/components/common/LayoutComponent/Layout.tsx b/src/components/common/LayoutComponent/Layout.tsx index 966f2f935..284d3d324 100644 --- a/src/components/common/LayoutComponent/Layout.tsx +++ b/src/components/common/LayoutComponent/Layout.tsx @@ -1,13 +1,19 @@ import React from "react" import { Header } from "../HeaderComponent/Header" import "./Layout.scss" +import { useTheme } from "../../ThemeProvider"; +import { useLanguage } from "../../LanguageProvider"; export const Layout: React.FC = () => { + const {theme} = useTheme(); + const {t} = useLanguage(); + const className="layout-div-"+theme; return ( <> -
+
+

{t('welcome')}

) diff --git a/src/components/common/ModalComponent/Modal.stories.tsx b/src/components/common/ModalComponent/Modal.stories.tsx index 5fd812d2f..9b92b1ea7 100644 --- a/src/components/common/ModalComponent/Modal.stories.tsx +++ b/src/components/common/ModalComponent/Modal.stories.tsx @@ -1,5 +1,5 @@ -import type { Story,Meta } from '@storybook/react'; -import { Modal, ModalProps } from './Modal'; +import type { Meta } from '@storybook/react'; +import { Modal } from './Modal'; import React from 'react'; const meta: Meta = { diff --git a/src/components/common/ToggleThemeComponent/ToggleTheme.tsx b/src/components/common/ToggleThemeComponent/ToggleTheme.tsx new file mode 100644 index 000000000..1ef767cef --- /dev/null +++ b/src/components/common/ToggleThemeComponent/ToggleTheme.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import {useTheme} from "../../ThemeProvider"; +import "../../../app/App.scss"; +import { useLanguage } from "../../LanguageProvider"; + +export const ToggleTheme: React.FC = () => { + const {theme, toggleTheme} = useTheme(); + const {t} = useLanguage(); + const className = "button-"+theme; + const h1ClName = "h1-"+theme; + return( + <> + + + ) +} \ No newline at end of file diff --git a/src/i18n/i18next.ts b/src/i18n/i18next.ts new file mode 100644 index 000000000..05c63f4da --- /dev/null +++ b/src/i18n/i18next.ts @@ -0,0 +1,33 @@ +import i18next from 'i18next'; +import { initReactI18next } from 'react-i18next'; + +// Ресурсы для перевода +const resources = { + en: { + translation: { + "theme":"Theme", + "changeTheme":"Change theme", + "welcome": "Welcome to my app!" + } + }, + ru: { + translation: { + "theme":"Тема", + "changeTheme":"Поменять тему", + "welcome": "Добро пожаловать в моё приложение!" + } + } +}; + +i18next + .use(initReactI18next) // Передаем i18next в react-i18next + .init({ + resources, + lng: 'ru', // Язык по умолчанию + fallbackLng: 'ru', // Запасной язык, если перевода нет + interpolation: { + escapeValue: false, // Не экранировать значения, для React + }, + }); + +export default i18next; \ No newline at end of file From 8b08a4808555ca497dabfc3061bf4ba1b9cceeb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Tue, 15 Jul 2025 21:57:50 +0300 Subject: [PATCH 17/38] fix: eslint errors and add components to storybook --- src/components/LanguageProvider.tsx | 2 +- src/components/ThemeProvider.tsx | 2 +- .../ChangeLanguage.stories.tsx | 12 ++++++++++++ .../FillInputModal.stories.ts | 2 +- .../FillInputModalComponent/FillInputModal.tsx | 2 +- .../ToggleThemeComponent/ToggleTheme.stories.tsx | 12 ++++++++++++ .../common/ToggleThemeComponent/ToggleTheme.tsx | 1 - .../BasketButtonComponent/BasketButton.stories.ts | 2 +- 8 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 src/components/common/ChangeLanguageComponent/ChangeLanguage.stories.tsx create mode 100644 src/components/common/ToggleThemeComponent/ToggleTheme.stories.tsx diff --git a/src/components/LanguageProvider.tsx b/src/components/LanguageProvider.tsx index a47e92173..92d5d9301 100644 --- a/src/components/LanguageProvider.tsx +++ b/src/components/LanguageProvider.tsx @@ -9,7 +9,7 @@ interface LanguageContextType { const LanguageContext = createContext({ language: "ru", - changeLanguage: () => { }, + changeLanguage: () => {/*Do nothing*/}, t: (key: string) => key, }) diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx index 02536b498..470e371cb 100644 --- a/src/components/ThemeProvider.tsx +++ b/src/components/ThemeProvider.tsx @@ -9,7 +9,7 @@ interface ThemeContextType { const ThemeContext = createContext({ theme: "light", - toggleTheme: () => {} + toggleTheme: () => {/*Do nothing*/} }) type ThemeProviderProps = { diff --git a/src/components/common/ChangeLanguageComponent/ChangeLanguage.stories.tsx b/src/components/common/ChangeLanguageComponent/ChangeLanguage.stories.tsx new file mode 100644 index 000000000..be3ee3dfc --- /dev/null +++ b/src/components/common/ChangeLanguageComponent/ChangeLanguage.stories.tsx @@ -0,0 +1,12 @@ +import type { Meta } from '@storybook/react'; +import { ChangeLanguage } from './ChangeLanguage'; + + +const meta: Meta = { + title: "components/ChangeLanguage", + component: ChangeLanguage, +} + +export default meta; + +export const Primary = {} \ No newline at end of file diff --git a/src/components/common/FillInputModalComponent/FillInputModal.stories.ts b/src/components/common/FillInputModalComponent/FillInputModal.stories.ts index 17bab4640..52df4d764 100644 --- a/src/components/common/FillInputModalComponent/FillInputModal.stories.ts +++ b/src/components/common/FillInputModalComponent/FillInputModal.stories.ts @@ -2,7 +2,7 @@ import type { Meta } from '@storybook/react'; import { FillInputModal } from './FillInputModal'; const meta: Meta = { - title: "market/FillInputModal", + title: "components/FillInputModal", component: FillInputModal, } diff --git a/src/components/common/FillInputModalComponent/FillInputModal.tsx b/src/components/common/FillInputModalComponent/FillInputModal.tsx index 7acd78a8c..2ee785398 100644 --- a/src/components/common/FillInputModalComponent/FillInputModal.tsx +++ b/src/components/common/FillInputModalComponent/FillInputModal.tsx @@ -21,7 +21,7 @@ export const FillInputModal: React.FC = ()=>{ return( <> - + {childrenNode} ChangeInput(e.target.value)} value={text}> diff --git a/src/components/common/ToggleThemeComponent/ToggleTheme.stories.tsx b/src/components/common/ToggleThemeComponent/ToggleTheme.stories.tsx new file mode 100644 index 000000000..d567dae90 --- /dev/null +++ b/src/components/common/ToggleThemeComponent/ToggleTheme.stories.tsx @@ -0,0 +1,12 @@ +import type { Meta } from '@storybook/react'; +import {ToggleTheme} from './ToggleTheme' + + +const meta: Meta = { + title: "components/ToggleTheme", + component: ToggleTheme, +} + +export default meta; + +export const Primary = {} \ No newline at end of file diff --git a/src/components/common/ToggleThemeComponent/ToggleTheme.tsx b/src/components/common/ToggleThemeComponent/ToggleTheme.tsx index 1ef767cef..c1b0aa874 100644 --- a/src/components/common/ToggleThemeComponent/ToggleTheme.tsx +++ b/src/components/common/ToggleThemeComponent/ToggleTheme.tsx @@ -7,7 +7,6 @@ export const ToggleTheme: React.FC = () => { const {theme, toggleTheme} = useTheme(); const {t} = useLanguage(); const className = "button-"+theme; - const h1ClName = "h1-"+theme; return( <> diff --git a/src/components/market/BasketButtonComponent/BasketButton.stories.ts b/src/components/market/BasketButtonComponent/BasketButton.stories.ts index 55bf97de8..bda90bb32 100644 --- a/src/components/market/BasketButtonComponent/BasketButton.stories.ts +++ b/src/components/market/BasketButtonComponent/BasketButton.stories.ts @@ -1,5 +1,5 @@ import type { Meta } from '@storybook/react'; -import { BasketButton, BasketButtonProps } from './BasketButton'; +import { BasketButton } from './BasketButton'; const meta: Meta = { title: "market/BasketButton", From 4bf0c2fa6cb3ae93ca0a478b4a392ebbb59905df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Sat, 19 Jul 2025 13:36:20 +0300 Subject: [PATCH 18/38] fix: update providers and FillInputModal --- src/app/App.tsx | 23 +++++++------------ src/components/LanguageProvider.tsx | 14 +++++------ src/components/ThemeProvider.tsx | 13 ++++++----- .../ChangeLanguage.tsx | 2 +- .../FillInputModal.tsx | 17 +++----------- src/index.tsx | 8 ++++++- 6 files changed, 33 insertions(+), 44 deletions(-) diff --git a/src/app/App.tsx b/src/app/App.tsx index a6ad6ce34..e54f7a526 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,24 +1,17 @@ import React from 'react'; import logo from './logo.svg'; import './App.scss'; -import { ThemeProvider } from '../components/ThemeProvider'; -import { LanguageProvider } from '../components/LanguageProvider'; - function App() { return ( - - -
-
- logo -

- Текст писать тут -

-
-
-
-
+
+
+ logo +

+ Текст писать тут +

+
+
); } diff --git a/src/components/LanguageProvider.tsx b/src/components/LanguageProvider.tsx index 92d5d9301..d31773776 100644 --- a/src/components/LanguageProvider.tsx +++ b/src/components/LanguageProvider.tsx @@ -4,21 +4,21 @@ import React, { createContext, ReactNode, useContext, useState } from "react" interface LanguageContextType { language: string; changeLanguage: (lang: string) => void; - t: (key: string, options?: any) => string; + t: (key: string) => string; } -const LanguageContext = createContext({ - language: "ru", - changeLanguage: () => {/*Do nothing*/}, - t: (key: string) => key, -}) +const LanguageContext = createContext(null); type LanguageProviderProps = { children: ReactNode } export const useLanguage = () => { - return useContext(LanguageContext); + const context = useContext(LanguageContext); + + if(context === null) { throw new Error("useLanguage must be used within a LanguageProvider"); } + + return context; } export const LanguageProvider = ({children}: LanguageProviderProps) => { diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx index 470e371cb..ee271a082 100644 --- a/src/components/ThemeProvider.tsx +++ b/src/components/ThemeProvider.tsx @@ -1,23 +1,24 @@ import React, { createContext, ReactNode, useContext, useState } from "react" -type Theme = "light"|"dark" +type Theme = "light"|"dark"; interface ThemeContextType { theme: Theme; toggleTheme: () => void; } -const ThemeContext = createContext({ - theme: "light", - toggleTheme: () => {/*Do nothing*/} -}) +const ThemeContext = createContext(null); type ThemeProviderProps = { children: ReactNode } export const useTheme = () => { - return useContext(ThemeContext); + const context = useContext(ThemeContext); + + if(context === null) { throw new Error("useTheme must be used within a ThemeProvider"); } + + return context; } export const ThemeProvider = ({children}: ThemeProviderProps) => { diff --git a/src/components/common/ChangeLanguageComponent/ChangeLanguage.tsx b/src/components/common/ChangeLanguageComponent/ChangeLanguage.tsx index 74802456d..9390780fb 100644 --- a/src/components/common/ChangeLanguageComponent/ChangeLanguage.tsx +++ b/src/components/common/ChangeLanguageComponent/ChangeLanguage.tsx @@ -20,7 +20,7 @@ export const ChangeLanguage: React.FC = () => {
); diff --git a/src/components/common/FillInputModalComponent/FillInputModal.tsx b/src/components/common/FillInputModalComponent/FillInputModal.tsx index 2ee785398..a95a2153e 100644 --- a/src/components/common/FillInputModalComponent/FillInputModal.tsx +++ b/src/components/common/FillInputModalComponent/FillInputModal.tsx @@ -6,24 +6,13 @@ import { Modal } from "../ModalComponent/Modal" export const FillInputModal: React.FC = ()=>{ const [visible,setVisible]=useState(false); - const [childrenNode,setChildrenNode] = useState(null); const [text,setText] =useState(""); - const ShowModal=()=>{ - setVisible(!visible); - setChildrenNode(()=>{return( - - )}); - } - - const ChangeInput=(text:string)=>{ - setText(text); - } return( <> - {childrenNode} - ChangeInput(e.target.value)} value={text}> - + + {setText(e.target.value)}} value={text}> + ) } \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 26d2b1437..fbcce28c5 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,10 +2,16 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './app/index.css'; import App from './app/App'; +import { ThemeProvider } from './components/ThemeProvider' +import { LanguageProvider } from './components/LanguageProvider'; const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render( - + + + + + ); From e1caa62055e8b0e5a0d341f74b57baf9ab4c46ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Tue, 29 Jul 2025 12:14:27 +0300 Subject: [PATCH 19/38] add: ProductList, ProductLitsLazyLoad, Portal --- src/components/ProductCreator.tsx | 42 +++++++++++++++++++ .../FillInputModal.tsx | 4 +- .../common/HeaderComponent/Header.tsx | 6 +-- .../common/ModalComponent/Modal.tsx | 8 ++-- .../market/LazyLoad/IntersectionObserver.ts | 16 +++++++ src/components/market/LazyLoad/LazyLoad.tsx | 28 +++++++++++++ .../ProductList.stories.tsx | 26 ++++++++++++ .../ProductList.tsx | 36 ++++++++++++++++ .../ProductList.stories.tsx | 26 ++++++++++++ .../ProductListComponent/ProductList.tsx | 33 +++++++++++++++ .../ProductPreview.tsx | 2 +- 11 files changed, 217 insertions(+), 10 deletions(-) create mode 100644 src/components/ProductCreator.tsx create mode 100644 src/components/market/LazyLoad/IntersectionObserver.ts create mode 100644 src/components/market/LazyLoad/LazyLoad.tsx create mode 100644 src/components/market/ProductListComponent with LazyLoad/ProductList.stories.tsx create mode 100644 src/components/market/ProductListComponent with LazyLoad/ProductList.tsx create mode 100644 src/components/market/ProductListComponent/ProductList.stories.tsx create mode 100644 src/components/market/ProductListComponent/ProductList.tsx diff --git a/src/components/ProductCreator.tsx b/src/components/ProductCreator.tsx new file mode 100644 index 000000000..e5671d543 --- /dev/null +++ b/src/components/ProductCreator.tsx @@ -0,0 +1,42 @@ +import { v4 as uuidv4 } from 'uuid'; + +const categories : string[] = ["fruits", "vegetables", "clothes", "shoes"]; +const CNT_CATEGORIES = 4; +const CNT_PRODUCTS = 12; + +export type Product = { + id: string, + name: string, + price: number, + categoryName: string, + image?: string, + description?: string, +} + +const getRandomInt = (min: number, max: number) => { + return Math.floor(Math.random() * (max - min)) + min; +} + + +const getRandomCategory = (): string => { + const i = getRandomInt(1,CNT_CATEGORIES); + return categories[i]; +} + +export const getRandomProduct = (): Product => { + return { + id: uuidv4(), + name: `SomeProduct${getRandomInt(1,100)}`, + description: "descr", + price: getRandomInt(10,5000), + categoryName: getRandomCategory() + } +} + +export const getRandomProductList = (): Product[] => { + const products = []; + for (let i=0;i<10;i++){ + products[i]=getRandomProduct(); + } + return products; +} \ No newline at end of file diff --git a/src/components/common/FillInputModalComponent/FillInputModal.tsx b/src/components/common/FillInputModalComponent/FillInputModal.tsx index a95a2153e..71e7b4a5e 100644 --- a/src/components/common/FillInputModalComponent/FillInputModal.tsx +++ b/src/components/common/FillInputModalComponent/FillInputModal.tsx @@ -1,5 +1,5 @@ import "../../../app/App.scss" -import React, { ReactNode, useState } from "react" +import React, { useState } from "react" import { Modal } from "../ModalComponent/Modal" @@ -12,7 +12,7 @@ export const FillInputModal: React.FC = ()=>{ <> {setText(e.target.value)}} value={text}> - + ) } \ No newline at end of file diff --git a/src/components/common/HeaderComponent/Header.tsx b/src/components/common/HeaderComponent/Header.tsx index 21049aa85..9052705a9 100644 --- a/src/components/common/HeaderComponent/Header.tsx +++ b/src/components/common/HeaderComponent/Header.tsx @@ -9,9 +9,7 @@ import "./Header.scss" export const Header: React.FC = () => { const {theme} = useTheme(); const {language} = useLanguage(); - const className="header-div-"+theme; - console.log(language); return(
@@ -19,10 +17,10 @@ export const Header: React.FC = () => {
- +
- +
diff --git a/src/components/common/ModalComponent/Modal.tsx b/src/components/common/ModalComponent/Modal.tsx index ae67f7472..dce9613a6 100644 --- a/src/components/common/ModalComponent/Modal.tsx +++ b/src/components/common/ModalComponent/Modal.tsx @@ -1,16 +1,18 @@ -import React, { ReactNode } from "react" +import React, { ReactNode, useState } from "react" import "./Modal.scss" import "../../../app/App.scss" +import { createPortal } from "react-dom" export interface ModalProps { visible: boolean, - children: ReactNode, + children: ReactNode } export const Modal: React.FC = ({children, visible}) => { if (!visible) return null return( <> + {createPortal(
@@ -26,7 +28,7 @@ export const Modal: React.FC = ({children, visible}) => {
-
+
,document.body)} ) } \ No newline at end of file diff --git a/src/components/market/LazyLoad/IntersectionObserver.ts b/src/components/market/LazyLoad/IntersectionObserver.ts new file mode 100644 index 000000000..052f6c049 --- /dev/null +++ b/src/components/market/LazyLoad/IntersectionObserver.ts @@ -0,0 +1,16 @@ +// настройки +const options:IntersectionObserverInit = { + threshold: 1, +}; + +export const getObserver = (callback: ()=>void): IntersectionObserver => { + const observer = + new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + callback(); + } + }); + }, options); + return observer; +} \ No newline at end of file diff --git a/src/components/market/LazyLoad/LazyLoad.tsx b/src/components/market/LazyLoad/LazyLoad.tsx new file mode 100644 index 000000000..bd4981c19 --- /dev/null +++ b/src/components/market/LazyLoad/LazyLoad.tsx @@ -0,0 +1,28 @@ +import React, { useEffect, useRef } from "react" +import { getObserver } from "./IntersectionObserver"; + +interface LazyLoadProps{ + changeObject: number, + callback: () => void +} + +export const LazyLoad: React.FC = ({changeObject, callback}) => { + const loaderRef = useRef(null); + + useEffect(() => { + const observer = getObserver(callback); + + if (loaderRef.current) { + observer.observe(loaderRef.current); + } + + return () => { + observer.disconnect(); + }; + }, [changeObject]); + return( +
+
+ ) + +} \ No newline at end of file diff --git a/src/components/market/ProductListComponent with LazyLoad/ProductList.stories.tsx b/src/components/market/ProductListComponent with LazyLoad/ProductList.stories.tsx new file mode 100644 index 000000000..2a706f7b8 --- /dev/null +++ b/src/components/market/ProductListComponent with LazyLoad/ProductList.stories.tsx @@ -0,0 +1,26 @@ +import type { Meta } from '@storybook/react'; +import { ProductList } from './ProductList'; +import { Product } from "../../ProductType" +import { getRandomProductList } from '../../ProductCreator'; + + +const meta: Meta = { + title: "market/ProductListWithLazyLoad", + component: ProductList, + argTypes:{ + products:{control: 'object'} + } +} + +export default meta; + +export const EmptyList = { + args: { + products : [] as Product[] + } +} +export const WithList = { + args: { + products : getRandomProductList() + } +} \ No newline at end of file diff --git a/src/components/market/ProductListComponent with LazyLoad/ProductList.tsx b/src/components/market/ProductListComponent with LazyLoad/ProductList.tsx new file mode 100644 index 000000000..b3ecc3b0e --- /dev/null +++ b/src/components/market/ProductListComponent with LazyLoad/ProductList.tsx @@ -0,0 +1,36 @@ +import React, { useEffect, useRef, useState } from "react" +import { Product } from "../../ProductCreator" +import { ProductBasket } from "../ProductBasketComponent/ProductBasket" +import { getRandomProduct } from "../../ProductCreator" +import { LazyLoad } from "../LazyLoad/LazyLoad" + +export interface ProductListProps { + products: Product[] +} + +export const ProductList: React.FC= ({products}) => { + const [items, setItems] = useState(products); + const [nextId, setNextId] = useState(products.length); + + const addItem = ()=>{ + const newItem = getRandomProduct(); + setItems([...items,newItem]); + setNextId(nextId+1); + } + + return ( + <> +

Список товаров

+
    + {items.map((product)=>( +
  • + +
  • + ))} +
+ + + + + ) +} \ No newline at end of file diff --git a/src/components/market/ProductListComponent/ProductList.stories.tsx b/src/components/market/ProductListComponent/ProductList.stories.tsx new file mode 100644 index 000000000..6b407b5ba --- /dev/null +++ b/src/components/market/ProductListComponent/ProductList.stories.tsx @@ -0,0 +1,26 @@ +import type { Meta } from '@storybook/react'; +import { ProductList } from './ProductList'; +import { Product } from "../../ProductType" +import { getRandomProductList } from '../../ProductCreator'; + +const meta: Meta = { + title: "market/ProductList", + component: ProductList, + argTypes:{ + products:{control: 'object'} + } +} + +export default meta; + +export const EmptyList = { + args: { + products : [] as Product[] + } +} + +export const WithList = { + args: { + products : getRandomProductList() + } +} diff --git a/src/components/market/ProductListComponent/ProductList.tsx b/src/components/market/ProductListComponent/ProductList.tsx new file mode 100644 index 000000000..37a17e574 --- /dev/null +++ b/src/components/market/ProductListComponent/ProductList.tsx @@ -0,0 +1,33 @@ +import React, { useState } from "react" +import { Product } from "../../ProductCreator" +import { ProductBasket } from "../ProductBasketComponent/ProductBasket" +import { getRandomProduct } from "../../ProductCreator" + +export interface ProductListProps { + products: Product[] +} + +export const ProductList: React.FC= ({products}) => { + const [items, setItems] = useState(products); + const [nextId, setNextId] = useState(products.length); + + const addItem = ()=>{ + const newItem = getRandomProduct(); + setItems([...items,newItem]); + setNextId(nextId+1); + } + + return ( + <> +

Список товаров

+
    + {items.map((product)=>( +
  • + +
  • + ))} +
+ + + ) +} \ No newline at end of file diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.tsx b/src/components/market/ProductPreviewComponent/ProductPreview.tsx index d97a45f0a..7583b5585 100644 --- a/src/components/market/ProductPreviewComponent/ProductPreview.tsx +++ b/src/components/market/ProductPreviewComponent/ProductPreview.tsx @@ -8,7 +8,7 @@ export interface ProductPreviewProps extends Product{ } export const ProductPreview: React.FC = ({name, counter,price,description,image}) => { - const descSmall = description.length>20?description.substring(0,20)+"...":description; + const descSmall = description&&description.length>20?description.substring(0,20)+"...":description; return( <>
From 0dca5b8e5786b41652f0c52859f0c66de11708ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Tue, 5 Aug 2025 11:05:30 +0300 Subject: [PATCH 20/38] add: Patterns --- .../{ProductCreator.tsx => ProductCreator.ts} | 1 - src/components/common/Button/Button.tsx | 13 +++++++ .../FillInputModal.tsx | 5 +-- .../common/HeaderComponent/Header.tsx | 4 +-- .../{ModalComponent => Modal}/Modal.scss | 0 .../Modal.stories.tsx | 0 .../{ModalComponent => Modal}/Modal.tsx | 5 +-- .../ToggleTheme.stories.tsx | 0 .../ToggleTheme.tsx | 6 ++-- .../BasketButon.scss | 0 .../BasketButton.stories.ts | 0 .../market/BasketButton/BasketButton.tsx | 21 +++++++++++ .../BasketButtonComponent/BasketButton.tsx | 29 --------------- src/components/market/LazyLoad/LazyLoad.scss | 3 ++ src/components/market/LazyLoad/LazyLoad.tsx | 6 ++-- .../OperationFullComponent/OperationFull.tsx | 2 +- .../ProductBasketComponent/ProductBasket.scss | 3 ++ .../ProductBasketComponent/ProductBasket.tsx | 3 +- .../market/ProductList/ProductList.scss | 3 ++ .../market/ProductList/ProductList.tsx | 21 +++++++++++ .../ProductListAddButton.stories.tsx} | 8 ++--- .../ProductListAddButton.tsx | 29 +++++++++++++++ .../ProductList.tsx | 36 ------------------- .../ProductListComponent/ProductList.tsx | 33 ----------------- .../ProductListLazyLoad.stories.tsx} | 8 ++--- .../ProductListLazyLoad.tsx | 30 ++++++++++++++++ .../ProductPreview.tsx | 2 +- .../TransactionFull.tsx | 3 +- 28 files changed, 150 insertions(+), 124 deletions(-) rename src/components/{ProductCreator.tsx => ProductCreator.ts} (97%) create mode 100644 src/components/common/Button/Button.tsx rename src/components/common/{ModalComponent => Modal}/Modal.scss (100%) rename src/components/common/{ModalComponent => Modal}/Modal.stories.tsx (100%) rename src/components/common/{ModalComponent => Modal}/Modal.tsx (87%) rename src/components/common/{ToggleThemeComponent => ToggleTheme}/ToggleTheme.stories.tsx (100%) rename src/components/common/{ToggleThemeComponent => ToggleTheme}/ToggleTheme.tsx (72%) rename src/components/market/{BasketButtonComponent => BasketButton}/BasketButon.scss (100%) rename src/components/market/{BasketButtonComponent => BasketButton}/BasketButton.stories.ts (100%) create mode 100644 src/components/market/BasketButton/BasketButton.tsx delete mode 100644 src/components/market/BasketButtonComponent/BasketButton.tsx create mode 100644 src/components/market/LazyLoad/LazyLoad.scss create mode 100644 src/components/market/ProductList/ProductList.scss create mode 100644 src/components/market/ProductList/ProductList.tsx rename src/components/market/{ProductListComponent/ProductList.stories.tsx => ProductListAddButton/ProductListAddButton.stories.tsx} (67%) create mode 100644 src/components/market/ProductListAddButton/ProductListAddButton.tsx delete mode 100644 src/components/market/ProductListComponent with LazyLoad/ProductList.tsx delete mode 100644 src/components/market/ProductListComponent/ProductList.tsx rename src/components/market/{ProductListComponent with LazyLoad/ProductList.stories.tsx => ProductListLazyLoad/ProductListLazyLoad.stories.tsx} (68%) create mode 100644 src/components/market/ProductListLazyLoad/ProductListLazyLoad.tsx diff --git a/src/components/ProductCreator.tsx b/src/components/ProductCreator.ts similarity index 97% rename from src/components/ProductCreator.tsx rename to src/components/ProductCreator.ts index e5671d543..c4b64a507 100644 --- a/src/components/ProductCreator.tsx +++ b/src/components/ProductCreator.ts @@ -2,7 +2,6 @@ import { v4 as uuidv4 } from 'uuid'; const categories : string[] = ["fruits", "vegetables", "clothes", "shoes"]; const CNT_CATEGORIES = 4; -const CNT_PRODUCTS = 12; export type Product = { id: string, diff --git a/src/components/common/Button/Button.tsx b/src/components/common/Button/Button.tsx new file mode 100644 index 000000000..b55c9d074 --- /dev/null +++ b/src/components/common/Button/Button.tsx @@ -0,0 +1,13 @@ +import React from "react" + +interface ButtonProps{ + label:string, + className?:string, + onClick?: () => void; +} + +export const Button: React.FC = ({label, ...props}:ButtonProps) => { + return ( + + ) +} \ No newline at end of file diff --git a/src/components/common/FillInputModalComponent/FillInputModal.tsx b/src/components/common/FillInputModalComponent/FillInputModal.tsx index 71e7b4a5e..8c291f8d0 100644 --- a/src/components/common/FillInputModalComponent/FillInputModal.tsx +++ b/src/components/common/FillInputModalComponent/FillInputModal.tsx @@ -1,6 +1,7 @@ import "../../../app/App.scss" import React, { useState } from "react" -import { Modal } from "../ModalComponent/Modal" +import { Modal } from "../Modal/Modal" +import { Button } from "../Button/Button"; @@ -12,7 +13,7 @@ export const FillInputModal: React.FC = ()=>{ <> {setText(e.target.value)}} value={text}> - + +
,document.body)} diff --git a/src/components/common/ToggleThemeComponent/ToggleTheme.stories.tsx b/src/components/common/ToggleTheme/ToggleTheme.stories.tsx similarity index 100% rename from src/components/common/ToggleThemeComponent/ToggleTheme.stories.tsx rename to src/components/common/ToggleTheme/ToggleTheme.stories.tsx diff --git a/src/components/common/ToggleThemeComponent/ToggleTheme.tsx b/src/components/common/ToggleTheme/ToggleTheme.tsx similarity index 72% rename from src/components/common/ToggleThemeComponent/ToggleTheme.tsx rename to src/components/common/ToggleTheme/ToggleTheme.tsx index c1b0aa874..d7be5f8fd 100644 --- a/src/components/common/ToggleThemeComponent/ToggleTheme.tsx +++ b/src/components/common/ToggleTheme/ToggleTheme.tsx @@ -2,14 +2,14 @@ import React from "react"; import {useTheme} from "../../ThemeProvider"; import "../../../app/App.scss"; import { useLanguage } from "../../LanguageProvider"; +import { Button } from "../Button/Button"; export const ToggleTheme: React.FC = () => { const {theme, toggleTheme} = useTheme(); const {t} = useLanguage(); const className = "button-"+theme; return( - <> - - +
+ :
+
+ ) +} \ No newline at end of file diff --git a/src/components/market/BasketButtonComponent/BasketButton.tsx b/src/components/market/BasketButtonComponent/BasketButton.tsx deleted file mode 100644 index bedb9311c..000000000 --- a/src/components/market/BasketButtonComponent/BasketButton.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import "./BasketButon.scss" -import "../../../app/App.scss" - -import React from "react" - -export interface BasketButtonProps { - counter: number -} - -export const BasketButton: React.FC = ({counter}) => { - if(counter===0){ - return( -
- -
- ) - } - else - return( - <> -
- - - -
- - - ) -} \ No newline at end of file diff --git a/src/components/market/LazyLoad/LazyLoad.scss b/src/components/market/LazyLoad/LazyLoad.scss new file mode 100644 index 000000000..206e44d12 --- /dev/null +++ b/src/components/market/LazyLoad/LazyLoad.scss @@ -0,0 +1,3 @@ +.intersection-div{ + height: '10px' +} \ No newline at end of file diff --git a/src/components/market/LazyLoad/LazyLoad.tsx b/src/components/market/LazyLoad/LazyLoad.tsx index bd4981c19..dbe18ee31 100644 --- a/src/components/market/LazyLoad/LazyLoad.tsx +++ b/src/components/market/LazyLoad/LazyLoad.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useRef } from "react" import { getObserver } from "./IntersectionObserver"; +import "./LazyLoad.scss" interface LazyLoadProps{ changeObject: number, @@ -19,10 +20,9 @@ export const LazyLoad: React.FC = ({changeObject, callback}) => { return () => { observer.disconnect(); }; - }, [changeObject]); + }, [changeObject, callback]); return( -
-
+
) } \ No newline at end of file diff --git a/src/components/market/OperationFullComponent/OperationFull.tsx b/src/components/market/OperationFullComponent/OperationFull.tsx index a38bf4f79..b50d610d4 100644 --- a/src/components/market/OperationFullComponent/OperationFull.tsx +++ b/src/components/market/OperationFullComponent/OperationFull.tsx @@ -1,5 +1,5 @@ import React from "react" -import { BasketButton } from "../BasketButtonComponent/BasketButton" +import { BasketButton } from "../BasketButton/BasketButton" import { Product } from "../../ProductType" import "./OperationFull.scss" diff --git a/src/components/market/ProductBasketComponent/ProductBasket.scss b/src/components/market/ProductBasketComponent/ProductBasket.scss index 4e6e8c728..d1bb5abd2 100644 --- a/src/components/market/ProductBasketComponent/ProductBasket.scss +++ b/src/components/market/ProductBasketComponent/ProductBasket.scss @@ -1,5 +1,8 @@ .productBasket-div{ width: 200px; + border: solid 0.1em black; + padding: 0.5em; + margin: 0.5em; } .delete-button-div{ padding-top: 0.5em; diff --git a/src/components/market/ProductBasketComponent/ProductBasket.tsx b/src/components/market/ProductBasketComponent/ProductBasket.tsx index a08d0b9dc..18688f77d 100644 --- a/src/components/market/ProductBasketComponent/ProductBasket.tsx +++ b/src/components/market/ProductBasketComponent/ProductBasket.tsx @@ -2,6 +2,7 @@ import React from "react" import { ProductPreview } from "../ProductPreviewComponent/ProductPreview" import { Product } from "../../ProductType" import "./ProductBasket.scss" +import { Button } from "../../common/Button/Button" export interface ProductBasketProps extends Product { counter: number @@ -20,7 +21,7 @@ export const ProductBasket: React.FC = ({name, categoryName, counter={counter} />
- +
diff --git a/src/components/market/ProductList/ProductList.scss b/src/components/market/ProductList/ProductList.scss new file mode 100644 index 000000000..0548f0cd5 --- /dev/null +++ b/src/components/market/ProductList/ProductList.scss @@ -0,0 +1,3 @@ +.product-list-ul{ + padding-left: 0; +} \ No newline at end of file diff --git a/src/components/market/ProductList/ProductList.tsx b/src/components/market/ProductList/ProductList.tsx new file mode 100644 index 000000000..493f19b5f --- /dev/null +++ b/src/components/market/ProductList/ProductList.tsx @@ -0,0 +1,21 @@ +import React from "react" +import { Product } from "../../ProductCreator" +import { ProductBasket } from "../ProductBasketComponent/ProductBasket" +import "./ProductList.scss" + +export interface ProductListProps { + products: Product[] +} + +export const ProductList: React.FC= ({products}) => { + return ( + <> +

Список товаров

+
    + {products.map((product)=>( + + ))} +
+ + ) +} \ No newline at end of file diff --git a/src/components/market/ProductListComponent/ProductList.stories.tsx b/src/components/market/ProductListAddButton/ProductListAddButton.stories.tsx similarity index 67% rename from src/components/market/ProductListComponent/ProductList.stories.tsx rename to src/components/market/ProductListAddButton/ProductListAddButton.stories.tsx index 6b407b5ba..c1d0b7149 100644 --- a/src/components/market/ProductListComponent/ProductList.stories.tsx +++ b/src/components/market/ProductListAddButton/ProductListAddButton.stories.tsx @@ -1,11 +1,11 @@ import type { Meta } from '@storybook/react'; -import { ProductList } from './ProductList'; +import { ProductListAddButton } from './ProductListAddButton'; import { Product } from "../../ProductType" import { getRandomProductList } from '../../ProductCreator'; -const meta: Meta = { - title: "market/ProductList", - component: ProductList, +const meta: Meta = { + title: "market/ProductListAddButton", + component: ProductListAddButton, argTypes:{ products:{control: 'object'} } diff --git a/src/components/market/ProductListAddButton/ProductListAddButton.tsx b/src/components/market/ProductListAddButton/ProductListAddButton.tsx new file mode 100644 index 000000000..25c305e75 --- /dev/null +++ b/src/components/market/ProductListAddButton/ProductListAddButton.tsx @@ -0,0 +1,29 @@ +import React, { useState } from "react" +import { Product } from "../../ProductCreator" +import { getRandomProduct } from "../../ProductCreator" +import { ProductList } from "../ProductList/ProductList" +import { Button } from "../../common/Button/Button" + +interface ProductProps{ + products: Product[] +} + +const withAddButton = (ProductListComponent: React.FC) => ({products}:ProductProps) => { + const [items, setItems] = useState(products); + const [nextId, setNextId] = useState(products.length); + + const addItem = ()=>{ + const newItem = getRandomProduct(); + setItems([...items,newItem]); + setNextId(nextId+1); + } + + return( + <> + + - - ) -} \ No newline at end of file diff --git a/src/components/market/ProductListComponent with LazyLoad/ProductList.stories.tsx b/src/components/market/ProductListLazyLoad/ProductListLazyLoad.stories.tsx similarity index 68% rename from src/components/market/ProductListComponent with LazyLoad/ProductList.stories.tsx rename to src/components/market/ProductListLazyLoad/ProductListLazyLoad.stories.tsx index 2a706f7b8..0d7b98d62 100644 --- a/src/components/market/ProductListComponent with LazyLoad/ProductList.stories.tsx +++ b/src/components/market/ProductListLazyLoad/ProductListLazyLoad.stories.tsx @@ -1,12 +1,12 @@ import type { Meta } from '@storybook/react'; -import { ProductList } from './ProductList'; +import { ProductListLazyLoad } from './ProductListLazyLoad'; import { Product } from "../../ProductType" import { getRandomProductList } from '../../ProductCreator'; -const meta: Meta = { - title: "market/ProductListWithLazyLoad", - component: ProductList, +const meta: Meta = { + title: "market/ProductListLazyLoad", + component: ProductListLazyLoad, argTypes:{ products:{control: 'object'} } diff --git a/src/components/market/ProductListLazyLoad/ProductListLazyLoad.tsx b/src/components/market/ProductListLazyLoad/ProductListLazyLoad.tsx new file mode 100644 index 000000000..204b95cfe --- /dev/null +++ b/src/components/market/ProductListLazyLoad/ProductListLazyLoad.tsx @@ -0,0 +1,30 @@ +import React, { useCallback, useState } from "react" +import { Product } from "../../ProductCreator" +import { getRandomProduct } from "../../ProductCreator" +import { LazyLoad } from "../LazyLoad/LazyLoad" +import { ProductList } from "../ProductList/ProductList" + +interface ProductProps{ + products: Product[] +} + +const withLazyLoad = (ProductListComponent: React.FC) => ({products}:ProductProps) => { + const [items, setItems] = useState(products); + const [nextId, setNextId] = useState(products.length); + + const addItem = useCallback(()=>{ + const newItem = getRandomProduct(); + setItems([...items,newItem]); + setNextId(nextId+1); + },[items, nextId]) + + return( + <> + + + + ) +} + + +export const ProductListLazyLoad = withLazyLoad(ProductList) diff --git a/src/components/market/ProductPreviewComponent/ProductPreview.tsx b/src/components/market/ProductPreviewComponent/ProductPreview.tsx index 7583b5585..648271d84 100644 --- a/src/components/market/ProductPreviewComponent/ProductPreview.tsx +++ b/src/components/market/ProductPreviewComponent/ProductPreview.tsx @@ -1,5 +1,5 @@ import React from "react" -import { BasketButton } from "../BasketButtonComponent/BasketButton" +import { BasketButton } from "../BasketButton/BasketButton" import { Product } from "../../ProductType" import "./ProductPreview.scss" diff --git a/src/components/operations/TransactionFullComponent/TransactionFull.tsx b/src/components/operations/TransactionFullComponent/TransactionFull.tsx index 847ef78f9..8b2737cd3 100644 --- a/src/components/operations/TransactionFullComponent/TransactionFull.tsx +++ b/src/components/operations/TransactionFullComponent/TransactionFull.tsx @@ -1,5 +1,6 @@ import React from "react" import "./TransactionFull.scss" +import { Button } from "../../common/Button/Button" export interface TransactionFullProps { title: string, @@ -19,7 +20,7 @@ export const TransactionFull: React.FC=({amount,category,d

Категория: {category}

{description}

- +
From 1730ee4988e037dc9f31a36b26f3ceedab159060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Tue, 5 Aug 2025 11:19:51 +0300 Subject: [PATCH 21/38] fix: ProductListAddButton --- .../ProductListAddButton.tsx | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/components/market/ProductListAddButton/ProductListAddButton.tsx b/src/components/market/ProductListAddButton/ProductListAddButton.tsx index 25c305e75..390cdccfb 100644 --- a/src/components/market/ProductListAddButton/ProductListAddButton.tsx +++ b/src/components/market/ProductListAddButton/ProductListAddButton.tsx @@ -8,22 +8,23 @@ interface ProductProps{ products: Product[] } -const withAddButton = (ProductListComponent: React.FC) => ({products}:ProductProps) => { - const [items, setItems] = useState(products); - const [nextId, setNextId] = useState(products.length); +function withAddButton (ProductListComponent: React.FC) { + ({products}:ProductProps) => { + const [items, setItems] = useState(products); + const [nextId, setNextId] = useState(products.length); - const addItem = ()=>{ - const newItem = getRandomProduct(); - setItems([...items,newItem]); - setNextId(nextId+1); - } + const addItem = ()=>{ + const newItem = getRandomProduct(); + setItems([...items,newItem]); + setNextId(nextId+1); + } - return( - <> - -
+ ) + } return ( - counter===0?
-
- :
-
+
+
) -} \ No newline at end of file +}) \ No newline at end of file diff --git a/src/components/market/ProductList/ProductList.tsx b/src/components/market/ProductList/ProductList.tsx index 493f19b5f..c4c1f155a 100644 --- a/src/components/market/ProductList/ProductList.tsx +++ b/src/components/market/ProductList/ProductList.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { memo, useMemo } from "react" import { Product } from "../../ProductCreator" import { ProductBasket } from "../ProductBasketComponent/ProductBasket" import "./ProductList.scss" @@ -7,15 +7,16 @@ export interface ProductListProps { products: Product[] } -export const ProductList: React.FC= ({products}) => { +export const ProductList: React.FC= memo(({products}) => { + const productItems = useMemo(() => products.map((product)=>( + + )),[products]) return ( <>

Список товаров

    - {products.map((product)=>( - - ))} + {productItems}
) -} \ No newline at end of file +}) \ No newline at end of file diff --git a/src/components/market/ProductListLazyLoad/ProductListLazyLoad.tsx b/src/components/market/ProductListLazyLoad/ProductListLazyLoad.tsx index c85a31553..9657dabc8 100644 --- a/src/components/market/ProductListLazyLoad/ProductListLazyLoad.tsx +++ b/src/components/market/ProductListLazyLoad/ProductListLazyLoad.tsx @@ -9,15 +9,15 @@ interface ProductProps{ } function withLazyLoad(ProductListComponent: React.FC){ - return function LazyLoadComponent({products}:ProductProps) { + return function LazyLoadComponent({products}:ProductProps) { const [items, setItems] = useState(products); const [nextId, setNextId] = useState(products.length); - const addItem = useCallback(()=>{ + const addItem = ()=>{ const newItem = getRandomProduct(); setItems([...items,newItem]); setNextId(nextId+1); - },[items, nextId]) + } return( <> From ed98d000aefc5a2c912e05a0a4e17559c4f74d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Wed, 6 Aug 2025 12:42:18 +0300 Subject: [PATCH 25/38] fix: add displayName for tests and linter --- src/components/market/BasketButton/BasketButton.tsx | 7 +++++-- src/components/market/ProductList/ProductList.tsx | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/market/BasketButton/BasketButton.tsx b/src/components/market/BasketButton/BasketButton.tsx index 6593bfa9f..95160a4d6 100644 --- a/src/components/market/BasketButton/BasketButton.tsx +++ b/src/components/market/BasketButton/BasketButton.tsx @@ -7,13 +7,14 @@ export interface BasketButtonProps { counter: number } -export const BasketButton: React.FC = memo(({counter}) => { +export const BasketButton: React.FC = ({counter}) => { if (counter===0) { return (
) + } return (
@@ -22,4 +23,6 @@ export const BasketButton: React.FC = memo(({counter}) => {
) -}) \ No newline at end of file +} + +export default memo(BasketButton); \ No newline at end of file diff --git a/src/components/market/ProductList/ProductList.tsx b/src/components/market/ProductList/ProductList.tsx index c4c1f155a..50e2bfd8a 100644 --- a/src/components/market/ProductList/ProductList.tsx +++ b/src/components/market/ProductList/ProductList.tsx @@ -7,7 +7,7 @@ export interface ProductListProps { products: Product[] } -export const ProductList: React.FC= memo(({products}) => { +export const ProductList: React.FC= ({products}) => { const productItems = useMemo(() => products.map((product)=>( )),[products]) @@ -19,4 +19,6 @@ export const ProductList: React.FC= memo(({products}) => { ) -}) \ No newline at end of file +} + +export default memo(ProductList) \ No newline at end of file From 2115a2ac8b739fe8ff084e99837cbe68bed2b181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BA=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=BD=D0=B0?= Date: Fri, 8 Aug 2025 12:22:04 +0300 Subject: [PATCH 26/38] add: complex components --- src/app/App.scss | 1 + src/components/ProductCreator.ts | 2 +- .../market/BasketButton/BasketButon.scss | 14 ++- .../market/BasketButton/BasketButton.tsx | 4 +- .../ComponentInfo/ComponentInfo.module.sass | 21 ++++ .../market/ComponentInfo/ComponentInfo.tsx | 21 ++++ src/components/market/ComponentInfo/index.ts | 1 + .../CroppedText/CroppedText.module.sass | 2 + .../CroppedText/CroppedText.stories.tsx | 32 ++++++ .../market/CroppedText/CroppedText.tsx | 104 ++++++++++++++++++ src/components/market/CroppedText/index.ts | 1 + .../ProductBasketComponent/ProductBasket.scss | 6 +- .../ProductBasketComponent/ProductBasket.tsx | 2 +- .../market/ProductList/ProductList.scss | 3 + .../market/ProductList/ProductList.tsx | 4 +- .../ProductListAddButton.scss | 23 ++++ .../ProductListAddButton.tsx | 25 ++++- .../ProductListLazyLoad.tsx | 6 +- .../market/ProductPreview/ProductPreview.scss | 3 + .../ProductPreview.stories.ts | 2 +- .../ProductPreview.tsx | 4 +- .../ProductPreview.scss | 3 - .../SliderRange/SliderRange.module.sass | 22 ++++ .../SliderRange/SliderRange.stories.tsx | 33 ++++++ .../market/SliderRange/SliderRange.tsx | 66 +++++++++++ .../SliderRange/SliderRangeInput.module.sass | 0 .../market/SliderRange/SliderRangeInput.tsx | 23 ++++ src/components/market/SliderRange/helpers.ts | 24 ++++ src/components/market/SliderRange/index.ts | 1 + src/hooks/useEvent.ts | 15 +++ 30 files changed, 444 insertions(+), 24 deletions(-) create mode 100644 src/components/market/ComponentInfo/ComponentInfo.module.sass create mode 100644 src/components/market/ComponentInfo/ComponentInfo.tsx create mode 100644 src/components/market/ComponentInfo/index.ts create mode 100644 src/components/market/CroppedText/CroppedText.module.sass create mode 100644 src/components/market/CroppedText/CroppedText.stories.tsx create mode 100644 src/components/market/CroppedText/CroppedText.tsx create mode 100644 src/components/market/CroppedText/index.ts create mode 100644 src/components/market/ProductListAddButton/ProductListAddButton.scss create mode 100644 src/components/market/ProductPreview/ProductPreview.scss rename src/components/market/{ProductPreviewComponent => ProductPreview}/ProductPreview.stories.ts (89%) rename src/components/market/{ProductPreviewComponent => ProductPreview}/ProductPreview.tsx (79%) delete mode 100644 src/components/market/ProductPreviewComponent/ProductPreview.scss create mode 100644 src/components/market/SliderRange/SliderRange.module.sass create mode 100644 src/components/market/SliderRange/SliderRange.stories.tsx create mode 100644 src/components/market/SliderRange/SliderRange.tsx create mode 100644 src/components/market/SliderRange/SliderRangeInput.module.sass create mode 100644 src/components/market/SliderRange/SliderRangeInput.tsx create mode 100644 src/components/market/SliderRange/helpers.ts create mode 100644 src/components/market/SliderRange/index.ts create mode 100644 src/hooks/useEvent.ts diff --git a/src/app/App.scss b/src/app/App.scss index dd6340284..b29098946 100644 --- a/src/app/App.scss +++ b/src/app/App.scss @@ -4,6 +4,7 @@ button{ font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-weight: 700; border: 0.01em solid black; + border-radius: 4px; cursor: pointer; display: inline-block; line-height: 1; diff --git a/src/components/ProductCreator.ts b/src/components/ProductCreator.ts index c4b64a507..e27654210 100644 --- a/src/components/ProductCreator.ts +++ b/src/components/ProductCreator.ts @@ -26,7 +26,7 @@ export const getRandomProduct = (): Product => { return { id: uuidv4(), name: `SomeProduct${getRandomInt(1,100)}`, - description: "descr", + description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid at, dolore earum enim est eveniet facilis illo impedit in, itaque maxime necessitatibus nesciunt nihil non officiis placeat provident quasi reiciendis.", price: getRandomInt(10,5000), categoryName: getRandomCategory() } diff --git a/src/components/market/BasketButton/BasketButon.scss b/src/components/market/BasketButton/BasketButon.scss index 227bc0172..c6990c41d 100644 --- a/src/components/market/BasketButton/BasketButon.scss +++ b/src/components/market/BasketButton/BasketButon.scss @@ -3,8 +3,17 @@ justify-content: flex-end; padding-right: 0.75em; } -.basket-button{ - border-radius: 0.5em; +.basket-buttons{ + display: flex; +} +.basket-button-left{ + border-bottom-right-radius: 0; + border-top-right-radius: 0; + padding: 8px 14px; +} +.basket-button-right{ + border-bottom-left-radius: 0; + border-top-left-radius: 0; padding: 8px 14px; } .basket-input{ @@ -19,6 +28,5 @@ background-color: #fff; background-clip: padding-box; border: 1px solid #bdbdbd; - border-radius: 0.25rem; padding-bottom: 2px; } \ No newline at end of file diff --git a/src/components/market/BasketButton/BasketButton.tsx b/src/components/market/BasketButton/BasketButton.tsx index 95160a4d6..d59499f7b 100644 --- a/src/components/market/BasketButton/BasketButton.tsx +++ b/src/components/market/BasketButton/BasketButton.tsx @@ -18,9 +18,9 @@ export const BasketButton: React.FC = ({counter}) => { } return (
-
) } diff --git a/src/components/market/ComponentInfo/ComponentInfo.module.sass b/src/components/market/ComponentInfo/ComponentInfo.module.sass new file mode 100644 index 000000000..35c0113fc --- /dev/null +++ b/src/components/market/ComponentInfo/ComponentInfo.module.sass @@ -0,0 +1,21 @@ +.root + font-family: Montserrat, sans-serif + +.title + font-size: 28px + font-weight: 600 + margin-bottom: 16px + +.main + display: inline-block + margin-top: 16px + border-radius: 8px + padding: 16px + border: 1px solid #f0f0f0 + box-shadow: 1px 3px 20px 0 rgba(110, 110, 110, 0.3) + + &:empty + display: none + + &.fullWidth + display: block \ No newline at end of file diff --git a/src/components/market/ComponentInfo/ComponentInfo.tsx b/src/components/market/ComponentInfo/ComponentInfo.tsx new file mode 100644 index 000000000..6cd3b2581 --- /dev/null +++ b/src/components/market/ComponentInfo/ComponentInfo.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import cn from 'clsx'; +import s from './ComponentInfo.module.sass'; + +export type ComponentInfoProps = React.HTMLAttributes & { + className?: string; + title?: React.ReactNode; + desc?: React.ReactNode; + children?: React.ReactNode; + fullWidth?: boolean; +}; + +export const ComponentInfo = ({ className, desc, fullWidth, title, children, ...props }: ComponentInfoProps) => { + return ( +
+
{title}
+
{desc}
+
{children}
+
+ ); +}; diff --git a/src/components/market/ComponentInfo/index.ts b/src/components/market/ComponentInfo/index.ts new file mode 100644 index 000000000..96e53bb81 --- /dev/null +++ b/src/components/market/ComponentInfo/index.ts @@ -0,0 +1 @@ +export * from './ComponentInfo'; diff --git a/src/components/market/CroppedText/CroppedText.module.sass b/src/components/market/CroppedText/CroppedText.module.sass new file mode 100644 index 000000000..9ae7afc08 --- /dev/null +++ b/src/components/market/CroppedText/CroppedText.module.sass @@ -0,0 +1,2 @@ +.root + \ No newline at end of file diff --git a/src/components/market/CroppedText/CroppedText.stories.tsx b/src/components/market/CroppedText/CroppedText.stories.tsx new file mode 100644 index 000000000..2614d715f --- /dev/null +++ b/src/components/market/CroppedText/CroppedText.stories.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { CroppedText, CroppedTextProps } from './CroppedText'; +import { ComponentInfo } from '../ComponentInfo'; + +const Wrapper = (props: CroppedTextProps) => ( + + + +); + +const meta: Meta = { + title: 'complexComponents/CroppedText', + component: Wrapper, + argTypes: { + rows: { control: { type: 'number', min: 0 } }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default = { + args: { + opened: false, + rows: 1, + children: `Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid at, dolore earum enim est eveniet facilis illo impedit in, itaque maxime necessitatibus nesciunt nihil non officiis placeat provident quasi reiciendis.`, + }, +}; diff --git a/src/components/market/CroppedText/CroppedText.tsx b/src/components/market/CroppedText/CroppedText.tsx new file mode 100644 index 000000000..5726d42dd --- /dev/null +++ b/src/components/market/CroppedText/CroppedText.tsx @@ -0,0 +1,104 @@ +import React, { FC, useLayoutEffect, useRef, useState } from 'react'; +import cn from 'clsx'; +import { useEvent } from '../../../hooks/useEvent' +import s from './CroppedText.module.sass'; + +export type CroppedTextProps = { + className?: string; + children: string; + opened: boolean; + rows?: number; +}; + +const INITIAL_VALUE = 'I'; + +export const CroppedText: FC = ({ className, children, opened, rows = 3 }) => { + const [text, setText] = useState(INITIAL_VALUE); + + const min = useRef(0); + const max = useRef(0); + const mid = useRef(0); + const root = useRef(); + const texts = useRef([]); + const items = useRef(); + const height = useRef(); + const lineHeight = useRef(); + + const reset = useEvent(() => { + height.current = Math.round(lineHeight.current * rows); + texts.current = []; + min.current = mid.current = 0; + max.current = items.current.length - 1; + }); + + useLayoutEffect(() => { + lineHeight.current = lineHeight.current ?? root.current.getBoundingClientRect()?.height; + items.current = children?.split(' ') || []; + reset(); + }, [reset, children]); + + useLayoutEffect(() => { + let timeout: number; + let prevWidth: number = root.current?.getBoundingClientRect()?.width; + const fn = () => { + cancelAnimationFrame(timeout); + timeout = window.requestAnimationFrame(() => { + setText(INITIAL_VALUE); + reset(); + }); + }; + + fn(); + + const observer = new ResizeObserver((entries) => { + for (const entry of entries) { + if (prevWidth !== entry.contentRect.width) { + prevWidth = entry.contentRect.width; + fn(); + } + } + }); + + observer.observe(root.current); + + return () => observer.disconnect(); + }, [reset, rows]); + + useLayoutEffect(() => { + const checkoutTexts = (callback: () => void) => { + if (texts.current.length < 3) { + texts.current.push(text); + callback(); + return; + } + texts.current.splice(0, 1); + texts.current.push(text); + if (texts.current[0] === texts.current[2]) { + reset(); + return; + } + callback(); + }; + const getNewText = (count: number): string => { + if (count >= items.current.length - 1) return items.current.join(' '); + if (count <= 0) return ''; + return [items.current.slice(0, count).join(' '), '...'].join(''); + }; + + checkoutTexts(() => { + if (root.current.getBoundingClientRect().height <= height.current) { + min.current = mid.current; + } else { + max.current = mid.current - 1; + } + mid.current = Math.round((min.current + max.current) / 2); + setText(getNewText(mid.current)); + }); + }, [reset, text, children]); + + return ( +
+ {opened ? children : text} +
+ ); +}; diff --git a/src/components/market/CroppedText/index.ts b/src/components/market/CroppedText/index.ts new file mode 100644 index 000000000..bfc2e7066 --- /dev/null +++ b/src/components/market/CroppedText/index.ts @@ -0,0 +1 @@ +export * from './CroppedText'; diff --git a/src/components/market/ProductBasketComponent/ProductBasket.scss b/src/components/market/ProductBasketComponent/ProductBasket.scss index d1bb5abd2..45b1d209e 100644 --- a/src/components/market/ProductBasketComponent/ProductBasket.scss +++ b/src/components/market/ProductBasketComponent/ProductBasket.scss @@ -1,8 +1,10 @@ .productBasket-div{ width: 200px; - border: solid 0.1em black; - padding: 0.5em; + padding: 16px; margin: 0.5em; + border-radius: 8px; + border: 1px solid #f0f0f0; + box-shadow: 1px 3px 20px 0 rgba(110, 110, 110, 0.3); } .delete-button-div{ padding-top: 0.5em; diff --git a/src/components/market/ProductBasketComponent/ProductBasket.tsx b/src/components/market/ProductBasketComponent/ProductBasket.tsx index 18688f77d..56f3210c9 100644 --- a/src/components/market/ProductBasketComponent/ProductBasket.tsx +++ b/src/components/market/ProductBasketComponent/ProductBasket.tsx @@ -1,5 +1,5 @@ import React from "react" -import { ProductPreview } from "../ProductPreviewComponent/ProductPreview" +import { ProductPreview } from "../ProductPreview/ProductPreview" import { Product } from "../../ProductType" import "./ProductBasket.scss" import { Button } from "../../common/Button/Button" diff --git a/src/components/market/ProductList/ProductList.scss b/src/components/market/ProductList/ProductList.scss index 0548f0cd5..348286f28 100644 --- a/src/components/market/ProductList/ProductList.scss +++ b/src/components/market/ProductList/ProductList.scss @@ -1,3 +1,6 @@ .product-list-ul{ padding-left: 0; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; } \ No newline at end of file diff --git a/src/components/market/ProductList/ProductList.tsx b/src/components/market/ProductList/ProductList.tsx index 50e2bfd8a..a9dedcf78 100644 --- a/src/components/market/ProductList/ProductList.tsx +++ b/src/components/market/ProductList/ProductList.tsx @@ -12,12 +12,12 @@ export const ProductList: React.FC= ({products}) => { )),[products]) return ( - <> +

Список товаров

    {productItems}
- +
) } diff --git a/src/components/market/ProductListAddButton/ProductListAddButton.scss b/src/components/market/ProductListAddButton/ProductListAddButton.scss new file mode 100644 index 000000000..aa182b2f0 --- /dev/null +++ b/src/components/market/ProductListAddButton/ProductListAddButton.scss @@ -0,0 +1,23 @@ +.add-div{ + display:flex; + justify-content: space-between; +} +.add-div-button{ + top:0; + position:sticky; + padding-top: 10px; + height: 12px; + display: grid; +} +.range-div{ + display: flex; + justify-content: space-between; +} + +.range-slider{ + position: sticky; + top: 0; + height: 100px; + width: 200px; + padding-top: 12px; +} \ No newline at end of file diff --git a/src/components/market/ProductListAddButton/ProductListAddButton.tsx b/src/components/market/ProductListAddButton/ProductListAddButton.tsx index 4755934b1..f86a62d09 100644 --- a/src/components/market/ProductListAddButton/ProductListAddButton.tsx +++ b/src/components/market/ProductListAddButton/ProductListAddButton.tsx @@ -3,6 +3,8 @@ import { Product } from "../../ProductCreator" import { getRandomProduct } from "../../ProductCreator" import { ProductList } from "../ProductList/ProductList" import { Button } from "../../common/Button/Button" +import "./ProductListAddButton.scss" +import { SliderRange } from "../SliderRange" interface ProductProps{ products: Product[] @@ -10,19 +12,34 @@ interface ProductProps{ function withAddButton (ProductListComponent: React.FC) { return function AddButtonComponent({products}:ProductProps) { + const [value, onChange] = useState(5000); const [items, setItems] = useState(products); - const [nextId, setNextId] = useState(products.length); - + + const handleValueChange = (value:number) => { + onChange(value); + }; + + const [nextId, setNextId] = useState(products.length); + const filteredItems=items.filter((product: Product) => { + return product.price <= value; + }); + const addItem = ()=>{ const newItem = getRandomProduct(); setItems([...items,newItem]); setNextId(nextId+1); + onChange(5000); } return( <> - -