import { action, Default, handler, NAME, nonPrivateRandom, pattern, UI, type VNode, Writable, } from "commonfabric"; interface ProjectItem { id: string; title: string; done: boolean; } interface ProjectListInput { items?: Writable< ProjectItem[] | Default<[]> >; } export interface ProjectListOutput { [NAME]: string; [UI]: VNode; items: Writable; } // Exported for tests. Writes through the element's cell (`.key(index)`) — // rebuilding the array with a fresh object literal for the toggled item would // re-mint its entity identity and orphan previously-held references (see // packages/patterns/primitives/editable-list.tsx). export const toggleItem = handler< void, { index: number; items: Writable } >( (_, { index, items }) => { const list = items.get(); if (index < 0 || index >= list.length) return; items.key(index).key("done").set(!list[index].done); }, ); const removeItem = handler< void, { index: number; items: Writable } >( (_, { index, items }) => { const list = items.get(); items.set(list.filter((_, i) => i !== index)); }, ); export default pattern(({ items }) => { const addItem = action(() => { const id = nonPrivateRandom().toString(36).slice(2, 8); items.set([ ...items.get(), { id, title: `Project ${items.get().length + 1}`, done: false }, ]); }); return { [NAME]: "Project List", [UI]: ( {items.map((item, index) => ( x ))}
+ Label + Label + Label
), items, }; });