paintcannon-react 0.0.13 → 0.0.15
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 +15 -0
- package/dist/src/host-components/button/reconcile-button.js +1 -1
- package/dist/src/host-components/div/reconcile-div.js +1 -1
- package/dist/src/host-components/form/reconcile-form.js +1 -1
- package/dist/src/host-components/input/reconcile-input.js +1 -1
- package/dist/src/host-components/mounted.d.ts +6 -1
- package/dist/src/host-components/span/reconcile-span.js +1 -1
- package/dist/src/host-components/textarea/reconcile-textarea.js +1 -1
- package/dist/src/reconciler.js +20 -19
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -97,6 +97,21 @@ These components map to PaintCannon's DOM-like core API and support typed style
|
|
|
97
97
|
props, bubbling events, forms, focus handling, controlled inputs, and mouse
|
|
98
98
|
interactions. The subset of the React-DOM props they support is as follows:
|
|
99
99
|
|
|
100
|
+
Host component `onFocus` and `onBlur` are element focus events. Terminal
|
|
101
|
+
window/pane focus is exposed by the underlying PaintCannon instance as
|
|
102
|
+
`paintCannon.hasFocus` and app-level `focus`/`blur` events. The root returned
|
|
103
|
+
from `render()` includes that instance:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
const app = render(<App />, { alternateScreen: true });
|
|
107
|
+
|
|
108
|
+
app.paintCannon.addEventListener("blur", () => {
|
|
109
|
+
// Dim or pause the app while the terminal is unfocused.
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Inside tmux, terminal focus reporting requires `set -g focus-events on`.
|
|
114
|
+
|
|
100
115
|
### Common props:
|
|
101
116
|
|
|
102
117
|
All host components accept:
|
|
@@ -3,7 +3,7 @@ import { applyScrollableProps } from "../reconcile-shared.js";
|
|
|
3
3
|
export function create(paintCannon, props, applyCommonProps) {
|
|
4
4
|
const node = paintCannon.createElement("button");
|
|
5
5
|
applyProps(node, {}, props, applyCommonProps);
|
|
6
|
-
return { kind: "element", type: button.type, props, children:
|
|
6
|
+
return { kind: "element", type: button.type, props, children: new Set(), node };
|
|
7
7
|
}
|
|
8
8
|
export function applyProps(node, oldProps, newProps, applyCommonProps) {
|
|
9
9
|
applyCommonProps(node, oldProps, newProps);
|
|
@@ -3,7 +3,7 @@ import { applyScrollableElementProps } from "../reconcile-shared.js";
|
|
|
3
3
|
export function create(paintCannon, props, applyCommonProps) {
|
|
4
4
|
const node = paintCannon.createElement("div");
|
|
5
5
|
applyProps(node, {}, props, applyCommonProps);
|
|
6
|
-
return { kind: "element", type: div.type, props, children:
|
|
6
|
+
return { kind: "element", type: div.type, props, children: new Set(), node };
|
|
7
7
|
}
|
|
8
8
|
export function applyProps(node, oldProps, newProps, applyCommonProps) {
|
|
9
9
|
applyScrollableElementProps(node, oldProps, newProps, applyCommonProps);
|
|
@@ -3,7 +3,7 @@ import { applyScrollableElementProps } from "../reconcile-shared.js";
|
|
|
3
3
|
export function create(paintCannon, props, applyCommonProps) {
|
|
4
4
|
const node = paintCannon.createElement("form");
|
|
5
5
|
applyProps(node, {}, props, applyCommonProps);
|
|
6
|
-
return { kind: "element", type: form.type, props, children:
|
|
6
|
+
return { kind: "element", type: form.type, props, children: new Set(), node };
|
|
7
7
|
}
|
|
8
8
|
export function applyProps(node, oldProps, newProps, applyCommonProps) {
|
|
9
9
|
applyScrollableElementProps(node, oldProps, newProps, applyCommonProps);
|
|
@@ -3,7 +3,7 @@ import { applyTextControlProps } from "../reconcile-shared.js";
|
|
|
3
3
|
export function create(paintCannon, props, applyCommonProps) {
|
|
4
4
|
const node = paintCannon.createElement("input");
|
|
5
5
|
applyProps(node, {}, props, applyCommonProps);
|
|
6
|
-
return { kind: "element", type: input.type, props, children:
|
|
6
|
+
return { kind: "element", type: input.type, props, children: new Set(), node };
|
|
7
7
|
}
|
|
8
8
|
export function applyProps(node, oldProps, newProps, applyCommonProps) {
|
|
9
9
|
applyCommonProps(node, oldProps, newProps);
|
|
@@ -11,7 +11,8 @@ export type MountedHostElement<Type extends HostType, Props, Element extends Pai
|
|
|
11
11
|
kind: "element";
|
|
12
12
|
type: Type;
|
|
13
13
|
props: Props;
|
|
14
|
-
children: HostNode
|
|
14
|
+
children: Set<HostNode>;
|
|
15
|
+
parent?: HostParent;
|
|
15
16
|
node: Element;
|
|
16
17
|
};
|
|
17
18
|
export type MountedComponent<Module> = Module extends {
|
|
@@ -22,9 +23,13 @@ export type HostElement = MountedComponent<typeof div> | MountedComponent<typeof
|
|
|
22
23
|
export type HostText = {
|
|
23
24
|
kind: "text";
|
|
24
25
|
text: string;
|
|
26
|
+
parent?: HostParent;
|
|
25
27
|
node: TextNode;
|
|
26
28
|
};
|
|
27
29
|
export type HostNode = HostElement | HostText;
|
|
30
|
+
export type HostParent = {
|
|
31
|
+
children: Set<HostNode>;
|
|
32
|
+
};
|
|
28
33
|
declare const hostPropsForType: {
|
|
29
34
|
"paintcannon.div": div.Props;
|
|
30
35
|
"paintcannon.span": span.Props;
|
|
@@ -3,7 +3,7 @@ import { applyScrollableElementProps } from "../reconcile-shared.js";
|
|
|
3
3
|
export function create(paintCannon, props, applyCommonProps) {
|
|
4
4
|
const node = paintCannon.createElement("span");
|
|
5
5
|
applyProps(node, {}, props, applyCommonProps);
|
|
6
|
-
return { kind: "element", type: span.type, props, children:
|
|
6
|
+
return { kind: "element", type: span.type, props, children: new Set(), node };
|
|
7
7
|
}
|
|
8
8
|
export function applyProps(node, oldProps, newProps, applyCommonProps) {
|
|
9
9
|
applyScrollableElementProps(node, oldProps, newProps, applyCommonProps);
|
|
@@ -3,7 +3,7 @@ import { applyScrollableProps, applyTextControlProps, } from "../reconcile-share
|
|
|
3
3
|
export function create(paintCannon, props, applyCommonProps) {
|
|
4
4
|
const node = paintCannon.createElement("textarea");
|
|
5
5
|
applyProps(node, {}, props, applyCommonProps);
|
|
6
|
-
return { kind: "element", type: textarea.type, props, children:
|
|
6
|
+
return { kind: "element", type: textarea.type, props, children: new Set(), node };
|
|
7
7
|
}
|
|
8
8
|
export function applyProps(node, oldProps, newProps, applyCommonProps) {
|
|
9
9
|
applyCommonProps(node, oldProps, newProps);
|
package/dist/src/reconciler.js
CHANGED
|
@@ -21,14 +21,17 @@ const reconciler = createReconciler({
|
|
|
21
21
|
},
|
|
22
22
|
resetAfterCommit(container) {
|
|
23
23
|
container.paintCannon.commitTransaction();
|
|
24
|
-
container.
|
|
24
|
+
if (container.presentCommits) {
|
|
25
|
+
container.paintCannon.render();
|
|
26
|
+
}
|
|
25
27
|
},
|
|
26
28
|
preparePortalMount: () => null,
|
|
27
29
|
clearContainer(container) {
|
|
28
30
|
for (const child of container.children) {
|
|
31
|
+
child.parent = undefined;
|
|
29
32
|
destroyHostNode(child);
|
|
30
33
|
}
|
|
31
|
-
container.children
|
|
34
|
+
container.children.clear();
|
|
32
35
|
return false;
|
|
33
36
|
},
|
|
34
37
|
shouldSetTextContent: () => false,
|
|
@@ -55,11 +58,11 @@ const reconciler = createReconciler({
|
|
|
55
58
|
container.root.appendChild(child.node);
|
|
56
59
|
},
|
|
57
60
|
insertBefore(parent, child, before) {
|
|
58
|
-
insertVirtualChild(parent, child
|
|
61
|
+
insertVirtualChild(parent, child);
|
|
59
62
|
insertPaintChild(parent.node, child.node, before.node);
|
|
60
63
|
},
|
|
61
64
|
insertInContainerBefore(container, child, before) {
|
|
62
|
-
insertVirtualChild(container, child
|
|
65
|
+
insertVirtualChild(container, child);
|
|
63
66
|
container.root.insertBefore(child.node, before.node);
|
|
64
67
|
},
|
|
65
68
|
removeChild(parent, child) {
|
|
@@ -148,7 +151,8 @@ export function createRoot(options = {}) {
|
|
|
148
151
|
const rootContainer = {
|
|
149
152
|
paintCannon,
|
|
150
153
|
root: container,
|
|
151
|
-
children:
|
|
154
|
+
children: new Set(),
|
|
155
|
+
presentCommits: true,
|
|
152
156
|
};
|
|
153
157
|
const animationScheduler = new AnimationScheduler(paintCannon);
|
|
154
158
|
const reactRoot = reconciler.createContainer(rootContainer, 0, null, false, null, "", reportReactError, reportReactError, reportReactError, () => { });
|
|
@@ -173,6 +177,7 @@ export function createRoot(options = {}) {
|
|
|
173
177
|
return;
|
|
174
178
|
}
|
|
175
179
|
exited = true;
|
|
180
|
+
rootContainer.presentCommits = false;
|
|
176
181
|
reconciler.updateContainer(null, reactRoot, null, () => {
|
|
177
182
|
animationScheduler.stop();
|
|
178
183
|
paintCannon.stop();
|
|
@@ -209,23 +214,19 @@ export function render(element, options = {}) {
|
|
|
209
214
|
return root;
|
|
210
215
|
}
|
|
211
216
|
function appendVirtualChild(parent, child) {
|
|
212
|
-
|
|
213
|
-
parent.children.
|
|
217
|
+
child.parent?.children.delete(child);
|
|
218
|
+
parent.children.add(child);
|
|
219
|
+
child.parent = parent;
|
|
214
220
|
}
|
|
215
|
-
function insertVirtualChild(parent, child
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
parent.children.push(child);
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
parent.children.splice(index, 0, child);
|
|
223
|
-
}
|
|
221
|
+
function insertVirtualChild(parent, child) {
|
|
222
|
+
child.parent?.children.delete(child);
|
|
223
|
+
parent.children.add(child);
|
|
224
|
+
child.parent = parent;
|
|
224
225
|
}
|
|
225
226
|
function removeVirtualChild(parent, child) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
parent
|
|
227
|
+
if (child.parent === parent) {
|
|
228
|
+
parent.children.delete(child);
|
|
229
|
+
child.parent = undefined;
|
|
229
230
|
}
|
|
230
231
|
}
|
|
231
232
|
function createHostElement(paintCannon, type, props) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "paintcannon-react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"scheduler": "^0.25.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"paintcannon": "^0.0.
|
|
39
|
+
"paintcannon": "^0.0.15",
|
|
40
40
|
"react": "^19.0.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|