Skip to content

Commit fe7fb56

Browse files
authored
pattern to have an array of charms in a cell (#1771)
* pattern to have an array of charms in a cell UI to navigate to each charm created in the array * use cell.push() * use ifElse but still need to use derive inside clause due to bug in CTS
1 parent c409d6e commit fe7fb56

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/// <cts-enable />
2+
import {
3+
Cell,
4+
cell,
5+
createCell,
6+
derive,
7+
h,
8+
handler,
9+
ifElse,
10+
lift,
11+
NAME,
12+
navigateTo,
13+
recipe,
14+
UI,
15+
} from "commontools";
16+
17+
// the simple charm (to which we'll store references within a cell)
18+
const SimpleRecipe = recipe("Simple Recipe", () => ({
19+
[NAME]: "Some Simple Recipe",
20+
[UI]: <div>Some Simple Recipe</div>,
21+
}));
22+
23+
// Create a cell to store an array of charms
24+
const createCellRef = lift(
25+
{
26+
type: "object",
27+
properties: {
28+
isInitialized: { type: "boolean", default: false, asCell: true },
29+
storedCellRef: { type: "object", asCell: true },
30+
},
31+
},
32+
undefined,
33+
({ isInitialized, storedCellRef }) => {
34+
if (!isInitialized.get()) {
35+
console.log("Creating cellRef - first time");
36+
const newCellRef = createCell(undefined, "charmsArray");
37+
newCellRef.set([]);
38+
storedCellRef.set(newCellRef);
39+
isInitialized.set(true);
40+
return {
41+
cellRef: newCellRef,
42+
};
43+
} else {
44+
console.log("cellRef already initialized");
45+
}
46+
// If already initialized, return the stored cellRef
47+
return {
48+
cellRef: storedCellRef,
49+
};
50+
},
51+
);
52+
53+
// Add a charm to the array and navigate to it
54+
// we get a new isInitialized passed in for each
55+
// charm we add to the list. this makes sure
56+
// we only try to add the charm once to the list
57+
// and we only call navigateTo once
58+
const addCharmAndNavigate = lift(
59+
{
60+
type: "object",
61+
properties: {
62+
charm: { type: "object" },
63+
cellRef: { type: "array", asCell: true },
64+
isInitialized: { type: "boolean", asCell: true },
65+
},
66+
},
67+
undefined,
68+
({ charm, cellRef, isInitialized }) => {
69+
if (!isInitialized.get()) {
70+
if (cellRef) {
71+
cellRef.push(charm);
72+
isInitialized.set(true);
73+
return navigateTo(charm);
74+
} else {
75+
console.log("addCharmAndNavigate undefined cellRef");
76+
}
77+
}
78+
return undefined;
79+
},
80+
);
81+
82+
// Create a new SimpleRecipe and add it to the array
83+
const createSimpleRecipe = handler<unknown, { cellRef: Cell<any[]> }>(
84+
(_, { cellRef }) => {
85+
// Create isInitialized cell for this charm addition
86+
const isInitialized = cell(false);
87+
88+
// Create the charm
89+
const charm = SimpleRecipe({});
90+
91+
// Store the charm in the array and navigate
92+
return addCharmAndNavigate({ charm, cellRef, isInitialized });
93+
},
94+
);
95+
96+
// Handler to navigate to a specific charm from the list
97+
const goToCharm = handler<unknown, { charm: any }>(
98+
(_, { charm }) => {
99+
console.log("goToCharm clicked");
100+
return navigateTo(charm);
101+
},
102+
);
103+
104+
// create the named cell inside the recipe body, so we do it just once
105+
export default recipe("Charms Launcher", () => {
106+
// cell to store array of charms we created
107+
const { cellRef } = createCellRef({
108+
isInitialized: cell(false),
109+
storedCellRef: cell(),
110+
});
111+
112+
return {
113+
[NAME]: "Charms Launcher",
114+
[UI]: (
115+
<div>
116+
<h3>Stored Charms:</h3>
117+
{ifElse(
118+
!cellRef?.length,
119+
<div>No charms created yet</div>,
120+
<ul>
121+
{cellRef.map((charm: any, index: number) => (
122+
<li>
123+
<ct-button
124+
onClick={goToCharm({ charm })}
125+
>
126+
Go to Charm {derive(index, (i) => i + 1)}
127+
</ct-button>
128+
<span>
129+
Charm {derive(index, (i) => i + 1)}:{" "}
130+
{charm[NAME] || "Unnamed"}
131+
</span>
132+
</li>
133+
))}
134+
</ul>,
135+
)}
136+
137+
<ct-button
138+
onClick={createSimpleRecipe({ cellRef })}
139+
>
140+
Create New Charm
141+
</ct-button>
142+
</div>
143+
),
144+
cellRef,
145+
};
146+
});

0 commit comments

Comments
 (0)