diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index d278a405f..2991189a2 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -20,6 +20,7 @@ "i18next": "^23.5.1", "i18next-browser-languagedetector": "^7.1.0", "i18next-http-backend": "^2.2.2", + "jotai": "^2.4.3", "lucide-react": "^0.279.0", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -39,6 +40,7 @@ "devDependencies": { "@iconify/json": "^2.2.122", "@radix-ui/colors": "^3.0.0-rc.5", + "@swc-jotai/debug-label": "^0.1.0", "@types/react": "^18.2.24", "@types/react-dom": "^18.2.8", "@typescript-eslint/eslint-plugin": "^6.7.3", @@ -56,6 +58,7 @@ "postcss": "^8.4.31", "prettier": "^3.0.3", "react-git-info": "^2.0.1", + "rollup-plugin-bundle-analyzer": "^1.6.6", "sass": "^1.68.0", "tailwindcss": "^3.3.3", "typescript": "^5.2.2", @@ -1121,6 +1124,16 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", @@ -2439,6 +2452,12 @@ } } }, + "node_modules/@swc-jotai/debug-label": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@swc-jotai/debug-label/-/debug-label-0.1.0.tgz", + "integrity": "sha512-Fe0ag02uBaVBIS/ySKkLSyiMhTUKyw3F0pTAcH+Yc29wZgIt//yFuPv1+p0QrlV6n411BJ0sxq2ei89tvwpFXQ==", + "dev": true + }, "node_modules/@swc/core": { "version": "1.3.91", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.91.tgz", @@ -3699,6 +3718,12 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "node_modules/bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -5179,6 +5204,26 @@ "jiti": "bin/jiti.js" } }, + "node_modules/jotai": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.4.3.tgz", + "integrity": "sha512-CSAHX9LqWG5WCrU8OgBoZbBJ+Bo9rQU0mPusEF4e0CZ/SNFgurG26vb3UpgvCSJZgYVcUQNiUBM5q86PA8rstQ==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=17.0.0", + "react": ">=17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", @@ -5551,6 +5596,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -5995,6 +6046,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -6839,6 +6899,135 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-bundle-analyzer": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/rollup-plugin-bundle-analyzer/-/rollup-plugin-bundle-analyzer-1.6.6.tgz", + "integrity": "sha512-H4FawRu0fkM+FC1GievBoQ1nN23AQHkffIgdZzMFCN3LOdpFzSH+Djwz14lrlT7ZzO5356aaip+McQ7kQtYZ6Q==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.21", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "terser": "^5.15.1", + "ws": "^7.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-bundle-analyzer/node_modules/totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/rtl-css-js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", @@ -7134,6 +7323,16 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -7393,6 +7592,30 @@ "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/terser": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", + "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -7931,6 +8154,27 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xstate": { "version": "4.38.2", "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.38.2.tgz", @@ -8669,6 +8913,16 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", @@ -9395,6 +9649,12 @@ "picomatch": "^2.3.1" } }, + "@swc-jotai/debug-label": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@swc-jotai/debug-label/-/debug-label-0.1.0.tgz", + "integrity": "sha512-Fe0ag02uBaVBIS/ySKkLSyiMhTUKyw3F0pTAcH+Yc29wZgIt//yFuPv1+p0QrlV6n411BJ0sxq2ei89tvwpFXQ==", + "dev": true + }, "@swc/core": { "version": "1.3.91", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.91.tgz", @@ -10240,6 +10500,12 @@ "update-browserslist-db": "^1.0.13" } }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -11311,6 +11577,12 @@ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==" }, + "jotai": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.4.3.tgz", + "integrity": "sha512-CSAHX9LqWG5WCrU8OgBoZbBJ+Bo9rQU0mPusEF4e0CZ/SNFgurG26vb3UpgvCSJZgYVcUQNiUBM5q86PA8rstQ==", + "requires": {} + }, "js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", @@ -11516,6 +11788,12 @@ "p-locate": "^5.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -11853,6 +12131,12 @@ "is-wsl": "^2.2.0" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -12394,6 +12678,96 @@ "fsevents": "~2.3.2" } }, + "rollup-plugin-bundle-analyzer": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/rollup-plugin-bundle-analyzer/-/rollup-plugin-bundle-analyzer-1.6.6.tgz", + "integrity": "sha512-H4FawRu0fkM+FC1GievBoQ1nN23AQHkffIgdZzMFCN3LOdpFzSH+Djwz14lrlT7ZzO5356aaip+McQ7kQtYZ6Q==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.21", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "terser": "^5.15.1", + "ws": "^7.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "dev": true, + "requires": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true + } + } + }, "rtl-css-js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", @@ -12601,6 +12975,16 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -12791,6 +13175,26 @@ "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", "requires": {} }, + "terser": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", + "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -13120,6 +13524,13 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "requires": {} + }, "xstate": { "version": "4.38.2", "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.38.2.tgz", diff --git a/packages/react/package.json b/packages/react/package.json index 4209f387b..25d9672e4 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -22,6 +22,7 @@ "i18next": "^23.5.1", "i18next-browser-languagedetector": "^7.1.0", "i18next-http-backend": "^2.2.2", + "jotai": "^2.4.3", "lucide-react": "^0.279.0", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -41,6 +42,7 @@ "devDependencies": { "@iconify/json": "^2.2.122", "@radix-ui/colors": "^3.0.0-rc.5", + "@swc-jotai/debug-label": "^0.1.0", "@types/react": "^18.2.24", "@types/react-dom": "^18.2.8", "@typescript-eslint/eslint-plugin": "^6.7.3", @@ -58,6 +60,7 @@ "postcss": "^8.4.31", "prettier": "^3.0.3", "react-git-info": "^2.0.1", + "rollup-plugin-bundle-analyzer": "^1.6.6", "sass": "^1.68.0", "tailwindcss": "^3.3.3", "typescript": "^5.2.2", diff --git a/packages/react/src/components/layout/Frame.tsx b/packages/react/src/components/layout/Frame.tsx index 853e8862f..25f4fa4f1 100644 --- a/packages/react/src/components/layout/Frame.tsx +++ b/packages/react/src/components/layout/Frame.tsx @@ -1,31 +1,37 @@ -import { ScrollArea } from '@radix-ui/themes' import './Frame.scss' import { RouterProvider } from 'react-router-dom' import router from '../../routes/router' -import { frameContext } from './useFrame' import { useSnapshot } from 'valtio' import { useEffect } from 'react' import classNames from 'classnames' import { Sidebar } from '../sidebar/sidebar' +import { isFloatingAtom, isMobileAtom, onResizeAtom, sidebarOpenAtom, sidebarShouldBeFullscreenAtom, toggleAtom } from './useFrame' +import { useAtom } from 'jotai/react' export function Frame() { - const fc = useSnapshot(frameContext); + const [, toggle] = useAtom(toggleAtom) + const [, resize] = useAtom(onResizeAtom) useEffect(() => { - window.addEventListener("resize", fc.onResize); - return () => window.removeEventListener("resize", fc.onResize) + window.addEventListener("resize", resize); + return () => window.removeEventListener("resize", resize) }, []); - const sidebarClasses = classNames() + + const [floating] = useAtom(isFloatingAtom) + const [open] = useAtom(sidebarOpenAtom) + const [isMobile] = useAtom(isMobileAtom) + const [fs] = useAtom(sidebarShouldBeFullscreenAtom) + console.log(fs) const mainClasses = classNames({ - 'mobile-footer': fc.isMobile, - 'sidebar-static': !fc.isFloating, - 'sidebar-floating': fc.isFloating, - 'sidebar-open': fc.sidebarOpen, - 'sidebar-closed': !fc.sidebarOpen, - 'sidebar-fullscreen': fc.sidebarShouldBeFullscreen, + 'mobile-footer': isMobile, + 'sidebar-static': !floating, + 'sidebar-floating': floating, + 'sidebar-open': open, + 'sidebar-closed': !open, + 'sidebar-fullscreen': fs, }) return ( @@ -34,14 +40,12 @@ export function Frame() {
Header - +
- - - +
- {fc.isMobile && } + {isMobile && } ) } \ No newline at end of file diff --git a/packages/react/src/components/layout/useFrame.ts b/packages/react/src/components/layout/useFrame.ts index e220dc87a..f1097884f 100644 --- a/packages/react/src/components/layout/useFrame.ts +++ b/packages/react/src/components/layout/useFrame.ts @@ -1,62 +1,73 @@ -import { proxyWithPersist } from '@/valtio-persist'; -import { proxy } from 'valtio'; +import { atom } from 'jotai'; +import { atomWithStorage } from 'jotai/utils'; const MobileSizeBreak = 768; const FooterSizeBreak = 500; -export const frameContext = proxy({ - pageIsFullscreen: false, - siteIsSmall: window.innerWidth < MobileSizeBreak, - sidebarShouldBeFullscreen: window.innerWidth < FooterSizeBreak, +export const sidebarPrefOpenAtom = atomWithStorage('frames_sidebar_pref_open', true); - get isFloating() { - return frameContext.siteIsSmall || frameContext.pageIsFullscreen - }, +export const pageIsFullscreenAtom = atom(false); - get isMobile() { - return frameContext.sidebarShouldBeFullscreen //&& /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) - }, +export const siteIsSmallAtom = atom(window.innerWidth < MobileSizeBreak); - // it's always open at init unless it's small. - sidebarOpen: window.innerWidth > MobileSizeBreak, - // sidebar would stay open if it could. - sidebarPrefOpen: true, +export const sidebarShouldBeFullscreenAtom = atom(window.innerWidth < FooterSizeBreak); - onResize: () => { +export const isFloatingAtom = atom( + (get) => get(siteIsSmallAtom) || get(pageIsFullscreenAtom) +); + +export const isMobileAtom = atom( + (get) => get(sidebarShouldBeFullscreenAtom) //&& /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) +); + +export const sidebarOpenAtom = atom(window.innerWidth > MobileSizeBreak); + +export const onResizeAtom = atom( + null, + (_, set) => { const width = window.innerWidth; - frameContext.siteIsSmall = width < MobileSizeBreak - frameContext.sidebarShouldBeFullscreen = width < FooterSizeBreak - }, - - onNavigate: (pageIsFullscreen: boolean) => { - if (frameContext.pageIsFullscreen != pageIsFullscreen && pageIsFullscreen) { - // hide the sidebar if we are navigating from a non-fullscreen page to a fullscreen page - frameContext.sidebarOpen = false; + set(siteIsSmallAtom, width < MobileSizeBreak); + set(sidebarShouldBeFullscreenAtom, width < FooterSizeBreak); + } +); + +export const onNavigateAtom = atom( + null, + (get, set, pageIsFullscreen: boolean) => { + const currentFullscreenStatus = get(pageIsFullscreenAtom); + if (currentFullscreenStatus !== pageIsFullscreen && pageIsFullscreen) { + set(sidebarOpenAtom, false); } - else if (frameContext.pageIsFullscreen != pageIsFullscreen && !pageIsFullscreen) { - // show the sidebar if we are navigating from a fullscreen page to a non-fullscreen page, but only if the preference is to be open. - // if a user has closed it then it'll prefer to stay closed. - // TODO maybe extract prefOpen into a separate stored state for long term? - frameContext.sidebarOpen = frameContext.sidebarPrefOpen + else if (currentFullscreenStatus !== pageIsFullscreen && !pageIsFullscreen) { + set(sidebarOpenAtom, get(sidebarPrefOpenAtom)); } - if (frameContext.pageIsFullscreen != pageIsFullscreen) { - frameContext.pageIsFullscreen = pageIsFullscreen + if (currentFullscreenStatus !== pageIsFullscreen) { + set(pageIsFullscreenAtom, pageIsFullscreen); } - }, - - toggle: () => { - frameContext.sidebarOpen = !frameContext.sidebarOpen; - frameContext.sidebarPrefOpen = frameContext.sidebarOpen; - }, + } +); - open: () => { - frameContext.sidebarOpen = true; - frameContext.sidebarPrefOpen = frameContext.sidebarOpen; - }, +export const toggleAtom = atom( + null, + (get, set) => { + const currentOpenStatus = get(sidebarOpenAtom); + set(sidebarOpenAtom, !currentOpenStatus); + set(sidebarPrefOpenAtom, !currentOpenStatus); + } +); - close: () => { - frameContext.sidebarOpen = true; - frameContext.sidebarPrefOpen = frameContext.sidebarOpen; +export const openAtom = atom( + null, + (_, set) => { + set(sidebarOpenAtom, true); + set(sidebarPrefOpenAtom, true); } -}) +); +export const closeAtom = atom( + null, + (_, set) => { + set(sidebarOpenAtom, false); + set(sidebarPrefOpenAtom, false); + } +); \ No newline at end of file diff --git a/packages/react/src/components/sidebar/sidebar.tsx b/packages/react/src/components/sidebar/sidebar.tsx index b67ae1b2d..da9a05701 100644 --- a/packages/react/src/components/sidebar/sidebar.tsx +++ b/packages/react/src/components/sidebar/sidebar.tsx @@ -1,6 +1,6 @@ import { cn } from "@/lib/utils" import { Button } from "@/shadcn/ui/button" -import { ScrollArea } from "@/shadcn/ui/scroll-area" +// import { ScrollArea } from "@/shadcn/ui/scroll-area" interface SidebarProps extends React.HTMLAttributes { } @@ -55,9 +55,9 @@ export function Sidebar({ className, id }: SidebarProps) {

Favorites

- + {/*
- {/* {playlists?.map((playlist, i) => ( + {playlists?.map((playlist, i) => ( - ))} */} + ))}
-
+
*/} diff --git a/packages/react/src/valtio-persist/index.ts b/packages/react/src/valtio-persist/index.ts index 55eb68bd5..2e87b8aeb 100644 --- a/packages/react/src/valtio-persist/index.ts +++ b/packages/react/src/valtio-persist/index.ts @@ -16,10 +16,12 @@ export function proxyWithPersist(key: string, initialObject: T const storageItem = localStorage.getItem(key); const state = proxy({ - ...initialObject, - ...(storageItem !== null ? JSON.parse(storageItem) : {}) + initialObject, + // ...(storageItem !== null ? JSON.parse(storageItem) : {}) } as T); + state + subscribe(state, () => { const subobject = pick(initialObject, ...persistFields) localStorage.setItem(key, JSON.stringify(subobject)) diff --git a/packages/react/vite.config.ts b/packages/react/vite.config.ts index b78f99a6f..8504443e3 100644 --- a/packages/react/vite.config.ts +++ b/packages/react/vite.config.ts @@ -4,19 +4,23 @@ import react from "@vitejs/plugin-react-swc"; import UnoCSS from 'unocss/vite' import presetIcons from "@unocss/preset-icons"; import { fileURLToPath, URL } from "url"; +import bundleAnalyzer from "rollup-plugin-bundle-analyzer"; // import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react(), UnoCSS({ presets: [presetIcons()], })], + build: { + // sourcemap: true + }, + plugins: [bundleAnalyzer({}), react({ plugins: [['@swc-jotai/debug-label', {}]] }), UnoCSS({ presets: [presetIcons()], })], resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), }, }, - css: { - modules: { - localsConvention: 'camelCaseOnly' - } - } + // css: { + // modules: { + // localsConvention: 'camelCaseOnly' + // } + // } });