@deepdub/react-arborist
Version:
85 lines (75 loc) • 2.27 kB
text/typescript
import { ActionTypes, IdObj } from "../types/utils";
import { identify } from "../utils";
import { initialState } from "./initial";
/* Types */
export type SelectionState = {
ids: Set<string>;
anchor: string | null;
mostRecent: string | null;
};
/* Actions */
export const actions = {
clear: () => ({ type: "SELECTION_CLEAR" as const }),
only: (id: string | IdObj) => ({
type: "SELECTION_ONLY" as const,
id: identify(id),
}),
add: (id: string | string[] | IdObj | IdObj[]) => ({
type: "SELECTION_ADD" as const,
ids: (Array.isArray(id) ? id : [id]).map(identify),
}),
remove: (id: string | string[] | IdObj | IdObj[]) => ({
type: "SELECTION_REMOVE" as const,
ids: (Array.isArray(id) ? id : [id]).map(identify),
}),
set: (args: {
ids: Set<string>;
anchor: string | null;
mostRecent: string | null;
}) => ({
type: "SELECTION_SET" as const,
...args,
}),
mostRecent: (id: string | null | IdObj) => ({
type: "SELECTION_MOST_RECENT" as const,
id: id === null ? null : identify(id),
}),
anchor: (id: string | null | IdObj) => ({
type: "SELECTION_ANCHOR" as const,
id: id === null ? null : identify(id),
}),
};
/* Reducer */
export function reducer(
state: SelectionState = initialState()["nodes"]["selection"],
action: ActionTypes<typeof actions>
): SelectionState {
const ids = state.ids;
switch (action.type) {
case "SELECTION_CLEAR":
return { ...state, ids: new Set() };
case "SELECTION_ONLY":
return { ...state, ids: new Set([action.id]) };
case "SELECTION_ADD":
if (action.ids.length === 0) return state;
action.ids.forEach((id) => ids.add(id));
return { ...state, ids: new Set(ids) };
case "SELECTION_REMOVE":
if (action.ids.length === 0) return state;
action.ids.forEach((id) => ids.delete(id));
return { ...state, ids: new Set(ids) };
case "SELECTION_SET":
return {
...state,
ids: action.ids,
mostRecent: action.mostRecent,
anchor: action.anchor,
};
case "SELECTION_MOST_RECENT":
return { ...state, mostRecent: action.id };
case "SELECTION_ANCHOR":
return { ...state, anchor: action.id };
default:
return state;
}
}