Files
kit-ui/lib/calculate/store.ts

108 lines
2.8 KiB
TypeScript
Raw Normal View History

import { create } from 'zustand';
import { persist } from 'zustand/middleware';
export const FUNCTION_COLORS = [
'#f472b6',
'#60a5fa',
'#4ade80',
'#fb923c',
'#a78bfa',
'#22d3ee',
'#fbbf24',
'#f87171',
];
export interface HistoryEntry {
id: string;
expression: string;
result: string;
error: boolean;
}
export interface GraphFunction {
id: string;
expression: string;
color: string;
visible: boolean;
}
interface CalculateStore {
expression: string;
history: HistoryEntry[];
variables: Record<string, string>;
graphFunctions: GraphFunction[];
setExpression: (expr: string) => void;
addToHistory: (entry: Omit<HistoryEntry, 'id'>) => void;
clearHistory: () => void;
setVariable: (name: string, value: string) => void;
removeVariable: (name: string) => void;
addGraphFunction: () => void;
updateGraphFunction: (
id: string,
updates: Partial<Pick<GraphFunction, 'expression' | 'color' | 'visible'>>
) => void;
removeGraphFunction: (id: string) => void;
}
const uid = () => `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
export const useCalculateStore = create<CalculateStore>()(
persist(
(set) => ({
expression: '',
history: [],
variables: {},
graphFunctions: [
{ id: 'init-1', expression: 'sin(x)', color: FUNCTION_COLORS[0], visible: true },
{ id: 'init-2', expression: 'cos(x)', color: FUNCTION_COLORS[1], visible: true },
],
setExpression: (expression) => set({ expression }),
addToHistory: (entry) =>
set((state) => ({
history: [{ ...entry, id: uid() }, ...state.history].slice(0, 50),
})),
clearHistory: () => set({ history: [] }),
setVariable: (name, value) =>
set((state) => ({ variables: { ...state.variables, [name]: value } })),
removeVariable: (name) =>
set((state) => {
const v = { ...state.variables };
delete v[name];
return { variables: v };
}),
addGraphFunction: () =>
set((state) => {
const used = new Set(state.graphFunctions.map((f) => f.color));
const color =
FUNCTION_COLORS.find((c) => !used.has(c)) ??
FUNCTION_COLORS[state.graphFunctions.length % FUNCTION_COLORS.length];
return {
graphFunctions: [
...state.graphFunctions,
{ id: uid(), expression: '', color, visible: true },
],
};
}),
updateGraphFunction: (id, updates) =>
set((state) => ({
graphFunctions: state.graphFunctions.map((f) =>
f.id === id ? { ...f, ...updates } : f
),
})),
removeGraphFunction: (id) =>
set((state) => ({
graphFunctions: state.graphFunctions.filter((f) => f.id !== id),
})),
}),
{ name: 'kit-calculate-v1' }
)
);