diff --git a/README.md b/README.md index 61c59bc..f63f9f2 100644 --- a/README.md +++ b/README.md @@ -25,70 +25,56 @@ import { div, h1, button, signal, mount } from "sibujs"; function Counter() { const [count, setCount] = signal(0); - return div({ class: "counter" }, [ + return div("counter", [ h1(() => `Count: ${count()}`), - button({ on: { click: () => setCount(c => c + 1) } }, "Increment"), + button( + { on: { click: () => setCount(count() + 1) } }, + "Increment", + ), ]); } mount(Counter, document.getElementById("app")); ``` -### Three Ways to Author Components +### Authoring Style -SibuJS gives you maximum flexibility with three interoperable styles: - -#### 1. Tag Factory -The canonical form: a props object followed by children as a second -positional argument. No `nodes:` key required at any level of the tree — -children can be a string, a number, a single node, an array, or a -reactive getter. +Every tag factory accepts children as an optional second positional +argument. This is **the canonical authoring style** — no `nodes:` key +at any level of the tree. The first argument can be a className string, +a props object, or the children themselves. ```javascript import { div, h1, label, input, button } from "sibujs"; -return div({ class: "counter" }, [ - h1({ class: "title" }, () => `Count: ${count()}`), - label({ for: "amount" }, "Step"), - input({ id: "amount", type: "number", value: 1 }), - button( - { class: "primary", on: { click: () => setCount(c => c + 1) } }, - "Increment", - ), +// Positional className + children — the default form for styled wrappers +div("page", [ + h1("title", "Welcome"), + div("row", [ + label({ for: "email" }, "Email"), + input({ id: "email", type: "email" }), + button( + { class: "primary", type: "submit", on: { click: handleSubmit } }, + "Submit", + ), + ]), ]); -``` -All legacy forms — `tag({ class, nodes })`, `tag("className", children)`, -`tag("text")`, `tag([children])`, `tag(node)`, `tag(() => reactive)` — -continue to work unchanged. When both `props.nodes` and the positional -second argument are present, the positional wins. +// Children-only — bare containers +div([h1("Hello"), p("World")]); -#### 2. Positional Shorthand -The tersest form. Class and children as positional arguments, for -layouts with no event handlers or custom props. - -```javascript -import { div, h1, button } from "sibujs"; +// Text-only +h1("Hello, world!"); -return div("counter", [ - h1(() => `Count: ${count()}`), - button({ on: { click: () => setCount(c => c + 1) } }, "Increment"), -]); +// Reactive children +div(() => `Count: ${count()}`); ``` -#### 3. HTML Tagged Template -Familiar HTML-like syntax using tagged template literals. No compiler needed! - -```javascript -import { html } from "sibujs"; - -return html` -