diff options
Diffstat (limited to 'apps/web/src/timeline/timeline-store.ts')
| -rw-r--r-- | apps/web/src/timeline/timeline-store.ts | 57 |
1 files changed, 57 insertions, 0 deletions
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<string>; + toggleElementExpanded: (elementId: string) => void; +} + +export const useTimelineStore = create<TimelineStore>()( + persist( + (set) => ({ + snappingEnabled: true, + + toggleSnapping: () => { + set((state) => ({ snappingEnabled: !state.snappingEnabled })); + }, + + rippleEditingEnabled: false, + + toggleRippleEditing: () => { + set((state) => ({ + rippleEditingEnabled: !state.rippleEditingEnabled, + })); + }, + + expandedElementIds: new Set<string>(), + + 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, + }), + }, + ), +); |
