Files
sigpro/docs/api/jsx.md
natxocc f4654a938a
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 3s
Update docs
2026-04-25 20:28:38 +02:00

7.6 KiB
Raw Blame History

Aquí tienes el archivo h.md actualizado, que ahora incluye:

  • La función h (hyperscript)
  • Los helpers globales de etiquetas (lowercase)
  • Una nueva sección sobre JSX con SigPro (configuración, ejemplos y alternativas como htm).

El documento está en inglés, como los originales, y listo para integrarse en tu documentación.


# Hyperscript & Tag Helpers

SigPro provides two complementary ways to create DOM elements:

1. **The `h` function**  the lowlevel DOM builder.
2. **Global Tag Helpers** (e.g., `div()`, `button()`, `span()`)  a convenient DSL built on top of `h`.

Both are reactive, autocleanup, and support SVG, events, twoway binding, and dynamic children.

---

## `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

// 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, h1h6, ul, ol, li, button, a, input, form, table, svg, circle, etc.

Usage Examples

// 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

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.

Configuration

TypeScript

// tsconfig.json
{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "h",
    "jsxFragmentFactory": "Fragment"
  }
}

Vite

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  esbuild: {
    jsxFactory: 'h',
    jsxFragmentFactory: 'Fragment'
  }
})

Babel

// babel.config.js
export default {
  plugins: [
    ['@babel/plugin-transform-react-jsx', {
      pragma: 'h',
      pragmaFrag: 'Fragment'
    }]
  ]
}

Note: You need to import h and Fragment from SigPro in every JSX file, or make them global.

JSX Example

// App.jsx
import { $, h, Fragment, mount } from 'sigpro';

const Button = ({ onClick, children }) => (
  <button class="btn btn-primary" onclick={onClick}>
    {children}
  </button>
);

const App = () => {
  const count = $(0);

  return (
    <div class="container p-8">
      <h1 class="text-2xl font-bold">SigPro with JSX</h1>
      
      <Button onClick={() => count(count() + 1)}>
        Clicks: {() => count()}
      </Button>

      <Fragment>
        <p>Multiple elements</p>
        <p>Without extra wrapper</p>
      </Fragment>
    </div>
  );
};

mount(App, '#app');

What Gets Compiled

Your JSX:

<div class="container">
  <Button>Click</Button>
</div>

Compiles to:

h('div', { class: "container" },
  h(Button, {}, "Click")
)

Without a Build Step (CDN + Tag Helpers)

If you dont want to configure a JSX compiler, you can use the global tag helpers directly. They are available after loading SigPro via CDN.

<!DOCTYPE html>
<html>
<head>
  <script type="module">
    import 'https://cdn.jsdelivr.net/npm/sigpro@1.2.18/+esm';
    // Now $, $$, watch, h, mount, div, button, etc. are global

    const count = $(0);
    const App = () =>
      div({ class: 'container' }, [
        h1(() => `Count: ${count()}`),
        button({ onClick: () => count(count() + 1) }, 'Increment')
      ]);

    mount(App, '#app');
  </script>
</head>
<body>
  <div id="app"></div>
</body>
</html>

Template Literals Alternative (htm)

For a JSXlike syntax without a build step, you can combine SigPro with htm.

import { $, h, mount } from 'https://cdn.jsdelivr.net/npm/sigpro@1.2.18/+esm';
import htm from 'https://esm.sh/htm';

const html = htm.bind(h); // bind to SigPro's h function

const App = () => {
  const count = $(0);
  
  return html`
    <div class="container">
      <h1>SigPro Demo</h1>
      <button onclick=${() => count(count() + 1)}>
        Clicks: ${() => count()}
      </button>
    </div>
  `;
};

mount(App, '#app');

Summary Comparison

Method Build Step Syntax Recommended for
h function Optional h('div', ...) Dynamic tag names, lowlevel control
Tag Helpers Optional div(...) Most cases clean, simple, no build step
JSX Required <div>...</div> Large projects, teams familiar with React syntax
htm Optional html`<div>...</div>` Buildless but HTMLlike syntax

Tip: All approaches are fully reactive, support twoway binding, events, SVG, and automatic cleanup. Choose the one that fits your workflow.