@solidrt/core 0.0.2 → 0.0.4
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 +2 -2
- package/src/focus.ts +6 -0
- package/src/index.ts +3 -1
- package/src/renderer.ts +4 -1
- package/src/text.ts +5 -0
- package/src/types.d.ts +13 -0
- package/src/window.ts +34 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidrt/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Antoine van Wel",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"colord": "^2.9.3"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@solidrt/flux-types": "0.0.
|
|
22
|
+
"@solidrt/flux-types": "0.0.4"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"@solidjs/signals": "2.0.0-beta.13",
|
package/src/focus.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { getEventHandler } from "./events"
|
|
|
3
3
|
// Currently-focused node id. Reset to null automatically across engine
|
|
4
4
|
// reloads because the JS environment is rebuilt from scratch.
|
|
5
5
|
let focusedNodeId: number | null = null
|
|
6
|
+
let textInputActive = false
|
|
6
7
|
|
|
7
8
|
export function setFocus(nodeId: number | null): void {
|
|
8
9
|
if (nodeId === focusedNodeId) return
|
|
@@ -14,6 +15,11 @@ export function setFocus(nodeId: number | null): void {
|
|
|
14
15
|
if (nodeId != null) {
|
|
15
16
|
getEventHandler(nodeId, "onFocus")?.()
|
|
16
17
|
}
|
|
18
|
+
let wantActive = nodeId != null && getEventHandler(nodeId, "onTextInput") != null
|
|
19
|
+
if (wantActive !== textInputActive) {
|
|
20
|
+
textInputActive = wantActive
|
|
21
|
+
ffi.setTextInputActive(wantActive)
|
|
22
|
+
}
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
export function getFocusedNodeId(): number | null {
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export * from "./renderer"
|
|
2
2
|
export { setFocus, getFocusedNodeId } from "./focus"
|
|
3
|
-
export { onRender, onResize, onWindowFocus, onWindowBlur } from "./window"
|
|
3
|
+
export { onRender, onLayout, onResize, onWindowFocus, onWindowBlur } from "./window"
|
|
4
|
+
export { measureText } from "./text"
|
|
5
|
+
export type { MeasureTextOptions } from "./types"
|
package/src/renderer.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { createRenderer } from "@solidjs/universal"
|
|
|
3
3
|
import { attachWindow } from "./window"
|
|
4
4
|
import { parseColorToU32, isColorProp } from "./color"
|
|
5
5
|
import { setEventHandler, cleanupNodeHandlers } from "./events"
|
|
6
|
+
import { getFocusedNodeId, setFocus } from "./focus"
|
|
6
7
|
|
|
7
8
|
export { getEventHandler } from "./events"
|
|
8
9
|
|
|
@@ -124,9 +125,11 @@ export let {
|
|
|
124
125
|
|
|
125
126
|
ffi.deleteNode(parent.id, node.id)
|
|
126
127
|
|
|
127
|
-
// Recursively clean up node and all descendants
|
|
128
|
+
// Recursively clean up node and all descendants. Clear focus before
|
|
129
|
+
// dropping handlers so onBlur still fires for a focused descendant.
|
|
128
130
|
let cleanup = (n: ProxyNode) => {
|
|
129
131
|
for (let child of n.children) cleanup(child)
|
|
132
|
+
if (n.id === getFocusedNodeId()) setFocus(null)
|
|
130
133
|
nodes.delete(n.id)
|
|
131
134
|
cleanupNodeHandlers(n.id)
|
|
132
135
|
}
|
package/src/text.ts
ADDED
package/src/types.d.ts
CHANGED
|
@@ -10,9 +10,19 @@ declare global {
|
|
|
10
10
|
insertNode(parentId: number, nodeId: number, anchorId?: number): void
|
|
11
11
|
deleteNode(parentId: number, nodeId: number): void
|
|
12
12
|
setProperty(nodeId: number, name: string, value: unknown): void
|
|
13
|
+
setTextInputActive(active: boolean): void
|
|
14
|
+
measureText(text: string, options?: MeasureTextOptions): { width: number, height: number }
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
export interface MeasureTextOptions {
|
|
19
|
+
fontFamily?: "sans" | "mono" | (string & {})
|
|
20
|
+
fontSize?: number
|
|
21
|
+
fontStyle?: "normal" | "italic"
|
|
22
|
+
fontWeight?: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
|
23
|
+
maxLines?: number
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
type Children = SolidJSX.Element
|
|
17
27
|
|
|
18
28
|
type OA<T> = T | Accessor<T>
|
|
@@ -101,6 +111,8 @@ export interface TransformProps {
|
|
|
101
111
|
y?: OA<number>
|
|
102
112
|
cx?: OA<number>
|
|
103
113
|
cy?: OA<number>
|
|
114
|
+
scrollX?: OA<number>
|
|
115
|
+
scrollY?: OA<number>
|
|
104
116
|
}
|
|
105
117
|
|
|
106
118
|
export interface PointerProps {
|
|
@@ -167,6 +179,7 @@ export interface TextProps extends PaintProps {
|
|
|
167
179
|
children?: Children
|
|
168
180
|
fontFamily?: "sans" | "mono" | (string & {})
|
|
169
181
|
fontSize?: number
|
|
182
|
+
lineHeight?: number
|
|
170
183
|
fontStyle?: "normal" | "italic"
|
|
171
184
|
fontWeight?: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
|
172
185
|
textAlign?: "left" | "right" | "center" | "justify"
|
package/src/window.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { onCleanup, onSettled } from "@solidjs/signals"
|
|
2
2
|
import { getEventHandler } from "./events"
|
|
3
|
-
import { getFocusedNodeId } from "./focus"
|
|
3
|
+
import { getFocusedNodeId, setFocus } from "./focus"
|
|
4
4
|
|
|
5
5
|
// ------ Animation frames ----------------
|
|
6
6
|
|
|
@@ -50,6 +50,16 @@ export function onResize(fn: (data: ResizeEvent) => void) {
|
|
|
50
50
|
return unsubscribe
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// Fires after layout has been computed for the current frame but before paint.
|
|
54
|
+
// Setting properties that affect layout from this callback will be picked up
|
|
55
|
+
// by a re-layout pass before painting (one extra pass; cascades beyond that
|
|
56
|
+
// paint stale).
|
|
57
|
+
export function onLayout(fn: () => void) {
|
|
58
|
+
let unsubscribe = Flux.on("postLayout", fn)
|
|
59
|
+
onCleanup(unsubscribe)
|
|
60
|
+
return unsubscribe
|
|
61
|
+
}
|
|
62
|
+
|
|
53
63
|
export function onWindowFocus(fn: () => void) {
|
|
54
64
|
let unsubscribe = Flux.on("windowFocus", fn)
|
|
55
65
|
onCleanup(unsubscribe)
|
|
@@ -74,6 +84,8 @@ export function attachWindow(_nodeId: number) {
|
|
|
74
84
|
let unsubWheel: () => void = null!
|
|
75
85
|
let unsubKeyDown: () => void = null!
|
|
76
86
|
let unsubKeyUp: () => void = null!
|
|
87
|
+
let unsubTextInput: () => void = null!
|
|
88
|
+
let unsubKeyboardVisibility: () => void = null!
|
|
77
89
|
|
|
78
90
|
onSettled(() => {
|
|
79
91
|
unsubscribe = Flux.on("render", ({ time, frame }: { time: number, frame: number }) => {
|
|
@@ -92,6 +104,12 @@ export function attachWindow(_nodeId: number) {
|
|
|
92
104
|
for (let nodeId of targets) {
|
|
93
105
|
getEventHandler(nodeId, "onPointerDown")?.(e)
|
|
94
106
|
}
|
|
107
|
+
// Outside-tap blur. Read focus AFTER per-node handlers so a tap that
|
|
108
|
+
// moves focus to a new node is not immediately blurred again.
|
|
109
|
+
let focused = getFocusedNodeId()
|
|
110
|
+
if (focused != null && !targets.includes(focused)) {
|
|
111
|
+
setFocus(null)
|
|
112
|
+
}
|
|
95
113
|
})
|
|
96
114
|
|
|
97
115
|
unsubUp = Flux.on("pointerUp", ({ targets, ...e }: { targets: number[], [k: string]: any }) => {
|
|
@@ -138,6 +156,19 @@ export function attachWindow(_nodeId: number) {
|
|
|
138
156
|
}
|
|
139
157
|
})
|
|
140
158
|
|
|
159
|
+
unsubTextInput = Flux.on("textInput", (e: any) => {
|
|
160
|
+
let id = getFocusedNodeId()
|
|
161
|
+
if (id != null) {
|
|
162
|
+
getEventHandler(id, "onTextInput")?.(e)
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// When the user dismisses the on-screen keyboard (swipe down, "Done",
|
|
167
|
+
// back button), blur the focused node so the app's UI state catches up.
|
|
168
|
+
unsubKeyboardVisibility = Flux.on("keyboardVisibility", ({ shown }: { shown: boolean }) => {
|
|
169
|
+
if (!shown) setFocus(null)
|
|
170
|
+
})
|
|
171
|
+
|
|
141
172
|
// trigger first draw
|
|
142
173
|
draw()
|
|
143
174
|
})
|
|
@@ -152,5 +183,7 @@ export function attachWindow(_nodeId: number) {
|
|
|
152
183
|
if (unsubWheel) unsubWheel()
|
|
153
184
|
if (unsubKeyDown) unsubKeyDown()
|
|
154
185
|
if (unsubKeyUp) unsubKeyUp()
|
|
186
|
+
if (unsubTextInput) unsubTextInput()
|
|
187
|
+
if (unsubKeyboardVisibility) unsubKeyboardVisibility()
|
|
155
188
|
})
|
|
156
189
|
}
|