-
Notifications
You must be signed in to change notification settings - Fork 1
/
Showcase.tsx
127 lines (113 loc) · 2.89 KB
/
Showcase.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { useState } from "react";
import { useAtom, useAtomValue, useSetAtom } from "jotai/react";
import { MiniDb } from "./lib/jotai-minidb";
type Item = {
name: string;
};
const version =
Number(
window && new URLSearchParams(new URL(location.href).search).get("version")
) || 0;
const simpleStore = new MiniDb<Item>({
version,
migrations: Object.fromEntries(
Array.from({ length: version }).map((_, index) => [
String(index + 1),
(doc) => {
return { ...doc, name: doc.name + `(migrated to v${index + 1})` };
},
])
),
onMigrationCompleted: () => {
document.write(
"<h1>Migrated in other browser tab. Now the page should be reloaded</h1>"
);
},
onVersionMissmatch: () => {
document.write("<h1>Client version is too old</h1>");
},
});
function getNewItem(): Item {
return {
name: "",
};
}
export default function Showcase() {
const [selectedId, setSelectedId] = useState<string | null>(null);
const entries = useAtomValue(simpleStore.entries);
const set = useSetAtom(simpleStore.set);
const del = useSetAtom(simpleStore.delete);
return (
<div className="container">
<h1>Jotai-minidb example app</h1>
<div className="sidebar">
<ul>
{entries.map(([key, item]) => (
<li key={key}>
<button onClick={() => setSelectedId(key)}>
{item.name || "Untitled"}
</button>
</li>
))}
</ul>
<button
onClick={() => {
set(crypto.randomUUID(), getNewItem());
}}
>
Add ➕
</button>
<Populate />
<Clear />
</div>
<div className="item">
{selectedId && (
<Item
id={selectedId}
onDelete={() => {
setSelectedId(null);
del(selectedId);
}}
/>
)}
</div>
</div>
);
}
function Item({ id, onDelete }: { id: string; onDelete: VoidFunction }) {
const [item, setItem] = useAtom(simpleStore.item(id));
if (!item) {
return null;
}
return (
<div>
<h3>Item #{id}</h3>
Name:{" "}
<input
placeholder="Enter name"
value={item.name}
onChange={(e) => setItem({ ...item, name: e.target.value })}
/>
<button onClick={onDelete}>Delete ❌ </button>
</div>
);
}
function Populate() {
const setMany = useSetAtom(simpleStore.setMany);
const clear = useSetAtom(simpleStore.clear);
const populate = async () => {
await clear();
const items: [string, Item][] = Array.from({ length: 10 }).map((_, i) => [
`id-${i}`,
{
name: `item ${i + 1}`,
},
]);
await setMany(items);
};
return <button onClick={populate}>Populate</button>;
}
function Clear() {
const clear = useSetAtom(simpleStore.clear);
return <button onClick={() => clear()}>Clear</button>;
}