paintcannon-react 0.0.14 → 0.0.16

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 CHANGED
@@ -124,6 +124,7 @@ All host components accept these event props:
124
124
 
125
125
  - `onKeyDown`
126
126
  - `onKeyUp`
127
+ - `onPaste`
127
128
  - `onClick`
128
129
  - `onMouseEnter`
129
130
  - `onMouseLeave`
@@ -136,6 +137,9 @@ All host components accept these event props:
136
137
  - `onTransitionEnd`
137
138
  - `onScroll`
138
139
 
140
+ `onPaste` receives the same `PaintClipboardEvent` as core, including detected terminal image paths
141
+ through `event.clipboardData.files`.
142
+
139
143
  `style` accepts the following CSS property names. Kebab-case and camelCase are
140
144
  both supported:
141
145
 
@@ -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: [], node };
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: [], node };
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: [], node };
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: [], node };
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;
@@ -11,6 +11,7 @@ export type HostComponent<Props, Element extends PaintElement> = React.ForwardRe
11
11
  export declare const EVENT_PROP_NAMES: {
12
12
  readonly keydown: "onKeyDown";
13
13
  readonly keyup: "onKeyUp";
14
+ readonly paste: "onPaste";
14
15
  readonly click: "onClick";
15
16
  readonly mouseenter: "onMouseEnter";
16
17
  readonly mouseleave: "onMouseLeave";
@@ -4,6 +4,7 @@ export function typeString(type) {
4
4
  export const EVENT_PROP_NAMES = {
5
5
  keydown: "onKeyDown",
6
6
  keyup: "onKeyUp",
7
+ paste: "onPaste",
7
8
  click: "onClick",
8
9
  mouseenter: "onMouseEnter",
9
10
  mouseleave: "onMouseLeave",
@@ -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: [], node };
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: [], node };
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);
@@ -21,14 +21,17 @@ const reconciler = createReconciler({
21
21
  },
22
22
  resetAfterCommit(container) {
23
23
  container.paintCannon.commitTransaction();
24
- container.paintCannon.render();
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, before);
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, before);
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
- removeVirtualChild(parent, child);
213
- parent.children.push(child);
217
+ child.parent?.children.delete(child);
218
+ parent.children.add(child);
219
+ child.parent = parent;
214
220
  }
215
- function insertVirtualChild(parent, child, before) {
216
- removeVirtualChild(parent, child);
217
- const index = parent.children.indexOf(before);
218
- if (index === -1) {
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
- const index = parent.children.indexOf(child);
227
- if (index !== -1) {
228
- parent.children.splice(index, 1);
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.14",
3
+ "version": "0.0.16",
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.14",
39
+ "paintcannon": "^0.0.16",
40
40
  "react": "^19.0.0"
41
41
  },
42
42
  "devDependencies": {