mono-jsx-dom 0.1.12 → 0.1.13
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 +90 -45
- package/package.json +1 -1
- package/types/jsx-runtime.d.ts +1 -1
- package/types/jsx.d.ts +12 -2
package/README.md
CHANGED
|
@@ -382,84 +382,129 @@ function Counter(this: FC<{ count: number }>, props: { initialCount?: number })
|
|
|
382
382
|
}
|
|
383
383
|
```
|
|
384
384
|
|
|
385
|
-
|
|
385
|
+
### Atom signals
|
|
386
|
+
|
|
387
|
+
Call `this.atom(initialValue)` inside a component to get a reactive atom tied to that instance. It updates the view when you call `set`, and you can read the current value with `get` (for example in `effect` callbacks).
|
|
386
388
|
|
|
387
389
|
```tsx
|
|
388
|
-
function
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
get double() {
|
|
393
|
-
return this.value * 2;
|
|
394
|
-
}
|
|
390
|
+
function Counter(this: FC) {
|
|
391
|
+
const count = this.atom(0);
|
|
392
|
+
this.effect(() => {
|
|
393
|
+
console.log("count changed:", count.get());
|
|
395
394
|
});
|
|
396
|
-
|
|
397
395
|
return (
|
|
398
396
|
<div>
|
|
399
|
-
<span>count
|
|
400
|
-
<
|
|
401
|
-
<button onClick={() => counter.value++}>+</button>
|
|
397
|
+
<span>{count}</span>
|
|
398
|
+
<button onClick={() => count.set((prev) => prev + 1)}>Increment</button>
|
|
402
399
|
</div>
|
|
403
|
-
)
|
|
400
|
+
);
|
|
404
401
|
}
|
|
405
402
|
```
|
|
406
403
|
|
|
407
|
-
|
|
404
|
+
For state shared across the whole app (or a module), import `atom` and define it at the top level. Any component that reads that atom in JSX or effects stays in sync.
|
|
408
405
|
|
|
409
|
-
|
|
406
|
+
```tsx
|
|
407
|
+
import { atom } from "mono-jsx-dom";
|
|
410
408
|
|
|
411
|
-
|
|
412
|
-
|
|
409
|
+
const count = atom(0);
|
|
410
|
+
const double = count.ref((value) => value * 2);
|
|
411
|
+
|
|
412
|
+
function Counter(this: FC) {
|
|
413
|
+
this.effect(() => {
|
|
414
|
+
console.log("count changed:", count.get());
|
|
415
|
+
});
|
|
416
|
+
return (
|
|
417
|
+
<div>
|
|
418
|
+
<p>count: {count}</p>
|
|
419
|
+
<p>double: {double}</p>
|
|
420
|
+
</div>
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function App(this: FC) {
|
|
425
|
+
return (
|
|
426
|
+
<div>
|
|
427
|
+
<Counter />
|
|
428
|
+
<button onClick={() => count.set((prev) => prev + 1)}>Increment</button>
|
|
429
|
+
</div>
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
The type of atom signals is defined as follows:
|
|
413
435
|
|
|
414
436
|
```ts
|
|
415
437
|
export interface Atom<T> {
|
|
438
|
+
/** Read the current value. */
|
|
416
439
|
get(): T;
|
|
417
|
-
|
|
418
|
-
|
|
440
|
+
/** Assign a new value or compute one from the previous value. */
|
|
441
|
+
set(value: T): void;
|
|
442
|
+
set(fn: (value: T) => T): void;
|
|
443
|
+
/** When `T` is an array, map each item to a child for list rendering. */
|
|
444
|
+
map(
|
|
445
|
+
callback: (value: T extends (infer V)[] ? V : T, index: number) => ChildPrimitiveType,
|
|
446
|
+
): ChildPrimitiveType[];
|
|
447
|
+
/** Create signal ref to the atom. */
|
|
419
448
|
ref(): T;
|
|
449
|
+
/** Derived reactive value from the atom. */
|
|
420
450
|
ref<V>(callback: (value: T) => V): V;
|
|
451
|
+
/** Run `callback` when the atom changes; pass `signal` to tie lifetime to an `AbortSignal`. */
|
|
452
|
+
watch(callback: () => void, signal?: AbortSignal): void;
|
|
421
453
|
}
|
|
422
|
-
|
|
423
|
-
export const atom: <T>(initValue: T) => Atom<T>;
|
|
424
|
-
export const store: <T extends Record<string, unknown>>(initValue: T) => T;
|
|
425
454
|
```
|
|
426
455
|
|
|
427
|
-
|
|
456
|
+
### Signal stores
|
|
428
457
|
|
|
429
|
-
|
|
430
|
-
import { atom, store } from "mono-jsx-dom";
|
|
431
|
-
|
|
432
|
-
const count = atom(0);
|
|
433
|
-
const store = store({ text: 'Count:' });
|
|
458
|
+
The `this.store({ ... })` method in a component builds a reactive object: plain fields are signals, and getters become derived signals.
|
|
434
459
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
460
|
+
```tsx
|
|
461
|
+
function App(this: FC) {
|
|
462
|
+
const counter = this.store({
|
|
463
|
+
value: 0,
|
|
464
|
+
get double() {
|
|
465
|
+
return this.value * 2;
|
|
466
|
+
},
|
|
438
467
|
});
|
|
468
|
+
|
|
439
469
|
return (
|
|
440
|
-
|
|
441
|
-
|
|
470
|
+
<div>
|
|
471
|
+
<span>count: {counter.value}</span>
|
|
472
|
+
<span>double: {counter.double}</span>
|
|
473
|
+
<button onClick={() => counter.value++}>+</button>
|
|
474
|
+
</div>
|
|
475
|
+
);
|
|
442
476
|
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
You can also use the `store` function to create a global signal store. Like `atom` function, the global signals store is shared between all components.
|
|
443
480
|
|
|
444
|
-
|
|
481
|
+
```tsx
|
|
482
|
+
import { store } from "mono-jsx-dom";
|
|
483
|
+
|
|
484
|
+
const counter = store({
|
|
485
|
+
value: 0,
|
|
486
|
+
get double() {
|
|
487
|
+
return this.value * 2;
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
function Counter(this: FC) {
|
|
445
492
|
return (
|
|
446
|
-
|
|
447
|
-
<
|
|
448
|
-
<
|
|
449
|
-
|
|
450
|
-
)
|
|
493
|
+
<div>
|
|
494
|
+
<span>{counter.value}</span>
|
|
495
|
+
<span>{counter.double}</span>
|
|
496
|
+
</div>
|
|
497
|
+
);
|
|
451
498
|
}
|
|
452
499
|
|
|
453
500
|
function App(this: FC) {
|
|
454
501
|
return (
|
|
455
|
-
|
|
502
|
+
<div>
|
|
456
503
|
<Counter />
|
|
457
|
-
<
|
|
458
|
-
|
|
459
|
-
)
|
|
504
|
+
<button onClick={() => counter.value++}>Increment</button>
|
|
505
|
+
</div>
|
|
506
|
+
);
|
|
460
507
|
}
|
|
461
|
-
|
|
462
|
-
document.body.mount(<App />);
|
|
463
508
|
```
|
|
464
509
|
|
|
465
510
|
### Using Computed Signals
|
package/package.json
CHANGED
package/types/jsx-runtime.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export const html: JSX.Raw;
|
|
|
4
4
|
export const JSX: typeof globalThis.JSX;
|
|
5
5
|
export const Fragment: (props: {}) => VNode;
|
|
6
6
|
export const jsx: (tag: string | ComponentType, props: Record<string, unknown>, key?: string | number) => VNode;
|
|
7
|
-
export const render: (scope: null, node: VNode, container: HTMLElement, aboutSignal?: AbortSignal) => void;
|
|
7
|
+
export const render: (scope: null, node: VNode, container: HTMLElement | DocumentFragment | ShadowRoot, aboutSignal?: AbortSignal) => void;
|
|
8
8
|
|
|
9
9
|
// aliases
|
|
10
10
|
export { html as css, html as js, jsx as jsxDEV, jsx as jsxs };
|
package/types/jsx.d.ts
CHANGED
|
@@ -97,11 +97,21 @@ export interface MonoBuiltinElements {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
export interface Atom<T> {
|
|
100
|
+
/** Read the current value. */
|
|
100
101
|
get(): T;
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
/** Assign a new value or compute one from the previous value. */
|
|
103
|
+
set(value: T): void;
|
|
104
|
+
set(fn: (value: T) => T): void;
|
|
105
|
+
/** When `T` is an array, map each item to a child for list rendering. */
|
|
106
|
+
map(
|
|
107
|
+
callback: (value: T extends (infer V)[] ? V : T, index: number) => ChildPrimitiveType,
|
|
108
|
+
): ChildPrimitiveType[];
|
|
109
|
+
/** Create signal ref to the atom. */
|
|
103
110
|
ref(): T;
|
|
111
|
+
/** Derived reactive value from the atom. */
|
|
104
112
|
ref<V>(callback: (value: T) => V): V;
|
|
113
|
+
/** Run `callback` when the atom changes; pass `signal` to tie lifetime to an `AbortSignal`. */
|
|
114
|
+
watch(callback: () => void, signal?: AbortSignal): void;
|
|
105
115
|
}
|
|
106
116
|
|
|
107
117
|
declare global {
|