mono-jsx 0.7.4 β 0.8.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -20
- package/jsx-runtime.mjs +225 -213
- package/package.json +13 -3
- package/types/dom/jsx-runtime.d.ts +17 -0
- package/types/dom/mono.d.ts +83 -0
- package/types/html.d.ts +92 -6
- package/types/htmx.d.ts +1 -3
- package/types/jsx-runtime.d.ts +12 -0
- package/types/jsx.d.ts +66 -5
- package/types/mono.d.ts +43 -145
- package/types/render.d.ts +2 -0
package/README.md
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
mono-jsx is a JSX runtime that renders the `<html>` element to a `Response` object.
|
|
6
6
|
|
|
7
7
|
- π No build step needed
|
|
8
|
-
- π¦ Lightweight (
|
|
8
|
+
- π¦ Lightweight (12KB gzipped), zero dependencies
|
|
9
9
|
- π¦ Signals as reactive primitives
|
|
10
10
|
- β‘οΈ Use web components, no virtual DOM
|
|
11
11
|
- π‘ Complete Web API TypeScript definitions
|
|
12
12
|
- β³ Streaming rendering
|
|
13
|
-
- ποΈ Built-in router(SPA mode)
|
|
13
|
+
- ποΈ Built-in router (SPA mode)
|
|
14
14
|
- π Session storage
|
|
15
15
|
- π₯· [htmx](#using-htmx) integration
|
|
16
16
|
- π Universal, works in Node.js, Deno, Bun, Cloudflare Workers, etc.
|
|
@@ -428,41 +428,47 @@ export default {
|
|
|
428
428
|
|
|
429
429
|
mono-jsx renders HTML on the server side and sends no hydration JavaScript to the client. To render a component dynamically on the client, you can use the `<component>` element to ask the server to render a component:
|
|
430
430
|
|
|
431
|
+
To render a component by name, you can use the `<component>` element with the `name` prop, and ensure the component is registered in the `components` prop of root `<html>` element.
|
|
432
|
+
|
|
431
433
|
```tsx
|
|
434
|
+
function Foo(props: { bar: string }) {
|
|
435
|
+
return <h1>{props.bar}</h1>;
|
|
436
|
+
}
|
|
437
|
+
|
|
432
438
|
export default {
|
|
433
439
|
fetch: (req) => (
|
|
434
|
-
<html components={{ Foo }}>
|
|
435
|
-
<component name="Foo" props={{
|
|
440
|
+
<html request={req} components={{ Foo }}>
|
|
441
|
+
<component name="Foo" props={{ bar: "baz" }} placeholder={<p>Loading...</p>} />
|
|
436
442
|
</html>
|
|
437
443
|
)
|
|
438
444
|
}
|
|
439
445
|
```
|
|
440
446
|
|
|
441
|
-
You can use the `<
|
|
447
|
+
You can use the `<component>` element with the `is` prop to render a component by function reference without registering the component in the `components` prop of root `<html>` element.
|
|
442
448
|
|
|
443
449
|
```tsx
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
<component name="Foo" props={{ /* props for the component */ }} placeholder={<p>Loading...</p>} />
|
|
450
|
-
</toggle>
|
|
451
|
-
<button onClick={() => this.show = true }>Load `Foo` Component</button>
|
|
452
|
-
</div>
|
|
450
|
+
export default {
|
|
451
|
+
fetch: (req) => (
|
|
452
|
+
<html request={req}>
|
|
453
|
+
<component is={Foo} props={{ bar: "baz" }} placeholder={<p>Loading...</p>} />
|
|
454
|
+
</html>
|
|
453
455
|
)
|
|
454
456
|
}
|
|
457
|
+
```
|
|
455
458
|
|
|
459
|
+
Or you can use the `<component>` element with the `as` prop to render a component by JSX element.
|
|
460
|
+
|
|
461
|
+
```tsx
|
|
456
462
|
export default {
|
|
457
463
|
fetch: (req) => (
|
|
458
|
-
<html
|
|
459
|
-
<
|
|
464
|
+
<html request={req}>
|
|
465
|
+
<component as={<Foo bar="baz" />} placeholder={<p>Loading...</p>} />
|
|
460
466
|
</html>
|
|
461
467
|
)
|
|
462
468
|
}
|
|
463
469
|
```
|
|
464
470
|
|
|
465
|
-
You can also use signals for `name` or `props` attributes of a component. Changing the signal value will trigger the component to re-render with the new name or props:
|
|
471
|
+
You can also use [signals](#using-signals) for `name` or `props` attributes of a component. Changing the signal value will trigger the component to re-render with the new name or props:
|
|
466
472
|
|
|
467
473
|
```tsx
|
|
468
474
|
import { Profile, Projects, Settings } from "./pages.tsx"
|
|
@@ -486,13 +492,37 @@ function Dash(this: FC<{ page: "Profile" | "Projects" | "Settings" }>) {
|
|
|
486
492
|
|
|
487
493
|
export default {
|
|
488
494
|
fetch: (req) => (
|
|
489
|
-
<html components={{ Profile, Projects, Settings }}>
|
|
495
|
+
<html request={req} components={{ Profile, Projects, Settings }}>
|
|
490
496
|
<Dash />
|
|
491
497
|
</html>
|
|
492
498
|
)
|
|
493
499
|
}
|
|
494
500
|
```
|
|
495
501
|
|
|
502
|
+
You can use the `<toggle>` element to control when to render a component:
|
|
503
|
+
|
|
504
|
+
```tsx
|
|
505
|
+
async function Lazy(this: FC<{ show: boolean }>, props: { url: string }) {
|
|
506
|
+
this.show = false;
|
|
507
|
+
return (
|
|
508
|
+
<div>
|
|
509
|
+
<toggle show={this.show}>
|
|
510
|
+
<component name="Foo" props={{ bar: "baz" }} placeholder={<p>Loading...</p>} />
|
|
511
|
+
</toggle>
|
|
512
|
+
<button onClick={() => this.show = true }>Load `Foo` Component</button>
|
|
513
|
+
</div>
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
export default {
|
|
518
|
+
fetch: (req) => (
|
|
519
|
+
<html request={req} components={{ Foo }}>
|
|
520
|
+
<Lazy />
|
|
521
|
+
</html>
|
|
522
|
+
)
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
496
526
|
## Using Signals
|
|
497
527
|
|
|
498
528
|
mono-jsx uses signals for updating the view when a signal changes. Signals are similar to React's state, but they are more lightweight and efficient. You can use signals to manage state in your components.
|
|
@@ -682,7 +712,7 @@ function App(this: FC<{ lang: "en" | "zh" | "π" }>) {
|
|
|
682
712
|
<switch value={this.lang}>
|
|
683
713
|
<h1 slot="en">Hello, world!</h1>
|
|
684
714
|
<h1 slot="zh">δ½ ε₯½οΌδΈηοΌ</h1>
|
|
685
|
-
<h1>βπβοΈ</h1>
|
|
715
|
+
<h1 slot="π">βπβοΈ</h1>
|
|
686
716
|
</switch>
|
|
687
717
|
<p>
|
|
688
718
|
<button onClick={() => this.lang = "en"}>English</button>
|
|
@@ -885,6 +915,8 @@ The `<component>` element also supports the `ref` attribute, which allows you to
|
|
|
885
915
|
- `refresh`: A method to re-render the component with the current name and props.
|
|
886
916
|
|
|
887
917
|
```tsx
|
|
918
|
+
import type { ComponentElement } from "mono-jsx";
|
|
919
|
+
|
|
888
920
|
function App(this: Refs<FC, { component: ComponentElement }>) {
|
|
889
921
|
this.effect(() => {
|
|
890
922
|
// updating the component name and props will trigger a re-render of the component
|
|
@@ -892,7 +924,7 @@ function App(this: Refs<FC, { component: ComponentElement }>) {
|
|
|
892
924
|
this.refs.component.props = {};
|
|
893
925
|
|
|
894
926
|
const timer = setInterval(() => {
|
|
895
|
-
|
|
927
|
+
// re-render the component
|
|
896
928
|
this.refs.component.refresh();
|
|
897
929
|
}, 1000);
|
|
898
930
|
return () => clearInterval(timer); // cleanup
|