Major improvements to UI state management and user preferences: - Add theme toggle with dark/light mode support - Implement Zustand persist middleware for UI state - Add ui-store for panel layout preferences (dock width, heights, tabs) - Persist tool settings (active tool, size, opacity, hardness, etc.) - Persist canvas view preferences (grid, rulers, snap-to-grid) - Persist shape tool settings - Persist collapsible section states - Fix canvas coordinate transformation for centered rendering - Constrain checkerboard and grid to canvas bounds - Add icons to all tab buttons and collapsible sections - Restructure panel-dock to use persisted state Storage impact: ~3.5KB total across all preferences Storage keys: tool-storage, canvas-view-storage, shape-storage, ui-storage 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
93 lines
2.4 KiB
TypeScript
93 lines
2.4 KiB
TypeScript
import { create } from 'zustand';
|
|
import { persist } from 'zustand/middleware';
|
|
|
|
type PanelTab = 'adjustments' | 'tools' | 'history';
|
|
|
|
interface CollapsibleState {
|
|
filters: boolean;
|
|
selection: boolean;
|
|
transform: boolean;
|
|
shapeSettings: boolean;
|
|
}
|
|
|
|
interface PanelDockState {
|
|
activeTab: PanelTab;
|
|
width: number;
|
|
layersHeight: number;
|
|
colorsHeight: number;
|
|
}
|
|
|
|
interface UIStore {
|
|
panelDock: PanelDockState;
|
|
collapsed: CollapsibleState;
|
|
|
|
/** Set active tab in panel dock */
|
|
setActiveTab: (tab: PanelTab) => void;
|
|
/** Set panel dock width */
|
|
setPanelWidth: (width: number) => void;
|
|
/** Set layers panel height percentage */
|
|
setLayersHeight: (height: number) => void;
|
|
/** Set colors panel height percentage */
|
|
setColorsHeight: (height: number) => void;
|
|
/** Toggle collapsible section */
|
|
toggleCollapsed: (section: keyof CollapsibleState) => void;
|
|
/** Set collapsible section state */
|
|
setCollapsed: (section: keyof CollapsibleState, collapsed: boolean) => void;
|
|
}
|
|
|
|
const DEFAULT_PANEL_DOCK: PanelDockState = {
|
|
activeTab: 'adjustments',
|
|
width: 280,
|
|
layersHeight: 40,
|
|
colorsHeight: 20,
|
|
};
|
|
|
|
const DEFAULT_COLLAPSED: CollapsibleState = {
|
|
filters: true,
|
|
selection: true,
|
|
transform: true,
|
|
shapeSettings: true,
|
|
};
|
|
|
|
export const useUIStore = create<UIStore>()(
|
|
persist(
|
|
(set) => ({
|
|
panelDock: { ...DEFAULT_PANEL_DOCK },
|
|
collapsed: { ...DEFAULT_COLLAPSED },
|
|
|
|
setActiveTab: (tab) =>
|
|
set((state) => ({
|
|
panelDock: { ...state.panelDock, activeTab: tab },
|
|
})),
|
|
|
|
setPanelWidth: (width) =>
|
|
set((state) => ({
|
|
panelDock: { ...state.panelDock, width: Math.max(280, Math.min(600, width)) },
|
|
})),
|
|
|
|
setLayersHeight: (height) =>
|
|
set((state) => ({
|
|
panelDock: { ...state.panelDock, layersHeight: Math.max(15, Math.min(70, height)) },
|
|
})),
|
|
|
|
setColorsHeight: (height) =>
|
|
set((state) => ({
|
|
panelDock: { ...state.panelDock, colorsHeight: Math.max(10, Math.min(40, height)) },
|
|
})),
|
|
|
|
toggleCollapsed: (section) =>
|
|
set((state) => ({
|
|
collapsed: { ...state.collapsed, [section]: !state.collapsed[section] },
|
|
})),
|
|
|
|
setCollapsed: (section, collapsed) =>
|
|
set((state) => ({
|
|
collapsed: { ...state.collapsed, [section]: collapsed },
|
|
})),
|
|
}),
|
|
{
|
|
name: 'ui-storage',
|
|
}
|
|
)
|
|
);
|