Add JSX
This commit is contained in:
5
dist/sigpro.esm.js
vendored
5
dist/sigpro.esm.js
vendored
@@ -406,7 +406,8 @@ var $mount = (component, target) => {
|
|||||||
MOUNTED_NODES.set(el, instance);
|
MOUNTED_NODES.set(el, instance);
|
||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
var SigProCore = { $, $watch, $html, $if, $for, $router, $mount };
|
var Fragment = ({ children }) => children;
|
||||||
|
var SigProCore = { $, $watch, $html, $if, $for, $router, $mount, Fragment };
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
const install = (registry) => {
|
const install = (registry) => {
|
||||||
Object.keys(registry).forEach((key) => {
|
Object.keys(registry).forEach((key) => {
|
||||||
@@ -419,11 +420,13 @@ if (typeof window !== "undefined") {
|
|||||||
window[helperName] = (props, content) => $html(tagName, props, content);
|
window[helperName] = (props, content) => $html(tagName, props, content);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
window.Fragment = Fragment;
|
||||||
window.SigPro = Object.freeze(registry);
|
window.SigPro = Object.freeze(registry);
|
||||||
};
|
};
|
||||||
install(SigProCore);
|
install(SigProCore);
|
||||||
}
|
}
|
||||||
export {
|
export {
|
||||||
|
Fragment,
|
||||||
$watch,
|
$watch,
|
||||||
$router,
|
$router,
|
||||||
$mount,
|
$mount,
|
||||||
|
|||||||
2
dist/sigpro.esm.min.js
vendored
2
dist/sigpro.esm.min.js
vendored
File diff suppressed because one or more lines are too long
5
dist/sigpro.js
vendored
5
dist/sigpro.js
vendored
@@ -30,6 +30,7 @@
|
|||||||
// index.js
|
// index.js
|
||||||
var exports_sigpro = {};
|
var exports_sigpro = {};
|
||||||
__export(exports_sigpro, {
|
__export(exports_sigpro, {
|
||||||
|
Fragment: () => Fragment,
|
||||||
$watch: () => $watch,
|
$watch: () => $watch,
|
||||||
$router: () => $router,
|
$router: () => $router,
|
||||||
$mount: () => $mount,
|
$mount: () => $mount,
|
||||||
@@ -447,7 +448,8 @@
|
|||||||
MOUNTED_NODES.set(el, instance);
|
MOUNTED_NODES.set(el, instance);
|
||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
var SigProCore = { $, $watch, $html, $if, $for, $router, $mount };
|
var Fragment = ({ children }) => children;
|
||||||
|
var SigProCore = { $, $watch, $html, $if, $for, $router, $mount, Fragment };
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
const install = (registry) => {
|
const install = (registry) => {
|
||||||
Object.keys(registry).forEach((key) => {
|
Object.keys(registry).forEach((key) => {
|
||||||
@@ -460,6 +462,7 @@
|
|||||||
window[helperName] = (props, content) => $html(tagName, props, content);
|
window[helperName] = (props, content) => $html(tagName, props, content);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
window.Fragment = Fragment;
|
||||||
window.SigPro = Object.freeze(registry);
|
window.SigPro = Object.freeze(registry);
|
||||||
};
|
};
|
||||||
install(SigProCore);
|
install(SigProCore);
|
||||||
|
|||||||
2
dist/sigpro.min.js
vendored
2
dist/sigpro.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -16,6 +16,7 @@
|
|||||||
* [$html](api/html.md)
|
* [$html](api/html.md)
|
||||||
* [Tags](api/tags.md)
|
* [Tags](api/tags.md)
|
||||||
* [Global Store](api/global.md)
|
* [Global Store](api/global.md)
|
||||||
|
* [JSX Style](api/jsx.md)
|
||||||
|
|
||||||
* **UI Components**
|
* **UI Components**
|
||||||
* [Quick Start](ui/quick.md)
|
* [Quick Start](ui/quick.md)
|
||||||
171
docs/api/jsx.md
Normal file
171
docs/api/jsx.md
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
# JSX with SigPro
|
||||||
|
|
||||||
|
SigPro works seamlessly with JSX.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
|
||||||
|
```json
|
||||||
|
// tsconfig.json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react",
|
||||||
|
"jsxFactory": "$html",
|
||||||
|
"jsxFragmentFactory": "Fragment"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vite
|
||||||
|
|
||||||
|
```js
|
||||||
|
// vite.config.js
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
esbuild: {
|
||||||
|
jsxFactory: '$html',
|
||||||
|
jsxFragmentFactory: 'Fragment'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Babel
|
||||||
|
|
||||||
|
```js
|
||||||
|
// babel.config.js
|
||||||
|
export default {
|
||||||
|
plugins: [
|
||||||
|
['@babel/plugin-transform-react-jsx', {
|
||||||
|
pragma: '$html',
|
||||||
|
pragmaFrag: 'Fragment'
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Example
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// App.jsx
|
||||||
|
import { $, $mount, Fragment } 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:
|
||||||
|
```jsx
|
||||||
|
<div class="container">
|
||||||
|
<Button>Click</Button>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
Compiles to:
|
||||||
|
```javascript
|
||||||
|
$html('div', { class: "container" },
|
||||||
|
$html(Button, {}, "Click")
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Without Build Step (CDN)
|
||||||
|
|
||||||
|
SigPro automatically injects `Div()`, `Button()`, `Span()`, and all other HTML tag helpers globally when loaded via CDN. `Fragment` is also available.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="https://unpkg.com/sigpro"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const { $, $mount, Fragment } = SigPro;
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
const count = $(0);
|
||||||
|
|
||||||
|
return Div({ class: "container p-8" }, [
|
||||||
|
H1({ class: "text-2xl font-bold" }, "SigPro Demo"),
|
||||||
|
Button({
|
||||||
|
class: "btn-primary",
|
||||||
|
onclick: () => count(count() + 1)
|
||||||
|
}, () => `Clicks: ${count()}`),
|
||||||
|
Fragment({}, [
|
||||||
|
P({}, "Multiple elements"),
|
||||||
|
P({}, "Without wrapper")
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
$mount(App, '#app');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Template Literals Alternative (htm)
|
||||||
|
|
||||||
|
For a JSX-like syntax without a build step, use `htm`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { $, $mount } from 'https://unpkg.com/sigpro';
|
||||||
|
import htm from 'https://esm.sh/htm';
|
||||||
|
|
||||||
|
const html = htm.bind($html);
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
| Method | Build Step | Syntax |
|
||||||
|
|--------|------------|--------|
|
||||||
|
| JSX | Required | `<div>...</div>` |
|
||||||
|
| CDN (Tag Helpers) | Optional | `Div({}, ...)` |
|
||||||
|
| htm | Optional | `` html`<div>...</div>` `` |
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> **Recommendation:** Use JSX for large projects, CDN tag helpers (`Div()`, `Button()`) for simple projects, or htm for buildless projects that want HTML-like syntax.
|
||||||
@@ -42,7 +42,6 @@ bun add sigpro
|
|||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="radio" name="install_method" class="tab border-base-300 whitespace-nowrap" aria-label="CDN (ESM)" />
|
<input type="radio" name="install_method" class="tab border-base-300 whitespace-nowrap" aria-label="CDN (ESM)" />
|
||||||
<div class="tab-content bg-base-100 border-base-300 rounded-box p-6">
|
<div class="tab-content bg-base-100 border-base-300 rounded-box p-6">
|
||||||
|
|
||||||
@@ -153,17 +152,17 @@ $mount(App, "#app");
|
|||||||
|
|
||||||
One of SigPro's core strengths is its **Global API**, which eliminates "Import Hell" while remaining ESM-compatible.
|
One of SigPro's core strengths is its **Global API**, which eliminates "Import Hell" while remaining ESM-compatible.
|
||||||
|
|
||||||
* **The "Zero-Config" Import:** By simply adding `import SigPro from "sigpro"`, the framework automatically "hydrates" the global `window` object.
|
- **The "Zero-Config" Import:** By simply adding `import SigPro from "sigpro"`, the framework automatically "hydrates" the global `window` object.
|
||||||
* **Core Functions:** You get immediate access to `$`, `$watch`, `$html`, `$if`, `$for`, and `$router` anywhere in your scripts without using the `SigPro.` prefix.
|
- **Core Functions:** You get immediate access to `$`, `$watch`, `$html`, `$if`, `$for`, and `$router` anywhere in your scripts without using the `SigPro.` prefix.
|
||||||
* **Auto-Installation:** This happens instantly upon import thanks to its built-in `install()` routine, making it "Plug & Play" for both local projects and CDN usage.
|
- **Auto-Installation:** This happens instantly upon import thanks to its built-in `install()` routine, making it "Plug & Play" for both local projects and CDN usage.
|
||||||
|
|
||||||
* **PascalCase Tag Helpers:** Standard HTML tags are pre-registered as global functions (`Div`, `Span`, `Button`, `Section`, etc.).
|
- **PascalCase Tag Helpers:** Standard HTML tags are pre-registered as global functions (`Div`, `Span`, `Button`, `Section`, etc.).
|
||||||
* **Clean UI Syntax:** This allows you to write UI structures that look like HTML but are pure, reactive JavaScript: `Div({ class: "card" }, [ H1("Title") ])`.
|
- **Clean UI Syntax:** This allows you to write UI structures that look like HTML but are pure, reactive JavaScript: `Div({ class: "card" }, [ H1("Title") ])`.
|
||||||
|
|
||||||
* **Hybrid Tree Shaking:** * For **Maximum Speed**, use `import SigPro from "sigpro"`.
|
- **Hybrid Tree Shaking:** \* For **Maximum Speed**, use `import SigPro from "sigpro"`.
|
||||||
* For **Maximum Optimization**, you can still use Named Imports: `import { $, $html } from "sigpro"`. This allows modern bundlers like Vite to prune unused code while keeping your core reactive.
|
- For **Maximum Optimization**, you can still use Named Imports: `import { $, $html } from "sigpro"`. This allows modern bundlers like Vite to prune unused code while keeping your core reactive.
|
||||||
|
|
||||||
* **Custom Components:** We recommend using **PascalCase** for your own components (e.g., `UserCard()`) to maintain visual consistency with the built-in Tag Helpers and distinguish them from standard logic.
|
- **Custom Components:** We recommend using **PascalCase** for your own components (e.g., `UserCard()`) to maintain visual consistency with the built-in Tag Helpers and distinguish them from standard logic.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
2
index.js
2
index.js
@@ -1,2 +1,2 @@
|
|||||||
// index.js
|
// index.js
|
||||||
export * from './dist/sigpro.esm.js';
|
export * from './sigpro/index.js';
|
||||||
@@ -443,7 +443,9 @@ const $mount = (component, target) => {
|
|||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SigProCore = { $, $watch, $html, $if, $for, $router, $mount };
|
export const Fragment = ({ children }) => children;
|
||||||
|
|
||||||
|
const SigProCore = { $, $watch, $html, $if, $for, $router, $mount, Fragment };
|
||||||
|
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
const install = (registry) => {
|
const install = (registry) => {
|
||||||
@@ -459,6 +461,7 @@ if (typeof window !== "undefined") {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.Fragment = Fragment;
|
||||||
window.SigPro = Object.freeze(registry);
|
window.SigPro = Object.freeze(registry);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user