@opentui/solid 0.1.23 → 0.1.25
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/dist/index.d.ts +134 -0
- package/index.d.ts +9 -0
- package/index.js +656 -302
- package/jsx-runtime.d.ts +13 -2
- package/package.json +8 -7
- package/scripts/solid-plugin.ts +6 -0
- package/src/elements/extras.d.ts +41 -0
- package/src/elements/hooks.d.ts +1 -0
- package/src/elements/index.d.ts +32 -1
- package/src/elements/slot.d.ts +37 -0
- package/src/reconciler.d.ts +5 -4
- package/src/renderer/index.d.ts +3 -0
- package/src/renderer/universal.d.ts +29 -0
- package/src/types/elements.d.ts +10 -6
- package/src/elements/text-node.d.ts +0 -48
package/index.js
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// index.ts
|
|
3
3
|
import { createCliRenderer } from "@opentui/core";
|
|
4
|
+
import { createTestRenderer } from "@opentui/core/testing";
|
|
4
5
|
|
|
5
6
|
// src/elements/index.ts
|
|
6
7
|
import {
|
|
7
8
|
ASCIIFontRenderable,
|
|
8
9
|
BoxRenderable,
|
|
9
|
-
InputRenderable,
|
|
10
|
+
InputRenderable as InputRenderable2,
|
|
10
11
|
ScrollBoxRenderable,
|
|
11
|
-
SelectRenderable,
|
|
12
|
-
TabSelectRenderable,
|
|
13
|
-
|
|
12
|
+
SelectRenderable as SelectRenderable2,
|
|
13
|
+
TabSelectRenderable as TabSelectRenderable2,
|
|
14
|
+
TextAttributes,
|
|
15
|
+
TextNodeRenderable as TextNodeRenderable3,
|
|
16
|
+
TextRenderable as TextRenderable3
|
|
14
17
|
} from "@opentui/core";
|
|
15
18
|
|
|
16
19
|
// src/elements/hooks.ts
|
|
17
20
|
import {
|
|
18
|
-
getKeyHandler,
|
|
19
21
|
Timeline
|
|
20
22
|
} from "@opentui/core";
|
|
21
23
|
import { createContext, createSignal, onCleanup, onMount, useContext } from "solid-js";
|
|
@@ -46,7 +48,8 @@ var useTerminalDimensions = () => {
|
|
|
46
48
|
return terminalDimensions;
|
|
47
49
|
};
|
|
48
50
|
var useKeyboard = (callback) => {
|
|
49
|
-
const
|
|
51
|
+
const renderer = useRenderer();
|
|
52
|
+
const keyHandler = renderer.keyInput;
|
|
50
53
|
onMount(() => {
|
|
51
54
|
keyHandler.on("keypress", callback);
|
|
52
55
|
});
|
|
@@ -54,6 +57,16 @@ var useKeyboard = (callback) => {
|
|
|
54
57
|
keyHandler.off("keypress", callback);
|
|
55
58
|
});
|
|
56
59
|
};
|
|
60
|
+
var usePaste = (callback) => {
|
|
61
|
+
const renderer = useRenderer();
|
|
62
|
+
const keyHandler = renderer.keyInput;
|
|
63
|
+
onMount(() => {
|
|
64
|
+
keyHandler.on("paste", callback);
|
|
65
|
+
});
|
|
66
|
+
onCleanup(() => {
|
|
67
|
+
keyHandler.off("paste", callback);
|
|
68
|
+
});
|
|
69
|
+
};
|
|
57
70
|
var useKeyHandler = useKeyboard;
|
|
58
71
|
var useSelectionHandler = (callback) => {
|
|
59
72
|
const renderer = useRenderer();
|
|
@@ -93,285 +106,421 @@ var useTimeline = (timeline, initialValue, targetValue, options, startTime = 0)
|
|
|
93
106
|
}, startTime);
|
|
94
107
|
return store;
|
|
95
108
|
};
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
var baseComponents = {
|
|
99
|
-
box: BoxRenderable,
|
|
100
|
-
text: TextRenderable,
|
|
101
|
-
input: InputRenderable,
|
|
102
|
-
select: SelectRenderable,
|
|
103
|
-
ascii_font: ASCIIFontRenderable,
|
|
104
|
-
tab_select: TabSelectRenderable,
|
|
105
|
-
scrollbox: ScrollBoxRenderable
|
|
106
|
-
};
|
|
107
|
-
var componentCatalogue = { ...baseComponents };
|
|
108
|
-
function extend(objects) {
|
|
109
|
-
Object.assign(componentCatalogue, objects);
|
|
110
|
-
}
|
|
111
|
-
function getComponentCatalogue() {
|
|
112
|
-
return componentCatalogue;
|
|
113
|
-
}
|
|
109
|
+
// src/elements/extras.ts
|
|
110
|
+
import { createEffect, createMemo as createMemo2, getOwner, onCleanup as onCleanup2, runWithOwner, splitProps, untrack as untrack2 } from "solid-js";
|
|
114
111
|
|
|
115
112
|
// src/reconciler.ts
|
|
116
113
|
import {
|
|
117
|
-
|
|
114
|
+
BaseRenderable,
|
|
115
|
+
createTextAttributes,
|
|
116
|
+
InputRenderable,
|
|
118
117
|
InputRenderableEvents,
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
isTextNodeRenderable,
|
|
119
|
+
parseColor,
|
|
120
|
+
Renderable,
|
|
121
|
+
RootTextNodeRenderable,
|
|
122
|
+
SelectRenderable,
|
|
121
123
|
SelectRenderableEvents,
|
|
122
|
-
|
|
123
|
-
TabSelectRenderable as TabSelectRenderable2,
|
|
124
|
+
TabSelectRenderable,
|
|
124
125
|
TabSelectRenderableEvents,
|
|
125
|
-
|
|
126
|
+
TextNodeRenderable,
|
|
127
|
+
TextRenderable
|
|
126
128
|
} from "@opentui/core";
|
|
127
129
|
import { useContext as useContext2 } from "solid-js";
|
|
128
|
-
import { createRenderer } from "solid-js/universal";
|
|
129
|
-
|
|
130
|
-
// src/elements/text-node.ts
|
|
131
|
-
import { Renderable, TextRenderable as TextRenderable2 } from "@opentui/core";
|
|
132
130
|
|
|
133
|
-
// src/
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
131
|
+
// src/renderer/universal.js
|
|
132
|
+
import { createRoot, createRenderEffect, createMemo, createComponent, untrack, mergeProps } from "solid-js";
|
|
133
|
+
var memo = (fn) => createMemo(() => fn());
|
|
134
|
+
function createRenderer({
|
|
135
|
+
createElement,
|
|
136
|
+
createTextNode,
|
|
137
|
+
createSlotNode,
|
|
138
|
+
isTextNode,
|
|
139
|
+
replaceText,
|
|
140
|
+
insertNode,
|
|
141
|
+
removeNode,
|
|
142
|
+
setProperty,
|
|
143
|
+
getParentNode,
|
|
144
|
+
getFirstChild,
|
|
145
|
+
getNextSibling
|
|
146
|
+
}) {
|
|
147
|
+
function insert(parent, accessor, marker, initial) {
|
|
148
|
+
if (marker !== undefined && !initial)
|
|
149
|
+
initial = [];
|
|
150
|
+
if (typeof accessor !== "function")
|
|
151
|
+
return insertExpression(parent, accessor, initial, marker);
|
|
152
|
+
createRenderEffect((current) => insertExpression(parent, accessor(), current, marker), initial);
|
|
138
153
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
154
|
+
function insertExpression(parent, value, current, marker, unwrapArray) {
|
|
155
|
+
while (typeof current === "function")
|
|
156
|
+
current = current();
|
|
157
|
+
if (value === current)
|
|
158
|
+
return current;
|
|
159
|
+
const t = typeof value, multi = marker !== undefined;
|
|
160
|
+
if (t === "string" || t === "number") {
|
|
161
|
+
if (t === "number")
|
|
162
|
+
value = value.toString();
|
|
163
|
+
if (multi) {
|
|
164
|
+
let node = current[0];
|
|
165
|
+
if (node && isTextNode(node)) {
|
|
166
|
+
replaceText(node, value);
|
|
167
|
+
} else
|
|
168
|
+
node = createTextNode(value);
|
|
169
|
+
current = cleanChildren(parent, current, marker, node);
|
|
170
|
+
} else {
|
|
171
|
+
if (current !== "" && typeof current === "string") {
|
|
172
|
+
replaceText(getFirstChild(parent), current = value);
|
|
173
|
+
} else {
|
|
174
|
+
cleanChildren(parent, current, marker, createTextNode(value));
|
|
175
|
+
current = value;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} else if (value == null || t === "boolean") {
|
|
179
|
+
current = cleanChildren(parent, current, marker);
|
|
180
|
+
} else if (t === "function") {
|
|
181
|
+
createRenderEffect(() => {
|
|
182
|
+
let v = value();
|
|
183
|
+
while (typeof v === "function")
|
|
184
|
+
v = v();
|
|
185
|
+
current = insertExpression(parent, v, current, marker);
|
|
186
|
+
});
|
|
187
|
+
return () => current;
|
|
188
|
+
} else if (Array.isArray(value)) {
|
|
189
|
+
const array = [];
|
|
190
|
+
if (normalizeIncomingArray(array, value, unwrapArray)) {
|
|
191
|
+
createRenderEffect(() => current = insertExpression(parent, array, current, marker, true));
|
|
192
|
+
return () => current;
|
|
193
|
+
}
|
|
194
|
+
if (array.length === 0) {
|
|
195
|
+
const replacement = cleanChildren(parent, current, marker);
|
|
196
|
+
if (multi)
|
|
197
|
+
return current = replacement;
|
|
198
|
+
} else {
|
|
199
|
+
if (Array.isArray(current)) {
|
|
200
|
+
if (current.length === 0) {
|
|
201
|
+
appendNodes(parent, array, marker);
|
|
202
|
+
} else
|
|
203
|
+
reconcileArrays(parent, current, array);
|
|
204
|
+
} else if (current == null || current === "") {
|
|
205
|
+
appendNodes(parent, array);
|
|
206
|
+
} else {
|
|
207
|
+
reconcileArrays(parent, multi && current || [getFirstChild(parent)], array);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
current = array;
|
|
211
|
+
} else {
|
|
212
|
+
if (Array.isArray(current)) {
|
|
213
|
+
if (multi)
|
|
214
|
+
return current = cleanChildren(parent, current, marker, value);
|
|
215
|
+
cleanChildren(parent, current, null, value);
|
|
216
|
+
} else if (current == null || current === "" || !getFirstChild(parent)) {
|
|
217
|
+
insertNode(parent, value);
|
|
218
|
+
} else
|
|
219
|
+
replaceNode(parent, value, getFirstChild(parent));
|
|
220
|
+
current = value;
|
|
221
|
+
}
|
|
222
|
+
return current;
|
|
148
223
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (!textParent) {
|
|
171
|
-
log("No parent found for text node:", this.id);
|
|
172
|
-
return;
|
|
224
|
+
function normalizeIncomingArray(normalized, array, unwrap) {
|
|
225
|
+
let dynamic = false;
|
|
226
|
+
for (let i = 0, len = array.length;i < len; i++) {
|
|
227
|
+
let item = array[i], t;
|
|
228
|
+
if (item == null || item === true || item === false)
|
|
229
|
+
;
|
|
230
|
+
else if (Array.isArray(item)) {
|
|
231
|
+
dynamic = normalizeIncomingArray(normalized, item) || dynamic;
|
|
232
|
+
} else if ((t = typeof item) === "string" || t === "number") {
|
|
233
|
+
normalized.push(createTextNode(item));
|
|
234
|
+
} else if (t === "function") {
|
|
235
|
+
if (unwrap) {
|
|
236
|
+
while (typeof item === "function")
|
|
237
|
+
item = item();
|
|
238
|
+
dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item]) || dynamic;
|
|
239
|
+
} else {
|
|
240
|
+
normalized.push(item);
|
|
241
|
+
dynamic = true;
|
|
242
|
+
}
|
|
243
|
+
} else
|
|
244
|
+
normalized.push(item);
|
|
173
245
|
}
|
|
174
|
-
|
|
175
|
-
this.chunk = newChunk;
|
|
176
|
-
ChunkToTextNodeMap.set(newChunk, this);
|
|
177
|
-
}
|
|
178
|
-
static getTextNodeFromChunk(chunk) {
|
|
179
|
-
return ChunkToTextNodeMap.get(chunk);
|
|
246
|
+
return dynamic;
|
|
180
247
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
textParent = this.getOrCreateTextGhostNode(parent, anchor);
|
|
189
|
-
} else {
|
|
190
|
-
textParent = parent;
|
|
191
|
-
}
|
|
192
|
-
this.textParent = textParent;
|
|
193
|
-
let styledText = textParent.content;
|
|
194
|
-
if (anchor) {
|
|
195
|
-
if (anchor instanceof Renderable) {
|
|
196
|
-
console.warn("text node can't be anchored to Renderable");
|
|
197
|
-
return;
|
|
198
|
-
} else if (isTextChunk(anchor)) {
|
|
199
|
-
anchor = ChunkToTextNodeMap.get(anchor);
|
|
248
|
+
function reconcileArrays(parentNode, a, b) {
|
|
249
|
+
let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = getNextSibling(a[aEnd - 1]), map = null;
|
|
250
|
+
while (aStart < aEnd || bStart < bEnd) {
|
|
251
|
+
if (a[aStart] === b[bStart]) {
|
|
252
|
+
aStart++;
|
|
253
|
+
bStart++;
|
|
254
|
+
continue;
|
|
200
255
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
styledText = styledText.insert(this.chunk);
|
|
205
|
-
} else {
|
|
206
|
-
styledText = styledText.insert(this.chunk, anchorIndex);
|
|
256
|
+
while (a[aEnd - 1] === b[bEnd - 1]) {
|
|
257
|
+
aEnd--;
|
|
258
|
+
bEnd--;
|
|
207
259
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
260
|
+
if (aEnd === aStart) {
|
|
261
|
+
const node = bEnd < bLength ? bStart ? getNextSibling(b[bStart - 1]) : b[bEnd - bStart] : after;
|
|
262
|
+
while (bStart < bEnd)
|
|
263
|
+
insertNode(parentNode, b[bStart++], node);
|
|
264
|
+
} else if (bEnd === bStart) {
|
|
265
|
+
while (aStart < aEnd) {
|
|
266
|
+
if (!map || !map.has(a[aStart]))
|
|
267
|
+
removeNode(parentNode, a[aStart]);
|
|
268
|
+
aStart++;
|
|
269
|
+
}
|
|
270
|
+
} else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
|
|
271
|
+
const node = getNextSibling(a[--aEnd]);
|
|
272
|
+
insertNode(parentNode, b[bStart++], getNextSibling(a[aStart++]));
|
|
273
|
+
insertNode(parentNode, b[--bEnd], node);
|
|
274
|
+
a[aEnd] = b[bEnd];
|
|
212
275
|
} else {
|
|
213
|
-
|
|
276
|
+
if (!map) {
|
|
277
|
+
map = new Map;
|
|
278
|
+
let i = bStart;
|
|
279
|
+
while (i < bEnd)
|
|
280
|
+
map.set(b[i], i++);
|
|
281
|
+
}
|
|
282
|
+
const index = map.get(a[aStart]);
|
|
283
|
+
if (index != null) {
|
|
284
|
+
if (bStart < index && index < bEnd) {
|
|
285
|
+
let i = aStart, sequence = 1, t;
|
|
286
|
+
while (++i < aEnd && i < bEnd) {
|
|
287
|
+
if ((t = map.get(a[i])) == null || t !== index + sequence)
|
|
288
|
+
break;
|
|
289
|
+
sequence++;
|
|
290
|
+
}
|
|
291
|
+
if (sequence > index - bStart) {
|
|
292
|
+
const node = a[aStart];
|
|
293
|
+
while (bStart < index)
|
|
294
|
+
insertNode(parentNode, b[bStart++], node);
|
|
295
|
+
} else
|
|
296
|
+
replaceNode(parentNode, b[bStart++], a[aStart++]);
|
|
297
|
+
} else
|
|
298
|
+
aStart++;
|
|
299
|
+
} else
|
|
300
|
+
removeNode(parentNode, a[aStart++]);
|
|
214
301
|
}
|
|
215
302
|
}
|
|
216
|
-
textParent.content = styledText;
|
|
217
|
-
textParent.visible = textParent.textLength !== 0;
|
|
218
|
-
this.parent = parent;
|
|
219
303
|
}
|
|
220
|
-
|
|
221
|
-
if (
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (!this.textParent.parent) {
|
|
242
|
-
this.textParent.destroyRecursively();
|
|
243
|
-
}
|
|
244
|
-
});
|
|
304
|
+
function cleanChildren(parent, current, marker, replacement) {
|
|
305
|
+
if (marker === undefined) {
|
|
306
|
+
let removed;
|
|
307
|
+
while (removed = getFirstChild(parent))
|
|
308
|
+
removeNode(parent, removed);
|
|
309
|
+
replacement && insertNode(parent, replacement);
|
|
310
|
+
return replacement;
|
|
311
|
+
}
|
|
312
|
+
const node = replacement || createSlotNode();
|
|
313
|
+
if (current.length) {
|
|
314
|
+
let inserted = false;
|
|
315
|
+
for (let i = current.length - 1;i >= 0; i--) {
|
|
316
|
+
const el = current[i];
|
|
317
|
+
if (node !== el) {
|
|
318
|
+
const isParent = getParentNode(el) === parent;
|
|
319
|
+
if (!inserted && !i)
|
|
320
|
+
isParent ? replaceNode(parent, node, el) : insertNode(parent, node, marker);
|
|
321
|
+
else
|
|
322
|
+
isParent && removeNode(parent, el);
|
|
323
|
+
} else
|
|
324
|
+
inserted = true;
|
|
245
325
|
}
|
|
246
|
-
}
|
|
326
|
+
} else
|
|
327
|
+
insertNode(parent, node, marker);
|
|
328
|
+
return [node];
|
|
247
329
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
330
|
+
function appendNodes(parent, array, marker) {
|
|
331
|
+
for (let i = 0, len = array.length;i < len; i++)
|
|
332
|
+
insertNode(parent, array[i], marker);
|
|
333
|
+
}
|
|
334
|
+
function replaceNode(parent, newNode, oldNode) {
|
|
335
|
+
insertNode(parent, newNode, oldNode);
|
|
336
|
+
removeNode(parent, oldNode);
|
|
337
|
+
}
|
|
338
|
+
function spreadExpression(node, props, prevProps = {}, skipChildren) {
|
|
339
|
+
props || (props = {});
|
|
340
|
+
if (!skipChildren) {
|
|
341
|
+
createRenderEffect(() => prevProps.children = insertExpression(node, props.children, prevProps.children));
|
|
342
|
+
}
|
|
343
|
+
createRenderEffect(() => props.ref && props.ref(node));
|
|
344
|
+
createRenderEffect(() => {
|
|
345
|
+
for (const prop in props) {
|
|
346
|
+
if (prop === "children" || prop === "ref")
|
|
347
|
+
continue;
|
|
348
|
+
const value = props[prop];
|
|
349
|
+
if (value === prevProps[prop])
|
|
350
|
+
continue;
|
|
351
|
+
setProperty(node, prop, value, prevProps[prop]);
|
|
352
|
+
prevProps[prop] = value;
|
|
258
353
|
}
|
|
259
|
-
}
|
|
260
|
-
const lastChild = children.at(-1);
|
|
261
|
-
if (lastChild instanceof GhostTextRenderable) {
|
|
262
|
-
return lastChild;
|
|
263
|
-
}
|
|
264
|
-
const ghostNode = new GhostTextRenderable(parent.ctx, {
|
|
265
|
-
id: getNextId(GHOST_NODE_TAG)
|
|
266
354
|
});
|
|
267
|
-
|
|
268
|
-
return ghostNode;
|
|
355
|
+
return prevProps;
|
|
269
356
|
}
|
|
357
|
+
return {
|
|
358
|
+
render(code, element) {
|
|
359
|
+
let disposer;
|
|
360
|
+
createRoot((dispose) => {
|
|
361
|
+
disposer = dispose;
|
|
362
|
+
insert(element, code());
|
|
363
|
+
});
|
|
364
|
+
return disposer;
|
|
365
|
+
},
|
|
366
|
+
insert,
|
|
367
|
+
spread(node, accessor, skipChildren) {
|
|
368
|
+
if (typeof accessor === "function") {
|
|
369
|
+
createRenderEffect((current) => spreadExpression(node, accessor(), current, skipChildren));
|
|
370
|
+
} else
|
|
371
|
+
spreadExpression(node, accessor, undefined, skipChildren);
|
|
372
|
+
},
|
|
373
|
+
createElement,
|
|
374
|
+
createTextNode,
|
|
375
|
+
insertNode,
|
|
376
|
+
setProp(node, name, value, prev) {
|
|
377
|
+
setProperty(node, name, value, prev);
|
|
378
|
+
return value;
|
|
379
|
+
},
|
|
380
|
+
mergeProps,
|
|
381
|
+
effect: createRenderEffect,
|
|
382
|
+
memo,
|
|
383
|
+
createComponent,
|
|
384
|
+
use(fn, element, arg) {
|
|
385
|
+
return untrack(() => fn(element, arg));
|
|
386
|
+
}
|
|
387
|
+
};
|
|
270
388
|
}
|
|
271
389
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
390
|
+
// src/renderer/index.ts
|
|
391
|
+
import { mergeProps as mergeProps2 } from "solid-js";
|
|
392
|
+
function createRenderer2(options) {
|
|
393
|
+
const renderer = createRenderer(options);
|
|
394
|
+
renderer.mergeProps = mergeProps2;
|
|
395
|
+
return renderer;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// src/utils/id-counter.ts
|
|
399
|
+
var idCounter = new Map;
|
|
400
|
+
function getNextId(elementType) {
|
|
401
|
+
if (!idCounter.has(elementType)) {
|
|
402
|
+
idCounter.set(elementType, 0);
|
|
278
403
|
}
|
|
404
|
+
const value = idCounter.get(elementType) + 1;
|
|
405
|
+
idCounter.set(elementType, value);
|
|
406
|
+
return `${elementType}-${value}`;
|
|
279
407
|
}
|
|
280
408
|
|
|
409
|
+
// src/utils/log.ts
|
|
410
|
+
var log = (...args) => {
|
|
411
|
+
if (process.env.DEBUG) {
|
|
412
|
+
console.log("[Reconciler]", ...args);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
|
|
281
416
|
// src/reconciler.ts
|
|
417
|
+
class TextNode extends TextNodeRenderable {
|
|
418
|
+
static fromString(text, options = {}) {
|
|
419
|
+
const node = new TextNode(options);
|
|
420
|
+
node.add(text);
|
|
421
|
+
return node;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
282
424
|
var logId = (node) => {
|
|
283
425
|
if (!node)
|
|
284
426
|
return;
|
|
285
|
-
if (isTextChunk(node)) {
|
|
286
|
-
return node.text;
|
|
287
|
-
}
|
|
288
427
|
return node.id;
|
|
289
428
|
};
|
|
429
|
+
var getNodeChildren = (node) => {
|
|
430
|
+
let children;
|
|
431
|
+
if (node instanceof TextRenderable) {
|
|
432
|
+
children = node.getTextChildren();
|
|
433
|
+
} else {
|
|
434
|
+
children = node.getChildren();
|
|
435
|
+
}
|
|
436
|
+
return children;
|
|
437
|
+
};
|
|
290
438
|
function _insertNode(parent, node, anchor) {
|
|
291
439
|
log("Inserting node:", logId(node), "into parent:", logId(parent), "with anchor:", logId(anchor), node instanceof TextNode);
|
|
292
|
-
if (node instanceof
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
_insertNode(parent, _createTextNode(chunk), anchor);
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
440
|
+
if (node instanceof SlotRenderable) {
|
|
441
|
+
node.parent = parent;
|
|
442
|
+
node = node.getSlotChild(parent);
|
|
298
443
|
}
|
|
299
|
-
if (
|
|
300
|
-
|
|
301
|
-
return;
|
|
444
|
+
if (anchor && anchor instanceof SlotRenderable) {
|
|
445
|
+
anchor = anchor.getSlotChild(parent);
|
|
302
446
|
}
|
|
303
|
-
if (node
|
|
304
|
-
|
|
447
|
+
if (isTextNodeRenderable(node)) {
|
|
448
|
+
if (!(parent instanceof TextRenderable) && !isTextNodeRenderable(parent)) {
|
|
449
|
+
throw new Error(`Orphan text error: "${node.toChunks().map((c) => c.text).join("")}" must have a <text> as a parent: ${parent.id} above ${node.id}`);
|
|
450
|
+
}
|
|
305
451
|
}
|
|
306
|
-
if (!(parent instanceof
|
|
307
|
-
|
|
452
|
+
if (!(parent instanceof BaseRenderable)) {
|
|
453
|
+
console.error("[INSERT]", "Tried to mount a non base renderable");
|
|
454
|
+
throw new Error("Tried to mount a non base renderable");
|
|
308
455
|
}
|
|
309
|
-
if (anchor) {
|
|
310
|
-
if (isTextChunk(anchor)) {
|
|
311
|
-
console.warn("Cannot add non text node with text chunk anchor");
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
const anchorIndex = parent.getChildren().findIndex((el) => {
|
|
315
|
-
if (anchor instanceof TextNode) {
|
|
316
|
-
return el.id === anchor.textParent?.id;
|
|
317
|
-
}
|
|
318
|
-
return el.id === anchor.id;
|
|
319
|
-
});
|
|
320
|
-
parent.add(node, anchorIndex);
|
|
321
|
-
} else {
|
|
456
|
+
if (!anchor) {
|
|
322
457
|
parent.add(node);
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const children = getNodeChildren(parent);
|
|
461
|
+
const anchorIndex = children.findIndex((el) => el.id === anchor.id);
|
|
462
|
+
if (anchorIndex === -1) {
|
|
463
|
+
log("[INSERT]", "Could not find anchor", logId(parent), logId(anchor), "[children]", ...children.map((c) => c.id));
|
|
323
464
|
}
|
|
465
|
+
parent.add(node, anchorIndex);
|
|
324
466
|
}
|
|
325
467
|
function _removeNode(parent, node) {
|
|
326
468
|
log("Removing node:", logId(node), "from parent:", logId(parent));
|
|
327
|
-
if (
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
_removeNode(parent, textNode);
|
|
331
|
-
}
|
|
332
|
-
} else if (node instanceof StyledText) {
|
|
333
|
-
for (const chunk of node.chunks) {
|
|
334
|
-
const textNode = TextNode.getTextNodeFromChunk(chunk);
|
|
335
|
-
if (!textNode)
|
|
336
|
-
continue;
|
|
337
|
-
_removeNode(parent, textNode);
|
|
338
|
-
}
|
|
469
|
+
if (node instanceof SlotRenderable) {
|
|
470
|
+
node.parent = null;
|
|
471
|
+
node = node.getSlotChild(parent);
|
|
339
472
|
}
|
|
340
|
-
if (
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
473
|
+
if (isTextNodeRenderable(parent)) {
|
|
474
|
+
if (typeof node !== "string" && !isTextNodeRenderable(node)) {
|
|
475
|
+
console.warn("Node not a valid child of TextNode");
|
|
476
|
+
} else {
|
|
477
|
+
parent.remove(node);
|
|
478
|
+
}
|
|
479
|
+
} else {
|
|
344
480
|
parent.remove(node.id);
|
|
345
|
-
process.nextTick(() => {
|
|
346
|
-
if (!node.parent) {
|
|
347
|
-
node.destroyRecursively();
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
481
|
}
|
|
482
|
+
process.nextTick(() => {
|
|
483
|
+
if (node instanceof BaseRenderable && !node.parent) {
|
|
484
|
+
node.destroyRecursively();
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
});
|
|
351
488
|
}
|
|
352
489
|
function _createTextNode(value) {
|
|
353
490
|
log("Creating text node:", value);
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
|
|
491
|
+
const id = getNextId("text-node");
|
|
492
|
+
if (typeof value === "number") {
|
|
493
|
+
value = value.toString();
|
|
494
|
+
}
|
|
495
|
+
return TextNode.fromString(value, { id });
|
|
496
|
+
}
|
|
497
|
+
function createSlotNode() {
|
|
498
|
+
const id = getNextId("slot-node");
|
|
499
|
+
log("Creating slot node", id);
|
|
500
|
+
return new SlotRenderable(id);
|
|
501
|
+
}
|
|
502
|
+
function _getParentNode(childNode) {
|
|
503
|
+
log("Getting parent of node:", logId(childNode));
|
|
504
|
+
let parent = childNode.parent ?? undefined;
|
|
505
|
+
if (parent instanceof RootTextNodeRenderable) {
|
|
506
|
+
parent = parent.textParent ?? undefined;
|
|
507
|
+
}
|
|
508
|
+
return parent;
|
|
360
509
|
}
|
|
361
510
|
var {
|
|
362
511
|
render: _render,
|
|
363
512
|
effect,
|
|
364
|
-
memo,
|
|
365
|
-
createComponent,
|
|
513
|
+
memo: memo2,
|
|
514
|
+
createComponent: createComponent2,
|
|
366
515
|
createElement,
|
|
367
516
|
createTextNode,
|
|
368
517
|
insertNode,
|
|
369
518
|
insert,
|
|
370
519
|
spread,
|
|
371
520
|
setProp,
|
|
372
|
-
mergeProps,
|
|
521
|
+
mergeProps: mergeProps3,
|
|
373
522
|
use
|
|
374
|
-
} =
|
|
523
|
+
} = createRenderer2({
|
|
375
524
|
createElement(tagName) {
|
|
376
525
|
log("Creating element:", tagName);
|
|
377
526
|
const id = getNextId(tagName);
|
|
@@ -388,25 +537,14 @@ var {
|
|
|
388
537
|
return element;
|
|
389
538
|
},
|
|
390
539
|
createTextNode: _createTextNode,
|
|
540
|
+
createSlotNode,
|
|
391
541
|
replaceText(textNode, value) {
|
|
392
542
|
log("Replacing text:", value, "in node:", logId(textNode));
|
|
393
|
-
if (textNode instanceof
|
|
394
|
-
return;
|
|
395
|
-
if (isTextChunk(textNode)) {
|
|
396
|
-
console.warn("Cannot replace text on text chunk", logId(textNode));
|
|
543
|
+
if (!(textNode instanceof TextNode))
|
|
397
544
|
return;
|
|
398
|
-
|
|
399
|
-
const newChunk = {
|
|
400
|
-
__isChunk: true,
|
|
401
|
-
text: value
|
|
402
|
-
};
|
|
403
|
-
textNode.replaceText(newChunk);
|
|
545
|
+
textNode.replace(value, 0);
|
|
404
546
|
},
|
|
405
547
|
setProperty(node, name, value, prev) {
|
|
406
|
-
if (node instanceof TextNode || isTextChunk(node)) {
|
|
407
|
-
console.warn("Cannot set property on text node:", logId(node));
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
548
|
if (name.startsWith("on:")) {
|
|
411
549
|
const eventName = name.slice(3);
|
|
412
550
|
if (value) {
|
|
@@ -417,8 +555,23 @@ var {
|
|
|
417
555
|
}
|
|
418
556
|
return;
|
|
419
557
|
}
|
|
558
|
+
if (isTextNodeRenderable(node)) {
|
|
559
|
+
if (name !== "style") {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
node.attributes |= createTextAttributes(value);
|
|
563
|
+
node.fg = value.fg ? parseColor(value.fg) : node.fg;
|
|
564
|
+
node.bg = value.bg ? parseColor(value.bg) : node.bg;
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
420
567
|
switch (name) {
|
|
568
|
+
case "id":
|
|
569
|
+
log("Id mapped", node.id, "=", value);
|
|
570
|
+
node[name] = value;
|
|
571
|
+
break;
|
|
421
572
|
case "focused":
|
|
573
|
+
if (!(node instanceof Renderable))
|
|
574
|
+
return;
|
|
422
575
|
if (value) {
|
|
423
576
|
node.focus();
|
|
424
577
|
} else {
|
|
@@ -427,11 +580,11 @@ var {
|
|
|
427
580
|
break;
|
|
428
581
|
case "onChange":
|
|
429
582
|
let event = undefined;
|
|
430
|
-
if (node instanceof
|
|
583
|
+
if (node instanceof SelectRenderable) {
|
|
431
584
|
event = SelectRenderableEvents.SELECTION_CHANGED;
|
|
432
|
-
} else if (node instanceof
|
|
585
|
+
} else if (node instanceof TabSelectRenderable) {
|
|
433
586
|
event = TabSelectRenderableEvents.SELECTION_CHANGED;
|
|
434
|
-
} else if (node instanceof
|
|
587
|
+
} else if (node instanceof InputRenderable) {
|
|
435
588
|
event = InputRenderableEvents.CHANGE;
|
|
436
589
|
}
|
|
437
590
|
if (!event)
|
|
@@ -444,7 +597,7 @@ var {
|
|
|
444
597
|
}
|
|
445
598
|
break;
|
|
446
599
|
case "onInput":
|
|
447
|
-
if (node instanceof
|
|
600
|
+
if (node instanceof InputRenderable) {
|
|
448
601
|
if (value) {
|
|
449
602
|
node.on(InputRenderableEvents.INPUT, value);
|
|
450
603
|
}
|
|
@@ -454,7 +607,7 @@ var {
|
|
|
454
607
|
}
|
|
455
608
|
break;
|
|
456
609
|
case "onSubmit":
|
|
457
|
-
if (node instanceof
|
|
610
|
+
if (node instanceof InputRenderable) {
|
|
458
611
|
if (value) {
|
|
459
612
|
node.on(InputRenderableEvents.ENTER, value);
|
|
460
613
|
}
|
|
@@ -464,14 +617,14 @@ var {
|
|
|
464
617
|
}
|
|
465
618
|
break;
|
|
466
619
|
case "onSelect":
|
|
467
|
-
if (node instanceof
|
|
620
|
+
if (node instanceof SelectRenderable) {
|
|
468
621
|
if (value) {
|
|
469
622
|
node.on(SelectRenderableEvents.ITEM_SELECTED, value);
|
|
470
623
|
}
|
|
471
624
|
if (prev) {
|
|
472
625
|
node.off(SelectRenderableEvents.ITEM_SELECTED, prev);
|
|
473
626
|
}
|
|
474
|
-
} else if (node instanceof
|
|
627
|
+
} else if (node instanceof TabSelectRenderable) {
|
|
475
628
|
if (value) {
|
|
476
629
|
node.on(TabSelectRenderableEvents.ITEM_SELECTED, value);
|
|
477
630
|
}
|
|
@@ -501,37 +654,10 @@ var {
|
|
|
501
654
|
},
|
|
502
655
|
insertNode: _insertNode,
|
|
503
656
|
removeNode: _removeNode,
|
|
504
|
-
getParentNode
|
|
505
|
-
log("Getting parent of node:", logId(childNode));
|
|
506
|
-
let node = childNode;
|
|
507
|
-
if (isTextChunk(childNode)) {
|
|
508
|
-
const parentTextNode = TextNode.getTextNodeFromChunk(childNode);
|
|
509
|
-
if (!parentTextNode)
|
|
510
|
-
return;
|
|
511
|
-
node = parentTextNode;
|
|
512
|
-
}
|
|
513
|
-
const parent = node.parent;
|
|
514
|
-
if (!parent) {
|
|
515
|
-
log("No parent found for node:", logId(node));
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
log("Parent found:", logId(parent), "for node:", logId(node));
|
|
519
|
-
return parent;
|
|
520
|
-
},
|
|
657
|
+
getParentNode: _getParentNode,
|
|
521
658
|
getFirstChild(node) {
|
|
522
659
|
log("Getting first child of node:", logId(node));
|
|
523
|
-
|
|
524
|
-
const chunk = node.content.chunks[0];
|
|
525
|
-
if (chunk) {
|
|
526
|
-
return TextNode.getTextNodeFromChunk(chunk);
|
|
527
|
-
} else {
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
if (node instanceof TextNode || isTextChunk(node)) {
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
const firstChild = node.getChildren()[0];
|
|
660
|
+
const firstChild = getNodeChildren(node)[0];
|
|
535
661
|
if (!firstChild) {
|
|
536
662
|
log("No first child found for node:", logId(node));
|
|
537
663
|
return;
|
|
@@ -541,34 +667,12 @@ var {
|
|
|
541
667
|
},
|
|
542
668
|
getNextSibling(node) {
|
|
543
669
|
log("Getting next sibling of node:", logId(node));
|
|
544
|
-
|
|
545
|
-
console.warn("Cannot get next sibling of text chunk");
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
const parent = node.parent;
|
|
670
|
+
const parent = _getParentNode(node);
|
|
549
671
|
if (!parent) {
|
|
550
672
|
log("No parent found for node:", logId(node));
|
|
551
673
|
return;
|
|
552
674
|
}
|
|
553
|
-
|
|
554
|
-
if (parent instanceof TextRenderable3) {
|
|
555
|
-
const siblings2 = parent.content.chunks;
|
|
556
|
-
const index2 = siblings2.indexOf(node.chunk);
|
|
557
|
-
if (index2 === -1 || index2 === siblings2.length - 1) {
|
|
558
|
-
log("No next sibling found for node:", logId(node));
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
const nextSibling2 = siblings2[index2 + 1];
|
|
562
|
-
if (!nextSibling2) {
|
|
563
|
-
log("Next sibling is null for node:", logId(node));
|
|
564
|
-
return;
|
|
565
|
-
}
|
|
566
|
-
return TextNode.getTextNodeFromChunk(nextSibling2);
|
|
567
|
-
}
|
|
568
|
-
console.warn("Text parent is not a text node:", logId(node));
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
const siblings = parent.getChildren();
|
|
675
|
+
const siblings = getNodeChildren(parent);
|
|
572
676
|
const index = siblings.indexOf(node);
|
|
573
677
|
if (index === -1 || index === siblings.length - 1) {
|
|
574
678
|
log("No next sibling found for node:", logId(node));
|
|
@@ -584,43 +688,293 @@ var {
|
|
|
584
688
|
}
|
|
585
689
|
});
|
|
586
690
|
|
|
691
|
+
// src/elements/extras.ts
|
|
692
|
+
function Portal(props) {
|
|
693
|
+
const renderer = useRenderer();
|
|
694
|
+
const marker = createSlotNode(), mount = () => props.mount || renderer.root, owner = getOwner();
|
|
695
|
+
let content;
|
|
696
|
+
createEffect(() => {
|
|
697
|
+
content || (content = runWithOwner(owner, () => createMemo2(() => props.children)));
|
|
698
|
+
const el = mount();
|
|
699
|
+
const container = createElement("box"), renderRoot = container;
|
|
700
|
+
Object.defineProperty(container, "_$host", {
|
|
701
|
+
get() {
|
|
702
|
+
return marker.parent;
|
|
703
|
+
},
|
|
704
|
+
configurable: true
|
|
705
|
+
});
|
|
706
|
+
insert(renderRoot, content);
|
|
707
|
+
el.add(container);
|
|
708
|
+
props.ref && props.ref(container);
|
|
709
|
+
onCleanup2(() => el.remove(container.id));
|
|
710
|
+
}, undefined, { render: true });
|
|
711
|
+
return marker;
|
|
712
|
+
}
|
|
713
|
+
function createDynamic(component, props) {
|
|
714
|
+
const cached = createMemo2(component);
|
|
715
|
+
return createMemo2(() => {
|
|
716
|
+
const component2 = cached();
|
|
717
|
+
switch (typeof component2) {
|
|
718
|
+
case "function":
|
|
719
|
+
return untrack2(() => component2(props));
|
|
720
|
+
case "string":
|
|
721
|
+
const el = createElement(component2);
|
|
722
|
+
spread(el, props);
|
|
723
|
+
return el;
|
|
724
|
+
default:
|
|
725
|
+
break;
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
function Dynamic(props) {
|
|
730
|
+
const [, others] = splitProps(props, ["component"]);
|
|
731
|
+
return createDynamic(() => props.component, others);
|
|
732
|
+
}
|
|
733
|
+
// src/elements/slot.ts
|
|
734
|
+
import { BaseRenderable as BaseRenderable2, isTextNodeRenderable as isTextNodeRenderable2, TextNodeRenderable as TextNodeRenderable2, TextRenderable as TextRenderable2, Yoga } from "@opentui/core";
|
|
735
|
+
|
|
736
|
+
class SlotBaseRenderable extends BaseRenderable2 {
|
|
737
|
+
constructor(id) {
|
|
738
|
+
super({
|
|
739
|
+
id
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
add(obj, index) {
|
|
743
|
+
throw new Error("Can't add children on an Slot renderable");
|
|
744
|
+
}
|
|
745
|
+
getChildren() {
|
|
746
|
+
return [];
|
|
747
|
+
}
|
|
748
|
+
remove(id) {}
|
|
749
|
+
insertBefore(obj, anchor) {
|
|
750
|
+
throw new Error("Can't add children on an Slot renderable");
|
|
751
|
+
}
|
|
752
|
+
getRenderable(id) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
getChildrenCount() {
|
|
756
|
+
return 0;
|
|
757
|
+
}
|
|
758
|
+
requestRender() {}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
class TextSlotRenderable extends TextNodeRenderable2 {
|
|
762
|
+
slotParent;
|
|
763
|
+
destroyed = false;
|
|
764
|
+
constructor(id, parent) {
|
|
765
|
+
super({ id });
|
|
766
|
+
this._visible = false;
|
|
767
|
+
this.slotParent = parent;
|
|
768
|
+
}
|
|
769
|
+
destroy() {
|
|
770
|
+
if (this.destroyed) {
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
this.destroyed = true;
|
|
774
|
+
this.slotParent?.destroy();
|
|
775
|
+
super.destroy();
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
class LayoutSlotRenderable extends SlotBaseRenderable {
|
|
780
|
+
yogaNode;
|
|
781
|
+
slotParent;
|
|
782
|
+
destroyed = false;
|
|
783
|
+
constructor(id, parent) {
|
|
784
|
+
super(id);
|
|
785
|
+
this._visible = false;
|
|
786
|
+
this.slotParent = parent;
|
|
787
|
+
this.yogaNode = Yoga.default.Node.create();
|
|
788
|
+
this.yogaNode.setDisplay(Yoga.Display.None);
|
|
789
|
+
}
|
|
790
|
+
getLayoutNode() {
|
|
791
|
+
return this.yogaNode;
|
|
792
|
+
}
|
|
793
|
+
updateFromLayout() {}
|
|
794
|
+
updateLayout() {}
|
|
795
|
+
onRemove() {}
|
|
796
|
+
destroy() {
|
|
797
|
+
if (this.destroyed) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
this.destroyed = true;
|
|
801
|
+
super.destroy();
|
|
802
|
+
this.slotParent?.destroy();
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
class SlotRenderable extends SlotBaseRenderable {
|
|
807
|
+
layoutNode;
|
|
808
|
+
textNode;
|
|
809
|
+
destroyed = false;
|
|
810
|
+
constructor(id) {
|
|
811
|
+
super(id);
|
|
812
|
+
this._visible = false;
|
|
813
|
+
}
|
|
814
|
+
getSlotChild(parent) {
|
|
815
|
+
if (isTextNodeRenderable2(parent) || parent instanceof TextRenderable2) {
|
|
816
|
+
if (!this.textNode) {
|
|
817
|
+
this.textNode = new TextSlotRenderable(`slot-text-${this.id}`, this);
|
|
818
|
+
}
|
|
819
|
+
return this.textNode;
|
|
820
|
+
}
|
|
821
|
+
if (!this.layoutNode) {
|
|
822
|
+
this.layoutNode = new LayoutSlotRenderable(`slot-layout-${this.id}`, this);
|
|
823
|
+
}
|
|
824
|
+
return this.layoutNode;
|
|
825
|
+
}
|
|
826
|
+
destroy() {
|
|
827
|
+
if (this.destroyed) {
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
this.destroyed = true;
|
|
831
|
+
if (this.layoutNode) {
|
|
832
|
+
this.layoutNode.destroy();
|
|
833
|
+
}
|
|
834
|
+
if (this.textNode) {
|
|
835
|
+
this.textNode.destroy();
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// src/elements/index.ts
|
|
841
|
+
class SpanRenderable extends TextNodeRenderable3 {
|
|
842
|
+
_ctx;
|
|
843
|
+
constructor(_ctx, options) {
|
|
844
|
+
super(options);
|
|
845
|
+
this._ctx = _ctx;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
var textNodeKeys = ["span", "b", "strong", "i", "em", "u"];
|
|
849
|
+
|
|
850
|
+
class TextModifierRenderable extends SpanRenderable {
|
|
851
|
+
constructor(options, modifier) {
|
|
852
|
+
super(null, options);
|
|
853
|
+
if (modifier === "b" || modifier === "strong") {
|
|
854
|
+
this.attributes = (this.attributes || 0) | TextAttributes.BOLD;
|
|
855
|
+
} else if (modifier === "i" || modifier === "em") {
|
|
856
|
+
this.attributes = (this.attributes || 0) | TextAttributes.ITALIC;
|
|
857
|
+
} else if (modifier === "u") {
|
|
858
|
+
this.attributes = (this.attributes || 0) | TextAttributes.UNDERLINE;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
class BoldSpanRenderable extends TextModifierRenderable {
|
|
864
|
+
constructor(options) {
|
|
865
|
+
super(options, "b");
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
class ItalicSpanRenderable extends TextModifierRenderable {
|
|
870
|
+
constructor(options) {
|
|
871
|
+
super(options, "i");
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
class UnderlineSpanRenderable extends TextModifierRenderable {
|
|
876
|
+
constructor(options) {
|
|
877
|
+
super(options, "u");
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
class LineBreakRenderable extends SpanRenderable {
|
|
882
|
+
constructor(_ctx, options) {
|
|
883
|
+
super(null, options);
|
|
884
|
+
this.add();
|
|
885
|
+
}
|
|
886
|
+
add() {
|
|
887
|
+
return super.add(`
|
|
888
|
+
`);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
var baseComponents = {
|
|
892
|
+
box: BoxRenderable,
|
|
893
|
+
text: TextRenderable3,
|
|
894
|
+
input: InputRenderable2,
|
|
895
|
+
select: SelectRenderable2,
|
|
896
|
+
ascii_font: ASCIIFontRenderable,
|
|
897
|
+
tab_select: TabSelectRenderable2,
|
|
898
|
+
scrollbox: ScrollBoxRenderable,
|
|
899
|
+
span: SpanRenderable,
|
|
900
|
+
strong: BoldSpanRenderable,
|
|
901
|
+
b: BoldSpanRenderable,
|
|
902
|
+
em: ItalicSpanRenderable,
|
|
903
|
+
i: ItalicSpanRenderable,
|
|
904
|
+
u: UnderlineSpanRenderable,
|
|
905
|
+
br: LineBreakRenderable
|
|
906
|
+
};
|
|
907
|
+
var componentCatalogue = { ...baseComponents };
|
|
908
|
+
function extend(objects) {
|
|
909
|
+
Object.assign(componentCatalogue, objects);
|
|
910
|
+
}
|
|
911
|
+
function getComponentCatalogue() {
|
|
912
|
+
return componentCatalogue;
|
|
913
|
+
}
|
|
914
|
+
|
|
587
915
|
// index.ts
|
|
588
916
|
var render = async (node, renderConfig = {}) => {
|
|
589
917
|
const renderer = await createCliRenderer(renderConfig);
|
|
590
|
-
_render(() =>
|
|
918
|
+
_render(() => createComponent2(RendererContext.Provider, {
|
|
591
919
|
get value() {
|
|
592
920
|
return renderer;
|
|
593
921
|
},
|
|
594
922
|
get children() {
|
|
595
|
-
return
|
|
923
|
+
return createComponent2(node, {});
|
|
596
924
|
}
|
|
597
925
|
}), renderer.root);
|
|
598
926
|
};
|
|
927
|
+
var testRender = async (node, renderConfig = {}) => {
|
|
928
|
+
const testSetup = await createTestRenderer(renderConfig);
|
|
929
|
+
_render(() => createComponent2(RendererContext.Provider, {
|
|
930
|
+
get value() {
|
|
931
|
+
return testSetup.renderer;
|
|
932
|
+
},
|
|
933
|
+
get children() {
|
|
934
|
+
return createComponent2(node, {});
|
|
935
|
+
}
|
|
936
|
+
}), testSetup.renderer.root);
|
|
937
|
+
return testSetup;
|
|
938
|
+
};
|
|
599
939
|
export {
|
|
600
940
|
useTimeline,
|
|
601
941
|
useTerminalDimensions,
|
|
602
942
|
useSelectionHandler,
|
|
603
943
|
useRenderer,
|
|
944
|
+
usePaste,
|
|
604
945
|
useKeyboard,
|
|
605
946
|
useKeyHandler,
|
|
606
947
|
use,
|
|
948
|
+
textNodeKeys,
|
|
949
|
+
testRender,
|
|
607
950
|
spread,
|
|
608
951
|
setProp,
|
|
609
952
|
render,
|
|
610
953
|
onResize,
|
|
611
|
-
mergeProps,
|
|
612
|
-
memo,
|
|
954
|
+
mergeProps3 as mergeProps,
|
|
955
|
+
memo2 as memo,
|
|
613
956
|
insertNode,
|
|
614
957
|
insert,
|
|
615
958
|
getComponentCatalogue,
|
|
616
959
|
extend,
|
|
617
960
|
effect,
|
|
618
961
|
createTextNode,
|
|
962
|
+
createSlotNode,
|
|
619
963
|
createElement,
|
|
964
|
+
createDynamic,
|
|
620
965
|
createComponentTimeline,
|
|
621
|
-
createComponent,
|
|
966
|
+
createComponent2 as createComponent,
|
|
622
967
|
componentCatalogue,
|
|
623
968
|
baseComponents,
|
|
624
969
|
_render,
|
|
625
|
-
|
|
970
|
+
UnderlineSpanRenderable,
|
|
971
|
+
TextSlotRenderable,
|
|
972
|
+
SlotRenderable,
|
|
973
|
+
RendererContext,
|
|
974
|
+
Portal,
|
|
975
|
+
LineBreakRenderable,
|
|
976
|
+
LayoutSlotRenderable,
|
|
977
|
+
ItalicSpanRenderable,
|
|
978
|
+
Dynamic,
|
|
979
|
+
BoldSpanRenderable
|
|
626
980
|
};
|