diff --git a/.all-contributorsrc b/.all-contributorsrc
index 3aca0aa4..5953908b 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -521,6 +521,72 @@
"plugin",
"code"
]
+ },
+ {
+ "login": "pearmini",
+ "name": "Bairui Su",
+ "avatar_url": "https://avatars.githubusercontent.com/u/49330279?v=4",
+ "profile": "https://github.com/pearmini",
+ "contributions": [
+ "code"
+ ]
+ },
+ {
+ "login": "jroush-ipg",
+ "name": "jroush-ipg",
+ "avatar_url": "https://avatars.githubusercontent.com/u/144253148?v=4",
+ "profile": "https://github.com/jroush-ipg",
+ "contributions": [
+ "bug"
+ ]
+ },
+ {
+ "login": "kangaroolab",
+ "name": "kangaroolab",
+ "avatar_url": "https://avatars.githubusercontent.com/u/163623573?v=4",
+ "profile": "https://github.com/kangaroolab",
+ "contributions": [
+ "example"
+ ]
+ },
+ {
+ "login": "gramie",
+ "name": "Graham Stratford",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1507443?v=4",
+ "profile": "https://github.com/gramie",
+ "contributions": [
+ "bug"
+ ]
+ },
+ {
+ "login": "kursataktas",
+ "name": "Kursat Aktas",
+ "avatar_url": "https://avatars.githubusercontent.com/u/17837825?v=4",
+ "profile": "https://github.com/kursataktas",
+ "contributions": [
+ "code",
+ "plugin"
+ ]
+ },
+ {
+ "login": "bleistivt",
+ "name": "bleistivt",
+ "avatar_url": "https://avatars.githubusercontent.com/u/5205806?v=4",
+ "profile": "http://bleistivt.net",
+ "contributions": [
+ "bug"
+ ]
+ },
+ {
+ "login": "dbismut",
+ "name": "David Bismut",
+ "avatar_url": "https://avatars.githubusercontent.com/u/5003380?v=4",
+ "profile": "https://github.com/dbismut",
+ "contributions": [
+ "code",
+ "plugin",
+ "bug"
+ ]
}
],
"repoType": "github"
diff --git a/.vscode/settings.json b/.vscode/settings.json
index df424ce2..42db334d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,7 +2,8 @@
"deno.enablePaths": [
"demo/terminal/server.ts",
"components/scripts",
- "x/scripts"
+ "x/scripts",
+ "graph/scripts"
],
"cSpell.words": [
"currentcolor",
diff --git a/README.md b/README.md
index 3a068959..873d5536 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,8 @@
+[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20VanJS%20Guru-006BFF)](https://gurubase.io/g/vanjs)
+
# π¦ **VanJS**: The Smallest Reactive UI Framework in the World
π£ [Introducing VanX β](https://github.com/vanjs-org/van/discussions/144)
-π£ [Introducing VanJS App Builder β](https://github.com/vanjs-org/van/discussions/179)
@@ -111,10 +112,12 @@ Simplicity at its core. Only 5 functions (`van.tags`, `van.add`, `van.state`, `v
* Get bored? [Play a fun game](https://vanjs.org/demo#game) built with **VanJS** under 60 lines
* Convert HTML or MD snippet to **VanJS** code with our online [HTML/MD to **VanJS** Converter](https://vanjs.org/convert)
* Check out [**VanUI**](https://github.com/vanjs-org/van/tree/main/components) - A collection of grab 'n go reusable utility and UI components for **VanJS**
-* Want reactive list, global app state, server-driven UI, serialization and more? Check out [**VanX**](https://vanjs.org/x) - The 1.1 kB official **VanJS** extension
+* Want reactive list, global app state, server-driven UI, serialization and more? Check out [**VanX**](https://vanjs.org/x) - The 1.2kB official **VanJS** extension
* Want server-side rendering? Check out [**Mini-Van**](https://github.com/vanjs-org/mini-van) and [Hydration](https://vanjs.org/ssr) (the entire [vanjs.org](https://vanjs.org/) site is built on top of **Mini-Van**)
+* Debugging complex dependencies in your app? checkout [**VanGraph**](https://github.com/vanjs-org/van/tree/main/graph)
* For questions, feedback or general discussions, visit our [Discussions](https://github.com/vanjs-org/van/discussions) page
* [How did **VanJS** get its name?](https://vanjs.org/about#name)
+* β¨ [Ask **VanJS** Guru](https://gurubase.io/g/vanjs) - a **VanJS**-focused AI to answer your questions
## IDE Plug-ins
@@ -130,7 +133,7 @@ Simplicity at its core. Only 5 functions (`van.tags`, `van.add`, `van.state`, `v
> In the name of **Van**illa of the House **J**ava**S**cript, [the First of its name](https://vanjs.org/about#name), Smallest Reactive UI Framework, 1.0kB JSX-free Grab 'n Go Library, [Scripting Language](https://vanjs.org/about#story) for GUI, [GPT-Empowered](https://chat.openai.com/g/g-7tcSHUu27-vanjs-app-builder) Toolkit, by the word of Tao of the House Xin, Founder and Maintainer of **VanJS**, I do hereby grant you the permission of **VanJS** under [MIT License](https://github.com/vanjs-org/van/blob/main/LICENSE).
-Contact us: [@taoxin](https://twitter.com/intent/follow?region=follow_link&screen_name=taoxin) / [tao@vanjs.org](mailto:tao@vanjs.org) / [Tao Xin](https://www.linkedin.com/in/tao-xin-64234920/)
+Contact us: [@taoxin](https://twitter.com/intent/follow?region=follow_link&screen_name=taoxin) / [tao@vanjs.org](mailto:tao@vanjs.org) / [Tao Xin](https://www.linkedin.com/in/taoxin/)
## Community Add-ons
@@ -150,7 +153,7 @@ Contact us: [@taoxin](https://twitter.com/intent/follow?region=follow_link&scree
| [vanrx](https://github.com/MeddahAbdellah/vanrx) | An ultra-lightweight Redux addon for **VanJS** | [Meddah Abdallah](https://github.com/MeddahAbdellah) |
| [VanFS](https://github.com/ken-okabe/vanfs) | 1:1 bindings from F# to **VanJS** | [Ken Okabe](https://github.com/ken-okabe) |
-## Contributors (53)
+## Contributors (61)
*If I miss anyone's contribution here, apologies for my oversight π, please comment on [#87](https://github.com/vanjs-org/van/issues/87) to let me know.*
@@ -230,6 +233,15 @@ Contact us: [@taoxin](https://twitter.com/intent/follow?region=follow_link&scree
Ken Okabe π |
Nick π‘ |
thednp π π» |
+ Bairui Su π» |
+ jroush-ipg π |
+
+
+ kangaroolab π‘ |
+ Graham Stratford π |
+ Kursat Aktas π» π |
+ bleistivt π |
+ David Bismut π» π π |
diff --git a/addons/van_jsx/src/createElement.js b/addons/van_jsx/src/createElement.js
index 16486003..bfc2e615 100644
--- a/addons/van_jsx/src/createElement.js
+++ b/addons/van_jsx/src/createElement.js
@@ -18,6 +18,15 @@ const createElement = (jsxTag, { children, style, ref, ...props }) => {
ele.addEventListener(key.replace("on", "").toLowerCase(), value);
continue;
}
+
+ // Handle reactive attributes
+ if (typeof value === "object" && "val" in value) {
+ van.derive(() => {
+ setAttribute(ele, key, value.val);
+ });
+ continue;
+ }
+
setAttribute(ele, key, value);
continue;
}
diff --git a/addons/van_jsx/src/hyper.js b/addons/van_jsx/src/hyper.js
index 352b3aa2..d1565d5e 100644
--- a/addons/van_jsx/src/hyper.js
+++ b/addons/van_jsx/src/hyper.js
@@ -34,4 +34,12 @@ export const setAttribute = (element, key, value) => {
element.setAttribute(key, value);
return;
}
+ // Set Boolean Attribute
+ if (typeof value === "boolean") {
+ if (value) {
+ element.setAttribute(key, "");
+ return;
+ }
+ element.removeAttribute(key);
+ }
};
diff --git a/bun-examples/hydration/README.md b/bun-examples/hydration/README.md
index ea47a3d5..6708d0dd 100644
--- a/bun-examples/hydration/README.md
+++ b/bun-examples/hydration/README.md
@@ -7,8 +7,8 @@ This is a [Bun 1.0](https://bun.sh/blog/bun-v1.0)-based variation of the fullsta
```json
"dependencies": {
- "mini-van-plate": "^0.5.6",
- "vanjs-core": "^1.5.0"
+ "mini-van-plate": "^0.6.1",
+ "vanjs-core": "^1.5.2"
},
"devDependencies": {
"bun": "^1.0.0",
diff --git a/bun-examples/hydration/package-lock.json b/bun-examples/hydration/package-lock.json
index 2d33e2dd..4e01bf6e 100644
--- a/bun-examples/hydration/package-lock.json
+++ b/bun-examples/hydration/package-lock.json
@@ -8,12 +8,12 @@
"name": "vanjs-bun-example-hydration",
"version": "0.1.0",
"dependencies": {
- "mini-van-plate": "^0.5.6",
- "vanjs-core": "^1.5.0"
+ "mini-van-plate": "^0.6.1",
+ "vanjs-core": "^1.5.2"
},
"devDependencies": {
- "bun": "^1.0.0",
- "bun-types": "^1.0.1"
+ "@types/bun": "^1.1.6",
+ "bun": "^1.0.0"
}
},
"node_modules/@oven/bun-darwin-aarch64": {
@@ -94,6 +94,33 @@
"linux"
]
},
+ "node_modules/@types/bun": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.1.6.tgz",
+ "integrity": "sha512-uJgKjTdX0GkWEHZzQzFsJkWp5+43ZS7HC8sZPFnOwnSo1AsNl2q9o2bFeS23disNDqbggEgyFkKCHl/w8iZsMA==",
+ "dev": true,
+ "dependencies": {
+ "bun-types": "1.1.17"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "20.12.14",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.14.tgz",
+ "integrity": "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/@types/ws": {
+ "version": "8.5.10",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
+ "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/bun": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/bun/-/bun-1.0.0.tgz",
@@ -122,20 +149,30 @@
}
},
"node_modules/bun-types": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.0.1.tgz",
- "integrity": "sha512-7NrXqhMIaNKmWn2dSWEQ50znMZqrN/5Z0NBMXvQTRu/+Y1CvoXRznFy0pnqLe024CeZgVdXoEpARNO1JZLAPGw==",
- "dev": true
+ "version": "1.1.17",
+ "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.1.17.tgz",
+ "integrity": "sha512-Z4+OplcSd/YZq7ZsrfD00DKJeCwuNY96a1IDJyR73+cTBaFIS7SC6LhpY/W3AMEXO9iYq5NJ58WAwnwL1p5vKg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "~20.12.8",
+ "@types/ws": "~8.5.10"
+ }
},
"node_modules/mini-van-plate": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mini-van-plate/-/mini-van-plate-0.5.6.tgz",
- "integrity": "sha512-gAJPXBihI8EFTutUc7oj9tmnOJKgLme5SQNAwj3gN0VU95Nzptiwo1oZy5SJRBwl5ZH7KmjQ6tsqxGHfSgdcoQ=="
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/mini-van-plate/-/mini-van-plate-0.6.1.tgz",
+ "integrity": "sha512-i4kCD5xzkdtQiVnBSN4xFHru6QGPPWJALAm4IB0IRPawIHUK5J/Zv2bx94Nev1YABKN1zJgwxqvuSygoltrQIg=="
+ },
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "dev": true
},
"node_modules/vanjs-core": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/vanjs-core/-/vanjs-core-1.5.0.tgz",
- "integrity": "sha512-kOM9XVOciL9Q3Ihn3ruycTL5NCvuR5Ub7wwQIU9sZJdMBWSxesbeyN3+PWceLz57ImgHTF0eOVvhkoKJLlE3hw=="
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/vanjs-core/-/vanjs-core-1.5.2.tgz",
+ "integrity": "sha512-z9MHAzxYbNFJ6MYP+4j9l9KMxDU3ryI65JjIfUbGQwF1paLfiuqtIiq9Ve1UGKLd774Z7mtdWzd+/FR785dKjQ=="
}
}
}
diff --git a/bun-examples/hydration/package.json b/bun-examples/hydration/package.json
index 7346fefc..a94180b3 100644
--- a/bun-examples/hydration/package.json
+++ b/bun-examples/hydration/package.json
@@ -8,11 +8,11 @@
"build": "bun build --minify src/client.ts --outdir dist && echo Run the following command to start the server: bun src/server.ts [port]"
},
"dependencies": {
- "mini-van-plate": "^0.5.6",
- "vanjs-core": "^1.5.0"
+ "mini-van-plate": "^0.6.1",
+ "vanjs-core": "^1.5.2"
},
"devDependencies": {
- "bun": "^1.0.0",
- "bun-types": "^1.0.1"
+ "@types/bun": "^1.1.6",
+ "bun": "^1.0.0"
}
}
diff --git a/bun-examples/hydration/src/client.ts b/bun-examples/hydration/src/client.ts
index f534e263..4996c7b4 100644
--- a/bun-examples/hydration/src/client.ts
+++ b/bun-examples/hydration/src/client.ts
@@ -1,14 +1,16 @@
import van from "vanjs-core"
+import { registerEnv } from "mini-van-plate/shared"
import Hello from "./components/hello.js"
import Counter from "./components/counter.js"
+registerEnv({van})
+
const {button, p} = van.tags
-van.add(document.getElementById("hello-container")!, Hello({van}))
+van.add(document.getElementById("hello-container")!, Hello())
const hydrate = () => {
van.hydrate(document.getElementById("basic-counter")!, dom => Counter({
- van,
id: dom.id,
init: Number(dom.getAttribute("data-counter")),
}))
@@ -17,7 +19,6 @@ const hydrate = () => {
const buttonStyle = van.state(styleSelectDom.value)
styleSelectDom.oninput = e => buttonStyle.val = (
e.target).value
van.hydrate(document.getElementById("styled-counter")!, dom => Counter({
- van,
id: dom.id,
init: Number(dom.getAttribute("data-counter")),
buttonStyle,
diff --git a/bun-examples/hydration/src/components/counter.ts b/bun-examples/hydration/src/components/counter.ts
index ec52837b..dad86f43 100644
--- a/bun-examples/hydration/src/components/counter.ts
+++ b/bun-examples/hydration/src/components/counter.ts
@@ -1,24 +1,21 @@
-import { VanObj, State } from "mini-van-plate/shared"
+import { env, State } from "mini-van-plate/shared"
interface Props {
- van: VanObj
- id?: string
- init?: number
- buttonStyle?: string | State
+ readonly id?: string
+ readonly init?: number
+ readonly buttonStyle?: string | State
}
-export default ({
- van, id, init = 0, buttonStyle = "ππ",
-}: Props) => {
- const {button, div} = van.tags
+export default ({id, init = 0, buttonStyle = "ππ"}: Props) => {
+ const {button, div} = env.van.tags
- const stateProto = Object.getPrototypeOf(van.state())
+ const stateProto = Object.getPrototypeOf(env.van.state())
const val = (v: T | State) =>
Object.getPrototypeOf(v ?? 0) === stateProto ? (>v).val : v
const [up, down] = [...val(buttonStyle)]
- const counter = van.state(init)
+ const counter = env.van.state(init)
return div({...(id ? {id} : {}), "data-counter": counter},
"β€οΈ ", counter, " ",
button({onclick: () => ++counter.val}, up),
diff --git a/bun-examples/hydration/src/components/hello.ts b/bun-examples/hydration/src/components/hello.ts
index 9b1fc71c..2e962958 100644
--- a/bun-examples/hydration/src/components/hello.ts
+++ b/bun-examples/hydration/src/components/hello.ts
@@ -1,11 +1,7 @@
-import { VanObj } from "mini-van-plate/shared"
+import { env } from "mini-van-plate/shared"
-interface Props {
- van: VanObj
-}
-
-export default ({van} : Props) => {
- const {a, div, li, p, ul} = van.tags
+export default () => {
+ const {a, div, li, p, ul} = env.van.tags
const fromServer = typeof window === "undefined"
return div(
diff --git a/bun-examples/hydration/src/components/optimized-counter.ts b/bun-examples/hydration/src/components/optimized-counter.ts
index 95b83d08..07eb426f 100644
--- a/bun-examples/hydration/src/components/optimized-counter.ts
+++ b/bun-examples/hydration/src/components/optimized-counter.ts
@@ -1,23 +1,20 @@
-import { VanObj, State } from "mini-van-plate/shared"
+import { env, State } from "mini-van-plate/shared"
interface Props {
- van: VanObj
- id?: string
- init?: number
- buttonStyle?: string | State
+ readonly id?: string
+ readonly init?: number
+ readonly buttonStyle?: string | State
}
-export default ({
- van, id, init = 0, buttonStyle = "ππ",
-}: Props) => {
- const {button, div} = van.tags
+export default ({id, init = 0, buttonStyle = "ππ"}: Props) => {
+ const {button, div} = env.van.tags
- const stateProto = Object.getPrototypeOf(van.state())
+ const stateProto = Object.getPrototypeOf(env.van.state())
const val = (v: T | State) =>
Object.getPrototypeOf(v ?? 0) === stateProto ? (>v).val : v
- const counter = van.state(init)
+ const counter = env.van.state(init)
return div({...(id ? {id} : {}), "data-counter": counter},
"β€οΈ ", counter, " ",
button({onclick: () => ++counter.val}, () => [...val(buttonStyle)][0]),
diff --git a/bun-examples/hydration/src/server.ts b/bun-examples/hydration/src/server.ts
index fca27db4..9c24bfeb 100644
--- a/bun-examples/hydration/src/server.ts
+++ b/bun-examples/hydration/src/server.ts
@@ -1,9 +1,12 @@
import van from "mini-van-plate/van-plate"
+import { registerEnv } from "mini-van-plate/shared"
import Hello from "./components/hello.js"
import Counter from "./components/counter.js"
const {body, div, h1, h2, head, link, meta, option, p, script, select, title} = van.tags
+registerEnv({van})
+
const server = Bun.serve({
port: Bun.argv[2] ?? 8080,
fetch(req) {
@@ -19,13 +22,11 @@ const server = Bun.serve({
body(
script({type: "text/javascript", src: `dist/client.js`, defer: true}),
h1("Hello Components"),
- div({id: "hello-container"},
- Hello({van}),
- ),
+ div({id: "hello-container"}, Hello()),
h1("Counter Components"),
div({id: "counter-container"},
h2("Basic Counter"),
- Counter({van, id: "basic-counter", init: counterInit}),
+ Counter({id: "basic-counter", init: counterInit}),
h2("Styled Counter"),
p("Select the button style: ",
select({id: "button-style", value: "ππ"},
@@ -36,7 +37,7 @@ const server = Bun.serve({
option("ππ"),
),
),
- Counter({van, id: "styled-counter", init: counterInit, buttonStyle: "ππ"}),
+ Counter({id: "styled-counter", init: counterInit, buttonStyle: "ππ"}),
),
)
), {headers: {"Content-Type": "text/html; charset=UTF-8"}})
diff --git a/bun-examples/hydration/tsconfig.json b/bun-examples/hydration/tsconfig.json
index 447815fd..1b83c190 100644
--- a/bun-examples/hydration/tsconfig.json
+++ b/bun-examples/hydration/tsconfig.json
@@ -1,6 +1,6 @@
{
"compilerOptions": {
- "lib": ["ESNext"],
+ "lib": ["ESNext", "DOM"],
"module": "ESNext",
"target": "ESNext",
"moduleResolution": "bundler",
@@ -14,13 +14,7 @@
"jsx": "preserve",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
- "allowJs": true,
- "types": [
- "bun-types" // add Bun global
- ]
+ "allowJs": true
},
- "include": [
- "src/components/*.ts",
- "src/server.ts"
- ]
+ "include": ["src"]
}
diff --git a/components/README.md b/components/README.md
index 159c2a8a..8b1a72c1 100644
--- a/components/README.md
+++ b/components/README.md
@@ -52,14 +52,14 @@ import { } from "vanjs-ui"
Alternatively, you can import **VanUI** from CDN via a `
+
```
-`https://cdn.jsdelivr.net/npm/vanjs-ui@0.10.0/dist/van-ui.nomodule.js` can be used for the non-minified version.
+`https://cdn.jsdelivr.net/npm/vanjs-ui@0.11.5/dist/van-ui.nomodule.js` can be used for the non-minified version.
Note that: **VanJS** needs to be imported via a `
+