visual-notebook / frontend /src /store /notebook.ts
Sid-WC121
initial
c21180c
Raw History Blame Contribute Delete
1.73 kB
import { create } from 'zustand';
import type { Cell, CellType } from '../api/types';
interface NotebookState {
cells: Cell[];
activeCellId: string | null;
addCell: (type: CellType, title?: string, config?: Record<string, any>) => string;
removeCell: (id: string) => void;
updateCell: (id: string, updates: Partial<Cell>) => void;
setActiveCell: (id: string | null) => void;
moveCell: (fromIndex: number, toIndex: number) => void;
toggleCollapse: (id: string) => void;
}
let cellCounter = 0;
export const useNotebookStore = create<NotebookState>((set) => ({
cells: [],
activeCellId: null,
addCell: (type, title, config = {}) => {
const id = `cell-${++cellCounter}-${Date.now()}`;
const cell: Cell = {
id,
type,
title: title || `${type.charAt(0).toUpperCase() + type.slice(1)} Cell`,
config,
};
set((state) => ({
cells: [...state.cells, cell],
activeCellId: id,
}));
return id;
},
removeCell: (id) =>
set((state) => ({
cells: state.cells.filter((c) => c.id !== id),
activeCellId: state.activeCellId === id ? null : state.activeCellId,
})),
updateCell: (id, updates) =>
set((state) => ({
cells: state.cells.map((c) => (c.id === id ? { ...c, ...updates } : c)),
})),
setActiveCell: (id) => set({ activeCellId: id }),
moveCell: (fromIndex, toIndex) =>
set((state) => {
const cells = [...state.cells];
const [moved] = cells.splice(fromIndex, 1);
cells.splice(toIndex, 0, moved);
return { cells };
}),
toggleCollapse: (id) =>
set((state) => ({
cells: state.cells.map((c) =>
c.id === id ? { ...c, collapsed: !c.collapsed } : c,
),
})),
}));