44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
"use client";
|
|
import { createContext, useCallback, useContext, useMemo, useState } from "react";
|
|
|
|
type Ctx = {
|
|
ids: Set<number>;
|
|
has: (id: number) => boolean;
|
|
toggle: (id: number) => void;
|
|
setMany: (ids: number[]) => void;
|
|
clear: () => void;
|
|
};
|
|
|
|
const CollectionSelectCtx = createContext<Ctx | null>(null);
|
|
|
|
export function CollectionSelectionProvider({ children }: { children: React.ReactNode }) {
|
|
const [ids, setIds] = useState<Set<number>>(new Set());
|
|
|
|
const toggle = useCallback((id: number) => {
|
|
setIds((cur) => {
|
|
const next = new Set(cur);
|
|
if (next.has(id)) next.delete(id); else next.add(id);
|
|
return next;
|
|
});
|
|
}, []);
|
|
|
|
const setMany = useCallback((newIds: number[]) => setIds(new Set(newIds)), []);
|
|
const clear = useCallback(() => setIds(new Set()), []);
|
|
|
|
const value = useMemo<Ctx>(() => ({
|
|
ids,
|
|
has: (id) => ids.has(id),
|
|
toggle,
|
|
setMany,
|
|
clear,
|
|
}), [ids, toggle, setMany, clear]);
|
|
|
|
return <CollectionSelectCtx.Provider value={value}>{children}</CollectionSelectCtx.Provider>;
|
|
}
|
|
|
|
export function useCollectionSelection() {
|
|
const ctx = useContext(CollectionSelectCtx);
|
|
if (!ctx) throw new Error("useCollectionSelection must be used within CollectionSelectionProvider");
|
|
return ctx;
|
|
}
|