diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml index 11cf6e06..33414486 100644 --- a/.github/workflows/version-bump.yml +++ b/.github/workflows/version-bump.yml @@ -58,23 +58,30 @@ jobs: MINOR="${VERSION_PARTS[1]}" PATCH="${VERSION_PARTS[2]}" - # Bump version based on type - case "${{ github.event.inputs.bump_type }}" in - major) - MAJOR=$((MAJOR + 1)) - MINOR=0 - PATCH=0 - ;; - minor) - MINOR=$((MINOR + 1)) - PATCH=0 - ;; - patch) - PATCH=$((PATCH + 1)) - ;; - esac - - NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" + # If requesting a pre-release and current is already a pre-release, keep base version + # Otherwise, bump the version based on type + if [ -n "${{ github.event.inputs.pre_release }}" ] && [ "$IS_PRERELEASE" = "true" ]; then + # Keep existing base version for iterative betas (7.6.0-beta.1 -> 7.6.0-beta.2) + NEW_VERSION="$BASE_VERSION" + else + # Bump version based on type + case "${{ github.event.inputs.bump_type }}" in + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + patch) + PATCH=$((PATCH + 1)) + ;; + esac + + NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" + fi # Add pre-release label if specified if [ -n "${{ github.event.inputs.pre_release }}" ]; then diff --git a/bun.lock b/bun.lock index 3219a5f8..c029e655 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,5 @@ { "lockfileVersion": 1, - "configVersion": 0, "workspaces": { "": { "name": "mue", @@ -9,46 +8,40 @@ "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@eartharoid/i18n": "1.2.1", - "@emotion/react": "^11.14.0", - "@emotion/styled": "^11.14.1", "@floating-ui/react-dom": "2.1.6", "@fontsource/lexend-deca": "5.0.14", "@fontsource/montserrat": "5.0.19", - "@mui/material": "7.3.7", - "@sentry/react": "^10.22.0", - "embla-carousel-autoplay": "8.6.0", - "embla-carousel-react": "8.6.0", + "@sentry/react": "^10.36.0", "fast-blurhash": "^1.1.4", "image-conversion": "^2.1.1", - "mue": "file:", - "react": "^19", + "react": "^19.2.3", "react-best-gradient-color-picker": "^3.0.14", "react-clock": "6.0.0", - "react-dom": "^19", + "react-dom": "^19.2.3", "react-icons": "^5.5.0", "react-modal": "3.16.3", "react-toastify": "11.0.5", - "use-debounce": "^10.0.6", + "use-debounce": "^10.1.0", }, "devDependencies": { - "@commitlint/cli": "^20.1.0", - "@commitlint/config-conventional": "^20.0.0", + "@commitlint/cli": "^20.3.1", + "@commitlint/config-conventional": "^20.3.1", "@eartharoid/deep-merge": "^0.0.2", - "@eslint/js": "^9", - "@vitejs/plugin-react-swc": "^4", + "@eslint/js": "^9.39.2", + "@vitejs/plugin-react-swc": "^4.2.2", "adm-zip": "0.5.16", - "eslint": "^9", + "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-jsx-a11y": "^6", - "eslint-plugin-react": "^7", - "eslint-plugin-react-hooks": "^7", + "eslint-plugin-jsx-a11y": "^6.10.2", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.0.1", "husky": "^9.1.7", - "prettier": "^3.6.2", - "sass": "^1.93.2", + "prettier": "^3.8.1", + "sass": "^1.97.3", "stylelint": "^17.0.0", "stylelint-config-standard-scss": "^17.0.0", "stylelint-scss": "^7.0.0", - "vite": "^7", + "vite": "^7.3.1", "vite-plugin-progress": "^0.0.7", }, }, @@ -66,7 +59,7 @@ "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], - "@babel/helper-module-imports": ["@babel/helper-module-imports@7.25.7", "", { "dependencies": { "@babel/traverse": "7.25.7", "@babel/types": "7.25.8" } }, "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw=="], + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="], @@ -82,8 +75,6 @@ "@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="], - "@babel/runtime": ["@babel/runtime@7.26.0", "", { "dependencies": { "regenerator-runtime": "0.14.1" } }, "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw=="], - "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], "@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], @@ -152,32 +143,6 @@ "@eartharoid/i18n": ["@eartharoid/i18n@1.2.1", "", {}, "sha512-nMQdHrGgpw+vNL5DbivELW2K3KAUGaMvTjjmFsEPf8mUW8+LAgRjvfFn2gkJq1mnlD6HoqUaHqEL4YpWr2T5MA=="], - "@emotion/babel-plugin": ["@emotion/babel-plugin@11.13.5", "", { "dependencies": { "@babel/helper-module-imports": "7.25.7", "@babel/runtime": "7.26.0", "@emotion/hash": "0.9.2", "@emotion/memoize": "0.9.0", "@emotion/serialize": "1.3.3", "babel-plugin-macros": "3.1.0", "convert-source-map": "1.9.0", "escape-string-regexp": "4.0.0", "find-root": "1.1.0", "source-map": "0.5.7", "stylis": "4.2.0" } }, "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ=="], - - "@emotion/cache": ["@emotion/cache@11.14.0", "", { "dependencies": { "@emotion/memoize": "0.9.0", "@emotion/sheet": "1.4.0", "@emotion/utils": "1.4.2", "@emotion/weak-memoize": "0.4.0", "stylis": "4.2.0" } }, "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA=="], - - "@emotion/hash": ["@emotion/hash@0.9.2", "", {}, "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g=="], - - "@emotion/is-prop-valid": ["@emotion/is-prop-valid@1.3.1", "", { "dependencies": { "@emotion/memoize": "0.9.0" } }, "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw=="], - - "@emotion/memoize": ["@emotion/memoize@0.9.0", "", {}, "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="], - - "@emotion/react": ["@emotion/react@11.14.0", "", { "dependencies": { "@babel/runtime": "7.26.0", "@emotion/babel-plugin": "11.13.5", "@emotion/cache": "11.14.0", "@emotion/serialize": "1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "1.2.0", "@emotion/utils": "1.4.2", "@emotion/weak-memoize": "0.4.0", "hoist-non-react-statics": "3.3.2" }, "optionalDependencies": { "@types/react": "18.3.11" }, "peerDependencies": { "react": "18.3.1" } }, "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA=="], - - "@emotion/serialize": ["@emotion/serialize@1.3.3", "", { "dependencies": { "@emotion/hash": "0.9.2", "@emotion/memoize": "0.9.0", "@emotion/unitless": "0.10.0", "@emotion/utils": "1.4.2", "csstype": "3.1.3" } }, "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA=="], - - "@emotion/sheet": ["@emotion/sheet@1.4.0", "", {}, "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg=="], - - "@emotion/styled": ["@emotion/styled@11.14.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", "@emotion/is-prop-valid": "^1.3.0", "@emotion/serialize": "^1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", "@emotion/utils": "^1.4.2" }, "peerDependencies": { "@emotion/react": "^11.0.0-rc.0", "react": ">=16.8.0" } }, "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw=="], - - "@emotion/unitless": ["@emotion/unitless@0.10.0", "", {}, "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg=="], - - "@emotion/use-insertion-effect-with-fallbacks": ["@emotion/use-insertion-effect-with-fallbacks@1.2.0", "", { "peerDependencies": { "react": "18.3.1" } }, "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg=="], - - "@emotion/utils": ["@emotion/utils@1.4.2", "", {}, "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA=="], - - "@emotion/weak-memoize": ["@emotion/weak-memoize@0.4.0", "", {}, "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="], @@ -274,8 +239,6 @@ "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], - "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="], - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], @@ -284,20 +247,6 @@ "@keyv/serialize": ["@keyv/serialize@1.1.1", "", {}, "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA=="], - "@mui/core-downloads-tracker": ["@mui/core-downloads-tracker@7.3.7", "", {}, "sha512-8jWwS6FweMkpyRkrJooamUGe1CQfO1yJ+lM43IyUJbrhHW/ObES+6ry4vfGi8EKaldHL3t3BG1bcLcERuJPcjg=="], - - "@mui/material": ["@mui/material@7.3.7", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/core-downloads-tracker": "^7.3.7", "@mui/system": "^7.3.7", "@mui/types": "^7.4.10", "@mui/utils": "^7.3.7", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "csstype": "^3.2.3", "prop-types": "^15.8.1", "react-is": "^19.2.3", "react-transition-group": "^4.4.5" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", "@mui/material-pigment-css": "^7.3.7", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/react", "@emotion/styled", "@mui/material-pigment-css", "@types/react"] }, "sha512-6bdIxqzeOtBAj2wAsfhWCYyMKPLkRO9u/2o5yexcL0C3APqyy91iGSWgT3H7hg+zR2XgE61+WAu12wXPON8b6A=="], - - "@mui/private-theming": ["@mui/private-theming@7.3.7", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/utils": "^7.3.7", "prop-types": "^15.8.1" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-w7r1+CYhG0syCAQUWAuV5zSaU2/67WA9JXUderdb7DzCIJdp/5RmJv6L85wRjgKCMsxFF0Kfn0kPgPbPgw/jdw=="], - - "@mui/styled-engine": ["@mui/styled-engine@7.3.7", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", "csstype": "^3.2.3", "prop-types": "^15.8.1" }, "peerDependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/react", "@emotion/styled"] }, "sha512-y/QkNXv6cF6dZ5APztd/dFWfQ6LHKPx3skyYO38YhQD4+Cxd6sFAL3Z38WMSSC8LQz145Mpp3CcLrSCLKPwYAg=="], - - "@mui/system": ["@mui/system@7.3.7", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/private-theming": "^7.3.7", "@mui/styled-engine": "^7.3.7", "@mui/types": "^7.4.10", "@mui/utils": "^7.3.7", "clsx": "^2.1.1", "csstype": "^3.2.3", "prop-types": "^15.8.1" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/react", "@emotion/styled", "@types/react"] }, "sha512-DovL3k+FBRKnhmatzUMyO5bKkhMLlQ9L7Qw5qHrre3m8zCZmE+31NDVBFfqrbrA7sq681qaEIHdkWD5nmiAjyQ=="], - - "@mui/types": ["@mui/types@7.4.10", "", { "dependencies": { "@babel/runtime": "^7.28.4" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-0+4mSjknSu218GW3isRqoxKRTOrTLd/vHi/7UC4+wZcUrOAqD9kRk7UQRL1mcrzqRoe7s3UT6rsRpbLkW5mHpQ=="], - - "@mui/utils": ["@mui/utils@7.3.7", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@mui/types": "^7.4.10", "@types/prop-types": "^15.7.15", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^19.2.3" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-+YjnjMRnyeTkWnspzoxRdiSOgkrcpTikhNPoxOZW0APXx+urHtUoXJ9lbtCZRCA5a4dg5gSbd19alL1DvRs5fg=="], - "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "1.2.0" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], @@ -332,8 +281,6 @@ "@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="], - "@popperjs/core": ["@popperjs/core@2.11.8", "", {}, "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="], - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.47", "", {}, "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.5", "", { "os": "android", "cpu": "arm" }, "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ=="], @@ -430,14 +377,10 @@ "@types/node": ["@types/node@10.17.60", "", {}, "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="], - "@types/parse-json": ["@types/parse-json@4.0.2", "", {}, "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="], - "@types/prop-types": ["@types/prop-types@15.7.14", "", {}, "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ=="], "@types/react": ["@types/react@18.3.11", "", { "dependencies": { "@types/prop-types": "15.7.14", "csstype": "3.1.3" } }, "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ=="], - "@types/react-transition-group": ["@types/react-transition-group@4.4.12", "", { "peerDependencies": { "@types/react": "18.3.11" } }, "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w=="], - "@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@4.2.2", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-beta.47", "@swc/core": "^1.13.5" }, "peerDependencies": { "vite": "^4 || ^5 || ^6 || ^7" } }, "sha512-x+rE6tsxq/gxrEJN3Nv3dIV60lFflPj94c90b+NNo6n1QV1QQUTLoL0MpaOVasUZ0zqVBn7ead1B5ecx1JAGfA=="], "@wojtekmaj/date-utils": ["@wojtekmaj/date-utils@2.0.2", "", {}, "sha512-Do66mSlSNifFFuo3l9gNKfRMSFi26CRuQMsDJuuKO/ekrDWuTTtE4ZQxoFCUOG+NgxnpSeBq/k5TY8ZseEzLpA=="], @@ -486,8 +429,6 @@ "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], - "babel-plugin-macros": ["babel-plugin-macros@3.1.0", "", { "dependencies": { "@babel/runtime": "7.27.0", "cosmiconfig": "7.1.0", "resolve": "1.22.8" } }, "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg=="], - "balanced-match": ["balanced-match@3.0.1", "", {}, "sha512-vjtV3hiLqYDNRoiAv0zC4QaGAMPomEoq83PRmYIofPswwZurCeWR5LByXm7SyoL0Zh5+2z0+HC7jG8gSZJUh0w=="], "base64-arraybuffer": ["base64-arraybuffer@1.0.2", "", {}, "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="], @@ -552,7 +493,7 @@ "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], - "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], "damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="], @@ -576,22 +517,12 @@ "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "2.0.3" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], - "dom-helpers": ["dom-helpers@5.2.1", "", { "dependencies": { "@babel/runtime": "7.27.0", "csstype": "3.1.3" } }, "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA=="], - "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "electron-to-chromium": ["electron-to-chromium@1.5.244", "", {}, "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw=="], - "embla-carousel": ["embla-carousel@8.6.0", "", {}, "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="], - - "embla-carousel-autoplay": ["embla-carousel-autoplay@8.6.0", "", { "peerDependencies": { "embla-carousel": "8.6.0" } }, "sha512-OBu5G3nwaSXkZCo1A6LTaFMZ8EpkYbwIaH+bPqdBnDGQ2fh4+NbzjXjs2SktoPNKCtflfVMc75njaDHOYXcrsA=="], - - "embla-carousel-react": ["embla-carousel-react@8.6.0", "", { "dependencies": { "embla-carousel": "8.6.0", "embla-carousel-reactive-utils": "8.6.0" }, "peerDependencies": { "react": "18.3.1" } }, "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA=="], - - "embla-carousel-reactive-utils": ["embla-carousel-reactive-utils@8.6.0", "", { "peerDependencies": { "embla-carousel": "8.6.0" } }, "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A=="], - "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], @@ -668,8 +599,6 @@ "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - "find-root": ["find-root@1.1.0", "", {}, "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="], - "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "6.0.0", "path-exists": "4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], @@ -740,8 +669,6 @@ "hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="], - "hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "16.13.1" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="], - "hookified": ["hookified@1.15.0", "", {}, "sha512-51w+ZZGt7Zw5q7rM3nC4t3aLn/xvKDETsXqMczndvwyVQhAHfUmUuFBRFcos8Iyebtk7OAE9dL26wFNzZVVOkw=="], "html-tags": ["html-tags@5.1.0", "", {}, "sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ=="], @@ -920,8 +847,6 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "mue": ["mue@root:", {}], - "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], @@ -964,8 +889,6 @@ "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], - "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], @@ -1012,7 +935,7 @@ "react-icons": ["react-icons@5.5.0", "", { "peerDependencies": { "react": "*" } }, "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw=="], - "react-is": ["react-is@19.2.3", "", {}, "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA=="], + "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], "react-lifecycles-compat": ["react-lifecycles-compat@3.0.4", "", {}, "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="], @@ -1020,14 +943,10 @@ "react-toastify": ["react-toastify@11.0.5", "", { "dependencies": { "clsx": "2.1.1" }, "peerDependencies": { "react": "18.3.1", "react-dom": "18.3.1" } }, "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA=="], - "react-transition-group": ["react-transition-group@4.4.5", "", { "dependencies": { "@babel/runtime": "7.27.0", "dom-helpers": "5.2.1", "loose-envify": "1.4.0", "prop-types": "15.8.1" }, "peerDependencies": { "react": "18.3.1", "react-dom": "18.3.1" } }, "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g=="], - "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="], - "regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="], - "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="], "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], @@ -1080,8 +999,6 @@ "slice-ansi": ["slice-ansi@4.0.0", "", { "dependencies": { "ansi-styles": "4.3.0", "astral-regex": "2.0.0", "is-fullwidth-code-point": "3.0.0" } }, "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ=="], - "source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], @@ -1118,8 +1035,6 @@ "stylelint-scss": ["stylelint-scss@7.0.0", "", { "dependencies": { "css-tree": "^3.0.1", "is-plain-object": "^5.0.0", "known-css-properties": "^0.37.0", "mdn-data": "^2.25.0", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.6", "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "stylelint": "^16.8.2 || ^17.0.0" } }, "sha512-H88kCC+6Vtzj76NsC8rv6x/LW8slBzIbyeSjsKVlS+4qaEJoDrcJR4L+8JdrR2ORdTscrBzYWiiT2jq6leYR1Q=="], - "stylis": ["stylis@4.2.0", "", {}, "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="], - "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "supports-hyperlinks": ["supports-hyperlinks@4.4.0", "", { "dependencies": { "has-flag": "^5.0.1", "supports-color": "^10.2.2" } }, "sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg=="], @@ -1218,12 +1133,6 @@ "@babel/generator/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": "./bin/babel-parser.js" }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], - "@babel/helper-module-imports/@babel/traverse": ["@babel/traverse@7.25.7", "", { "dependencies": { "@babel/code-frame": "7.25.7", "@babel/generator": "7.25.7", "@babel/parser": "7.25.8", "@babel/template": "7.25.7", "@babel/types": "7.25.8", "debug": "4.3.7", "globals": "11.12.0" } }, "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg=="], - - "@babel/helper-module-imports/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "7.25.7", "@babel/helper-validator-identifier": "7.25.7", "to-fast-properties": "2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="], - - "@babel/helper-module-transforms/@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], - "@babel/highlight/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="], "@babel/highlight/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", "supports-color": "5.5.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], @@ -1250,42 +1159,14 @@ "@commitlint/types/chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="], - "@emotion/babel-plugin/convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="], - - "@emotion/serialize/csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], - - "@emotion/styled/@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], - "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@keyv/bigmap/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], - "@mui/material/@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], - - "@mui/private-theming/@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], - - "@mui/styled-engine/@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], - - "@mui/system/@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], - - "@mui/types/@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], - - "@mui/utils/@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], - - "@mui/utils/@types/prop-types": ["@types/prop-types@15.7.15", "", {}, "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw=="], - "@types/conventional-commits-parser/@types/node": ["@types/node@22.7.5", "", { "dependencies": { "undici-types": "6.19.8" } }, "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ=="], - "@types/react/csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], - "acorn-jsx/acorn": ["acorn@8.12.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg=="], - "babel-plugin-macros/@babel/runtime": ["@babel/runtime@7.27.0", "", { "dependencies": { "regenerator-runtime": "0.14.1" } }, "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw=="], - - "babel-plugin-macros/cosmiconfig": ["cosmiconfig@7.1.0", "", { "dependencies": { "@types/parse-json": "4.0.2", "import-fresh": "3.3.0", "parse-json": "5.2.0", "path-type": "4.0.0", "yaml": "1.10.2" } }, "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA=="], - - "babel-plugin-macros/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "2.15.1", "path-parse": "1.0.7", "supports-preserve-symlinks-flag": "1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="], - "brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], "cacheable/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], @@ -1304,10 +1185,6 @@ "define-data-property/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "1.2.4" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="], - "dom-helpers/@babel/runtime": ["@babel/runtime@7.27.0", "", { "dependencies": { "regenerator-runtime": "0.14.1" } }, "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw=="], - - "dom-helpers/csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], - "es-abstract/es-set-tostringtag": ["es-set-tostringtag@2.0.3", "", { "dependencies": { "get-intrinsic": "1.2.4", "has-tostringtag": "1.0.2", "hasown": "2.0.2" } }, "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ=="], "es-abstract/gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "1.2.4" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="], @@ -1352,8 +1229,6 @@ "has-tostringtag/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="], - "hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], - "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "is-symbol/has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="], @@ -1384,10 +1259,6 @@ "postcss-scss/postcss": ["postcss@8.4.49", "", { "dependencies": { "nanoid": "3.3.8", "picocolors": "1.1.1", "source-map-js": "1.2.1" } }, "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA=="], - "prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], - - "react-transition-group/@babel/runtime": ["@babel/runtime@7.27.0", "", { "dependencies": { "regenerator-runtime": "0.14.1" } }, "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw=="], - "reflect.getprototypeof/call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], "reflect.getprototypeof/es-abstract": ["es-abstract@1.24.1", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw=="], @@ -1480,20 +1351,6 @@ "yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "8.0.0", "is-fullwidth-code-point": "3.0.0", "strip-ansi": "6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "@babel/helper-module-imports/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.25.7", "", { "dependencies": { "@babel/highlight": "7.25.7", "picocolors": "1.1.1" } }, "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g=="], - - "@babel/helper-module-imports/@babel/traverse/@babel/generator": ["@babel/generator@7.25.7", "", { "dependencies": { "@babel/types": "7.25.8", "@jridgewell/gen-mapping": "0.3.5", "@jridgewell/trace-mapping": "0.3.25", "jsesc": "3.0.2" } }, "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA=="], - - "@babel/helper-module-imports/@babel/traverse/@babel/template": ["@babel/template@7.25.7", "", { "dependencies": { "@babel/code-frame": "7.25.7", "@babel/parser": "7.25.8", "@babel/types": "7.25.8" } }, "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA=="], - - "@babel/helper-module-imports/@babel/traverse/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="], - - "@babel/helper-module-imports/@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], - - "@babel/helper-module-imports/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="], - - "@babel/helper-module-imports/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="], - "@babel/highlight/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "1.9.3" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], "@babel/highlight/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], @@ -1838,10 +1695,6 @@ "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "@babel/helper-module-imports/@babel/traverse/@babel/generator/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.5", "", { "dependencies": { "@jridgewell/set-array": "1.2.1", "@jridgewell/sourcemap-codec": "1.5.0", "@jridgewell/trace-mapping": "0.3.25" } }, "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg=="], - - "@babel/helper-module-imports/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "3.1.2", "@jridgewell/sourcemap-codec": "1.5.0" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], - "@babel/highlight/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], "@babel/highlight/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], diff --git a/manifest/chrome.json b/manifest/chrome.json index c97cd76d..82864c1e 100644 --- a/manifest/chrome.json +++ b/manifest/chrome.json @@ -4,7 +4,7 @@ "default_locale": "en", "name": "__MSG_name__", "description": "__MSG_description__", - "version": "7.5.0", + "version": "7.6.0", "homepage_url": "https://muetab.com", "permissions": ["search"], "action": { diff --git a/manifest/firefox.json b/manifest/firefox.json index 4119f002..d036efc7 100644 --- a/manifest/firefox.json +++ b/manifest/firefox.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "Mue", "description": "Fast, open and free-to-use new tab page for modern browsers.", - "version": "7.5.0", + "version": "7.6.0", "homepage_url": "https://muetab.com", "action": { "default_icon": "icons/128x128.png" diff --git a/package.json b/package.json index 0a0b7d6b..f7b6906a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "homepage": "https://muetab.com", "bugs": "https://github.com/mue/mue/issues/new?assignees=&labels=bug&template=bug-report.md&title=%5BBUG%5D", "license": "BSD-3-Clause", - "version": "7.5.0", + "version": "7.6.0", "type": "module", "packageManager": "bun@1.3.1", "engines": { @@ -21,18 +21,12 @@ "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@eartharoid/i18n": "1.2.1", - "@emotion/react": "^11.14.0", - "@emotion/styled": "^11.14.1", "@floating-ui/react-dom": "2.1.6", "@fontsource/lexend-deca": "5.0.14", "@fontsource/montserrat": "5.0.19", - "@mui/material": "7.3.7", "@sentry/react": "^10.36.0", - "embla-carousel-autoplay": "8.6.0", - "embla-carousel-react": "8.6.0", "fast-blurhash": "^1.1.4", "image-conversion": "^2.1.1", - "mue": "file:", "react": "^19.2.3", "react-best-gradient-color-picker": "^3.0.14", "react-clock": "6.0.0", diff --git a/safari/Mue Extension/Resources/manifest.json b/safari/Mue Extension/Resources/manifest.json index 1821da96..2afad899 100644 --- a/safari/Mue Extension/Resources/manifest.json +++ b/safari/Mue Extension/Resources/manifest.json @@ -4,7 +4,7 @@ "default_locale": "en", "name": "__MSG_name__", "description": "__MSG_description__", - "version": "7.5.0", + "version": "7.6.0", "homepage_url": "https://muetab.com", "permissions": ["search"], "chrome_url_overrides": { diff --git a/safari/Mue.xcodeproj/project.pbxproj b/safari/Mue.xcodeproj/project.pbxproj index c0b4e9ae..bbe452c0 100644 --- a/safari/Mue.xcodeproj/project.pbxproj +++ b/safari/Mue.xcodeproj/project.pbxproj @@ -255,7 +255,7 @@ "@executable_path/../../../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = 7.5.0; + MARKETING_VERSION = 7.6.0; OTHER_LDFLAGS = ( "-framework", SafariServices, @@ -289,7 +289,7 @@ "@executable_path/../../../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = 7.5.0; + MARKETING_VERSION = 7.6.0; OTHER_LDFLAGS = ( "-framework", SafariServices, @@ -445,7 +445,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 7.5.0; + MARKETING_VERSION = 7.6.0; OTHER_LDFLAGS = ( "-framework", SafariServices, @@ -486,7 +486,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 7.5.0; + MARKETING_VERSION = 7.6.0; OTHER_LDFLAGS = ( "-framework", SafariServices, diff --git a/src/components/Elements/AddModal/AddModal.jsx b/src/components/Elements/AddModal/AddModal.jsx index fa97493d..4f68e975 100644 --- a/src/components/Elements/AddModal/AddModal.jsx +++ b/src/components/Elements/AddModal/AddModal.jsx @@ -1,7 +1,6 @@ import variables from 'config/variables'; import { useState, memo } from 'react'; -import { TextareaAutosize } from '@mui/material'; import { MdAddLink, MdClose } from 'react-icons/md'; import { Tooltip } from 'components/Elements'; import { Button } from 'components/Elements'; @@ -26,22 +25,24 @@ function AddModal({ urlError, iconError, addLink, closeModal, edit, editData, ed
- setName(e.target.value.replace(/(\r\n|\n|\r)/gm, ''))} style={{ gridColumn: 'span 2' }} /> - setUrl(e.target.value.replace(/(\r\n|\n|\r)/gm, ''))} /> - setIcon(e.target.value.replace(/(\r\n|\n|\r)/gm, ''))} diff --git a/src/components/Elements/MainModal/scss/index.scss b/src/components/Elements/MainModal/scss/index.scss index 609ef95f..03a274c8 100644 --- a/src/components/Elements/MainModal/scss/index.scss +++ b/src/components/Elements/MainModal/scss/index.scss @@ -206,7 +206,7 @@ h5 { } .languageSettings { - margin-bottom: 15px; + padding-bottom: 50px; .MuiFormGroup-root { gap: 5px; diff --git a/src/components/Elements/MainModal/scss/marketplace/_main.scss b/src/components/Elements/MainModal/scss/marketplace/_main.scss index 27eec856..f9b3c8d0 100644 --- a/src/components/Elements/MainModal/scss/marketplace/_main.scss +++ b/src/components/Elements/MainModal/scss/marketplace/_main.scss @@ -21,7 +21,7 @@ .items { display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(250px, 280px)); grid-gap: 1.5rem; margin-top: 15px; margin-bottom: 30px; @@ -62,6 +62,20 @@ width: 60px !important; border-radius: 12px; transition: 0.5s; + + &.item-icon-text { + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + font-weight: 600; + letter-spacing: 1px; + + @include themed { + background-color: t($modal-sidebarActive); + color: t($color); + } + } } .card-details { @@ -113,6 +127,28 @@ } } + .item-uninstall-btn { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 50%; + border: none; + background-color: rgba(0, 0, 0, 0.5); + cursor: pointer; + transition: background-color 0.2s ease; + + svg { + color: white; + font-size: 18px; + } + + &:hover { + background-color: rgba(220, 50, 50, 0.9); + } + } + .item-installed-badge { position: absolute; top: 12px; @@ -135,9 +171,33 @@ } } + .item-sideload-badge { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 50%; + background-color: rgba(100, 100, 100, 0.9); + cursor: help; + + svg { + color: white; + font-size: 16px; + } + } + &:hover .item-installed-badge { transform: scale(1.05); } + + &.item-sideloaded { + cursor: default; + + &:hover { + transform: none; + } + } } } diff --git a/src/components/Form/Settings/Checkbox/Checkbox.jsx b/src/components/Form/Settings/Checkbox/Checkbox.jsx index 22d65564..76deb876 100644 --- a/src/components/Form/Settings/Checkbox/Checkbox.jsx +++ b/src/components/Form/Settings/Checkbox/Checkbox.jsx @@ -1,9 +1,11 @@ import variables from 'config/variables'; import { memo, useState, useCallback } from 'react'; -import { Checkbox as CheckboxUI, FormControlLabel } from '@mui/material'; +import { MdCheck } from 'react-icons/md'; import EventBus from 'utils/eventbus'; +import './Checkbox.scss'; + const Checkbox = memo((props) => { const [checked, setChecked] = useState(localStorage.getItem(props.name) === 'true'); @@ -18,7 +20,7 @@ const Checkbox = memo((props) => { variables.stats.postEvent( 'setting', - `${props.name} ${checked ? 'enabled' : 'disabled'}`, + `${props.name} ${value ? 'enabled' : 'disabled'}`, ); if (props.element) { @@ -31,20 +33,30 @@ const Checkbox = memo((props) => { EventBus.emit('refresh', props.category); }, [checked, props]); + const handleKeyDown = useCallback((e) => { + if ((e.key === ' ' || e.key === 'Enter') && !props.disabled) { + e.preventDefault(); + handleChange(); + } + }, [handleChange, props.disabled]); + return ( - - } - label={props.text} - /> +
+ {props.text} + +
+ {checked && } +
+
); }); diff --git a/src/components/Form/Settings/Checkbox/Checkbox.scss b/src/components/Form/Settings/Checkbox/Checkbox.scss new file mode 100644 index 00000000..5755d111 --- /dev/null +++ b/src/components/Form/Settings/Checkbox/Checkbox.scss @@ -0,0 +1,118 @@ +@use 'scss/variables' as *; +@use 'scss/mixins' as *; + +@include keyframes(checkScale) { + 0% { + transform: scale(0); + opacity: 0; + } + + 50% { + transform: scale(1.1); + } + + 100% { + transform: scale(1); + opacity: 1; + } +} + +.checkbox-wrapper { + position: relative; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + cursor: pointer; + padding: 8px 0; + + &.disabled { + opacity: 0.5; + cursor: not-allowed; + } + + &:hover:not(.disabled) .checkbox-label { + @include themed { + color: t($link); + } + } + + .checkbox-label { + flex: 1; + transition: color 0.2s ease; + pointer-events: none; + + @include themed { + color: t($color); + } + } + + .checkbox-box { + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + border-radius: 6px; + transition: all 0.2s ease; + cursor: pointer; + flex-shrink: 0; + pointer-events: none; + + @include themed { + border: 2px solid t($modal-sidebarActive); + background: t($modal-sidebar); + color: t($color); + + &:hover:not(.disabled) { + border-color: t($color); + transform: scale(1.05); + } + } + + &:active:not(.disabled) { + transform: scale(0.95); + + @include themed { + box-shadow: 0 0 0 4px rgba(255, 92, 37, 0.1); + } + } + + &.checked { + @include themed { + background: t($link); + border-color: t($link); + } + + svg { + @include animation(checkScale 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)); + } + } + + svg { + font-size: 18px; + color: white; + } + } + + .checkbox-input { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + margin: 0; + + &:focus-visible + .checkbox-box { + @include themed { + box-shadow: 0 0 0 3px t($link); + } + } + + &:disabled { + cursor: not-allowed; + } + } +} diff --git a/src/components/Form/Settings/ChipSelect/ChipSelect.jsx b/src/components/Form/Settings/ChipSelect/ChipSelect.jsx index f4cb8b1a..0bb1815c 100644 --- a/src/components/Form/Settings/ChipSelect/ChipSelect.jsx +++ b/src/components/Form/Settings/ChipSelect/ChipSelect.jsx @@ -1,12 +1,7 @@ -import { useState, memo } from 'react'; +import { useState, memo, useRef, useEffect } from 'react'; +import { MdExpandMore, MdClose } from 'react-icons/md'; -import Box from '@mui/material/Box'; -import OutlinedInput from '@mui/material/OutlinedInput'; -import InputLabel from '@mui/material/InputLabel'; -import MenuItem from '@mui/material/MenuItem'; -import FormControl from '@mui/material/FormControl'; -import Select from '@mui/material/Select'; -import Chip from '@mui/material/Chip'; +import './ChipSelect.scss'; function ChipSelect({ label, options, onChange }) { let start = (localStorage.getItem('apiCategories') || '').split(','); @@ -14,47 +9,88 @@ function ChipSelect({ label, options, onChange }) { start = []; } - const [optionsSelected, setoptionsSelected] = useState(start); + const [optionsSelected, setOptionsSelected] = useState(start); + const [isOpen, setIsOpen] = useState(false); + const containerRef = useRef(null); - const handleChange = (event) => { - const { - target: { value }, - } = event; - setoptionsSelected(typeof value === 'string' ? value.split(',') : value); - localStorage.setItem('apiCategories', value); + useEffect(() => { + const handleClickOutside = (event) => { + if (containerRef.current && !containerRef.current.contains(event.target)) { + setIsOpen(false); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, []); + + const handleToggle = (optionName) => { + let newSelected; + if (optionsSelected.includes(optionName)) { + newSelected = optionsSelected.filter((item) => item !== optionName); + } else { + newSelected = [...optionsSelected, optionName]; + } + + setOptionsSelected(newSelected); + localStorage.setItem('apiCategories', newSelected.join(',')); - // Call parent onChange if provided if (onChange) { - onChange(value); + onChange(newSelected); } }; + const handleRemoveChip = (e, optionName) => { + e.stopPropagation(); + handleToggle(optionName); + }; + return ( - - {label} - - +
+ {label && } +
setIsOpen(!isOpen)}> +
+ {optionsSelected.length === 0 ? ( + Select options... + ) : ( +
+ {optionsSelected.map((value) => ( + + {value.charAt(0).toUpperCase() + value.slice(1)} + + + ))} +
+ )} +
+ +
+ {isOpen && ( +
+ {options.map((option) => ( +
handleToggle(option.name)} + > + + {optionsSelected.includes(option.name) && '✓'} + + + {option.name.charAt(0).toUpperCase() + option.name.slice(1)} + {option.count && ` (${option.count})`} + +
+ ))} +
+ )} +
); } diff --git a/src/components/Form/Settings/ChipSelect/ChipSelect.scss b/src/components/Form/Settings/ChipSelect/ChipSelect.scss new file mode 100644 index 00000000..31bb4009 --- /dev/null +++ b/src/components/Form/Settings/ChipSelect/ChipSelect.scss @@ -0,0 +1,178 @@ +@use 'scss/variables' as *; + +.chipSelect { + position: relative; + width: 300px; + margin-top: 10px; + + .chipSelect-label { + display: block; + margin-bottom: 8px; + font-size: 12px; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; + + @include themed { + color: t($subColor); + } + } + + .chipSelect-control { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 56px; + padding: 8px 12px; + cursor: pointer; + transition: 0.2s ease; + + @include themed { + background: t($modal-sidebar); + border: 1px solid t($modal-sidebarActive); + border-radius: t($borderRadius); + color: t($color); + + &:hover { + border-color: t($color); + } + } + } + + .chipSelect-value { + flex: 1; + min-width: 0; + } + + .chipSelect-placeholder { + @include themed { + color: t($subColor); + } + } + + .chipSelect-chips { + display: flex; + flex-wrap: wrap; + gap: 6px; + } + + .chipSelect-chip { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 4px 8px; + font-size: 13px; + text-transform: capitalize; + + @include themed { + background: t($modal-sidebarActive); + border-radius: calc(t($borderRadius) / 2); + color: t($color); + } + + .chipSelect-chip-remove { + display: flex; + align-items: center; + justify-content: center; + padding: 2px; + margin-left: 2px; + border: none; + background: transparent; + cursor: pointer; + border-radius: 50%; + transition: 0.2s ease; + + @include themed { + color: t($subColor); + + &:hover { + background: rgba(255, 255, 255, 0.1); + color: t($color); + } + } + + svg { + font-size: 14px; + } + } + } + + .chipSelect-arrow { + flex-shrink: 0; + font-size: 24px; + transition: transform 0.2s ease; + + @include themed { + color: t($subColor); + } + + &.open { + transform: rotate(180deg); + } + } + + .chipSelect-dropdown { + position: absolute; + top: calc(100% + 4px); + left: 0; + right: 0; + max-height: 250px; + overflow-y: auto; + z-index: 100; + + @include themed { + background: t($modal-background); + border: 1px solid t($modal-sidebarActive); + border-radius: t($borderRadius); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + } + } + + .chipSelect-option { + display: flex; + align-items: center; + gap: 10px; + padding: 12px 16px; + cursor: pointer; + transition: 0.2s ease; + + @include themed { + color: t($color); + + &:hover { + background: t($modal-sidebarActive); + } + + &.selected { + background: t($modal-sidebar); + } + } + + .chipSelect-option-checkbox { + display: flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + font-size: 12px; + font-weight: bold; + + @include themed { + border: 2px solid t($modal-sidebarActive); + border-radius: 4px; + color: t($color); + } + } + + &.selected .chipSelect-option-checkbox { + @include themed { + background: t($modal-sidebarActive); + border-color: t($color); + } + } + + .chipSelect-option-label { + flex: 1; + } + } +} diff --git a/src/components/Form/Settings/Dropdown/Dropdown.jsx b/src/components/Form/Settings/Dropdown/Dropdown.jsx index ac4eebfb..d4585d45 100644 --- a/src/components/Form/Settings/Dropdown/Dropdown.jsx +++ b/src/components/Form/Settings/Dropdown/Dropdown.jsx @@ -1,69 +1,165 @@ import variables from 'config/variables'; -import { memo, useState, useCallback, useRef } from 'react'; -import { InputLabel, MenuItem, FormControl, Select } from '@mui/material'; +import { memo, useState, useCallback, useRef, useEffect } from 'react'; +import { MdExpandMore, MdCheck, MdRefresh } from 'react-icons/md'; +import { toast } from 'react-toastify'; import EventBus from 'utils/eventbus'; +import './Dropdown.scss'; + const Dropdown = memo((props) => { const [value, setValue] = useState( - localStorage.getItem(props.name) || props.items[0].value, + localStorage.getItem(props.name) || props.items[0]?.value, ); - const dropdown = useRef(); + const [isOpen, setIsOpen] = useState(false); + const [focusedIndex, setFocusedIndex] = useState(-1); + const containerRef = useRef(null); + const optionsRef = useRef([]); - const onChange = useCallback((e) => { - const newValue = e.target.value; - - if (newValue === variables.getMessage('modals.main.loading')) { - return; - } - - variables.stats.postEvent('setting', `${props.name} from ${value} to ${newValue}`); - - setValue(newValue); - - if (!props.noSetting) { - localStorage.setItem(props.name, newValue); - localStorage.setItem(props.name2, props.value2); - } - - if (props.onChange) { - props.onChange(newValue); - } - - if (props.element) { - if (!document.querySelector(props.element)) { - document.querySelector('.reminder-info').style.display = 'flex'; - return localStorage.setItem('showReminder', true); + useEffect(() => { + const handleClickOutside = (event) => { + if (containerRef.current && !containerRef.current.contains(event.target)) { + setIsOpen(false); + setFocusedIndex(-1); } - } + }; - EventBus.emit('refresh', props.category); - }, [value, props]); + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, []); + + const onChange = useCallback( + (newValue) => { + if (newValue === variables.getMessage('modals.main.loading')) { + return; + } + + variables.stats.postEvent('setting', `${props.name} from ${value} to ${newValue}`); + + setValue(newValue); + setIsOpen(false); + setFocusedIndex(-1); + + if (!props.noSetting) { + localStorage.setItem(props.name, newValue); + localStorage.setItem(props.name2, props.value2); + } + + if (props.onChange) { + props.onChange(newValue); + } + + if (props.element) { + if (!document.querySelector(props.element)) { + document.querySelector('.reminder-info').style.display = 'flex'; + return localStorage.setItem('showReminder', true); + } + } + + EventBus.emit('refresh', props.category); + }, + [value, props], + ); + + const handleKeyDown = useCallback( + (e) => { + if (props.disabled) return; + + switch (e.key) { + case 'Enter': + case ' ': + e.preventDefault(); + setIsOpen(!isOpen); + break; + case 'Escape': + setIsOpen(false); + setFocusedIndex(-1); + break; + case 'ArrowDown': + e.preventDefault(); + if (!isOpen) { + setIsOpen(true); + } else { + setFocusedIndex((prev) => (prev < props.items.filter((i) => i !== null).length - 1 ? prev + 1 : prev)); + } + break; + case 'ArrowUp': + e.preventDefault(); + if (isOpen) { + setFocusedIndex((prev) => (prev > 0 ? prev - 1 : prev)); + } + break; + } + }, + [isOpen, props.items, props.disabled], + ); + + const handleOptionKeyDown = useCallback( + (e, item) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + onChange(item.value); + } + }, + [onChange], + ); + + const resetItem = useCallback(() => { + const defaultValue = props.default || props.items[0]?.value; + onChange(defaultValue); + toast(variables.getMessage('toasts.reset')); + }, [onChange, props.default, props.items]); const id = 'dropdown' + props.name; const label = props.label || ''; + const selectedItem = props.items.find((item) => item?.value === value); return ( - - {label} - - + {selectedItem?.text || value} + +
+ {isOpen && ( +
+ {props.items.map((item, index) => + item !== null ? ( +
(optionsRef.current[index] = el)} + className={`dropdown-option ${value === item.value ? 'selected' : ''} ${index === focusedIndex ? 'focused' : ''}`} + onClick={() => onChange(item.value)} + onKeyDown={(e) => handleOptionKeyDown(e, item)} + role="option" + aria-selected={value === item.value} + tabIndex={0} + > + {item.text} + {value === item.value && } +
+ ) : null, + )} +
+ )} + ); }); diff --git a/src/components/Form/Settings/Dropdown/Dropdown.scss b/src/components/Form/Settings/Dropdown/Dropdown.scss new file mode 100644 index 00000000..637fad37 --- /dev/null +++ b/src/components/Form/Settings/Dropdown/Dropdown.scss @@ -0,0 +1,218 @@ +@use 'scss/variables' as *; +@use 'scss/mixins' as *; + +@include keyframes(dropdownSlideIn) { + 0% { + opacity: 0; + transform: translateY(-10px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.dropdown { + position: relative; + width: 300px; + margin-top: 10px; + gap: 8px; + display: flex; + flex-flow: column; + + + &.disabled { + opacity: 0.5; + cursor: not-allowed; + pointer-events: none; + } + + .dropdown-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 8px; + } + + .dropdown-label { + font-size: 12px; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; + + @include themed { + color: t($subColor); + } + } + + .dropdown-reset { + display: flex; + align-items: center; + gap: 5px; + cursor: pointer; + font-size: 12px; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; + + @include themed { + color: t($link); + } + + &:hover { + opacity: 0.8; + } + + svg { + font-size: 12px; + } + } + + .dropdown-control { + display: flex; + align-items: center; + justify-content: space-between; + height: 56px; + padding: 0 16px; + cursor: pointer; + transition: all 0.2s ease; + outline: none; + + @include themed { + background: t($modal-sidebar); + border: 1px solid t($modal-sidebarActive); + border-radius: t($borderRadius); + color: t($color); + + &:hover { + border-color: t($color); + } + } + + &:focus-visible { + outline: none; + + @include themed { + border-color: t($link); + box-shadow: 0 0 0 3px t($link); + } + } + } + + .dropdown-value { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + transition: color 0.2s ease; + } + + .dropdown-arrow { + flex-shrink: 0; + font-size: 24px; + transition: transform 0.2s ease; + + @include themed { + color: t($subColor); + } + + &.open { + transform: rotate(180deg); + } + } + + .dropdown-menu { + position: absolute; + top: calc(100% + 4px); + left: 0; + right: 0; + max-height: 250px; + overflow-y: auto; + z-index: 9999; + @include animation(dropdownSlideIn 0.2s ease-out); + + @include themed { + background: t($modal-background); + border: 1px solid t($modal-sidebarActive); + border-radius: t($borderRadius); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + @include themed { + background: t($modal-sidebar); + } + } + + &::-webkit-scrollbar-thumb { + @include themed { + background: t($modal-sidebarActive); + border-radius: 3px; + } + + &:hover { + @include themed { + background: t($color); + } + } + } + } + + .dropdown-option { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 12px 16px; + cursor: pointer; + transition: all 0.15s ease; + outline: none; + + @include themed { + color: t($color); + + &:hover { + background: t($modal-sidebarActive); + padding-left: 20px; + } + + &.selected { + background: t($modal-sidebar); + font-weight: 500; + } + + &.focused { + background: t($modal-sidebarActive); + border-left: 2px solid t($link); + } + } + + .dropdown-option-text { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .dropdown-option-check { + flex-shrink: 0; + font-size: 14px; + width: 20px; + height: 20px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + + @include themed { + background: t($link); + color: white; + } + } + } +} diff --git a/src/components/Form/Settings/Radio/Radio.jsx b/src/components/Form/Settings/Radio/Radio.jsx index cf5fa311..b1a96969 100644 --- a/src/components/Form/Settings/Radio/Radio.jsx +++ b/src/components/Form/Settings/Radio/Radio.jsx @@ -1,85 +1,88 @@ import variables from 'config/variables'; import { memo, useState, useCallback } from 'react'; import { useTranslation } from 'contexts/TranslationContext'; -import { - Radio as RadioUI, - RadioGroup, - FormControlLabel, - FormControl, - FormLabel, -} from '@mui/material'; import EventBus from 'utils/eventbus'; +import './Radio.scss'; + const Radio = memo((props) => { const { changeLanguage } = useTranslation(); const [value, setValue] = useState(localStorage.getItem(props.name)); - const handleChange = useCallback(async (e) => { - const newValue = e.target.value; + const handleChange = useCallback( + async (newValue) => { + if (newValue === 'loading') { + return; + } - if (newValue === 'loading') { - return; - } + if (props.name === 'language') { + changeLanguage(newValue); + setValue(newValue); - if (props.name === 'language') { - // Use context to change language directly - no EventBus needed - changeLanguage(newValue); + variables.stats.postEvent('setting', `${props.name} from ${value} to ${newValue}`); + + if (props.onChange) { + props.onChange(newValue); + } + + EventBus.emit('refresh', props.category); + return; + } + + localStorage.setItem(props.name, newValue); setValue(newValue); - variables.stats.postEvent('setting', `${props.name} from ${value} to ${newValue}`); - if (props.onChange) { props.onChange(newValue); } - EventBus.emit('refresh', props.category); - return; - } + variables.stats.postEvent('setting', `${props.name} from ${value} to ${newValue}`); - localStorage.setItem(props.name, newValue); - setValue(newValue); - - if (props.onChange) { - props.onChange(newValue); - } - - variables.stats.postEvent('setting', `${props.name} from ${value} to ${newValue}`); - - if (props.element) { - if (!document.querySelector(props.element)) { - document.querySelector('.reminder-info').style.display = 'flex'; - return localStorage.setItem('showReminder', true); + if (props.element) { + if (!document.querySelector(props.element)) { + document.querySelector('.reminder-info').style.display = 'flex'; + return localStorage.setItem('showReminder', true); + } } - } - EventBus.emit('refresh', props.category); - }, [value, props, changeLanguage]); + EventBus.emit('refresh', props.category); + }, + [value, props, changeLanguage], + ); return ( - - - {props.title} - - +
+ {props.title && ( + + {props.title} + + )} +
{props.options.map((option) => ( - } - label={option.name} +
); }); diff --git a/src/components/Form/Settings/Radio/Radio.scss b/src/components/Form/Settings/Radio/Radio.scss new file mode 100644 index 00000000..2bd09236 --- /dev/null +++ b/src/components/Form/Settings/Radio/Radio.scss @@ -0,0 +1,159 @@ +@use 'scss/variables' as *; +@use 'scss/mixins' as *; + +@include keyframes(radioDotScale) { + 0% { + transform: scale(0); + opacity: 0; + } + + 50% { + transform: scale(1.2); + } + + 100% { + transform: scale(1); + opacity: 1; + } +} + +.radio-group { + width: 100%; + margin-top: 10px; + + .radio-title { + font-weight: bold; + font-size: 1.17rem; + margin-bottom: 12px; + display: block; + + @include themed { + color: t($color); + } + } + + .radio-title-small { + font-weight: bold; + font-size: 1rem; + margin-bottom: 10px; + display: block; + + @include themed { + color: t($color); + } + } + + .radio-options { + display: flex; + flex-direction: column; + gap: 10px; + } + + .radio-option { + position: relative; + display: flex; + align-items: center; + justify-content: space-between; + cursor: pointer; + padding: 16px 20px; + transition: all 0.2s ease; + + @include themed { + background: t($modal-sidebar); + border-radius: t($borderRadius); + box-shadow: 0 0 0 1px t($modal-sidebarActive); + + &:hover:not(.disabled) { + background: t($modal-secondaryColour); + transform: translateY(-1px); + } + } + + &:active:not(.disabled) { + transform: translateY(0); + } + + &.selected .radio-circle { + @include themed { + border-color: t($link); + } + } + + &.disabled { + opacity: 0.5; + cursor: not-allowed; + pointer-events: none; + } + } + + .radio-label { + flex: 1; + font-size: 15px; + pointer-events: none; + + @include themed { + color: t($color); + } + } + + .radio-circle { + display: flex; + align-items: center; + justify-content: center; + width: 22px; + height: 22px; + border-radius: 50%; + transition: all 0.2s ease; + cursor: pointer; + flex-shrink: 0; + margin-left: 20px; + pointer-events: none; + + @include themed { + border: 2px solid t($modal-sidebarActive); + background: t($modal-secondaryColour); + } + + &:hover:not(.disabled) { + transform: scale(1.1); + } + + &:active:not(.disabled) { + @include themed { + box-shadow: 0 0 0 4px rgba(255, 92, 37, 0.1); + } + } + } + + .radio-dot { + width: 12px; + height: 12px; + border-radius: 50%; + @include animation(radioDotScale 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)); + + @include themed { + background: t($link); + } + } + + .radio-input { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + margin: 0; + + &:focus-visible + .radio-circle { + @include themed { + box-shadow: 0 0 0 3px t($link); + } + } + + &:disabled { + cursor: not-allowed; + } + } +} diff --git a/src/components/Form/Settings/SearchInput/SearchInput.jsx b/src/components/Form/Settings/SearchInput/SearchInput.jsx new file mode 100644 index 00000000..ba2cebb2 --- /dev/null +++ b/src/components/Form/Settings/SearchInput/SearchInput.jsx @@ -0,0 +1,23 @@ +import { memo } from 'react'; +import { MdSearch } from 'react-icons/md'; + +import './SearchInput.scss'; + +const SearchInput = memo(({ value, onChange, placeholder, fullWidth }) => { + return ( +
+ + +
+ ); +}); + +SearchInput.displayName = 'SearchInput'; + +export { SearchInput as default, SearchInput }; diff --git a/src/components/Form/Settings/SearchInput/SearchInput.scss b/src/components/Form/Settings/SearchInput/SearchInput.scss new file mode 100644 index 00000000..123e25cb --- /dev/null +++ b/src/components/Form/Settings/SearchInput/SearchInput.scss @@ -0,0 +1,48 @@ +@use 'scss/variables' as *; + +.search-input-container { + position: relative; + display: flex; + align-items: center; + width: 250px; + + &.full-width { + width: 100%; + } + + .search-input-icon { + position: absolute; + left: 16px; + font-size: 20px; + pointer-events: none; + + @include themed { + color: t($subColor); + } + } + + .search-input-field { + width: 100%; + height: 48px; + padding: 0 16px 0 44px; + font-size: 15px; + outline: none; + transition: 0.2s ease; + + @include themed { + background: t($modal-sidebar); + border: 1px solid t($modal-sidebarActive); + border-radius: 24px; + color: t($color); + + &:hover, + &:focus { + border-color: t($color); + } + + &::placeholder { + color: t($subColor); + } + } + } +} diff --git a/src/components/Form/Settings/SearchInput/index.jsx b/src/components/Form/Settings/SearchInput/index.jsx new file mode 100644 index 00000000..c068bf43 --- /dev/null +++ b/src/components/Form/Settings/SearchInput/index.jsx @@ -0,0 +1 @@ +export * from './SearchInput'; diff --git a/src/components/Form/Settings/Slider/Slider.jsx b/src/components/Form/Settings/Slider/Slider.jsx index 4c88badb..49e42329 100644 --- a/src/components/Form/Settings/Slider/Slider.jsx +++ b/src/components/Form/Settings/Slider/Slider.jsx @@ -1,23 +1,20 @@ import variables from 'config/variables'; -import { memo, useState, useCallback } from 'react'; +import { memo, useState, useCallback, useRef } from 'react'; import { toast } from 'react-toastify'; -import { Slider } from '@mui/material'; import { MdRefresh } from 'react-icons/md'; import EventBus from 'utils/eventbus'; +import './Slider.scss'; + const SliderComponent = memo((props) => { const [value, setValue] = useState(localStorage.getItem(props.name) || props.default); + const animationRef = useRef(null); - const handleChange = useCallback((e, text) => { - let newValue = e.target.value; - newValue = Number(newValue); - - if (text) { - if (newValue === '') { - setValue(0); - return; - } + const handleChange = useCallback( + (e) => { + let newValue = e.target.value; + newValue = Number(newValue); if (newValue > props.max) { newValue = props.max; @@ -26,52 +23,104 @@ const SliderComponent = memo((props) => { if (newValue < props.min) { newValue = props.min; } - } - localStorage.setItem(props.name, newValue); - setValue(newValue); + localStorage.setItem(props.name, newValue); + setValue(newValue); - if (props.element) { - if (!document.querySelector(props.element)) { - document.querySelector('.reminder-info').style.display = 'flex'; - return localStorage.setItem('showReminder', true); + if (props.element) { + if (!document.querySelector(props.element)) { + document.querySelector('.reminder-info').style.display = 'flex'; + return localStorage.setItem('showReminder', true); + } } - } - EventBus.emit('refresh', props.category); - }, [props]); + EventBus.emit('refresh', props.category); + }, + [props], + ); const resetItem = useCallback(() => { - handleChange({ - target: { - value: props.default || '', - }, - }); + if (animationRef.current) { + cancelAnimationFrame(animationRef.current); + } + + const startValue = Number(value); + const endValue = Number(props.default || 0); + const duration = 300; // milliseconds + const startTime = performance.now(); + + const animate = (currentTime) => { + const elapsed = currentTime - startTime; + const progress = Math.min(elapsed / duration, 1); + + // Easing function for smooth animation + const easeOutCubic = 1 - Math.pow(1 - progress, 3); + + const currentValue = startValue + (endValue - startValue) * easeOutCubic; + const roundedValue = Math.round(currentValue / (Number(props.step) || 1)) * (Number(props.step) || 1); + + localStorage.setItem(props.name, roundedValue); + setValue(roundedValue); + + if (progress < 1) { + animationRef.current = requestAnimationFrame(animate); + } else { + // Ensure we end exactly at the target value + localStorage.setItem(props.name, endValue); + setValue(endValue); + EventBus.emit('refresh', props.category); + } + }; + + animationRef.current = requestAnimationFrame(animate); toast(variables.getMessage('toasts.reset')); - }, [handleChange, props.default]); + }, [value, props]); + + const percentage = + ((Number(value) - Number(props.min)) / (Number(props.max) - Number(props.min))) * 100; return ( - <> - - {props.title} - {Number(value)} - +
+
+ {Number(value)} + {variables.getMessage('modals.main.settings.buttons.reset')} - - `${value}`} - marks={props.marks || []} - /> - +
+
+ + {props.marks && props.marks.length > 0 && ( +
+ {props.marks.map((mark) => ( + + {mark.label} + + ))} +
+ )} +
+
); }); diff --git a/src/components/Form/Settings/Slider/Slider.scss b/src/components/Form/Settings/Slider/Slider.scss new file mode 100644 index 00000000..252bf342 --- /dev/null +++ b/src/components/Form/Settings/Slider/Slider.scss @@ -0,0 +1,174 @@ +@use 'scss/variables' as *; + +.slider-container { + width: 300px; + margin-bottom: 30px; + + .slider-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; + } + + .slider-value { + font-size: 16px; + font-weight: 600; + + @include themed { + color: t($color); + } + } + + .slider-reset { + display: flex; + align-items: center; + gap: 5px; + cursor: pointer; + font-size: 12px; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; + + @include themed { + color: t($link); + } + + &:hover { + opacity: 0.8; + } + + svg { + font-size: 12px; + } + } + + .slider-wrapper { + position: relative; + width: 100%; + } + + .slider-input { + -webkit-appearance: none; + appearance: none; + width: 100%; + height: 6px; + border-radius: 3px; + outline: none; + cursor: pointer; + transition: background 0.3s ease; + + @include themed { + background: linear-gradient( + to right, + t($link) 0%, + t($link) var(--slider-percentage), + t($modal-sidebarActive) var(--slider-percentage), + t($modal-sidebarActive) 100% + ); + } + + &::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 20px; + height: 20px; + border-radius: 50%; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); + + @include themed { + background: t($color); + border: 2px solid t($link); + } + + &:hover { + transform: scale(1.1); + box-shadow: 0 3px 8px rgba(0, 0, 0, 0.3); + } + } + + &::-moz-range-thumb { + width: 20px; + height: 20px; + border-radius: 50%; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); + border: none; + + @include themed { + background: t($color); + border: 2px solid t($link); + } + + &:hover { + transform: scale(1.1); + box-shadow: 0 3px 8px rgba(0, 0, 0, 0.3); + } + } + + &:focus-visible { + outline: none; + + &::-webkit-slider-thumb { + @include themed { + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 0 0 3px t($link); + } + + transform: scale(1.15); + } + + &::-moz-range-thumb { + @include themed { + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 0 0 3px t($link); + } + + transform: scale(1.15); + } + } + + &:active:not(:disabled) { + &::-webkit-slider-thumb { + transform: scale(1.2); + } + + &::-moz-range-thumb { + transform: scale(1.2); + } + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + + &::-webkit-slider-thumb { + cursor: not-allowed; + transform: scale(1) !important; + } + + &::-moz-range-thumb { + cursor: not-allowed; + transform: scale(1) !important; + } + } + } + + .slider-marks { + position: relative; + width: 100%; + height: 20px; + margin-top: 8px; + + .slider-mark { + position: absolute; + transform: translateX(-50%); + font-size: 12px; + + @include themed { + color: t($subColor); + } + } + } +} diff --git a/src/components/Form/Settings/Switch/Switch.jsx b/src/components/Form/Settings/Switch/Switch.jsx index 841ca65e..56e9cfdd 100644 --- a/src/components/Form/Settings/Switch/Switch.jsx +++ b/src/components/Form/Settings/Switch/Switch.jsx @@ -1,9 +1,10 @@ import variables from 'config/variables'; import { memo, useState, useCallback } from 'react'; -import { Switch as SwitchUI, FormControlLabel } from '@mui/material'; import EventBus from 'utils/eventbus'; +import './Switch.scss'; + const Switch = memo((props) => { const [checked, setChecked] = useState(localStorage.getItem(props.name) === 'true'); @@ -32,18 +33,20 @@ const Switch = memo((props) => { }, [checked, props]); return ( - - } - label={props.header ? '' : props.text} - labelPlacement="start" - /> +
+ {!props.header && {props.text}} +
+
+
+ +
); }); diff --git a/src/components/Form/Settings/Switch/Switch.scss b/src/components/Form/Settings/Switch/Switch.scss new file mode 100644 index 00000000..2a7bf5d3 --- /dev/null +++ b/src/components/Form/Settings/Switch/Switch.scss @@ -0,0 +1,63 @@ +@use 'scss/variables' as *; + +.switch-wrapper { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + cursor: pointer; + padding: 8px 0; + + .switch-label { + flex: 1; + + @include themed { + color: t($color); + } + } + + .switch-track { + position: relative; + width: 52px; + height: 32px; + border-radius: 16px; + cursor: pointer; + transition: 0.2s ease; + flex-shrink: 0; + + @include themed { + background: t($modal-sidebarActive); + } + + &.checked { + @include themed { + background: t($link); + } + + .switch-thumb { + transform: translateX(20px); + } + } + } + + .switch-thumb { + position: absolute; + top: 4px; + left: 4px; + width: 24px; + height: 24px; + border-radius: 50%; + transition: 0.2s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + + @include themed { + background: t($color); + } + } + + .switch-input { + position: absolute; + opacity: 0; + pointer-events: none; + } +} diff --git a/src/components/Form/Settings/Text/Text.jsx b/src/components/Form/Settings/Text/Text.jsx index 11efbef0..6e53d729 100644 --- a/src/components/Form/Settings/Text/Text.jsx +++ b/src/components/Form/Settings/Text/Text.jsx @@ -1,79 +1,95 @@ import variables from 'config/variables'; import { memo, useState, useCallback } from 'react'; import { toast } from 'react-toastify'; -import { TextField } from '@mui/material'; import { MdRefresh } from 'react-icons/md'; import EventBus from 'utils/eventbus'; +import './Text.scss'; + const Text = memo((props) => { - const [value, setValue] = useState(localStorage.getItem(props.name) || ''); + const { name, upperCaseFirst, element, category, onChange, title, textarea, customcss, placeholder } = props; + const defaultValue = props.default; + const [value, setValue] = useState(localStorage.getItem(name) || ''); - const handleChange = useCallback((e) => { - let { value } = e.target; + const handleChange = useCallback( + (e) => { + let newValue = e.target.value; - // Alex wanted font to work with montserrat and Montserrat, so I made it work - if (props.upperCaseFirst === true) { - value = value.charAt(0).toUpperCase() + value.slice(1); - } - - localStorage.setItem(props.name, value); - setValue(value); - - // Call parent onChange if provided - if (props.onChange) { - props.onChange(value); - } - - if (props.element) { - if (!document.querySelector(props.element)) { - document.querySelector('.reminder-info').style.display = 'flex'; - return localStorage.setItem('showReminder', true); + if (upperCaseFirst === true) { + newValue = newValue.charAt(0).toUpperCase() + newValue.slice(1); } - } - EventBus.emit('refresh', props.category); - }, [props.name, props.upperCaseFirst, props.element, props.category, props.onChange]); + localStorage.setItem(name, newValue); + setValue(newValue); + + if (onChange) { + onChange(newValue); + } + + if (element) { + if (!document.querySelector(element)) { + document.querySelector('.reminder-info').style.display = 'flex'; + return localStorage.setItem('showReminder', true); + } + } + + EventBus.emit('refresh', category); + }, + [name, upperCaseFirst, element, category, onChange], + ); const resetItem = useCallback(() => { handleChange({ target: { - value: props.default || '', + value: defaultValue || '', }, }); toast(variables.getMessage('toasts.reset')); - }, [handleChange, props.default]); + }, [handleChange, defaultValue]); return ( - <> - {props.textarea === true ? ( - +
+ {textarea === true ? ( +
+ {title && ( +
+ + + + {variables.getMessage('modals.main.settings.buttons.reset')} + +
+ )} +