From 3e89d2998588f8e35c524e523ba2ee853f0f6475 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 20 Apr 2026 11:31:17 +0200 Subject: refactor: restructure files to their domains, new preview overlay system, and dep graph --- apps/web/src/timeline/timeline-store.ts | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 apps/web/src/timeline/timeline-store.ts (limited to 'apps/web/src/timeline/timeline-store.ts') diff --git a/apps/web/src/timeline/timeline-store.ts b/apps/web/src/timeline/timeline-store.ts new file mode 100644 index 00000000..b7ddb885 --- /dev/null +++ b/apps/web/src/timeline/timeline-store.ts @@ -0,0 +1,57 @@ +/** + * UI state for the timeline + * For core logic, use EditorCore instead. + */ + +import { create } from "zustand"; +import { persist } from "zustand/middleware"; + +interface TimelineStore { + snappingEnabled: boolean; + toggleSnapping: () => void; + rippleEditingEnabled: boolean; + toggleRippleEditing: () => void; + expandedElementIds: Set; + toggleElementExpanded: (elementId: string) => void; +} + +export const useTimelineStore = create()( + persist( + (set) => ({ + snappingEnabled: true, + + toggleSnapping: () => { + set((state) => ({ snappingEnabled: !state.snappingEnabled })); + }, + + rippleEditingEnabled: false, + + toggleRippleEditing: () => { + set((state) => ({ + rippleEditingEnabled: !state.rippleEditingEnabled, + })); + }, + + expandedElementIds: new Set(), + + toggleElementExpanded: (elementId) => { + set((state) => { + const next = new Set(state.expandedElementIds); + if (next.has(elementId)) { + next.delete(elementId); + } else { + next.add(elementId); + } + return { expandedElementIds: next }; + }); + }, + }), + { + name: "timeline-store", + partialize: (state) => ({ + snappingEnabled: state.snappingEnabled, + rippleEditingEnabled: state.rippleEditingEnabled, + }), + }, + ), +); -- cgit v1.3.1