summaryrefslogtreecommitdiff
path: root/apps/web/src/timeline/timeline-store.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/src/timeline/timeline-store.ts')
-rw-r--r--apps/web/src/timeline/timeline-store.ts57
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,
+ }),
+ },
+ ),
+);