1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { isGuideId, type GuideId } from "@/guides";
import { DEFAULT_GRID_CONFIG } from "@/guides/grid";
import type { GridConfig } from "@/guides/types";
type PreviewOverlaysState = Record<string, boolean>;
interface PersistedPreviewState {
activeGuide?: string | null;
layoutGuide?: {
platform?: string | null;
};
overlays?: PreviewOverlaysState;
gridConfig?: GridConfig;
}
interface PreviewState {
activeGuide: GuideId | null;
overlays: PreviewOverlaysState;
gridConfig: GridConfig;
toggleGuide: (guideId: GuideId) => void;
setGridConfig: (config: Partial<GridConfig>) => void;
setOverlayVisibility: ({
overlayId,
isVisible,
}: {
overlayId: string;
isVisible: boolean;
}) => void;
toggleOverlayVisibility: ({ overlayId }: { overlayId: string }) => void;
}
const DEFAULT_PREVIEW_OVERLAYS: PreviewOverlaysState = {};
function getPersistedActiveGuide(
state: PersistedPreviewState | undefined,
): GuideId | null {
const persistedGuide =
state?.activeGuide ?? state?.layoutGuide?.platform ?? null;
if (typeof persistedGuide !== "string") {
return null;
}
return isGuideId(persistedGuide) ? persistedGuide : null;
}
export const usePreviewStore = create<PreviewState>()(
persist(
(set) => ({
activeGuide: null,
overlays: DEFAULT_PREVIEW_OVERLAYS,
gridConfig: DEFAULT_GRID_CONFIG,
toggleGuide: (guideId) => {
set((state) => ({
activeGuide: state.activeGuide === guideId ? null : guideId,
}));
},
setGridConfig: (config) => {
set((state) => ({
gridConfig: { ...state.gridConfig, ...config },
}));
},
setOverlayVisibility: ({ overlayId, isVisible }) => {
set((state) => ({
overlays: {
...state.overlays,
[overlayId]: isVisible,
},
}));
},
toggleOverlayVisibility: ({ overlayId }) => {
set((state) => ({
overlays: {
...state.overlays,
[overlayId]: !state.overlays[overlayId],
},
}));
},
}),
{
name: "preview-settings",
version: 6,
migrate: (persistedState) => {
const state = persistedState as PersistedPreviewState | undefined;
return {
activeGuide: getPersistedActiveGuide(state),
overlays: DEFAULT_PREVIEW_OVERLAYS,
gridConfig: {
rows: state?.gridConfig?.rows ?? DEFAULT_GRID_CONFIG.rows,
cols: state?.gridConfig?.cols ?? DEFAULT_GRID_CONFIG.cols,
},
};
},
partialize: (state) => ({
activeGuide: state.activeGuide,
overlays: state.overlays,
gridConfig: state.gridConfig,
}),
},
),
);
|