@solidrt/core 0.0.1-exp.8 → 0.0.1-exp.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/core",
3
- "version": "0.0.1-exp.8",
3
+ "version": "0.0.1-exp.9",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -14,8 +14,11 @@
14
14
  "jsx-runtime.d.ts",
15
15
  "LICENSE"
16
16
  ],
17
+ "dependencies": {
18
+ "colord": "^2.9.3"
19
+ },
17
20
  "peerDependencies": {
18
- "@solidjs/signals": "2.0.0-beta.7",
19
- "@solidjs/universal": "2.0.0-beta.7"
21
+ "@solidjs/signals": "2.0.0-beta.13",
22
+ "@solidjs/universal": "2.0.0-beta.13"
20
23
  }
21
24
  }
package/src/color.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { colord, extend } from "colord"
2
+ import namesPlugin from "colord/plugins/names"
3
+ extend([namesPlugin])
4
+
5
+ // Parses any CSS color string and returns a packed u32: 0xRRGGBBAA
6
+ export function parseColorToU32(color: string): number {
7
+ let { r, g, b, a } = colord(color).toRgb()
8
+ return (((r & 0xFF) << 24) | ((g & 0xFF) << 16) | ((b & 0xFF) << 8) | ((a * 255) & 0xFF)) >>> 0
9
+ }
package/src/events.ts ADDED
@@ -0,0 +1,22 @@
1
+ let handlers = new Map<number, Map<string, Function>>()
2
+
3
+ export function setEventHandler(nodeId: number, name: string, fn: Function | null | undefined): void {
4
+ if (fn == null) {
5
+ handlers.get(nodeId)?.delete(name)
6
+ return
7
+ }
8
+ let nodeHandlers = handlers.get(nodeId)
9
+ if (!nodeHandlers) {
10
+ nodeHandlers = new Map()
11
+ handlers.set(nodeId, nodeHandlers)
12
+ }
13
+ nodeHandlers.set(name, fn)
14
+ }
15
+
16
+ export function getEventHandler(nodeId: number, name: string): Function | undefined {
17
+ return handlers.get(nodeId)?.get(name)
18
+ }
19
+
20
+ export function cleanupNodeHandlers(nodeId: number): void {
21
+ handlers.delete(nodeId)
22
+ }
package/src/renderer.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import { createRoot, createEffect } from "@solidjs/signals"
2
2
  import { createRenderer } from "@solidjs/universal"
3
3
  import { attachWindow } from "./window"
4
+ import { parseColorToU32, isColorProp } from "./color"
5
+ import { setEventHandler, cleanupNodeHandlers } from "./events"
6
+
7
+ export { getEventHandler } from "./events"
4
8
 
5
9
  export let nodes = new Map()
6
10
 
@@ -42,7 +46,7 @@ export let {
42
46
  createElement: (elementType: string): ProxyNode => {
43
47
  let proxy = createProxyNode(elementType)
44
48
 
45
- console.debug("[srt] createElement", proxy.id, elementType)
49
+ // console.debug("[srt] createElement", proxy.id, elementType)
46
50
 
47
51
  if (elementType === "window") ffi.createRoot(proxy.id)
48
52
  else ffi.createNode(proxy.id, elementType)
@@ -52,23 +56,32 @@ export let {
52
56
 
53
57
  createTextNode: (value: string): ProxyNode => {
54
58
  let proxy = createProxyNode("span")
55
- console.debug("[srt] createTextNode", proxy.id, value)
59
+ // console.debug("[srt] createTextNode", proxy.id, value)
56
60
  ffi.createNode(proxy.id, "span")
57
61
  ffi.setProperty(proxy.id, "text", "" + value)
58
62
  return proxy
59
63
  },
60
64
 
61
65
  replaceText: (node: ProxyNode, value: string): void => {
62
- console.debug("[srt] replaceText", node.id, value)
66
+ // console.debug("[srt] replaceText", node.id, value)
63
67
  ffi.setProperty(node.id, "text", "" + value)
64
68
  },
65
69
 
66
70
  isTextNode: (node: ProxyNode): boolean => node?.elementType === "span",
67
- setProperty: <T>(node: ProxyNode, name: string, value: T, prev?: T): void => {
71
+ setProperty: <T>(node: ProxyNode, name: string, value: T): void => {
68
72
  if (!node) return
69
73
 
70
- console.debug("[srt] setProperty", node.id, name, value)
71
- // if (runPropHandlers(node.id, name, value, prev)) return
74
+ // console.debug("[srt] setProperty", node.id, name, value)
75
+
76
+ if (/^on[A-Z]/.test(name) && (value == null || typeof value === "function")) {
77
+ setEventHandler(node.id, name, value as Function | null | undefined)
78
+ return
79
+ }
80
+
81
+ if (name === "color" && typeof value === "string") {
82
+ ffi.setProperty(node.id, name, parseColorToU32(value))
83
+ return
84
+ }
72
85
 
73
86
  ffi.setProperty(node.id, name, value)
74
87
  },
@@ -90,7 +103,7 @@ export let {
90
103
  }
91
104
  }
92
105
 
93
- console.debug("[srt] insertNode", parent.id, node.id, anchor?.id ?? "")
106
+ // console.debug("[srt] insertNode", parent.id, node.id, anchor?.id ?? "")
94
107
 
95
108
  if (anchor) ffi.insertNode(parent.id, node.id, anchor.id)
96
109
  else ffi.insertNode(parent.id, node.id)
@@ -100,7 +113,7 @@ export let {
100
113
  removeNode: (parent: ProxyNode, node: ProxyNode): void => {
101
114
  if (!node || !parent) return
102
115
 
103
- console.debug("[srt] removeNode", parent.id, node.id)
116
+ // console.debug("[srt] removeNode", parent.id, node.id)
104
117
 
105
118
  // Update JS tree references
106
119
  let index = parent.children.indexOf(node)
@@ -112,12 +125,12 @@ export let {
112
125
  ffi.deleteNode(parent.id, node.id)
113
126
 
114
127
  // Recursively clean up node and all descendants
115
- // let cleanup = (n: ProxyNode) => {
116
- // for (let child of n.children) cleanup(child)
117
- // nodes.delete(n.id)
118
- // runNodeCleanup(n.id)
119
- // }
120
- // cleanup(node)
128
+ let cleanup = (n: ProxyNode) => {
129
+ for (let child of n.children) cleanup(child)
130
+ nodes.delete(n.id)
131
+ cleanupNodeHandlers(n.id)
132
+ }
133
+ cleanup(node)
121
134
  },
122
135
 
123
136
  getParentNode: (node: ProxyNode) => node?.parent,
package/src/types.d.ts CHANGED
@@ -143,7 +143,9 @@ export interface AudioProps {
143
143
  export interface RectProps extends Position, PaintProps, PointerProps {
144
144
  w?: number
145
145
  h?: number
146
- r?: number
146
+ // Corner radius. A single number applies to all four corners; an array is
147
+ // [top-left, top-right, bottom-right, bottom-left] (CSS border-radius order).
148
+ radius?: number | [number, number, number, number]
147
149
  }
148
150
 
149
151
  export interface OvalProps extends Position, PaintProps, PointerProps {
package/src/window.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { onCleanup, onSettled } from "@solidjs/signals"
2
+ import { getEventHandler } from "./events"
2
3
 
3
4
  // ------ Animation frames ----------------
4
5
 
@@ -52,6 +53,9 @@ export function onResize(fn: (data: ResizeEvent) => void) {
52
53
 
53
54
  export function attachWindow(_nodeId: number) {
54
55
  let unsubscribe: () => void = null!
56
+ let unsubDown: () => void = null!
57
+ let unsubEnter: () => void = null!
58
+ let unsubLeave: () => void = null!
55
59
 
56
60
  onSettled(() => {
57
61
  unsubscribe = Flux.on("render", ({ time, frame }: { time: number, frame: number }) => {
@@ -66,11 +70,32 @@ export function attachWindow(_nodeId: number) {
66
70
  draw()
67
71
  })
68
72
 
73
+ unsubDown = Flux.on("pointerDown", ({ targets, button, clientX, clientY }: { targets: number[], button: number, clientX: number, clientY: number }) => {
74
+ for (let nodeId of targets) {
75
+ getEventHandler(nodeId, "onPointerDown")?.({ button, clientX, clientY })
76
+ }
77
+ })
78
+
79
+ unsubEnter = Flux.on("pointerEnter", ({ targets }: { targets: number[] }) => {
80
+ for (let nodeId of targets) {
81
+ getEventHandler(nodeId, "onPointerEnter")?.()
82
+ }
83
+ })
84
+
85
+ unsubLeave = Flux.on("pointerLeave", ({ targets }: { targets: number[] }) => {
86
+ for (let nodeId of targets) {
87
+ getEventHandler(nodeId, "onPointerLeave")?.()
88
+ }
89
+ })
90
+
69
91
  // trigger first draw
70
92
  draw()
71
93
  })
72
94
 
73
95
  onCleanup(() => {
74
96
  if (unsubscribe) unsubscribe()
97
+ if (unsubDown) unsubDown()
98
+ if (unsubEnter) unsubEnter()
99
+ if (unsubLeave) unsubLeave()
75
100
  })
76
101
  }