diff --git a/package.json b/package.json index c1197b0..39d7d87 100644 --- a/package.json +++ b/package.json @@ -30,13 +30,13 @@ "next": "14.2.7", "next-themes": "^0.3.0", "numeral": "^2.0.6", + "nuqs": "^1.19.1", "react": "^18", "react-dom": "^18", "react-hook-form": "^7.53.0", "sonner": "^1.5.0", "tailwind-merge": "^2.5.2", "tailwindcss-animate": "^1.0.7", - "valtio": "^2.0.0", "zod": "^3.23.8" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc6a1f2..edd1916 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ dependencies: numeral: specifier: ^2.0.6 version: 2.0.6 + nuqs: + specifier: ^1.19.1 + version: 1.19.1(next@14.2.7) react: specifier: ^18 version: 18.3.1 @@ -83,9 +86,6 @@ dependencies: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.10) - valtio: - specifier: ^2.0.0 - version: 2.0.0(@types/react@18.3.5)(react@18.3.1) zod: specifier: ^3.23.8 version: 3.23.8 @@ -4048,6 +4048,10 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + dev: false + /module-details-from-path@1.0.3: resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} dev: false @@ -4155,6 +4159,15 @@ packages: resolution: {integrity: sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==} dev: false + /nuqs@1.19.1(next@14.2.7): + resolution: {integrity: sha512-oixldNThB1wbu6B5K961++7wpTz/EZFPWnraGmIQhibDT+YxRJNplWMIoPJgL4dlsiSDVI5bbUWKpzsIWVh3Pg==} + peerDependencies: + next: '>=13.4 <14.0.2 || ^14.0.3' + dependencies: + mitt: 3.0.1 + next: 14.2.7(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(react-dom@18.3.1)(react@18.3.1) + dev: false + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -4528,10 +4541,6 @@ packages: react-is: 16.13.1 dev: true - /proxy-compare@3.0.0: - resolution: {integrity: sha512-y44MCkgtZUCT9tZGuE278fB7PWVf7fRYy0vbRXAts2o5F0EfC4fIQrvQQGBJo1WJbFcVLXzApOscyJuZqHQc1w==} - dev: false - /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: false @@ -5310,23 +5319,6 @@ packages: hasBin: true dev: false - /valtio@2.0.0(@types/react@18.3.5)(react@18.3.1): - resolution: {integrity: sha512-SzUU5UUK/vBRfHWXihwkJE55YNj8zhOkzxPOexcz0xIIT6Oux5VLynCmzyME2bYuEWcktW2NTaaLbpUydEsHiw==} - engines: {node: '>=12.20.0'} - peerDependencies: - '@types/react': '>=18.0.0' - react: '>=18.0.0' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - dependencies: - '@types/react': 18.3.5 - proxy-compare: 3.0.0 - react: 18.3.1 - dev: false - /watchpack@2.4.2: resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} engines: {node: '>=10.13.0'} diff --git a/src/components/controls/controls-background.tsx b/src/components/controls/controls-background.tsx index 04d846c..3320b47 100644 --- a/src/components/controls/controls-background.tsx +++ b/src/components/controls/controls-background.tsx @@ -1,20 +1,18 @@ "use client"; -import { previewStore, usePreviewStore } from "~/lib/store/preview.store"; +import { useControls } from "~/lib/params/controls.params"; import { Tooltip } from "../ui/tooltip"; import { ControlsToggle } from "./controls-toggle"; export function ControlsBackground() { - const { background } = usePreviewStore(); + const [{ background }, setControls] = useControls(); return (
{ - previewStore.background = !checked; - }} + onPressedChange={(checked) => setControls({ background: !checked })} >
{ - previewStore.darkMode = checked; - }} + onPressedChange={(checked) => setControls({ darkMode: checked })} > diff --git a/src/components/controls/controls-download.tsx b/src/components/controls/controls-download.tsx index 006c92d..13a4e06 100644 --- a/src/components/controls/controls-download.tsx +++ b/src/components/controls/controls-download.tsx @@ -7,7 +7,7 @@ import { toast } from "sonner"; import { EXPORT_SIZES } from "~/lib/const/export-size.const"; import { download } from "~/lib/download"; import { toBlob, toPng, toSvg } from "~/lib/image"; -import { previewStore, usePreviewStore } from "~/lib/store/preview.store"; +import { useControls } from "~/lib/params/controls.params"; import { Button } from "../ui/button"; import { DropdownMenu, @@ -26,7 +26,7 @@ import { Tooltip } from "../ui/tooltip"; export function ControlsDownload() { const params = useParams(); - const { size } = usePreviewStore(); + const [{ size }, setControls] = useControls(); function savePng() { const node = document.getElementById("preview"); @@ -123,7 +123,7 @@ export function ControlsDownload() { (previewStore.size = size)} + onClick={() => setControls({ size })} > {size}x diff --git a/src/components/controls/controls-padding.tsx b/src/components/controls/controls-padding.tsx index 1146f9b..63b880d 100644 --- a/src/components/controls/controls-padding.tsx +++ b/src/components/controls/controls-padding.tsx @@ -1,12 +1,12 @@ "use client"; import { PADDING_OPTIONS } from "~/lib/const/padding.const"; -import { previewStore, usePreviewStore } from "~/lib/store/preview.store"; +import { useControls } from "~/lib/params/controls.params"; import { cn } from "~/lib/utils"; import { Button } from "../ui/button"; export function ControlsPadding() { - const snapshot = usePreviewStore(); + const [{ padding: controlsPadding }, setControls] = useControls(); return (
@@ -17,11 +17,11 @@ export function ControlsPadding() { size="icon" className={cn( "relative size-6 text-xs", - padding === snapshot.padding + padding === controlsPadding ? "text-foreground after:absolute after:-bottom-[3px] after:left-1/2 after:size-1 after:-translate-x-1/2 after:rounded-full after:bg-primary/20 after:content-['']" : null, )} - onClick={() => (previewStore.padding = padding)} + onClick={() => setControls({ padding })} > {padding} diff --git a/src/components/controls/controls-theme.tsx b/src/components/controls/controls-theme.tsx index 2d8d072..88a1fde 100644 --- a/src/components/controls/controls-theme.tsx +++ b/src/components/controls/controls-theme.tsx @@ -1,18 +1,18 @@ "use client"; import { Theme, THEME_OPTIONS } from "~/lib/const/theme.const"; -import { previewStore, usePreviewStore } from "~/lib/store/preview.store"; +import { useControls } from "~/lib/params/controls.params"; import { themeBackground } from "~/lib/utils"; import { Select, SelectContent, SelectItem, SelectTrigger } from "../ui/select"; import { Tooltip } from "../ui/tooltip"; export function ControlsTheme() { - const { theme } = usePreviewStore(); + const [{ theme }, setControls] = useControls(); return (