diff --git a/package.json b/package.json index 0d2976d..bb6a9e5 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ ], "repository": "github:phosphor-icons/homepage", "private": true, - "packageManager": "pnpm@9", + "packageManager": "pnpm@10.6.3", "scripts": { "dev": "vite", "build": "tsc && vite build", @@ -31,8 +31,7 @@ }, "dependencies": { "@phosphor-icons/core": "^2.1.1", - "@phosphor-icons/react": "^2.1.4", - "@recoiljs/refine": "^0.1.1", + "@phosphor-icons/react": "^2.1.8", "file-saver": "^2.0.2", "framer-motion": "^10.17.12", "fuse.js": "^6.4.1", @@ -41,10 +40,9 @@ "react-dropdown-select": "^4.4.2", "react-ga4": "^2.1.0", "react-hotkeys-hook": "^4.4.3", - "recoil": "^0.7.7", - "recoil-sync": "^0.2.0", "svg2png-converter": "^1.0.2", - "tinycolor2": "^1.4.2" + "tinycolor2": "^1.4.2", + "zustand": "^5.0.4" }, "devDependencies": { "@types/file-saver": "^2.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6f640a3..a05d9c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,17 +12,14 @@ importers: specifier: ^2.1.1 version: 2.1.1 '@phosphor-icons/react': - specifier: ^2.1.4 - version: 2.1.4(react-dom@18.2.0)(react@18.2.0) - '@recoiljs/refine': - specifier: ^0.1.1 - version: 0.1.1 + specifier: ^2.1.8 + version: 2.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0) file-saver: specifier: ^2.0.2 version: 2.0.5 framer-motion: specifier: ^10.17.12 - version: 10.17.12(react-dom@18.2.0)(react@18.2.0) + version: 10.17.12(react-dom@18.2.0(react@18.2.0))(react@18.2.0) fuse.js: specifier: ^6.4.1 version: 6.6.2 @@ -34,25 +31,22 @@ importers: version: 18.2.0(react@18.2.0) react-dropdown-select: specifier: ^4.4.2 - version: 4.11.0(@types/react@18.2.47)(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + version: 4.11.0(@types/react@18.2.47)(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-ga4: specifier: ^2.1.0 version: 2.1.0 react-hotkeys-hook: specifier: ^4.4.3 - version: 4.4.3(react-dom@18.2.0)(react@18.2.0) - recoil: - specifier: ^0.7.7 - version: 0.7.7(react-dom@18.2.0)(react@18.2.0) - recoil-sync: - specifier: ^0.2.0 - version: 0.2.0(recoil@0.7.7) + version: 4.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) svg2png-converter: specifier: ^1.0.2 version: 1.0.2 tinycolor2: specifier: ^1.4.2 version: 1.6.0 + zustand: + specifier: ^5.0.4 + version: 5.0.4(@types/react@18.2.47)(react@18.2.0) devDependencies: '@types/file-saver': specifier: ^2.0.5 @@ -71,7 +65,7 @@ importers: version: 1.4.6 '@vitejs/plugin-react': specifier: ^3.1.0 - version: 3.1.0(vite@4.5.2) + version: 3.1.0(vite@4.5.2(@types/node@18.19.6)) iconjar-exporter: specifier: ^1.0.10 version: 1.0.10 @@ -89,7 +83,7 @@ importers: version: 4.5.2(@types/node@18.19.6) vite-plugin-svgr: specifier: ^2.4.0 - version: 2.4.0(vite@4.5.2) + version: 2.4.0(rollup@3.29.4)(vite@4.5.2(@types/node@18.19.6)) packages: @@ -555,16 +549,13 @@ packages: '@phosphor-icons/core@2.1.1': resolution: {integrity: sha512-v4ARvrip4qBCImOE5rmPUylOEK4iiED9ZyKjcvzuezqMaiRASCHKcRIuvvxL/twvLpkfnEODCOJp5dM4eZilxQ==} - '@phosphor-icons/react@2.1.4': - resolution: {integrity: sha512-EeNwgcg1aeK5vG/JYVTullnZzk5zjftOrjLb1iYetyhn5ImFFREc+xG0FAB/dAY277DGDSF8pNdNbqG1SUKIxQ==} + '@phosphor-icons/react@2.1.8': + resolution: {integrity: sha512-RxJlAkErO+t50DsY82ga9RGOULK6Jux0MdmXqvDjtOzG3PYQFz6rjdUU2q06lPMMbJTT+d+qurKYmF7i2Uv74A==} engines: {node: '>=10'} peerDependencies: react: '>= 16.8' react-dom: '>= 16.8' - '@recoiljs/refine@0.1.1': - resolution: {integrity: sha512-ry02rHswJePYkH1o8K99qL4O6TBntF9/g7W5wXVwaOUrIJEZUGfl/I3+btPXbUgyyEZvNs5xcwvOw13AufmFQw==} - '@rollup/pluginutils@5.1.0': resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -806,9 +797,6 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - hamt_plus@1.0.2: - resolution: {integrity: sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA==} - has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -944,23 +932,6 @@ packages: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} - recoil-sync@0.2.0: - resolution: {integrity: sha512-ZYZM1C4LAhGr3EeMMI5MwT4eaEqsr+ddjB4EwdgN8HXXLmE7P5FVCdFHV3HJtMzxR3Y8sOmJDfN1IPrezwKoRg==} - peerDependencies: - recoil: '>=0.7.3' - - recoil@0.7.7: - resolution: {integrity: sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==} - peerDependencies: - react: '>=16.13.1' - react-dom: '*' - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true - regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} @@ -1019,10 +990,6 @@ packages: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} - transit-js@0.8.874: - resolution: {integrity: sha512-IDJJGKRzUbJHmN0P15HBBa05nbKor3r2MmG6aSt0UxXIlJZZKcddTk67/U7WyAeW9Hv/VYI02IqLzolsC4sbPA==} - engines: {node: '>= 0.10.0'} - tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} @@ -1085,6 +1052,24 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + zustand@5.0.4: + resolution: {integrity: sha512-39VFTN5InDtMd28ZhjLyuTnlytDr9HfwO512Ai4I8ZABCoyAj4F1+sr7sD1jP/+p7k77Iko0Pb5NhgBFDCX0kQ==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + snapshots: '@ampproject/remapping@2.2.1': @@ -1280,9 +1265,10 @@ snapshots: '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 - '@types/react': 18.2.47 hoist-non-react-statics: 3.3.2 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.47 '@emotion/serialize@1.1.3': dependencies: @@ -1294,7 +1280,7 @@ snapshots: '@emotion/sheet@1.2.2': {} - '@emotion/styled@11.11.0(@emotion/react@11.11.0)(@types/react@18.2.47)(react@18.2.0)': + '@emotion/styled@11.11.0(@emotion/react@11.11.0(@types/react@18.2.47)(react@18.2.0))(@types/react@18.2.47)(react@18.2.0)': dependencies: '@babel/runtime': 7.23.8 '@emotion/babel-plugin': 11.11.0 @@ -1303,8 +1289,9 @@ snapshots: '@emotion/serialize': 1.1.3 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 - '@types/react': 18.2.47 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.47 '@emotion/unitless@0.8.1': {} @@ -1470,18 +1457,18 @@ snapshots: '@phosphor-icons/core@2.1.1': {} - '@phosphor-icons/react@2.1.4(react-dom@18.2.0)(react@18.2.0)': + '@phosphor-icons/react@2.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - '@recoiljs/refine@0.1.1': {} - - '@rollup/pluginutils@5.1.0': + '@rollup/pluginutils@5.1.0(rollup@3.29.4)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 + optionalDependencies: + rollup: 3.29.4 '@svgr/babel-plugin-add-jsx-attribute@6.5.1(@babel/core@7.23.7)': dependencies: @@ -1578,7 +1565,7 @@ snapshots: '@types/tinycolor2@1.4.6': {} - '@vitejs/plugin-react@3.1.0(vite@4.5.2)': + '@vitejs/plugin-react@3.1.0(vite@4.5.2(@types/node@18.19.6))': dependencies: '@babel/core': 7.23.7 '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.7) @@ -1713,13 +1700,13 @@ snapshots: find-root@1.1.0: {} - framer-motion@10.17.12(react-dom@18.2.0)(react@18.2.0): + framer-motion@10.17.12(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) tslib: 2.6.2 optionalDependencies: '@emotion/is-prop-valid': 0.8.8 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) fsevents@2.3.3: optional: true @@ -1736,8 +1723,6 @@ snapshots: globals@11.12.0: {} - hamt_plus@1.0.2: {} - has-flag@3.0.0: {} hasown@2.0.0: @@ -1830,10 +1815,10 @@ snapshots: react: 18.2.0 scheduler: 0.23.0 - react-dropdown-select@4.11.0(@types/react@18.2.47)(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): + react-dropdown-select@4.11.0(@types/react@18.2.47)(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@emotion/react': 11.11.0(@types/react@18.2.47)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.0)(@types/react@18.2.47)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.0(@types/react@18.2.47)(react@18.2.0))(@types/react@18.2.47)(react@18.2.0) prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1842,7 +1827,7 @@ snapshots: react-ga4@2.1.0: {} - react-hotkeys-hook@4.4.3(react-dom@18.2.0)(react@18.2.0): + react-hotkeys-hook@4.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1855,18 +1840,6 @@ snapshots: dependencies: loose-envify: 1.4.0 - recoil-sync@0.2.0(recoil@0.7.7): - dependencies: - '@recoiljs/refine': 0.1.1 - recoil: 0.7.7(react-dom@18.2.0)(react@18.2.0) - transit-js: 0.8.874 - - recoil@0.7.7(react-dom@18.2.0)(react@18.2.0): - dependencies: - hamt_plus: 1.0.2 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - regenerator-runtime@0.14.1: {} resolve-from@4.0.0: {} @@ -1909,8 +1882,6 @@ snapshots: to-fast-properties@2.0.0: {} - transit-js@0.8.874: {} - tslib@2.6.2: {} tsx@4.7.3: @@ -1930,9 +1901,9 @@ snapshots: escalade: 3.1.1 picocolors: 1.0.0 - vite-plugin-svgr@2.4.0(vite@4.5.2): + vite-plugin-svgr@2.4.0(rollup@3.29.4)(vite@4.5.2(@types/node@18.19.6)): dependencies: - '@rollup/pluginutils': 5.1.0 + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) '@svgr/core': 6.5.1 vite: 4.5.2(@types/node@18.19.6) transitivePeerDependencies: @@ -1941,13 +1912,18 @@ snapshots: vite@4.5.2(@types/node@18.19.6): dependencies: - '@types/node': 18.19.6 esbuild: 0.18.20 postcss: 8.4.33 rollup: 3.29.4 optionalDependencies: + '@types/node': 18.19.6 fsevents: 2.3.3 yallist@3.1.1: {} yaml@1.10.2: {} + + zustand@5.0.4(@types/react@18.2.47)(react@18.2.0): + optionalDependencies: + '@types/react': 18.2.47 + react: 18.2.0 diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx index 99de892..2ce7e3c 100644 --- a/src/components/App/App.tsx +++ b/src/components/App/App.tsx @@ -1,5 +1,4 @@ import { Fragment, Suspense, useMemo } from "react"; -import { useRecoilValue } from "recoil"; import "./App.css"; import Header from "@/components/Header"; @@ -10,13 +9,13 @@ import ErrorBoundary from "@/components/ErrorBoundary"; import Notice from "@/components/Notice"; // import Recipes from "@/components/Recipes"; import { useCSSVariables } from "@/hooks"; -import { isDarkThemeSelector } from "@/state"; +import { ApplicationTheme, useApplicationStore } from "@/state"; const errorFallback = ; const waitingFallback = ; const App: React.FC = () => { - const isDark = useRecoilValue(isDarkThemeSelector); + const isDark = useApplicationStore.use.applicationTheme() === ApplicationTheme.DARK; useCSSVariables( useMemo( diff --git a/src/components/Banner/Banner.tsx b/src/components/Banner/Banner.tsx index 78afdf7..cb5b827 100644 --- a/src/components/Banner/Banner.tsx +++ b/src/components/Banner/Banner.tsx @@ -1,6 +1,6 @@ import { ReactNode, Dispatch, SetStateAction } from "react"; import { motion, AnimatePresence, Variants } from "framer-motion"; -import { XCircle } from "@phosphor-icons/react"; +import { XCircleIcon } from "@phosphor-icons/react"; import ReactGA from "react-ga4"; import { useLocalStorage } from "@/hooks"; @@ -44,9 +44,9 @@ const Banner = ({ id, children, onClose }: BannerProps) => { onClose ? onClose(setBannerState) : setBannerState((state) => ({ - ...state, - seen: { ...state.seen, [id]: true }, - })); + ...state, + seen: { ...state.seen, [id]: true }, + })); }; return ( @@ -69,7 +69,7 @@ const Banner = ({ id, children, onClose }: BannerProps) => { e.key === "Enter" && handleClose(); }} > - + diff --git a/src/components/ColorInput/ColorInput.tsx b/src/components/ColorInput/ColorInput.tsx index 2fc03e9..c9062d1 100644 --- a/src/components/ColorInput/ColorInput.tsx +++ b/src/components/ColorInput/ColorInput.tsx @@ -1,17 +1,20 @@ import { useCallback } from "react"; -import { useRecoilState, useRecoilValue } from "recoil"; -import { EyedropperSample } from "@phosphor-icons/react"; +import { useShallow } from "zustand/react/shallow"; +import { EyedropperSampleIcon } from "@phosphor-icons/react"; import { useThrottled } from "@/hooks"; -import { iconColorAtom, isDarkThemeSelector } from "@/state"; +import { ApplicationTheme, useApplicationStore } from "@/state"; import "./ColorInput.css"; type ColorInputProps = {}; const ColorInput = (_: ColorInputProps) => { - const [color, setColor] = useRecoilState(iconColorAtom); - const isDark = useRecoilValue(isDarkThemeSelector); + const { color, setColor, theme } = useApplicationStore(useShallow((state) => ({ + color: state.iconColor, + setColor: state.setIconColor, + theme: state.applicationTheme, + }))); const handleColorChange = useCallback( (event: React.ChangeEvent) => { @@ -46,9 +49,9 @@ const ColorInput = (_: ColorInputProps) => { onChange={throttledColorChange} value={color} /> - + {color === "currentColor" ? ( - + ) : ( color )} diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index 6d716c2..9c23ea5 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -1,13 +1,12 @@ -import { useRecoilValue } from "recoil"; import { motion, AnimatePresence, Variants } from "framer-motion"; -import { ArrowULeftUp, Coffee, HandHeart } from "@phosphor-icons/react"; +import { ArrowULeftUpIcon, CoffeeIcon, HandHeartIcon } from "@phosphor-icons/react"; import Links from "@/components/Links/Links"; import { ReactComponent as RulerMarker } from "@/assets/ruler-marker.svg"; import { ReactComponent as RulerMarkerSpec } from "@/assets/ruler-marker-spec.svg"; import { useMediaQuery } from "@/hooks"; -import { selectionEntryAtom } from "@/state"; +import { useApplicationStore } from "@/state"; import "./Footer.css"; type FooterProps = {}; @@ -20,7 +19,7 @@ const variants: Variants = { const Footer = (_: FooterProps) => { const isMobile = useMediaQuery("(max-width: 719px)"); - const isViewing = !!useRecoilValue(selectionEntryAtom); + const isViewing = !!useApplicationStore.use.selectionEntry(); return (