Include Fragment for JSX
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 3s

This commit is contained in:
2026-04-30 11:19:37 +02:00
parent b1fa97afc3
commit bef6c20231
4 changed files with 7 additions and 135 deletions

View File

@@ -1,4 +1,4 @@
# Hyperscript & Tag Helpers
# Hyperscript & Tag Helpers & JSX Style
SigPro provides two complementary ways to create DOM elements:
@@ -9,135 +9,6 @@ Both are reactive, autocleanup, and support SVG, events, twoway binding, a
---
## `h( )` Hyperscript Function
The `h` function is the **core DOM builder** of SigPro. Use it directly when you need a dynamic tag name or prefer an explicit style.
### Function Signature
```typescript
h(
tag: string | Function,
props?: object | Node | any[],
children?: any
): Node
```
| Parameter | Type | Description |
| :--- | :--- | :--- |
| **`tag`** | `string` or `Function` | HTML tag name (e.g., `"div"`) or a component function. |
| **`props`** | `object` | Optional. Attributes, event handlers, refs, etc. |
| **`children`** | `any` | Optional. Text, nodes, arrays, or reactive functions. |
**Returns:** A DOM node (or array of nodes when the tag is a component that returns an array).
### Usage Examples
```js
// Basic element
h('div', {}, 'Hello world');
// With attributes and events
h('button', { class: 'btn', onclick: () => alert('clicked') }, 'Click me');
// Nested children
h('div', { class: 'container' }, [
h('h1', {}, 'Title'),
h('p', {}, 'Paragraph')
]);
// Reactive child (function)
const count = $(0);
h('div', {}, [
h('p', {}, () => `Count: ${count()}`),
h('button', { onclick: () => count(count() + 1) }, '+1')
]);
// Reactive attribute
const theme = $('dark');
h('div', { class: () => `box ${theme()}` }, 'Themed box');
// Two-way binding on input
const name = $('');
h('input', { type: 'text', value: name, placeholder: 'Your name' });
h('p', {}, () => `Hello, ${name()}`);
// Component as tag
const Button = (props, { children }) =>
h('button', { class: 'btn', onclick: props.onClick }, children);
h(Button, { onClick: () => alert('clicked') }, 'Click me');
// SVG (auto-namespace)
h('svg', { width: 100, height: 100 }, [
h('circle', { cx: 50, cy: 50, r: 40, fill: 'red' })
]);
```
### Special Props
| Prop | Behaviour |
| :--- | :--- |
| **`ref`** | `ref: (el) => ...` or `ref: { current: null }` direct DOM node access. |
| **`onEvent`** | Any prop starting with `on` (e.g., `onClick`) is an event listener autoremoved on cleanup. |
| **`value` / `checked`** | When a signal is passed, creates twoway binding for form elements. |
| **`class`** | Use `class` (not `className`). Accepts a string or reactive function. |
---
## Global Tag Helpers (Lowercase)
When you import SigPro (either via `import 'sigpro'` or the CDN), it automatically injects a helper function for **every standard HTML tag** directly onto `window`. These helpers are **lowercase** and work exactly like `h`, but with a cleaner syntax.
### Available Helpers
All standard HTML5 tags: `div`, `span`, `p`, `section`, `nav`, `header`, `footer`, `h1``h6`, `ul`, `ol`, `li`, `button`, `a`, `input`, `form`, `table`, `svg`, `circle`, etc.
### Usage Examples
```js
// Instead of h('div', ...)
div({ class: 'container' }, 'Content');
// Children only (skip props)
section([
h2('Title'),
p('Paragraph')
]);
// Reactive attribute
const theme = $('light');
div({ class: () => `app-${theme()}` }, 'Themed');
// Two-way binding
const search = $('');
input({ type: 'text', value: search, placeholder: 'Search...' });
p(() => `You typed: ${search()}`);
// Dynamic children
const count = $(0);
div([
p(() => `Count: ${count()}`),
button({ onClick: () => count(count() + 1) }, '+1')
]);
```
### Complete Example
```js
const App = () =>
div({ class: 'app' }, [
h1('Welcome'),
input({ value: name, placeholder: 'Your name' }),
p(() => `Hello, ${name() || 'stranger'}!`),
button({ onClick: () => alert('Hi') }, 'Click me')
]);
mount(App, '#app');
```
---
## JSX with SigPro
SigPro works seamlessly with JSX. You can use JSX as a compiletime syntax sugar for `h` calls.

View File

@@ -29,7 +29,7 @@ When you use the **IIFE bundle** (`sigpro.js` or `sigpro.min.js`) with a traditi
```
### B. ESM (Modern JavaScript) Explicit Activation
When you import the **ES module** (`import { ... } from 'sigpro'`), the core **does not** add helpers to `window` by default. To enable global tags, import the dedicated sideeffect module:
**ES module** (`import { ... } from 'sigpro'`) or full `import 'sigpro'`.
```js
import 'sigpro';
@@ -38,7 +38,6 @@ import 'sigpro';
const App = () => div({ class: "app" }, "Ready!");
```
> **Important:** The tag helpers are **not** exported as individual named exports from the core (`sigpro`). They become available as global functions (`window.div`, etc.) after the sideeffect runs.
> If you prefer to avoid globals, you can always use `h('div', ...)` directly—its perfectly fine.
---

View File

@@ -1,6 +1,6 @@
{
"name": "sigpro",
"version": "1.2.28",
"version": "1.2.30",
"type": "module",
"license": "MIT",
"author": {

View File

@@ -497,6 +497,8 @@ router.to = p => window.location.hash = p.replace(/^#?\/?/, "#/")
router.back = () => window.history.back()
router.path = () => window.location.hash.replace(/^#/, "") || "/"
const Fragment = (props) => props.children;
const mount = (comp, target) => {
const t = typeof target === "string" ? doc.querySelector(target) : target
if (!t) return
@@ -508,10 +510,10 @@ const mount = (comp, target) => {
}
if (typeof window !== "undefined") {
Object.assign(window, { $, $$, watch, h, when, each, router, mount, batch, onUnmount, isArr, isFunc, isObj })
Object.assign(window, { $, $$, watch, h, Fragment, when, each, router, mount, batch, onUnmount, isArr, isFunc, isObj })
"a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video"
.split(" ")
.forEach(tag => { window[tag] = (props, children) => h(tag, props, children) })
}
export { $, $$, watch, batch, h, mount, when, each, router, onUnmount, isArr, isFunc, isObj }
export { $, $$, watch, batch, h, Fragment, mount, when, each, router, onUnmount, isArr, isFunc, isObj }