Skip to content

Commit

Permalink
feat(examples): add rdom-klist example project, update readmes
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed May 6, 2024
1 parent cd526f1 commit 531437f
Show file tree
Hide file tree
Showing 20 changed files with 319 additions and 66 deletions.
Binary file added assets/examples/rdom-klist.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
127 changes: 64 additions & 63 deletions examples/README.md

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions examples/rdom-klist/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# rdom-klist

![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-klist.png)

[Live demo](http://demo.thi.ng/umbrella/rdom-klist/)

## Developing & building

Please refer to the instructions on the wiki:

- [Development](https://github.com/thi-ng/umbrella/wiki/Development-mode-for-examples-using-thi.ng-meta%E2%80%90css)
- [Production build](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions)

## Authors

- Karsten Schmidt

## License

© 2024 Karsten Schmidt // Apache Software License 2.0
7 changes: 7 additions & 0 deletions examples/rdom-klist/css/custom.mcss.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"tables": {},
"vars": {},
"decls": [],
"specs": [],
"templates": []
}
2 changes: 2 additions & 0 deletions examples/rdom-klist/css/includes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// list of CSS class names to force-include in generated CSS
// (one class per line, basic wildcards supported)
15 changes: 15 additions & 0 deletions examples/rdom-klist/css/style.mcss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// thi.ng/meta-css stylesheet
// see package readme for more details/usage
// use `yarn css:build` or `yarn css:watch` to transpile to CSS
// also see component-specific *.mcss files in /src folder

// (optional) variable declarations
:root {
// color1=#fff
}

body { system-sans-serif ma3 }

#app { mb4 }

li { cursor-pointer }
21 changes: 21 additions & 0 deletions examples/rdom-klist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link
rel="icon"
href='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">⛱️</text></svg>'
/>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>rdom-klist · @thi.ng/umbrella</title>
<link href="/css/style.css" rel="stylesheet">
<script>window.goatcounter = { path: (p) => location.host + p };</script>
<script data-goatcounter="https://thing.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>
</head>
<body>
<div id="app"></div>
<div><a class="link" href="https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-klist">Source code</a></div>
<script type="module" src="/src/index.ts"></script>
</body>
</html>
41 changes: 41 additions & 0 deletions examples/rdom-klist/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "@example/rdom-klist",
"version": "0.0.1",
"private": true,
"description": "Basic usage of thi.ng/rdom keyed list component wrapper",
"repository": "https://github.com/thi-ng/umbrella",
"author": "Karsten Schmidt <k+npm@thi.ng>",
"license": "Apache-2.0",
"scripts": {
"start": "yarn css:build && yarn start:only",
"start:only": "vite --host --open",
"css:watch": "../../node_modules/.bin/metacss develop --bundle --watch --pretty --out-specs css/framework.json --out-css css/style.css --force @css/includes.txt ../../packages/meta-css/specs/*.mcss.json css/*.mcss.json css/*.mcss",
"css:build": "../../node_modules/.bin/metacss develop --bundle --out-specs css/framework.json --out-css css/style.css --force @css/includes.txt ../../packages/meta-css/specs/*.mcss.json css/*.mcss.json css/*.mcss",
"build": "yarn css:build && tsc && vite build --base='./'",
"preview": "vite preview --host --open"
},
"devDependencies": {
"@thi.ng/meta-css": "workspace:^",
"typescript": "^5.4.3",
"vite": "^5.2.6"
},
"dependencies": {
"@thi.ng/arrays": "workspace:^",
"@thi.ng/atom": "workspace:^",
"@thi.ng/random": "workspace:^",
"@thi.ng/rdom": "workspace:^",
"@thi.ng/rstream": "workspace:^"
},
"browser": {
"process": false
},
"thi.ng": {
"readme": [
"atom",
"random",
"rdom",
"rstream"
],
"screenshot": "examples/rdom-klist.png"
}
}
117 changes: 117 additions & 0 deletions examples/rdom-klist/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { swap } from "@thi.ng/arrays";
import { defAtom } from "@thi.ng/atom";
import { uniqueIndices } from "@thi.ng/random";
import { $compile, $klist } from "@thi.ng/rdom";
import { fromAtom, fromView } from "@thi.ng/rstream";

const db = defAtom({
sel: -1,
items: ["one", "two", "three", "four"],
});

// reactive view of the atom
const $db = fromAtom(db);

// create a subscription on the selection ID only
// this will be more efficient when list items will later subscribe to this value
// since these downstream subs will only be triggered if the selection changes and
// not if ANY value in the atom changes
const $sel = fromView(db, { path: ["sel"] });

// similar to $sel, but for the list items only
const $items = fromView(db, { path: ["items"] });

// color chooser helper fn
const highlight = (sel: number, i: number) => (sel === i ? "red" : "blue");

// onclick handler to select/deselect items
const selectItem = (id: number) =>
db.swapIn(["sel"], (sel) => (id === sel ? -1 : id));

$compile([
"div",
{},
["div", {}, "Open DOM inspector to observe element/attribute changes..."],

["h2", {}, "Version 1"],
// version 1: subscribes to the entire atom (therefore triggers a list
// update when ANYTHING changes). here the key function for each list item
// also includes the current selection, supposedly to for each list item to
// determine if it's selected or not. this means though, that once the
// selection changes, *ALL* items will change and update (because their key
// changes too), regardless if the new selection impacts that item or not.
// in summary, this approach counteracts the entire purpose of using a keyed
// list and better solution is shown below...
$klist(
$db.map(({ sel, items }) =>
items.map((x, i) => <[number, number, string]>[sel, i, x])
),
"ul",
{},
([sel, i, x]) => [
"li",
{
style: { color: highlight(sel, i) },
onclick: () => selectItem(i),
// include key for debug
data: { key: `${sel}|${i}|${x}` },
},
x,
],
// key is "selection|index|item"
(item) => item.join("|")
),

["h2", {}, "Version 2"],

// version 2: subscribe to `items` array only and don't include selection in
// item keys. to update an item's color, we use a reactive attribute
// subscription attached to `$sel`. the result of this arrangement is that
// only max. 2 items (current & previous selected item) will be updated when
// the selection changes or when items are being re-ordered in the list (see
// shuffle button below).
//
// the general advice is: keep the information used in the item key to a
// minimum and only include those values relevant to an item's unique
// definition & position in the list (in this case here, if an item is
// selected has zero influence on its position or content).
$klist(
$items.map((items) => items.map((x, i) => <[number, string]>[i, x])),
"ul",
{},
([i, x]) => [
"li",
{
// reactive color attrib
style: { color: $sel.map((sel) => highlight(sel, i)) },
onclick: () => selectItem(i),
// include key for debug
data: { key: `${i}|${x}` },
},
x,
],
// key is only "index|item"
(item) => item.join("|")
),

// button to trigger swapping of 2 random list items & update selection if needed
[
"button",
{
onclick: () => {
let { items, sel } = db.deref();
// updates to values in atoms always should be immutable!
items = items.slice();
// pick 2 unique indices to swap
const [idx, idx2] = uniqueIndices(2, items.length);
swap(items, idx, idx2);
// swap selection if needed
if (sel === idx) sel = idx2;
else if (sel === idx2) sel = idx;
// update atom, trigger $klist updates
db.reset({ sel, items });
},
},
"swap items",
],
]).mount(document.getElementById("app")!);
1 change: 1 addition & 0 deletions examples/rdom-klist/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
6 changes: 6 additions & 0 deletions examples/rdom-klist/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"include": ["src/**/*"],
"compilerOptions": {
}
}
3 changes: 3 additions & 0 deletions examples/rdom-klist/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
build: { target: "esnext" },
};
1 change: 1 addition & 0 deletions packages/atom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ directory are using this package:
| | Hiccup / hdom DOM hydration example | [Demo](https://demo.thi.ng/umbrella/hydrate-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hydrate-basics) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/imgui/imgui-all.png" width="240"/> | Canvas based Immediate Mode GUI components | [Demo](https://demo.thi.ng/umbrella/imgui/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/imgui) |
| | Basic SPA example with atom-based UI router | [Demo](https://demo.thi.ng/umbrella/login-form/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/login-form) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-klist.png" width="240"/> | Basic usage of thi.ng/rdom keyed list component wrapper | [Demo](https://demo.thi.ng/umbrella/rdom-klist/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-klist) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-svg-nodes.png" width="240"/> | rdom powered SVG graph with draggable nodes | [Demo](https://demo.thi.ng/umbrella/rdom-svg-nodes/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-svg-nodes) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rotating-voronoi.jpg" width="240"/> | Animated Voronoi diagram, cubic splines & SVG download | [Demo](https://demo.thi.ng/umbrella/rotating-voronoi/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rotating-voronoi) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/router-basics.jpg" width="240"/> | Complete mini SPA app w/ router & async content loading | [Demo](https://demo.thi.ng/umbrella/router-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/router-basics) |
Expand Down
2 changes: 1 addition & 1 deletion packages/geom-axidraw/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ For Node.js REPL:
const gaxi = await import("@thi.ng/geom-axidraw");
```

Package sizes (brotli'd, pre-treeshake): ESM: 1.58 KB
Package sizes (brotli'd, pre-treeshake): ESM: 1.55 KB

## Dependencies

Expand Down
2 changes: 1 addition & 1 deletion packages/geom-isec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ For Node.js REPL:
const isec = await import("@thi.ng/geom-isec");
```

Package sizes (brotli'd, pre-treeshake): ESM: 2.92 KB
Package sizes (brotli'd, pre-treeshake): ESM: 2.96 KB

## Dependencies

Expand Down
2 changes: 1 addition & 1 deletion packages/geom-sdf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ For Node.js REPL:
const sdf = await import("@thi.ng/geom-sdf");
```

Package sizes (brotli'd, pre-treeshake): ESM: 3.66 KB
Package sizes (brotli'd, pre-treeshake): ESM: 3.71 KB

## Dependencies

Expand Down
1 change: 1 addition & 0 deletions packages/random/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ directory are using this package:
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/pixel-sorting.png" width="240"/> | Interactive pixel sorting tool using thi.ng/color & thi.ng/pixel | [Demo](https://demo.thi.ng/umbrella/pixel-sorting/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/pixel-sorting) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/poly-subdiv.jpg" width="240"/> | Animated, iterative polygon subdivisions & visualization | [Demo](https://demo.thi.ng/umbrella/poly-subdiv/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/poly-subdiv) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/procedural-text.jpg" width="240"/> | Procedural stochastic text generation via custom DSL, parse grammar & AST transformation | [Demo](https://demo.thi.ng/umbrella/procedural-text/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/procedural-text) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-klist.png" width="240"/> | Basic usage of thi.ng/rdom keyed list component wrapper | [Demo](https://demo.thi.ng/umbrella/rdom-klist/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-klist) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/render-audio.png" width="240"/> | Generative audio synth offline renderer and WAV file export | [Demo](https://demo.thi.ng/umbrella/render-audio/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/render-audio) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/shader-ast-evo.jpg" width="240"/> | Evolutionary shader generation using genetic programming | [Demo](https://demo.thi.ng/umbrella/shader-ast-evo/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/shader-ast-evo) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/stacked-layout.png" width="240"/> | Responsive & reactively computed stacked column layout | [Demo](https://demo.thi.ng/umbrella/stacked-layout/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/stacked-layout) |
Expand Down
1 change: 1 addition & 0 deletions packages/rdom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ directory are using this package:
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-dnd.png" width="240"/> | rdom drag & drop example | [Demo](https://demo.thi.ng/umbrella/rdom-dnd/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-dnd) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-formgen.jpg" width="240"/> | Basic usage of the declarative rdom-forms generator | [Demo](https://demo.thi.ng/umbrella/rdom-formgen/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-formgen) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-key-sequences.jpg" width="240"/> | rstream & transducer-based FSM for converting key event sequences into high-level commands | [Demo](https://demo.thi.ng/umbrella/rdom-key-sequences/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-key-sequences) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-klist.png" width="240"/> | Basic usage of thi.ng/rdom keyed list component wrapper | [Demo](https://demo.thi.ng/umbrella/rdom-klist/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-klist) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-lazy-load.png" width="240"/> | Lazy loading components via @thi.ng/rdom | [Demo](https://demo.thi.ng/umbrella/rdom-lazy-load/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-lazy-load) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-lissajous.png" width="240"/> | rdom & hiccup-canvas interop test | [Demo](https://demo.thi.ng/umbrella/rdom-lissajous/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-lissajous) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-reactive-svg.jpg" width="240"/> | Animated SVG elements with reactive attributes | [Demo](https://demo.thi.ng/umbrella/rdom-reactive-svg/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-reactive-svg) |
Expand Down
1 change: 1 addition & 0 deletions packages/rstream/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ directory are using this package:
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-delayed-update.jpg" width="240"/> | Dynamically loaded images w/ preloader state | [Demo](https://demo.thi.ng/umbrella/rdom-delayed-update/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-delayed-update) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-formgen.jpg" width="240"/> | Basic usage of the declarative rdom-forms generator | [Demo](https://demo.thi.ng/umbrella/rdom-formgen/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-formgen) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-key-sequences.jpg" width="240"/> | rstream & transducer-based FSM for converting key event sequences into high-level commands | [Demo](https://demo.thi.ng/umbrella/rdom-key-sequences/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-key-sequences) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-klist.png" width="240"/> | Basic usage of thi.ng/rdom keyed list component wrapper | [Demo](https://demo.thi.ng/umbrella/rdom-klist/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-klist) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-lissajous.png" width="240"/> | rdom & hiccup-canvas interop test | [Demo](https://demo.thi.ng/umbrella/rdom-lissajous/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-lissajous) |
| | Full umbrella repo doc string search w/ paginated results | [Demo](https://demo.thi.ng/umbrella/rdom-search-docs/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-search-docs) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-svg-nodes.png" width="240"/> | rdom powered SVG graph with draggable nodes | [Demo](https://demo.thi.ng/umbrella/rdom-svg-nodes/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-svg-nodes) |
Expand Down
15 changes: 15 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,21 @@ __metadata:
languageName: unknown
linkType: soft

"@example/rdom-klist@workspace:examples/rdom-klist":
version: 0.0.0-use.local
resolution: "@example/rdom-klist@workspace:examples/rdom-klist"
dependencies:
"@thi.ng/arrays": "workspace:^"
"@thi.ng/atom": "workspace:^"
"@thi.ng/meta-css": "workspace:^"
"@thi.ng/random": "workspace:^"
"@thi.ng/rdom": "workspace:^"
"@thi.ng/rstream": "workspace:^"
typescript: "npm:^5.4.3"
vite: "npm:^5.2.6"
languageName: unknown
linkType: soft

"@example/rdom-lazy-load@workspace:examples/rdom-lazy-load":
version: 0.0.0-use.local
resolution: "@example/rdom-lazy-load@workspace:examples/rdom-lazy-load"
Expand Down

0 comments on commit 531437f

Please sign in to comment.