@opentui/react 0.1.74 → 0.1.76
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 +1 -1
- package/chunk-eecw9x2f.js +4 -0
- package/{src/reconciler/renderer.js → chunk-mjrsec0j.js} +123 -119
- package/{src/test-utils/chunk-fcedq94e.js → chunk-pm1hna8x.js} +2 -3
- package/index.js +11 -566
- package/jsx-namespace.d.ts +2 -0
- package/package.json +6 -6
- package/src/components/index.d.ts +2 -1
- package/src/test-utils.d.ts +1 -0
- package/src/types/components.d.ts +6 -3
- package/test-utils.js +39 -0
- package/chunk-e11q5a3p.js +0 -20
- package/chunk-fcedq94e.js +0 -29
- package/src/reconciler/chunk-e11q5a3p.js +0 -20
- package/src/reconciler/chunk-fcedq94e.js +0 -29
- package/src/test-utils/chunk-e11q5a3p.js +0 -20
- package/src/test-utils/test-utils.js +0 -598
package/index.js
CHANGED
|
@@ -1,126 +1,16 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
LineNumberRenderable,
|
|
15
|
-
ScrollBoxRenderable,
|
|
16
|
-
SelectRenderable,
|
|
17
|
-
TabSelectRenderable,
|
|
18
|
-
TextareaRenderable,
|
|
19
|
-
TextRenderable
|
|
20
|
-
} from "@opentui/core";
|
|
21
|
-
|
|
22
|
-
// src/components/text.ts
|
|
23
|
-
import { TextAttributes, TextNodeRenderable } from "@opentui/core";
|
|
24
|
-
var textNodeKeys = ["span", "b", "strong", "i", "em", "u", "br", "a"];
|
|
25
|
-
|
|
26
|
-
class SpanRenderable extends TextNodeRenderable {
|
|
27
|
-
ctx;
|
|
28
|
-
constructor(ctx, options) {
|
|
29
|
-
super(options);
|
|
30
|
-
this.ctx = ctx;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
class TextModifierRenderable extends SpanRenderable {
|
|
35
|
-
constructor(options, modifier) {
|
|
36
|
-
super(null, options);
|
|
37
|
-
if (modifier === "b" || modifier === "strong") {
|
|
38
|
-
this.attributes = (this.attributes || 0) | TextAttributes.BOLD;
|
|
39
|
-
} else if (modifier === "i" || modifier === "em") {
|
|
40
|
-
this.attributes = (this.attributes || 0) | TextAttributes.ITALIC;
|
|
41
|
-
} else if (modifier === "u") {
|
|
42
|
-
this.attributes = (this.attributes || 0) | TextAttributes.UNDERLINE;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
class BoldSpanRenderable extends TextModifierRenderable {
|
|
48
|
-
constructor(_ctx, options) {
|
|
49
|
-
super(options, "b");
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
class ItalicSpanRenderable extends TextModifierRenderable {
|
|
54
|
-
constructor(_ctx, options) {
|
|
55
|
-
super(options, "i");
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
class UnderlineSpanRenderable extends TextModifierRenderable {
|
|
60
|
-
constructor(_ctx, options) {
|
|
61
|
-
super(options, "u");
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
class LineBreakRenderable extends SpanRenderable {
|
|
66
|
-
constructor(_ctx, options) {
|
|
67
|
-
super(null, options);
|
|
68
|
-
this.add();
|
|
69
|
-
}
|
|
70
|
-
add() {
|
|
71
|
-
return super.add(`
|
|
72
|
-
`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
class LinkRenderable extends SpanRenderable {
|
|
77
|
-
constructor(_ctx, options) {
|
|
78
|
-
const linkOptions = {
|
|
79
|
-
...options,
|
|
80
|
-
link: { url: options.href }
|
|
81
|
-
};
|
|
82
|
-
super(null, linkOptions);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// src/components/index.ts
|
|
87
|
-
var baseComponents = {
|
|
88
|
-
box: BoxRenderable,
|
|
89
|
-
text: TextRenderable,
|
|
90
|
-
code: CodeRenderable,
|
|
91
|
-
diff: DiffRenderable,
|
|
92
|
-
input: InputRenderable,
|
|
93
|
-
select: SelectRenderable,
|
|
94
|
-
textarea: TextareaRenderable,
|
|
95
|
-
scrollbox: ScrollBoxRenderable,
|
|
96
|
-
"ascii-font": ASCIIFontRenderable,
|
|
97
|
-
"tab-select": TabSelectRenderable,
|
|
98
|
-
"line-number": LineNumberRenderable,
|
|
99
|
-
span: SpanRenderable,
|
|
100
|
-
br: LineBreakRenderable,
|
|
101
|
-
b: BoldSpanRenderable,
|
|
102
|
-
strong: BoldSpanRenderable,
|
|
103
|
-
i: ItalicSpanRenderable,
|
|
104
|
-
em: ItalicSpanRenderable,
|
|
105
|
-
u: UnderlineSpanRenderable,
|
|
106
|
-
a: LinkRenderable
|
|
107
|
-
};
|
|
108
|
-
var componentCatalogue = { ...baseComponents };
|
|
109
|
-
function extend(objects) {
|
|
110
|
-
Object.assign(componentCatalogue, objects);
|
|
111
|
-
}
|
|
112
|
-
function getComponentCatalogue() {
|
|
113
|
-
return componentCatalogue;
|
|
114
|
-
}
|
|
115
|
-
// src/components/app.tsx
|
|
116
|
-
import { createContext, useContext } from "react";
|
|
117
|
-
var AppContext = createContext({
|
|
118
|
-
keyHandler: null,
|
|
119
|
-
renderer: null
|
|
120
|
-
});
|
|
121
|
-
var useAppContext = () => {
|
|
122
|
-
return useContext(AppContext);
|
|
123
|
-
};
|
|
3
|
+
AppContext,
|
|
4
|
+
baseComponents,
|
|
5
|
+
componentCatalogue,
|
|
6
|
+
createPortal,
|
|
7
|
+
createRoot,
|
|
8
|
+
extend,
|
|
9
|
+
flushSync,
|
|
10
|
+
getComponentCatalogue,
|
|
11
|
+
useAppContext
|
|
12
|
+
} from "./chunk-mjrsec0j.js";
|
|
13
|
+
import"./chunk-eecw9x2f.js";
|
|
124
14
|
// src/hooks/use-keyboard.ts
|
|
125
15
|
import { useEffect } from "react";
|
|
126
16
|
|
|
@@ -206,451 +96,6 @@ var useTimeline = (options = {}) => {
|
|
|
206
96
|
}, []);
|
|
207
97
|
return timeline;
|
|
208
98
|
};
|
|
209
|
-
// src/reconciler/renderer.ts
|
|
210
|
-
import { CliRenderEvents, engine as engine2 } from "@opentui/core";
|
|
211
|
-
import React2 from "react";
|
|
212
|
-
|
|
213
|
-
// src/components/error-boundary.tsx
|
|
214
|
-
import React from "react";
|
|
215
|
-
|
|
216
|
-
// jsx-dev-runtime.js
|
|
217
|
-
import { Fragment, jsxDEV } from "react/jsx-dev-runtime";
|
|
218
|
-
|
|
219
|
-
// src/components/error-boundary.tsx
|
|
220
|
-
class ErrorBoundary extends React.Component {
|
|
221
|
-
constructor(props) {
|
|
222
|
-
super(props);
|
|
223
|
-
this.state = { hasError: false, error: null };
|
|
224
|
-
}
|
|
225
|
-
static getDerivedStateFromError(error) {
|
|
226
|
-
return { hasError: true, error };
|
|
227
|
-
}
|
|
228
|
-
render() {
|
|
229
|
-
if (this.state.hasError && this.state.error) {
|
|
230
|
-
return /* @__PURE__ */ jsxDEV("box", {
|
|
231
|
-
style: { flexDirection: "column", padding: 2 },
|
|
232
|
-
children: /* @__PURE__ */ jsxDEV("text", {
|
|
233
|
-
fg: "red",
|
|
234
|
-
children: this.state.error.stack || this.state.error.message
|
|
235
|
-
}, undefined, false, undefined, this)
|
|
236
|
-
}, undefined, false, undefined, this);
|
|
237
|
-
}
|
|
238
|
-
return this.props.children;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// src/reconciler/reconciler.ts
|
|
243
|
-
import ReactReconciler from "react-reconciler";
|
|
244
|
-
import { ConcurrentRoot } from "react-reconciler/constants";
|
|
245
|
-
|
|
246
|
-
// src/reconciler/host-config.ts
|
|
247
|
-
import { TextNodeRenderable as TextNodeRenderable2 } from "@opentui/core";
|
|
248
|
-
// package.json
|
|
249
|
-
var package_default = {
|
|
250
|
-
name: "@opentui/react",
|
|
251
|
-
version: "0.1.74",
|
|
252
|
-
description: "React renderer for building terminal user interfaces using OpenTUI core",
|
|
253
|
-
license: "MIT",
|
|
254
|
-
repository: {
|
|
255
|
-
type: "git",
|
|
256
|
-
url: "https://github.com/anomalyco/opentui",
|
|
257
|
-
directory: "packages/react"
|
|
258
|
-
},
|
|
259
|
-
module: "src/index.ts",
|
|
260
|
-
type: "module",
|
|
261
|
-
private: true,
|
|
262
|
-
main: "src/index.ts",
|
|
263
|
-
exports: {
|
|
264
|
-
".": {
|
|
265
|
-
import: "./src/index.ts",
|
|
266
|
-
types: "./src/index.ts"
|
|
267
|
-
},
|
|
268
|
-
"./test-utils": {
|
|
269
|
-
import: "./src/test-utils.ts",
|
|
270
|
-
types: "./src/test-utils.d.ts"
|
|
271
|
-
},
|
|
272
|
-
"./jsx-runtime": {
|
|
273
|
-
import: "./jsx-runtime.js",
|
|
274
|
-
types: "./jsx-runtime.d.ts"
|
|
275
|
-
},
|
|
276
|
-
"./jsx-dev-runtime": {
|
|
277
|
-
import: "./jsx-dev-runtime.js",
|
|
278
|
-
types: "./jsx-dev-runtime.d.ts"
|
|
279
|
-
}
|
|
280
|
-
},
|
|
281
|
-
scripts: {
|
|
282
|
-
build: "bun run scripts/build.ts",
|
|
283
|
-
"build:dev": "bun run scripts/build.ts --dev",
|
|
284
|
-
publish: "bun run scripts/publish.ts",
|
|
285
|
-
test: "bun test"
|
|
286
|
-
},
|
|
287
|
-
devDependencies: {
|
|
288
|
-
"@types/bun": "latest",
|
|
289
|
-
"@types/node": "^24.0.0",
|
|
290
|
-
"@types/react": "^19.0.0",
|
|
291
|
-
"@types/react-reconciler": "^0.32.0",
|
|
292
|
-
"@types/ws": "^8.18.1",
|
|
293
|
-
react: ">=19.0.0",
|
|
294
|
-
"react-devtools-core": "^7.0.1",
|
|
295
|
-
typescript: "^5",
|
|
296
|
-
ws: "^8.18.0"
|
|
297
|
-
},
|
|
298
|
-
peerDependencies: {
|
|
299
|
-
react: ">=19.0.0",
|
|
300
|
-
"react-devtools-core": "^7.0.1",
|
|
301
|
-
ws: "^8.18.0"
|
|
302
|
-
},
|
|
303
|
-
peerDependenciesMeta: {
|
|
304
|
-
"react-devtools-core": {
|
|
305
|
-
optional: true
|
|
306
|
-
},
|
|
307
|
-
ws: {
|
|
308
|
-
optional: true
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
dependencies: {
|
|
312
|
-
"@opentui/core": "workspace:*",
|
|
313
|
-
"react-reconciler": "^0.32.0"
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
// src/reconciler/host-config.ts
|
|
318
|
-
import { createContext as createContext2 } from "react";
|
|
319
|
-
import { DefaultEventPriority, NoEventPriority } from "react-reconciler/constants";
|
|
320
|
-
|
|
321
|
-
// src/utils/id.ts
|
|
322
|
-
var idCounter = new Map;
|
|
323
|
-
function getNextId(type) {
|
|
324
|
-
if (!idCounter.has(type)) {
|
|
325
|
-
idCounter.set(type, 0);
|
|
326
|
-
}
|
|
327
|
-
const value = idCounter.get(type) + 1;
|
|
328
|
-
idCounter.set(type, value);
|
|
329
|
-
return `${type}-${value}`;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// src/utils/index.ts
|
|
333
|
-
import {
|
|
334
|
-
InputRenderable as InputRenderable2,
|
|
335
|
-
InputRenderableEvents,
|
|
336
|
-
isRenderable,
|
|
337
|
-
SelectRenderable as SelectRenderable2,
|
|
338
|
-
SelectRenderableEvents,
|
|
339
|
-
TabSelectRenderable as TabSelectRenderable2,
|
|
340
|
-
TabSelectRenderableEvents
|
|
341
|
-
} from "@opentui/core";
|
|
342
|
-
function initEventListeners(instance, eventName, listener, previousListener) {
|
|
343
|
-
if (previousListener) {
|
|
344
|
-
instance.off(eventName, previousListener);
|
|
345
|
-
}
|
|
346
|
-
if (listener) {
|
|
347
|
-
instance.on(eventName, listener);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
function setStyle(instance, styles, oldStyles) {
|
|
351
|
-
if (oldStyles != null && typeof oldStyles === "object") {
|
|
352
|
-
for (const styleName in oldStyles) {
|
|
353
|
-
if (oldStyles.hasOwnProperty(styleName)) {
|
|
354
|
-
if (styles == null || !styles.hasOwnProperty(styleName)) {
|
|
355
|
-
instance[styleName] = null;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
if (styles != null && typeof styles === "object") {
|
|
361
|
-
for (const styleName in styles) {
|
|
362
|
-
if (styles.hasOwnProperty(styleName)) {
|
|
363
|
-
const value = styles[styleName];
|
|
364
|
-
const oldValue = oldStyles?.[styleName];
|
|
365
|
-
if (value !== oldValue) {
|
|
366
|
-
instance[styleName] = value;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
function setProperty(instance, type, propKey, propValue, oldPropValue) {
|
|
373
|
-
switch (propKey) {
|
|
374
|
-
case "onChange":
|
|
375
|
-
if (instance instanceof InputRenderable2) {
|
|
376
|
-
initEventListeners(instance, InputRenderableEvents.CHANGE, propValue, oldPropValue);
|
|
377
|
-
} else if (instance instanceof SelectRenderable2) {
|
|
378
|
-
initEventListeners(instance, SelectRenderableEvents.SELECTION_CHANGED, propValue, oldPropValue);
|
|
379
|
-
} else if (instance instanceof TabSelectRenderable2) {
|
|
380
|
-
initEventListeners(instance, TabSelectRenderableEvents.SELECTION_CHANGED, propValue, oldPropValue);
|
|
381
|
-
}
|
|
382
|
-
break;
|
|
383
|
-
case "onInput":
|
|
384
|
-
if (instance instanceof InputRenderable2) {
|
|
385
|
-
initEventListeners(instance, InputRenderableEvents.INPUT, propValue, oldPropValue);
|
|
386
|
-
}
|
|
387
|
-
break;
|
|
388
|
-
case "onSubmit":
|
|
389
|
-
if (instance instanceof InputRenderable2) {
|
|
390
|
-
initEventListeners(instance, InputRenderableEvents.ENTER, propValue, oldPropValue);
|
|
391
|
-
}
|
|
392
|
-
break;
|
|
393
|
-
case "onSelect":
|
|
394
|
-
if (instance instanceof SelectRenderable2) {
|
|
395
|
-
initEventListeners(instance, SelectRenderableEvents.ITEM_SELECTED, propValue, oldPropValue);
|
|
396
|
-
} else if (instance instanceof TabSelectRenderable2) {
|
|
397
|
-
initEventListeners(instance, TabSelectRenderableEvents.ITEM_SELECTED, propValue, oldPropValue);
|
|
398
|
-
}
|
|
399
|
-
break;
|
|
400
|
-
case "focused":
|
|
401
|
-
if (isRenderable(instance)) {
|
|
402
|
-
if (!!propValue) {
|
|
403
|
-
instance.focus();
|
|
404
|
-
} else {
|
|
405
|
-
instance.blur();
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
break;
|
|
409
|
-
case "style":
|
|
410
|
-
setStyle(instance, propValue, oldPropValue);
|
|
411
|
-
break;
|
|
412
|
-
case "children":
|
|
413
|
-
break;
|
|
414
|
-
default:
|
|
415
|
-
instance[propKey] = propValue;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
function setInitialProperties(instance, type, props) {
|
|
419
|
-
for (const propKey in props) {
|
|
420
|
-
if (!props.hasOwnProperty(propKey)) {
|
|
421
|
-
continue;
|
|
422
|
-
}
|
|
423
|
-
const propValue = props[propKey];
|
|
424
|
-
if (propValue == null) {
|
|
425
|
-
continue;
|
|
426
|
-
}
|
|
427
|
-
setProperty(instance, type, propKey, propValue);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
function updateProperties(instance, type, oldProps, newProps) {
|
|
431
|
-
for (const propKey in oldProps) {
|
|
432
|
-
const oldProp = oldProps[propKey];
|
|
433
|
-
if (oldProps.hasOwnProperty(propKey) && oldProp != null && !newProps.hasOwnProperty(propKey)) {
|
|
434
|
-
setProperty(instance, type, propKey, null, oldProp);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
for (const propKey in newProps) {
|
|
438
|
-
const newProp = newProps[propKey];
|
|
439
|
-
const oldProp = oldProps[propKey];
|
|
440
|
-
if (newProps.hasOwnProperty(propKey) && newProp !== oldProp && (newProp != null || oldProp != null)) {
|
|
441
|
-
setProperty(instance, type, propKey, newProp, oldProp);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// src/reconciler/host-config.ts
|
|
447
|
-
var currentUpdatePriority = NoEventPriority;
|
|
448
|
-
var hostConfig = {
|
|
449
|
-
supportsMutation: true,
|
|
450
|
-
supportsPersistence: false,
|
|
451
|
-
supportsHydration: false,
|
|
452
|
-
createInstance(type, props, rootContainerInstance, hostContext) {
|
|
453
|
-
if (textNodeKeys.includes(type) && !hostContext.isInsideText) {
|
|
454
|
-
throw new Error(`Component of type "${type}" must be created inside of a text node`);
|
|
455
|
-
}
|
|
456
|
-
const id = getNextId(type);
|
|
457
|
-
const components = getComponentCatalogue();
|
|
458
|
-
if (!components[type]) {
|
|
459
|
-
throw new Error(`Unknown component type: ${type}`);
|
|
460
|
-
}
|
|
461
|
-
return new components[type](rootContainerInstance.ctx, {
|
|
462
|
-
id,
|
|
463
|
-
...props
|
|
464
|
-
});
|
|
465
|
-
},
|
|
466
|
-
appendChild(parent, child) {
|
|
467
|
-
parent.add(child);
|
|
468
|
-
},
|
|
469
|
-
removeChild(parent, child) {
|
|
470
|
-
parent.remove(child.id);
|
|
471
|
-
},
|
|
472
|
-
insertBefore(parent, child, beforeChild) {
|
|
473
|
-
parent.insertBefore(child, beforeChild);
|
|
474
|
-
},
|
|
475
|
-
insertInContainerBefore(parent, child, beforeChild) {
|
|
476
|
-
parent.insertBefore(child, beforeChild);
|
|
477
|
-
},
|
|
478
|
-
removeChildFromContainer(parent, child) {
|
|
479
|
-
parent.remove(child.id);
|
|
480
|
-
},
|
|
481
|
-
prepareForCommit(containerInfo) {
|
|
482
|
-
return null;
|
|
483
|
-
},
|
|
484
|
-
resetAfterCommit(containerInfo) {
|
|
485
|
-
containerInfo.requestRender();
|
|
486
|
-
},
|
|
487
|
-
getRootHostContext(rootContainerInstance) {
|
|
488
|
-
return { isInsideText: false };
|
|
489
|
-
},
|
|
490
|
-
getChildHostContext(parentHostContext, type, rootContainerInstance) {
|
|
491
|
-
const isInsideText = ["text", ...textNodeKeys].includes(type);
|
|
492
|
-
return { ...parentHostContext, isInsideText };
|
|
493
|
-
},
|
|
494
|
-
shouldSetTextContent(type, props) {
|
|
495
|
-
return false;
|
|
496
|
-
},
|
|
497
|
-
createTextInstance(text, rootContainerInstance, hostContext) {
|
|
498
|
-
if (!hostContext.isInsideText) {
|
|
499
|
-
throw new Error("Text must be created inside of a text node");
|
|
500
|
-
}
|
|
501
|
-
return TextNodeRenderable2.fromString(text);
|
|
502
|
-
},
|
|
503
|
-
scheduleTimeout: setTimeout,
|
|
504
|
-
cancelTimeout: clearTimeout,
|
|
505
|
-
noTimeout: -1,
|
|
506
|
-
shouldAttemptEagerTransition() {
|
|
507
|
-
return false;
|
|
508
|
-
},
|
|
509
|
-
finalizeInitialChildren(instance, type, props, rootContainerInstance, hostContext) {
|
|
510
|
-
setInitialProperties(instance, type, props);
|
|
511
|
-
return false;
|
|
512
|
-
},
|
|
513
|
-
commitMount(instance, type, props, internalInstanceHandle) {},
|
|
514
|
-
commitUpdate(instance, type, oldProps, newProps, internalInstanceHandle) {
|
|
515
|
-
updateProperties(instance, type, oldProps, newProps);
|
|
516
|
-
instance.requestRender();
|
|
517
|
-
},
|
|
518
|
-
commitTextUpdate(textInstance, oldText, newText) {
|
|
519
|
-
textInstance.children = [newText];
|
|
520
|
-
textInstance.requestRender();
|
|
521
|
-
},
|
|
522
|
-
appendChildToContainer(container, child) {
|
|
523
|
-
container.add(child);
|
|
524
|
-
},
|
|
525
|
-
appendInitialChild(parent, child) {
|
|
526
|
-
parent.add(child);
|
|
527
|
-
},
|
|
528
|
-
hideInstance(instance) {
|
|
529
|
-
instance.visible = false;
|
|
530
|
-
instance.requestRender();
|
|
531
|
-
},
|
|
532
|
-
unhideInstance(instance, props) {
|
|
533
|
-
instance.visible = true;
|
|
534
|
-
instance.requestRender();
|
|
535
|
-
},
|
|
536
|
-
hideTextInstance(textInstance) {
|
|
537
|
-
textInstance.visible = false;
|
|
538
|
-
textInstance.requestRender();
|
|
539
|
-
},
|
|
540
|
-
unhideTextInstance(textInstance, text) {
|
|
541
|
-
textInstance.visible = true;
|
|
542
|
-
textInstance.requestRender();
|
|
543
|
-
},
|
|
544
|
-
clearContainer(container) {
|
|
545
|
-
const children = container.getChildren();
|
|
546
|
-
children.forEach((child) => container.remove(child.id));
|
|
547
|
-
},
|
|
548
|
-
setCurrentUpdatePriority(newPriority) {
|
|
549
|
-
currentUpdatePriority = newPriority;
|
|
550
|
-
},
|
|
551
|
-
getCurrentUpdatePriority: () => currentUpdatePriority,
|
|
552
|
-
resolveUpdatePriority() {
|
|
553
|
-
if (currentUpdatePriority !== NoEventPriority) {
|
|
554
|
-
return currentUpdatePriority;
|
|
555
|
-
}
|
|
556
|
-
return DefaultEventPriority;
|
|
557
|
-
},
|
|
558
|
-
maySuspendCommit() {
|
|
559
|
-
return false;
|
|
560
|
-
},
|
|
561
|
-
NotPendingTransition: null,
|
|
562
|
-
HostTransitionContext: createContext2(null),
|
|
563
|
-
resetFormInstance() {},
|
|
564
|
-
requestPostPaintCallback() {},
|
|
565
|
-
trackSchedulerEvent() {},
|
|
566
|
-
resolveEventType() {
|
|
567
|
-
return null;
|
|
568
|
-
},
|
|
569
|
-
resolveEventTimeStamp() {
|
|
570
|
-
return -1.1;
|
|
571
|
-
},
|
|
572
|
-
preloadInstance() {
|
|
573
|
-
return true;
|
|
574
|
-
},
|
|
575
|
-
startSuspendingCommit() {},
|
|
576
|
-
suspendInstance() {},
|
|
577
|
-
waitForCommitToBeReady() {
|
|
578
|
-
return null;
|
|
579
|
-
},
|
|
580
|
-
detachDeletedInstance(instance) {
|
|
581
|
-
if (!instance.parent) {
|
|
582
|
-
instance.destroyRecursively();
|
|
583
|
-
}
|
|
584
|
-
},
|
|
585
|
-
getPublicInstance(instance) {
|
|
586
|
-
return instance;
|
|
587
|
-
},
|
|
588
|
-
preparePortalMount(containerInfo) {},
|
|
589
|
-
isPrimaryRenderer: true,
|
|
590
|
-
getInstanceFromNode() {
|
|
591
|
-
return null;
|
|
592
|
-
},
|
|
593
|
-
beforeActiveInstanceBlur() {},
|
|
594
|
-
afterActiveInstanceBlur() {},
|
|
595
|
-
prepareScopeUpdate() {},
|
|
596
|
-
getInstanceFromScope() {
|
|
597
|
-
return null;
|
|
598
|
-
},
|
|
599
|
-
rendererPackageName: "@opentui/react",
|
|
600
|
-
rendererVersion: package_default.version
|
|
601
|
-
};
|
|
602
|
-
|
|
603
|
-
// src/reconciler/reconciler.ts
|
|
604
|
-
var reconciler = ReactReconciler(hostConfig);
|
|
605
|
-
if (process.env["DEV"] === "true") {
|
|
606
|
-
try {
|
|
607
|
-
await import("./chunk-fcedq94e.js");
|
|
608
|
-
} catch (error) {
|
|
609
|
-
if (error.code === "ERR_MODULE_NOT_FOUND") {
|
|
610
|
-
console.warn(`
|
|
611
|
-
The environment variable DEV is set to true, so opentui tried to import \`react-devtools-core\`,
|
|
612
|
-
but this failed as it was not installed. Debugging with React DevTools requires it.
|
|
613
|
-
|
|
614
|
-
To install use this command:
|
|
615
|
-
|
|
616
|
-
$ bun add react-devtools-core@7 -d
|
|
617
|
-
`.trim() + `
|
|
618
|
-
`);
|
|
619
|
-
} else {
|
|
620
|
-
throw error;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
reconciler.injectIntoDevTools();
|
|
625
|
-
function _render(element, root) {
|
|
626
|
-
const container = reconciler.createContainer(root, ConcurrentRoot, null, false, null, "", console.error, console.error, console.error, console.error, null);
|
|
627
|
-
reconciler.updateContainer(element, container, null, () => {});
|
|
628
|
-
return container;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
// src/reconciler/renderer.ts
|
|
632
|
-
var _r = reconciler;
|
|
633
|
-
var flushSync = _r.flushSyncFromReconciler ?? _r.flushSync;
|
|
634
|
-
var { createPortal } = reconciler;
|
|
635
|
-
function createRoot(renderer) {
|
|
636
|
-
let container = null;
|
|
637
|
-
const cleanup = () => {
|
|
638
|
-
if (container) {
|
|
639
|
-
reconciler.updateContainer(null, container, null, () => {});
|
|
640
|
-
reconciler.flushSyncWork();
|
|
641
|
-
container = null;
|
|
642
|
-
}
|
|
643
|
-
};
|
|
644
|
-
renderer.once(CliRenderEvents.DESTROY, cleanup);
|
|
645
|
-
return {
|
|
646
|
-
render: (node) => {
|
|
647
|
-
engine2.attach(renderer);
|
|
648
|
-
container = _render(React2.createElement(AppContext.Provider, { value: { keyHandler: renderer.keyInput, renderer } }, React2.createElement(ErrorBoundary, null, node)), renderer.root);
|
|
649
|
-
},
|
|
650
|
-
unmount: cleanup
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
|
|
654
99
|
// src/index.ts
|
|
655
100
|
import { createElement } from "react";
|
|
656
101
|
export {
|
package/jsx-namespace.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
LineBreakProps,
|
|
10
10
|
LineNumberProps,
|
|
11
11
|
LinkProps,
|
|
12
|
+
MarkdownProps,
|
|
12
13
|
OpenTUIComponents,
|
|
13
14
|
ScrollBoxProps,
|
|
14
15
|
SelectProps,
|
|
@@ -41,6 +42,7 @@ export namespace JSX {
|
|
|
41
42
|
span: SpanProps
|
|
42
43
|
code: CodeProps
|
|
43
44
|
diff: DiffProps
|
|
45
|
+
markdown: MarkdownProps
|
|
44
46
|
input: InputProps
|
|
45
47
|
textarea: TextareaProps
|
|
46
48
|
select: SelectProps
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "src/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "0.1.
|
|
7
|
+
"version": "0.1.76",
|
|
8
8
|
"description": "React renderer for building terminal user interfaces using OpenTUI core",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"repository": {
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
},
|
|
21
21
|
"./renderer": {
|
|
22
22
|
"types": "./src/reconciler/renderer.d.ts",
|
|
23
|
-
"import": "./
|
|
24
|
-
"require": "./
|
|
23
|
+
"import": "./index.js",
|
|
24
|
+
"require": "./index.js"
|
|
25
25
|
},
|
|
26
26
|
"./test-utils": {
|
|
27
27
|
"types": "./src/test-utils.d.ts",
|
|
28
|
-
"import": "./
|
|
29
|
-
"require": "./
|
|
28
|
+
"import": "./test-utils.js",
|
|
29
|
+
"require": "./test-utils.js"
|
|
30
30
|
},
|
|
31
31
|
"./jsx-runtime": {
|
|
32
32
|
"types": "./jsx-runtime.d.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@opentui/core": "0.1.
|
|
43
|
+
"@opentui/core": "0.1.76",
|
|
44
44
|
"react-reconciler": "^0.32.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ASCIIFontRenderable, BoxRenderable, CodeRenderable, DiffRenderable, InputRenderable, LineNumberRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextareaRenderable, TextRenderable } from "@opentui/core";
|
|
1
|
+
import { ASCIIFontRenderable, BoxRenderable, CodeRenderable, DiffRenderable, InputRenderable, LineNumberRenderable, MarkdownRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextareaRenderable, TextRenderable } from "@opentui/core";
|
|
2
2
|
import type { RenderableConstructor } from "../types/components";
|
|
3
3
|
import { BoldSpanRenderable, ItalicSpanRenderable, LineBreakRenderable, LinkRenderable, SpanRenderable, UnderlineSpanRenderable } from "./text";
|
|
4
4
|
export declare const baseComponents: {
|
|
@@ -6,6 +6,7 @@ export declare const baseComponents: {
|
|
|
6
6
|
text: typeof TextRenderable;
|
|
7
7
|
code: typeof CodeRenderable;
|
|
8
8
|
diff: typeof DiffRenderable;
|
|
9
|
+
markdown: typeof MarkdownRenderable;
|
|
9
10
|
input: typeof InputRenderable;
|
|
10
11
|
select: typeof SelectRenderable;
|
|
11
12
|
textarea: typeof TextareaRenderable;
|
package/src/test-utils.d.ts
CHANGED
|
@@ -6,5 +6,6 @@ export declare function testRender(node: ReactNode, testRendererOptions: TestRen
|
|
|
6
6
|
mockMouse: import("@opentui/core/testing").MockMouse;
|
|
7
7
|
renderOnce: () => Promise<void>;
|
|
8
8
|
captureCharFrame: () => string;
|
|
9
|
+
captureSpans: () => import("@opentui/core").CapturedFrame;
|
|
9
10
|
resize: (width: number, height: number) => void;
|
|
10
11
|
}>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ASCIIFontOptions, ASCIIFontRenderable, BaseRenderable, BoxOptions, BoxRenderable, CodeOptions, CodeRenderable, DiffRenderable, DiffRenderableOptions, InputRenderable, InputRenderableOptions, LineNumberOptions, LineNumberRenderable, RenderableOptions, RenderContext, ScrollBoxOptions, ScrollBoxRenderable, SelectOption, SelectRenderable, SelectRenderableOptions, TabSelectOption, TabSelectRenderable, TabSelectRenderableOptions, TextareaOptions, TextareaRenderable, TextNodeOptions, TextNodeRenderable, TextOptions, TextRenderable } from "@opentui/core";
|
|
1
|
+
import type { ASCIIFontOptions, ASCIIFontRenderable, BaseRenderable, BoxOptions, BoxRenderable, CodeOptions, CodeRenderable, DiffRenderable, DiffRenderableOptions, InputRenderable, InputRenderableOptions, LineNumberOptions, LineNumberRenderable, MarkdownOptions, MarkdownRenderable, RenderableOptions, RenderContext, ScrollBoxOptions, ScrollBoxRenderable, SelectOption, SelectRenderable, SelectRenderableOptions, TabSelectOption, TabSelectRenderable, TabSelectRenderableOptions, TextareaOptions, TextareaRenderable, TextNodeOptions, TextNodeRenderable, TextOptions, TextRenderable } from "@opentui/core";
|
|
2
2
|
import type React from "react";
|
|
3
3
|
/** Properties that should not be included in the style prop */
|
|
4
4
|
export type NonStyledProps = "id" | "buffered" | "live" | "enableLayout" | "selectable" | "renderAfter" | "renderBefore" | `on${string}`;
|
|
@@ -14,7 +14,7 @@ type ExtractRenderableOptions<TConstructor> = TConstructor extends new (ctx: Ren
|
|
|
14
14
|
/** Extract the renderable type from a constructor */
|
|
15
15
|
type ExtractRenderable<TConstructor> = TConstructor extends new (ctx: RenderContext, options: any) => infer TRenderable ? TRenderable : never;
|
|
16
16
|
/** Determine which properties should be excluded from styling for different renderable types */
|
|
17
|
-
export type GetNonStyledProperties<TConstructor> = TConstructor extends RenderableConstructor<TextRenderable> ? NonStyledProps | "content" : TConstructor extends RenderableConstructor<BoxRenderable> ? NonStyledProps | "title" : TConstructor extends RenderableConstructor<ASCIIFontRenderable> ? NonStyledProps | "text" | "selectable" : TConstructor extends RenderableConstructor<InputRenderable> ? NonStyledProps | "placeholder" | "value" : TConstructor extends RenderableConstructor<TextareaRenderable> ? NonStyledProps | "placeholder" | "initialValue" : TConstructor extends RenderableConstructor<CodeRenderable> ? NonStyledProps | "content" | "filetype" | "syntaxStyle" | "treeSitterClient" | "conceal" | "drawUnstyledText" : NonStyledProps;
|
|
17
|
+
export type GetNonStyledProperties<TConstructor> = TConstructor extends RenderableConstructor<TextRenderable> ? NonStyledProps | "content" : TConstructor extends RenderableConstructor<BoxRenderable> ? NonStyledProps | "title" : TConstructor extends RenderableConstructor<ASCIIFontRenderable> ? NonStyledProps | "text" | "selectable" : TConstructor extends RenderableConstructor<InputRenderable> ? NonStyledProps | "placeholder" | "value" : TConstructor extends RenderableConstructor<TextareaRenderable> ? NonStyledProps | "placeholder" | "initialValue" : TConstructor extends RenderableConstructor<CodeRenderable> ? NonStyledProps | "content" | "filetype" | "syntaxStyle" | "treeSitterClient" | "conceal" | "drawUnstyledText" : TConstructor extends RenderableConstructor<MarkdownRenderable> ? NonStyledProps | "content" | "syntaxStyle" | "treeSitterClient" | "conceal" | "renderNode" : NonStyledProps;
|
|
18
18
|
/** Base props for container components that accept children */
|
|
19
19
|
type ContainerProps<TOptions> = TOptions & {
|
|
20
20
|
children?: React.ReactNode;
|
|
@@ -35,7 +35,9 @@ export type LinkProps = SpanProps & {
|
|
|
35
35
|
href: string;
|
|
36
36
|
};
|
|
37
37
|
export type LineBreakProps = Pick<SpanProps, "id">;
|
|
38
|
-
export type BoxProps = ComponentProps<ContainerProps<BoxOptions>, BoxRenderable
|
|
38
|
+
export type BoxProps = ComponentProps<ContainerProps<BoxOptions>, BoxRenderable> & {
|
|
39
|
+
focused?: boolean;
|
|
40
|
+
};
|
|
39
41
|
export type InputProps = ComponentProps<InputRenderableOptions, InputRenderable> & {
|
|
40
42
|
focused?: boolean;
|
|
41
43
|
onInput?: (value: string) => void;
|
|
@@ -46,6 +48,7 @@ export type TextareaProps = ComponentProps<TextareaOptions, TextareaRenderable>
|
|
|
46
48
|
focused?: boolean;
|
|
47
49
|
};
|
|
48
50
|
export type CodeProps = ComponentProps<CodeOptions, CodeRenderable>;
|
|
51
|
+
export type MarkdownProps = ComponentProps<MarkdownOptions, MarkdownRenderable>;
|
|
49
52
|
export type DiffProps = ComponentProps<DiffRenderableOptions, DiffRenderable>;
|
|
50
53
|
export type SelectProps = ComponentProps<SelectRenderableOptions, SelectRenderable> & {
|
|
51
54
|
focused?: boolean;
|