Skip to content

Commit faf92a1

Browse files
committed
fix: Computing unsaved changes. now based on matching current preset with styles
1 parent 8d4557b commit faf92a1

File tree

3 files changed

+33
-37
lines changed

3 files changed

+33
-37
lines changed

components/editor/code-panel.tsx

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from "react";
1+
import { useMemo, useState } from "react";
22
import { Button } from "@/components/ui/button";
33
import { Copy, Check, Heart } from "lucide-react";
44
import { ThemeEditorState } from "@/types/editor";
@@ -38,9 +38,7 @@ const CodePanel: React.FC<CodePanelProps> = ({ themeEditorState }) => {
3838
const setPackageManager = usePreferencesStore(
3939
(state) => state.setPackageManager
4040
);
41-
const hasUnsavedChanges = useEditorStore(
42-
(state) => state.hasThemeChangedFromCheckpoint
43-
);
41+
const hasUnsavedChanges = useEditorStore((state) => state.hasUnsavedChanges);
4442

4543
const isSavedPreset = useThemePresetStore(
4644
(state) => preset && state.getPreset(preset)?.source === "SAVED"
@@ -101,27 +99,17 @@ const CodePanel: React.FC<CodePanelProps> = ({ themeEditorState }) => {
10199
}
102100
};
103101

102+
const showRegistryCommand = useMemo(() => {
103+
return preset && preset !== "default" && !hasUnsavedChanges();
104+
}, [preset, hasUnsavedChanges]);
105+
104106
return (
105107
<div className="h-full flex flex-col">
106108
<div className="flex-none mb-4">
107109
<div className="flex items-center justify-between gap-2">
108110
<h2 className="text-lg font-semibold">Theme Code</h2>
109111
</div>
110-
{preset && preset !== "default" && hasUnsavedChanges() && (
111-
<Alert className="mt-4">
112-
<AlertTitle>You have unsaved changes.</AlertTitle>
113-
<AlertDescription className="flex flex-col gap-2 mt-2">
114-
<div className="flex items-center gap-1">
115-
<div className="flex items-center gap-1 px-2 py-0.5 border rounded-md">
116-
<Heart className="size-3.5" />
117-
<span>Save</span>
118-
</div>
119-
your theme to get the registry command.
120-
</div>
121-
</AlertDescription>
122-
</Alert>
123-
)}
124-
{preset && preset !== "default" && !hasUnsavedChanges() && (
112+
{showRegistryCommand ? (
125113
<div className="mt-4 rounded-md overflow-hidden border">
126114
<div className="flex border-b">
127115
{(["pnpm", "npm", "yarn", "bun"] as const).map((pm) => (
@@ -158,13 +146,26 @@ const CodePanel: React.FC<CodePanelProps> = ({ themeEditorState }) => {
158146
<ScrollArea className="w-full">
159147
<div className="whitespace-nowrap overflow-y-hidden pb-2">
160148
<code className="text-sm font-mono">
161-
{getRegistryCommand(preset)}
149+
{getRegistryCommand(preset as string)}
162150
</code>
163151
</div>
164152
<ScrollBar orientation="horizontal" />
165153
</ScrollArea>
166154
</div>
167155
</div>
156+
) : (
157+
<Alert className="mt-4">
158+
<AlertTitle>You have unsaved changes.</AlertTitle>
159+
<AlertDescription className="flex flex-col gap-2 mt-2">
160+
<div className="flex items-center gap-1">
161+
<div className="flex items-center gap-1 px-2 py-0.5 border rounded-md">
162+
<Heart className="size-3.5" />
163+
<span>Save</span>
164+
</div>
165+
your theme to get the registry command.
166+
</div>
167+
</AlertDescription>
168+
</Alert>
168169
)}
169170
</div>
170171
<div className="flex items-center gap-2 mb-4 ">

components/editor/theme-preset-select.tsx

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
} from "../ui/tooltip";
3737
import { Input } from "../ui/input";
3838
import { Badge } from "../ui/badge";
39-
import { cn, isDeepEqual } from "@/lib/utils";
39+
import { cn } from "@/lib/utils";
4040

4141
interface ThemePresetSelectProps {
4242
presets: Record<string, ThemePreset>;
@@ -168,7 +168,7 @@ const ThemePresetSelect: React.FC<ThemePresetSelectProps> = ({
168168
currentPreset,
169169
onPresetChange,
170170
}) => {
171-
const { themeState, hasThemeChangedFromCheckpoint } = useEditorStore();
171+
const { themeState, hasUnsavedChanges } = useEditorStore();
172172
const { theme, toggleTheme } = useTheme();
173173
const mode = themeState.currentMode;
174174
const [search, setSearch] = useState("");
@@ -256,19 +256,6 @@ const ThemePresetSelect: React.FC<ThemePresetSelectProps> = ({
256256
);
257257
}, [filteredPresets, isSavedTheme]);
258258

259-
const hasUnsavedChanges = useMemo(() => {
260-
return (
261-
hasThemeChangedFromCheckpoint() ||
262-
(!currentPreset &&
263-
!isDeepEqual(themeState.styles, presets["default"]?.styles))
264-
);
265-
}, [
266-
hasThemeChangedFromCheckpoint,
267-
currentPreset,
268-
themeState.styles,
269-
presets,
270-
]);
271-
272259
return (
273260
<div className="flex items-center">
274261
<TooltipProvider>
@@ -290,7 +277,7 @@ const ThemePresetSelect: React.FC<ThemePresetSelectProps> = ({
290277
{value !== "default" &&
291278
value &&
292279
isSavedTheme(value) &&
293-
!hasUnsavedChanges && (
280+
!hasUnsavedChanges() && (
294281
<div className="rounded-full bg-muted p-1">
295282
<Heart
296283
className="size-1"
@@ -300,7 +287,7 @@ const ThemePresetSelect: React.FC<ThemePresetSelectProps> = ({
300287
</div>
301288
)}
302289
<span className="capitalize font-medium">
303-
{hasUnsavedChanges ? (
290+
{hasUnsavedChanges() ? (
304291
<>Custom (Unsaved)</>
305292
) : (
306293
presets[value || "default"]?.label || "default"

store/editor-store.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface EditorStore {
1313
saveThemeCheckpoint: () => void;
1414
restoreThemeCheckpoint: () => void;
1515
hasThemeChangedFromCheckpoint: () => boolean;
16+
hasUnsavedChanges: () => boolean;
1617
}
1718

1819
export const useEditorStore = create<EditorStore>()(
@@ -53,6 +54,13 @@ export const useEditorStore = create<EditorStore>()(
5354
const checkpoint = get().themeCheckpoint;
5455
return !isDeepEqual(get().themeState, checkpoint);
5556
},
57+
hasUnsavedChanges: () => {
58+
const themeState = get().themeState;
59+
const presetThemeStyles = getPresetThemeStyles(
60+
themeState.preset ?? "default"
61+
);
62+
return !isDeepEqual(themeState.styles, presetThemeStyles);
63+
},
5664
}),
5765
{
5866
name: "editor-storage",

0 commit comments

Comments
 (0)