@lab206/dom 0.1.0

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.
Files changed (69) hide show
  1. package/LICENSE +114 -0
  2. package/README.md +6 -0
  3. package/dist/bind.d.ts +23 -0
  4. package/dist/bind.d.ts.map +1 -0
  5. package/dist/bind.js +170 -0
  6. package/dist/bind.js.map +1 -0
  7. package/dist/component.d.ts +47 -0
  8. package/dist/component.d.ts.map +1 -0
  9. package/dist/component.js +95 -0
  10. package/dist/component.js.map +1 -0
  11. package/dist/dynamic.d.ts +17 -0
  12. package/dist/dynamic.d.ts.map +1 -0
  13. package/dist/dynamic.js +68 -0
  14. package/dist/dynamic.js.map +1 -0
  15. package/dist/fragment.d.ts +13 -0
  16. package/dist/fragment.d.ts.map +1 -0
  17. package/dist/fragment.js +41 -0
  18. package/dist/fragment.js.map +1 -0
  19. package/dist/h.d.ts +26 -0
  20. package/dist/h.d.ts.map +1 -0
  21. package/dist/h.js +164 -0
  22. package/dist/h.js.map +1 -0
  23. package/dist/index.d.ts +29 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +23 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/insert.d.ts +5 -0
  28. package/dist/insert.d.ts.map +1 -0
  29. package/dist/insert.js +10 -0
  30. package/dist/insert.js.map +1 -0
  31. package/dist/jsx-runtime.d.ts +52 -0
  32. package/dist/jsx-runtime.d.ts.map +1 -0
  33. package/dist/jsx-runtime.js +43 -0
  34. package/dist/jsx-runtime.js.map +1 -0
  35. package/dist/list.d.ts +23 -0
  36. package/dist/list.d.ts.map +1 -0
  37. package/dist/list.js +77 -0
  38. package/dist/list.js.map +1 -0
  39. package/dist/mount.d.ts +19 -0
  40. package/dist/mount.d.ts.map +1 -0
  41. package/dist/mount.js +40 -0
  42. package/dist/mount.js.map +1 -0
  43. package/dist/on.d.ts +8 -0
  44. package/dist/on.d.ts.map +1 -0
  45. package/dist/on.js +7 -0
  46. package/dist/on.js.map +1 -0
  47. package/dist/props.d.ts +54 -0
  48. package/dist/props.d.ts.map +1 -0
  49. package/dist/props.js +211 -0
  50. package/dist/props.js.map +1 -0
  51. package/dist/show.d.ts +12 -0
  52. package/dist/show.d.ts.map +1 -0
  53. package/dist/show.js +42 -0
  54. package/dist/show.js.map +1 -0
  55. package/package.json +71 -0
  56. package/src/bind.ts +195 -0
  57. package/src/component.ts +127 -0
  58. package/src/dynamic.ts +93 -0
  59. package/src/fragment.ts +43 -0
  60. package/src/h.ts +236 -0
  61. package/src/index.ts +54 -0
  62. package/src/insert.ts +14 -0
  63. package/src/jsx-runtime.ts +100 -0
  64. package/src/list.ts +111 -0
  65. package/src/mount.ts +46 -0
  66. package/src/on.ts +31 -0
  67. package/src/props.ts +259 -0
  68. package/src/show.ts +52 -0
  69. package/src/test-setup.ts +17 -0
package/dist/h.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { type DynamicChild } from "./dynamic.js";
2
+ export type Child = Node | DocumentFragment | string | number | boolean | null | undefined | (() => DynamicChild);
3
+ export type FunctionComponent<P = Record<string, unknown>> = (props: P) => Node | DocumentFragment | null | undefined;
4
+ export type Props = {
5
+ /** Static or reactive text content (sets textContent). */
6
+ text?: string | number | (() => string | number | boolean | null | undefined);
7
+ class?: string | (() => string | Record<string, boolean | undefined | null> | null | undefined);
8
+ className?: string | (() => string | Record<string, boolean | undefined | null> | null | undefined);
9
+ style?: Record<string, string | number | null | undefined> | (() => Record<string, string | number | null | undefined> | null | undefined);
10
+ /** ref callback with the created element */
11
+ ref?: (el: HTMLElement) => void;
12
+ children?: unknown;
13
+ [key: string]: unknown;
14
+ };
15
+ /**
16
+ * Create an element — or invoke a function component.
17
+ *
18
+ * Classic JSX (`jsxFactory: "h"`) compiles `<App />` to `h(App, props)`.
19
+ * Automatic runtime uses `jsx()` which also supports function types.
20
+ */
21
+ export declare function h<K extends keyof HTMLElementTagNameMap>(tag: K, props?: Props | null, ...children: Child[]): HTMLElementTagNameMap[K];
22
+ export declare function h(tag: string, props?: Props | null, ...children: Child[]): HTMLElement;
23
+ export declare function h<P extends Record<string, unknown>>(tag: FunctionComponent<P>, props?: (P & Props) | null, ...children: Child[]): Node | DocumentFragment;
24
+ /** Create a reactive or static text node. */
25
+ export declare function text(value: string | number | (() => string | number | boolean | null | undefined)): Text;
26
+ //# sourceMappingURL=h.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h.d.ts","sourceRoot":"","sources":["../src/h.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAI9D,MAAM,MAAM,KAAK,GACb,IAAI,GACJ,gBAAgB,GAChB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,GACT,CAAC,MAAM,YAAY,CAAC,CAAC;AAEzB,MAAM,MAAM,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAC3D,KAAK,EAAE,CAAC,KACL,IAAI,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAAC;AAEhD,MAAM,MAAM,KAAK,GAAG;IAClB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAChG,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACpG,KAAK,CAAC,EACF,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAClD,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAClF,4CAA4C;IAC5C,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAWF;;;;;GAKG;AACH,wBAAgB,CAAC,CAAC,CAAC,SAAS,MAAM,qBAAqB,EACrD,GAAG,EAAE,CAAC,EACN,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EACpB,GAAG,QAAQ,EAAE,KAAK,EAAE,GACnB,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAE5B,wBAAgB,CAAC,CACf,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EACpB,GAAG,QAAQ,EAAE,KAAK,EAAE,GACnB,WAAW,CAAC;AAEf,wBAAgB,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjD,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC,EACzB,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,EAC1B,GAAG,QAAQ,EAAE,KAAK,EAAE,GACnB,IAAI,GAAG,gBAAgB,CAAC;AAmD3B,6CAA6C;AAC7C,wBAAgB,IAAI,CAClB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GAC5E,IAAI,CAQN"}
package/dist/h.js ADDED
@@ -0,0 +1,164 @@
1
+ import { bindAttr, bindClass, bindProp, bindStyle, bindText } from "./bind.js";
2
+ import { bindDynamic } from "./dynamic.js";
3
+ import { on } from "./on.js";
4
+ import { createProps } from "./props.js";
5
+ const RESERVED = new Set([
6
+ "text",
7
+ "class",
8
+ "className",
9
+ "style",
10
+ "ref",
11
+ "children",
12
+ ]);
13
+ export function h(tag, props, ...children) {
14
+ // Function component (classic JSX: h(App, props, ...children))
15
+ if (typeof tag === "function") {
16
+ const raw = { ...(props ?? {}) };
17
+ if (children.length === 1) {
18
+ raw.children = children[0];
19
+ }
20
+ else if (children.length > 1) {
21
+ raw.children = children;
22
+ }
23
+ const result = tag(createProps(raw));
24
+ if (result == null) {
25
+ return document.createComment("powers");
26
+ }
27
+ return result;
28
+ }
29
+ if (typeof tag !== "string" || tag === "") {
30
+ throw new Error(`[powers/dom] h() expected a tag name string or component function, got: ${typeof tag}`);
31
+ }
32
+ const el = document.createElement(tag);
33
+ if (props) {
34
+ applyProps(el, props);
35
+ }
36
+ for (const child of children) {
37
+ appendChild(el, child);
38
+ }
39
+ // Also support props.children (automatic runtime path sometimes)
40
+ if (props?.children != null && children.length === 0) {
41
+ const c = props.children;
42
+ if (Array.isArray(c)) {
43
+ for (const item of c)
44
+ appendChild(el, item);
45
+ }
46
+ else {
47
+ appendChild(el, c);
48
+ }
49
+ }
50
+ return el;
51
+ }
52
+ /** Create a reactive or static text node. */
53
+ export function text(value) {
54
+ const node = document.createTextNode("");
55
+ if (typeof value === "function") {
56
+ bindText(node, value);
57
+ }
58
+ else {
59
+ node.data = String(value);
60
+ }
61
+ return node;
62
+ }
63
+ function applyProps(el, props) {
64
+ for (const key of Object.keys(props)) {
65
+ if (RESERVED.has(key))
66
+ continue;
67
+ const value = props[key];
68
+ if (key.startsWith("on") && key.length > 2 && typeof value === "function") {
69
+ // onClick → click, onMouseDown → mousedown
70
+ const event = key.slice(2).toLowerCase();
71
+ on(el, event, value);
72
+ continue;
73
+ }
74
+ if (typeof value === "function") {
75
+ if (isDomProp(key)) {
76
+ bindProp(el, key, value);
77
+ }
78
+ else {
79
+ bindAttr(el, toAttrName(key), value);
80
+ }
81
+ continue;
82
+ }
83
+ if (isDomProp(key)) {
84
+ el[key] = value;
85
+ }
86
+ else if (value === true) {
87
+ el.setAttribute(toAttrName(key), "");
88
+ }
89
+ else if (value !== false && value != null) {
90
+ el.setAttribute(toAttrName(key), String(value));
91
+ }
92
+ }
93
+ const classValue = props.class ?? props.className;
94
+ if (classValue !== undefined) {
95
+ if (typeof classValue === "function") {
96
+ bindClass(el, classValue);
97
+ }
98
+ else if (classValue != null) {
99
+ el.className = classValue;
100
+ }
101
+ }
102
+ if (props.style !== undefined) {
103
+ if (typeof props.style === "function") {
104
+ bindStyle(el, props.style);
105
+ }
106
+ else if (props.style) {
107
+ bindStyle(el, () => props.style);
108
+ }
109
+ }
110
+ if (props.text !== undefined) {
111
+ if (typeof props.text === "function") {
112
+ bindText(el, props.text);
113
+ }
114
+ else {
115
+ el.textContent = String(props.text);
116
+ }
117
+ }
118
+ if (typeof props.ref === "function") {
119
+ props.ref(el);
120
+ }
121
+ }
122
+ function appendChild(parent, child) {
123
+ if (child == null || child === false || child === true)
124
+ return;
125
+ if (typeof child === "function") {
126
+ // May return text *or* DOM nodes (Tabs/Accordion content, etc.)
127
+ bindDynamic(parent, child);
128
+ return;
129
+ }
130
+ if (typeof child === "string" || typeof child === "number") {
131
+ parent.appendChild(document.createTextNode(String(child)));
132
+ return;
133
+ }
134
+ parent.appendChild(child);
135
+ }
136
+ const DOM_PROPS = new Set([
137
+ "value",
138
+ "checked",
139
+ "selected",
140
+ "disabled",
141
+ "hidden",
142
+ "readOnly",
143
+ "multiple",
144
+ "muted",
145
+ "controls",
146
+ "defaultValue",
147
+ "defaultChecked",
148
+ "innerHTML",
149
+ "tabIndex",
150
+ "spellcheck",
151
+ ]);
152
+ function isDomProp(name) {
153
+ return DOM_PROPS.has(name);
154
+ }
155
+ function toAttrName(key) {
156
+ if (key.startsWith("aria")) {
157
+ return key.replace(/([A-Z])/g, "-$1").toLowerCase();
158
+ }
159
+ if (key.startsWith("data") && key.length > 4 && key[4] !== "-") {
160
+ return key.replace(/([A-Z])/g, "-$1").toLowerCase();
161
+ }
162
+ return key;
163
+ }
164
+ //# sourceMappingURL=h.js.map
package/dist/h.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h.js","sourceRoot":"","sources":["../src/h.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @lab206/dom
3
+ *
4
+ * Thin, explicit DOM bindings over @lab206/core.
5
+ *
6
+ * Learn order:
7
+ * mount → h / JSX → component → reactive props → Show / For
8
+ *
9
+ * Form controls in @lab206/ui use `bind={signal}` for two-way state —
10
+ * `bind` is intentionally not unwrapped by createProps (see props.ts).
11
+ */
12
+ export { mount } from "./mount.js";
13
+ export type { MountResult } from "./mount.js";
14
+ export { h, text } from "./h.js";
15
+ export type { Child, Props, FunctionComponent } from "./h.js";
16
+ export { Fragment, normalizeChildren, appendChild } from "./fragment.js";
17
+ export { bindText, bindAttr, bindProp, bindClass, bindStyle, } from "./bind.js";
18
+ export { bindDynamic } from "./dynamic.js";
19
+ export type { DynamicChild } from "./dynamic.js";
20
+ export { on } from "./on.js";
21
+ export { show } from "./show.js";
22
+ export { list } from "./list.js";
23
+ export type { ListOptions } from "./list.js";
24
+ export { insert, remove } from "./insert.js";
25
+ export { component, Show, For } from "./component.js";
26
+ export type { Component, ComponentProps, ComponentSetup, } from "./component.js";
27
+ export { createProps, mergeProps, splitProps, unwrapProp, getRawProp, isSignal, isReactiveProps, } from "./props.js";
28
+ export type { ReactiveProps } from "./props.js";
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACjC,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAE9D,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACtD,YAAY,EACV,SAAS,EACT,cAAc,EACd,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,WAAW,EACX,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @lab206/dom
3
+ *
4
+ * Thin, explicit DOM bindings over @lab206/core.
5
+ *
6
+ * Learn order:
7
+ * mount → h / JSX → component → reactive props → Show / For
8
+ *
9
+ * Form controls in @lab206/ui use `bind={signal}` for two-way state —
10
+ * `bind` is intentionally not unwrapped by createProps (see props.ts).
11
+ */
12
+ export { mount } from "./mount.js";
13
+ export { h, text } from "./h.js";
14
+ export { Fragment, normalizeChildren, appendChild } from "./fragment.js";
15
+ export { bindText, bindAttr, bindProp, bindClass, bindStyle, } from "./bind.js";
16
+ export { bindDynamic } from "./dynamic.js";
17
+ export { on } from "./on.js";
18
+ export { show } from "./show.js";
19
+ export { list } from "./list.js";
20
+ export { insert, remove } from "./insert.js";
21
+ export { component, Show, For } from "./component.js";
22
+ export { createProps, mergeProps, splitProps, unwrapProp, getRawProp, isSignal, isReactiveProps, } from "./props.js";
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGjC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAOtD,OAAO,EACL,WAAW,EACX,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** Append or insert a node. Returns the node for chaining. */
2
+ export declare function insert<T extends Node>(parent: ParentNode, child: T, anchor?: Node | null): T;
3
+ /** Remove a node from its parent if attached. */
4
+ export declare function remove(node: Node): void;
5
+ //# sourceMappingURL=insert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insert.d.ts","sourceRoot":"","sources":["../src/insert.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,wBAAgB,MAAM,CAAC,CAAC,SAAS,IAAI,EACnC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,CAAC,EACR,MAAM,GAAE,IAAI,GAAG,IAAW,GACzB,CAAC,CAGH;AAED,iDAAiD;AACjD,wBAAgB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAEvC"}
package/dist/insert.js ADDED
@@ -0,0 +1,10 @@
1
+ /** Append or insert a node. Returns the node for chaining. */
2
+ export function insert(parent, child, anchor = null) {
3
+ parent.insertBefore(child, anchor);
4
+ return child;
5
+ }
6
+ /** Remove a node from its parent if attached. */
7
+ export function remove(node) {
8
+ node.parentNode?.removeChild(node);
9
+ }
10
+ //# sourceMappingURL=insert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insert.js","sourceRoot":"","sources":["../src/insert.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,MAAM,UAAU,MAAM,CACpB,MAAkB,EAClB,KAAQ,EACR,SAAsB,IAAI;IAE1B,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,MAAM,CAAC,IAAU;IAC/B,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Automatic JSX runtime for Powers.
3
+ *
4
+ * Vite / TypeScript:
5
+ * jsx: "react-jsx"
6
+ * jsxImportSource: "@lab206/dom"
7
+ *
8
+ * Function components receive **reactive props** via `createProps`
9
+ * (unless they already wrapped themselves with `component()`).
10
+ */
11
+ import { type Props } from "./h.js";
12
+ import { Fragment } from "./fragment.js";
13
+ export { Fragment };
14
+ export type FunctionComponent<P = Record<string, unknown>> = (props: P) => Node | DocumentFragment | null | undefined;
15
+ /** Marker set on components that already apply createProps. */
16
+ export declare const REACTIVE_PROPS: unique symbol;
17
+ export declare function jsx(type: string | FunctionComponent<Record<string, unknown>>, props: (Props & {
18
+ children?: unknown;
19
+ }) | null, _key?: string | number): Node | DocumentFragment;
20
+ export declare function jsxs(type: string | FunctionComponent<Record<string, unknown>>, props: (Props & {
21
+ children?: unknown;
22
+ }) | null, _key?: string | number): Node | DocumentFragment;
23
+ export declare function jsxDEV(type: string | FunctionComponent<Record<string, unknown>>, props: (Props & {
24
+ children?: unknown;
25
+ }) | null, _key?: string | number): Node | DocumentFragment;
26
+ export declare namespace JSX {
27
+ type Element = Node | DocumentFragment;
28
+ type ElementType = string | FunctionComponent<any>;
29
+ interface ElementAttributesProperty {
30
+ props: unknown;
31
+ }
32
+ interface ElementChildrenAttribute {
33
+ children: unknown;
34
+ }
35
+ type LibraryManagedAttributes<C, P> = P;
36
+ interface IntrinsicAttributes {
37
+ key?: string | number;
38
+ }
39
+ type IntrinsicElements = {
40
+ [K in keyof HTMLElementTagNameMap]: Props & {
41
+ children?: unknown;
42
+ } & {
43
+ [attr: string]: unknown;
44
+ };
45
+ } & {
46
+ [elemName: string]: Props & {
47
+ children?: unknown;
48
+ [attr: string]: unknown;
49
+ };
50
+ };
51
+ }
52
+ //# sourceMappingURL=jsx-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.d.ts","sourceRoot":"","sources":["../src/jsx-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAK,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAqB,MAAM,eAAe,CAAC;AAG5D,OAAO,EAAE,QAAQ,EAAE,CAAC;AAEpB,MAAM,MAAM,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAC3D,KAAK,EAAE,CAAC,KACL,IAAI,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAAC;AAEhD,+DAA+D;AAC/D,eAAO,MAAM,cAAc,eAAqC,CAAC;AAEjE,wBAAgB,GAAG,CACjB,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzD,KAAK,EAAE,CAAC,KAAK,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,IAAI,EAC9C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GACrB,IAAI,GAAG,gBAAgB,CAEzB;AAED,wBAAgB,IAAI,CAClB,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzD,KAAK,EAAE,CAAC,KAAK,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,IAAI,EAC9C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GACrB,IAAI,GAAG,gBAAgB,CAEzB;AAED,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzD,KAAK,EAAE,CAAC,KAAK,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,IAAI,EAC9C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GACrB,IAAI,GAAG,gBAAgB,CAEzB;AAyBD,yBAAiB,GAAG,CAAC;IACnB,KAAY,OAAO,GAAG,IAAI,GAAG,gBAAgB,CAAC;IAC9C,KAAY,WAAW,GAAG,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAE1D,UAAiB,yBAAyB;QACxC,KAAK,EAAE,OAAO,CAAC;KAChB;IACD,UAAiB,wBAAwB;QACvC,QAAQ,EAAE,OAAO,CAAC;KACnB;IAED,KAAY,wBAAwB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAE/C,UAAiB,mBAAmB;QAClC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB;IAED,KAAY,iBAAiB,GAAG;SAC7B,CAAC,IAAI,MAAM,qBAAqB,GAAG,KAAK,GAAG;YAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;SACpB,GAAG;YACF,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;SACzB;KACF,GAAG;QACF,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG;YAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;YACnB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;SACzB,CAAC;KACH,CAAC;CACH"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Automatic JSX runtime for Powers.
3
+ *
4
+ * Vite / TypeScript:
5
+ * jsx: "react-jsx"
6
+ * jsxImportSource: "@lab206/dom"
7
+ *
8
+ * Function components receive **reactive props** via `createProps`
9
+ * (unless they already wrapped themselves with `component()`).
10
+ */
11
+ import { h } from "./h.js";
12
+ import { Fragment, normalizeChildren } from "./fragment.js";
13
+ import { createProps } from "./props.js";
14
+ export { Fragment };
15
+ /** Marker set on components that already apply createProps. */
16
+ export const REACTIVE_PROPS = Symbol.for("powers.reactiveProps");
17
+ export function jsx(type, props, _key) {
18
+ return create(type, props);
19
+ }
20
+ export function jsxs(type, props, _key) {
21
+ return create(type, props);
22
+ }
23
+ export function jsxDEV(type, props, _key) {
24
+ return create(type, props);
25
+ }
26
+ function create(type, props) {
27
+ const p = props ?? {};
28
+ const { children, ...rest } = p;
29
+ if (typeof type === "function") {
30
+ // Always pass through createProps so bare function components get
31
+ // reactive field access. component() also wraps — double-wrap is OK
32
+ // (outer raw object, inner Proxy of raw; component's createProps runs first).
33
+ const reactive = createProps(p);
34
+ const result = type(reactive);
35
+ if (result == null) {
36
+ return document.createComment("powers");
37
+ }
38
+ return result;
39
+ }
40
+ const childList = normalizeChildren(children);
41
+ return h(type, rest, ...childList);
42
+ }
43
+ //# sourceMappingURL=jsx-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.js","sourceRoot":"","sources":["../src/jsx-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,CAAC,EAAc,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,CAAC;AAMpB,+DAA+D;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AAEjE,MAAM,UAAU,GAAG,CACjB,IAAyD,EACzD,KAA8C,EAC9C,IAAsB;IAEtB,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,IAAI,CAClB,IAAyD,EACzD,KAA8C,EAC9C,IAAsB;IAEtB,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,MAAM,CACpB,IAAyD,EACzD,KAA8C,EAC9C,IAAsB;IAEtB,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,MAAM,CACb,IAAyD,EACzD,KAA8C;IAE9C,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;IACtB,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;IAEhC,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,kEAAkE;QAClE,oEAAoE;QACpE,8EAA8E;QAC9E,MAAM,QAAQ,GAAG,WAAW,CAAC,CAA4B,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,QAAmC,CAAC,CAAC;QACzD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC9C,OAAO,CAAC,CAAC,IAAI,EAAE,IAAa,EAAE,GAAG,SAAS,CAAC,CAAC;AAC9C,CAAC"}
package/dist/list.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { type Dispose } from "@lab206/core";
2
+ export interface ListOptions<T> {
3
+ /** Stable identity for reuse. Defaults to index (fine for append-only demos). */
4
+ key?: (item: T, index: number) => string | number;
5
+ }
6
+ /**
7
+ * Reactive list rendering with keyed reconciliation.
8
+ *
9
+ * **Note:** `parent` should be a dedicated container (e.g. a `ul` or `div`)
10
+ * whose children are owned by this list.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * list(
15
+ * ul,
16
+ * () => todos(),
17
+ * (item, index) => h("li", { text: () => `${index()}: ${item().title}` }),
18
+ * { key: (t) => t.id },
19
+ * );
20
+ * ```
21
+ */
22
+ export declare function list<T>(parent: ParentNode, getItems: () => readonly T[], render: (item: () => T, index: () => number) => Node, options?: ListOptions<T>): Dispose;
23
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EAEb,MAAM,cAAc,CAAC;AAGtB,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,iFAAiF;IACjF,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC;CACnD;AAUD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,IAAI,CAAC,CAAC,EACpB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,SAAS,CAAC,EAAE,EAC5B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,MAAM,KAAK,IAAI,EACpD,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GACvB,OAAO,CAmET"}
package/dist/list.js ADDED
@@ -0,0 +1,77 @@
1
+ import { createRoot, effect, signal, } from "@lab206/core";
2
+ import { remove } from "./insert.js";
3
+ /**
4
+ * Reactive list rendering with keyed reconciliation.
5
+ *
6
+ * **Note:** `parent` should be a dedicated container (e.g. a `ul` or `div`)
7
+ * whose children are owned by this list.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * list(
12
+ * ul,
13
+ * () => todos(),
14
+ * (item, index) => h("li", { text: () => `${index()}: ${item().title}` }),
15
+ * { key: (t) => t.id },
16
+ * );
17
+ * ```
18
+ */
19
+ export function list(parent, getItems, render, options) {
20
+ const keyOf = options?.key;
21
+ const entries = new Map();
22
+ let order = [];
23
+ const stop = effect(() => {
24
+ const items = getItems();
25
+ const nextKeys = [];
26
+ const seen = new Set();
27
+ for (let i = 0; i < items.length; i++) {
28
+ const value = items[i];
29
+ const key = keyOf ? keyOf(value, i) : i;
30
+ nextKeys.push(key);
31
+ seen.add(key);
32
+ const existing = entries.get(key);
33
+ if (!existing) {
34
+ const index = signal(i);
35
+ const item = signal(value);
36
+ let node;
37
+ let dispose;
38
+ createRoot((d) => {
39
+ dispose = d;
40
+ node = render(() => item(), () => index());
41
+ });
42
+ entries.set(key, { key, node, dispose, index, item });
43
+ }
44
+ else {
45
+ existing.index.set(i);
46
+ existing.item.set(value);
47
+ }
48
+ }
49
+ for (const key of order) {
50
+ if (!seen.has(key)) {
51
+ const entry = entries.get(key);
52
+ if (entry) {
53
+ entry.dispose();
54
+ remove(entry.node);
55
+ entries.delete(key);
56
+ }
57
+ }
58
+ }
59
+ // Move nodes into correct order (appendChild relocates existing nodes).
60
+ for (const key of nextKeys) {
61
+ const entry = entries.get(key);
62
+ if (entry)
63
+ parent.appendChild(entry.node);
64
+ }
65
+ order = nextKeys;
66
+ });
67
+ return () => {
68
+ stop();
69
+ for (const entry of entries.values()) {
70
+ entry.dispose();
71
+ remove(entry.node);
72
+ }
73
+ entries.clear();
74
+ order = [];
75
+ };
76
+ }
77
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type Dispose } from "@lab206/core";
2
+ export type MountResult = Node | Node[] | null | undefined | void;
3
+ /**
4
+ * Mount a reactive app into a parent node.
5
+ * Returns a dispose function that tears down effects and removes mounted nodes.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const stop = mount(document.getElementById("app")!, () => {
10
+ * const count = signal(0);
11
+ * return h("button", {
12
+ * onClick: () => count.update(n => n + 1),
13
+ * text: () => `Count: ${count()}`,
14
+ * });
15
+ * });
16
+ * ```
17
+ */
18
+ export declare function mount(parent: ParentNode, app: () => MountResult): Dispose;
19
+ //# sourceMappingURL=mount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAGxD,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,WAAW,GACrB,OAAO,CAsBT"}
package/dist/mount.js ADDED
@@ -0,0 +1,40 @@
1
+ import { createRoot } from "@lab206/core";
2
+ import { remove } from "./insert.js";
3
+ /**
4
+ * Mount a reactive app into a parent node.
5
+ * Returns a dispose function that tears down effects and removes mounted nodes.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const stop = mount(document.getElementById("app")!, () => {
10
+ * const count = signal(0);
11
+ * return h("button", {
12
+ * onClick: () => count.update(n => n + 1),
13
+ * text: () => `Count: ${count()}`,
14
+ * });
15
+ * });
16
+ * ```
17
+ */
18
+ export function mount(parent, app) {
19
+ const nodes = [];
20
+ let disposeRoot;
21
+ createRoot((dispose) => {
22
+ disposeRoot = dispose;
23
+ const result = app();
24
+ if (result == null)
25
+ return;
26
+ const list = Array.isArray(result) ? result : [result];
27
+ for (const node of list) {
28
+ parent.appendChild(node);
29
+ nodes.push(node);
30
+ }
31
+ });
32
+ return () => {
33
+ disposeRoot();
34
+ for (const node of nodes) {
35
+ remove(node);
36
+ }
37
+ nodes.length = 0;
38
+ };
39
+ }
40
+ //# sourceMappingURL=mount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAgB,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,KAAK,CACnB,MAAkB,EAClB,GAAsB;IAEtB,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,IAAI,WAAqB,CAAC;IAE1B,UAAU,CAAC,CAAC,OAAO,EAAE,EAAE;QACrB,WAAW,GAAG,OAAO,CAAC;QACtB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC;QACrB,IAAI,MAAM,IAAI,IAAI;YAAE,OAAO;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvD,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACV,WAAW,EAAE,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC"}
package/dist/on.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { Dispose } from "@lab206/core";
2
+ /**
3
+ * Attach a DOM event listener. Returns a dispose that removes it.
4
+ * Does not track signals inside the handler (handlers are events, not renders).
5
+ */
6
+ export declare function on<K extends keyof HTMLElementEventMap>(el: EventTarget, type: K, handler: (event: HTMLElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions): Dispose;
7
+ export declare function on(el: EventTarget, type: string, handler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): Dispose;
8
+ //# sourceMappingURL=on.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"on.d.ts","sourceRoot":"","sources":["../src/on.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,EAAE,CAAC,CAAC,SAAS,MAAM,mBAAmB,EACpD,EAAE,EAAE,WAAW,EACf,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,IAAI,EAChD,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,OAAO,CAAC;AAEX,wBAAgB,EAAE,CAChB,EAAE,EAAE,WAAW,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kCAAkC,EAC3C,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,OAAO,CAAC"}
package/dist/on.js ADDED
@@ -0,0 +1,7 @@
1
+ export function on(el, type, handler, options) {
2
+ el.addEventListener(type, handler, options);
3
+ return () => {
4
+ el.removeEventListener(type, handler, options);
5
+ };
6
+ }
7
+ //# sourceMappingURL=on.js.map
package/dist/on.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"on.js","sourceRoot":"","sources":["../src/on.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,EAAE,CAChB,EAAe,EACf,IAAY,EACZ,OAA2C,EAC3C,OAA2C;IAE3C,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,GAAG,EAAE;QACV,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC"}