Skip to content

Commit e3e9393

Browse files
committed
Merge branch 'dark' of https://github.com/atellmer/js-framework-benchmark into atellmer-dark
2 parents d006211 + be2b0cd commit e3e9393

File tree

7 files changed

+147
-225
lines changed

7 files changed

+147
-225
lines changed

frameworks/keyed/dark/package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frameworks/keyed/dark/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"webpack-cli": "5.0.1"
2828
},
2929
"dependencies": {
30-
"@dark-engine/core": "0.25.1",
31-
"@dark-engine/platform-browser": "0.25.1"
30+
"@dark-engine/core": "1.0.2",
31+
"@dark-engine/platform-browser": "1.0.2"
3232
}
3333
}

frameworks/keyed/dark/src/index.ts

Lines changed: 0 additions & 206 deletions
This file was deleted.

frameworks/keyed/dark/src/index.tsx

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import {
2+
type WritableAtom,
3+
h,
4+
component,
5+
useMemo,
6+
memo,
7+
Flag,
8+
VERSION,
9+
TagVirtualNode as Tag,
10+
TextVirtualNode as Text,
11+
} from "@dark-engine/core";
12+
import { type SyntheticEvent, createRoot } from "@dark-engine/platform-browser";
13+
14+
import { type Item, Store } from "./store";
15+
16+
type Event = SyntheticEvent<MouseEvent>;
17+
18+
const shouldUpdate = () => false;
19+
const stop = (e: Event) => (e.stopPropagation(), true);
20+
21+
type ButtonProps = {
22+
id: string;
23+
label: string;
24+
onClick: (e: Event) => void;
25+
};
26+
27+
const Button = component<ButtonProps>(({ id, label, onClick }) => {
28+
return (
29+
<div class="col-sm-6 smallpad">
30+
<button id={id} type="button" class="btn btn-primary btn-block" onClick={onClick}>
31+
{label}
32+
</button>
33+
</div>
34+
);
35+
});
36+
37+
type HeaderProps = {
38+
run: (e: Event) => void;
39+
runLots: (e: Event) => void;
40+
add: (e: Event) => void;
41+
update: (e: Event) => void;
42+
clear: (e: Event) => void;
43+
swapRows: (e: Event) => void;
44+
};
45+
46+
const Header = memo(
47+
component<HeaderProps>(({ run, runLots, add, update, clear, swapRows }) => {
48+
return (
49+
<div class="jumbotron">
50+
<div class="row">
51+
<div class="col-md-6">
52+
<h1>Dark {VERSION} keyed</h1>
53+
</div>
54+
<div class="col-md-6">
55+
<div class="row">
56+
<Button id="run" label="Create 1,000 rows" onClick={run} />
57+
<Button id="runlots" label="Create 10,000 rows" onClick={runLots} />
58+
<Button id="add" label="Append 1,000 rows" onClick={add} />
59+
<Button id="update" label="Update every 10th row" onClick={update} />
60+
<Button id="clear" label="Clear" onClick={clear} />
61+
<Button id="swaprows" label="Swap Rows" onClick={swapRows} />
62+
</div>
63+
</div>
64+
</div>
65+
</div>
66+
);
67+
}),
68+
shouldUpdate
69+
);
70+
71+
const Label = component<{ label$: WritableAtom<string> }>(({ label$ }) => new Text(label$.val()));
72+
73+
type RowProps = {
74+
item: Item;
75+
selected$: WritableAtom<number>;
76+
select: (id: number, e: Event) => void;
77+
remove: (id: number, e: Event) => void;
78+
};
79+
80+
const Row = memo(
81+
component<RowProps>(({ item, selected$, select, remove }) => {
82+
const { id, label$ } = item;
83+
const className = selected$.val(null, id) === id ? "danger" : undefined;
84+
const attrs = {
85+
class: "glyphicon glyphicon-remove",
86+
onClick: [remove, id],
87+
"aria-hidden": "true",
88+
};
89+
90+
return new Tag("tr", { class: className, [Flag.STATIC_SLOT_OPT]: true }, [
91+
new Tag("td", { class: "col-md-1" }, [new Text(id)]),
92+
new Tag("td", { class: "col-md-4" }, [new Tag("a", { onClick: [select, id] }, [Label({ label$ })])]),
93+
new Tag("td", { class: "col-md-1" }, [new Tag("a", {}, [new Tag("span", attrs, [])])]),
94+
new Tag("td", { class: "col-md-6" }, []),
95+
]);
96+
}),
97+
shouldUpdate
98+
);
99+
100+
const App = component(() => {
101+
const store = useMemo(() => new Store(), []);
102+
const { data$, selected$ } = store.getState();
103+
const items = data$.val();
104+
const run = (e: Event) => stop(e) && store.run();
105+
const runLots = (e: Event) => stop(e) && store.runLots();
106+
const add = (e: Event) => stop(e) && store.add();
107+
const update = (e: Event) => stop(e) && store.update();
108+
const clear = (e: Event) => stop(e) && store.clear();
109+
const swapRows = (e: Event) => stop(e) && store.swapRows();
110+
const remove = (id: number, e: Event) => stop(e) && store.remove(id);
111+
const select = (id: number, e: Event) => stop(e) && store.select(id);
112+
const rows = items.map((item) => Row({ key: item.id, item, selected$, remove, select }));
113+
const content = new Tag("tbody", { key: items.length > 0 ? 1 : 2, [Flag.MEMO_SLOT_OPT]: true }, rows);
114+
115+
return (
116+
<div class="container">
117+
<Header run={run} runLots={runLots} add={add} update={update} clear={clear} swapRows={swapRows} />
118+
<table class="table table-hover table-striped test-data">{content}</table>
119+
<span class="preloadicon glyphicon glyphicon-remove" aria-hidden="true" />
120+
</div>
121+
);
122+
});
123+
124+
createRoot(document.getElementById("main")).render(<App />);

0 commit comments

Comments
 (0)