@opentui/react 0.1.6
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/LICENSE +21 -0
- package/README.md +464 -0
- package/index.js +418 -0
- package/jsx-dev-runtime.d.ts +2 -0
- package/jsx-dev-runtime.js +1 -0
- package/jsx-namespace.d.ts +25 -0
- package/jsx-runtime.d.ts +2 -0
- package/jsx-runtime.js +1 -0
- package/package.json +50 -0
- package/src/components/app.d.ts +8 -0
- package/src/components/index.d.ts +27 -0
- package/src/hooks/use-keyboard.d.ts +2 -0
- package/src/hooks/use-renderer.d.ts +1 -0
- package/src/hooks/use-resize.d.ts +1 -0
- package/src/index.d.ts +8 -0
- package/src/reconciler/host-config.d.ts +9 -0
- package/src/reconciler/reconciler.d.ts +5 -0
- package/src/reconciler/renderer.d.ts +3 -0
- package/src/reconciler/renderer.js +374 -0
- package/src/types/components.d.ts +32 -0
- package/src/types/extend.d.ts +15 -0
- package/src/types/host.d.ts +9 -0
- package/src/utils/id.d.ts +2 -0
- package/src/utils/index.d.ts +3 -0
package/index.js
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/components/index.ts
|
|
3
|
+
import {
|
|
4
|
+
BoxRenderable,
|
|
5
|
+
GroupRenderable,
|
|
6
|
+
InputRenderable,
|
|
7
|
+
SelectRenderable,
|
|
8
|
+
TabSelectRenderable,
|
|
9
|
+
TextRenderable
|
|
10
|
+
} from "@opentui/core";
|
|
11
|
+
var baseComponents = {
|
|
12
|
+
box: BoxRenderable,
|
|
13
|
+
text: TextRenderable,
|
|
14
|
+
group: GroupRenderable,
|
|
15
|
+
input: InputRenderable,
|
|
16
|
+
select: SelectRenderable,
|
|
17
|
+
"tab-select": TabSelectRenderable
|
|
18
|
+
};
|
|
19
|
+
var componentCatalogue = { ...baseComponents };
|
|
20
|
+
function extend(objects) {
|
|
21
|
+
Object.assign(componentCatalogue, objects);
|
|
22
|
+
}
|
|
23
|
+
function getComponentCatalogue() {
|
|
24
|
+
return componentCatalogue;
|
|
25
|
+
}
|
|
26
|
+
// src/components/app.tsx
|
|
27
|
+
import { createContext, useContext } from "react";
|
|
28
|
+
var AppContext = createContext({
|
|
29
|
+
keyHandler: null,
|
|
30
|
+
renderer: null
|
|
31
|
+
});
|
|
32
|
+
var useAppContext = () => {
|
|
33
|
+
return useContext(AppContext);
|
|
34
|
+
};
|
|
35
|
+
// src/hooks/use-keyboard.tsx
|
|
36
|
+
import { useEffect } from "react";
|
|
37
|
+
var useKeyboard = (handler) => {
|
|
38
|
+
const { keyHandler } = useAppContext();
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
keyHandler?.on("keypress", handler);
|
|
41
|
+
return () => {
|
|
42
|
+
keyHandler?.off("keypress", handler);
|
|
43
|
+
};
|
|
44
|
+
}, [keyHandler, handler]);
|
|
45
|
+
};
|
|
46
|
+
// src/hooks/use-renderer.tsx
|
|
47
|
+
var useRenderer = () => {
|
|
48
|
+
const { renderer } = useAppContext();
|
|
49
|
+
if (!renderer) {
|
|
50
|
+
throw new Error("Renderer not found.");
|
|
51
|
+
}
|
|
52
|
+
return renderer;
|
|
53
|
+
};
|
|
54
|
+
// src/hooks/use-resize.tsx
|
|
55
|
+
import { useEffect as useEffect2 } from "react";
|
|
56
|
+
var useOnResize = (callback) => {
|
|
57
|
+
const renderer = useRenderer();
|
|
58
|
+
useEffect2(() => {
|
|
59
|
+
renderer.on("resize", callback);
|
|
60
|
+
return () => {
|
|
61
|
+
renderer.off("resize", callback);
|
|
62
|
+
};
|
|
63
|
+
}, [renderer, callback]);
|
|
64
|
+
return renderer;
|
|
65
|
+
};
|
|
66
|
+
// src/reconciler/renderer.ts
|
|
67
|
+
import { createCliRenderer, getKeyHandler } from "@opentui/core";
|
|
68
|
+
import React from "react";
|
|
69
|
+
|
|
70
|
+
// src/reconciler/reconciler.ts
|
|
71
|
+
import ReactReconciler from "react-reconciler";
|
|
72
|
+
import { ConcurrentRoot } from "react-reconciler/constants";
|
|
73
|
+
|
|
74
|
+
// src/reconciler/host-config.ts
|
|
75
|
+
import { createContext as createContext2 } from "react";
|
|
76
|
+
import { DefaultEventPriority, NoEventPriority } from "react-reconciler/constants";
|
|
77
|
+
|
|
78
|
+
// src/utils/id.ts
|
|
79
|
+
var idCounter = new Map;
|
|
80
|
+
function getNextId(type) {
|
|
81
|
+
if (!idCounter.has(type)) {
|
|
82
|
+
idCounter.set(type, 0);
|
|
83
|
+
}
|
|
84
|
+
const value = idCounter.get(type) + 1;
|
|
85
|
+
idCounter.set(type, value);
|
|
86
|
+
return `${type}-${value}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/utils/index.ts
|
|
90
|
+
import {
|
|
91
|
+
InputRenderable as InputRenderable2,
|
|
92
|
+
InputRenderableEvents,
|
|
93
|
+
SelectRenderable as SelectRenderable2,
|
|
94
|
+
SelectRenderableEvents,
|
|
95
|
+
StyledText,
|
|
96
|
+
TabSelectRenderable as TabSelectRenderable2,
|
|
97
|
+
TabSelectRenderableEvents,
|
|
98
|
+
TextRenderable as TextRenderable2,
|
|
99
|
+
stringToStyledText
|
|
100
|
+
} from "@opentui/core";
|
|
101
|
+
function initEventListeners(instance, eventName, listener, previousListener) {
|
|
102
|
+
if (previousListener) {
|
|
103
|
+
instance.off(eventName, previousListener);
|
|
104
|
+
}
|
|
105
|
+
if (listener) {
|
|
106
|
+
instance.on(eventName, listener);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function handleTextChildren(textInstance, children) {
|
|
110
|
+
if (children == null) {
|
|
111
|
+
textInstance.content = stringToStyledText("");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (Array.isArray(children)) {
|
|
115
|
+
const chunks = [];
|
|
116
|
+
for (const child of children) {
|
|
117
|
+
if (typeof child === "string") {
|
|
118
|
+
chunks.push({
|
|
119
|
+
__isChunk: true,
|
|
120
|
+
text: new TextEncoder().encode(child),
|
|
121
|
+
plainText: child
|
|
122
|
+
});
|
|
123
|
+
} else if (child && typeof child === "object" && "__isChunk" in child) {
|
|
124
|
+
chunks.push(child);
|
|
125
|
+
} else if (child instanceof StyledText) {
|
|
126
|
+
chunks.push(...child.chunks);
|
|
127
|
+
} else if (child != null) {
|
|
128
|
+
const stringValue = String(child);
|
|
129
|
+
chunks.push({
|
|
130
|
+
__isChunk: true,
|
|
131
|
+
text: new TextEncoder().encode(stringValue),
|
|
132
|
+
plainText: stringValue
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
textInstance.content = new StyledText(chunks);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (typeof children === "string") {
|
|
140
|
+
textInstance.content = stringToStyledText(children);
|
|
141
|
+
} else if (children && typeof children === "object" && "__isChunk" in children) {
|
|
142
|
+
textInstance.content = new StyledText([children]);
|
|
143
|
+
} else if (children instanceof StyledText) {
|
|
144
|
+
textInstance.content = children;
|
|
145
|
+
} else {
|
|
146
|
+
textInstance.content = stringToStyledText(String(children));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function setStyle(instance, styles, oldStyles) {
|
|
150
|
+
if (styles && typeof styles === "object") {
|
|
151
|
+
if (oldStyles != null) {
|
|
152
|
+
for (const styleName in styles) {
|
|
153
|
+
const value = styles[styleName];
|
|
154
|
+
if (styles.hasOwnProperty(styleName) && oldStyles[styleName] !== value) {
|
|
155
|
+
instance[styleName] = value;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
for (const styleName in styles) {
|
|
160
|
+
if (styles.hasOwnProperty(styleName)) {
|
|
161
|
+
const value = styles[styleName];
|
|
162
|
+
instance[styleName] = value;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function setProperty(instance, type, propKey, propValue, oldPropValue) {
|
|
169
|
+
switch (propKey) {
|
|
170
|
+
case "onChange":
|
|
171
|
+
if (instance instanceof InputRenderable2) {
|
|
172
|
+
initEventListeners(instance, InputRenderableEvents.CHANGE, propValue, oldPropValue);
|
|
173
|
+
} else if (instance instanceof SelectRenderable2) {
|
|
174
|
+
initEventListeners(instance, SelectRenderableEvents.SELECTION_CHANGED, propValue, oldPropValue);
|
|
175
|
+
} else if (instance instanceof TabSelectRenderable2) {
|
|
176
|
+
initEventListeners(instance, TabSelectRenderableEvents.SELECTION_CHANGED, propValue, oldPropValue);
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
case "onInput":
|
|
180
|
+
if (instance instanceof InputRenderable2) {
|
|
181
|
+
initEventListeners(instance, InputRenderableEvents.INPUT, propValue, oldPropValue);
|
|
182
|
+
}
|
|
183
|
+
break;
|
|
184
|
+
case "onSubmit":
|
|
185
|
+
if (instance instanceof InputRenderable2) {
|
|
186
|
+
initEventListeners(instance, InputRenderableEvents.ENTER, propValue, oldPropValue);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
case "onSelect":
|
|
190
|
+
if (instance instanceof SelectRenderable2) {
|
|
191
|
+
initEventListeners(instance, SelectRenderableEvents.ITEM_SELECTED, propValue, oldPropValue);
|
|
192
|
+
} else if (instance instanceof TabSelectRenderable2) {
|
|
193
|
+
initEventListeners(instance, TabSelectRenderableEvents.ITEM_SELECTED, propValue, oldPropValue);
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
196
|
+
case "focused":
|
|
197
|
+
if (!!propValue) {
|
|
198
|
+
instance.focus();
|
|
199
|
+
} else {
|
|
200
|
+
instance.blur();
|
|
201
|
+
}
|
|
202
|
+
break;
|
|
203
|
+
case "style":
|
|
204
|
+
setStyle(instance, propValue, oldPropValue);
|
|
205
|
+
break;
|
|
206
|
+
case "children":
|
|
207
|
+
if (type === "text" && instance instanceof TextRenderable2) {
|
|
208
|
+
handleTextChildren(instance, propValue);
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
default:
|
|
212
|
+
instance[propKey] = propValue;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function setInitialProperties(instance, type, props) {
|
|
216
|
+
for (const propKey in props) {
|
|
217
|
+
if (!props.hasOwnProperty(propKey)) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
const propValue = props[propKey];
|
|
221
|
+
if (propValue == null) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
setProperty(instance, type, propKey, propValue);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function updateProperties(instance, type, oldProps, newProps) {
|
|
228
|
+
for (const propKey in oldProps) {
|
|
229
|
+
const oldProp = oldProps[propKey];
|
|
230
|
+
if (oldProps.hasOwnProperty(propKey) && oldProp != null && !newProps.hasOwnProperty(propKey)) {
|
|
231
|
+
setProperty(instance, type, propKey, null, oldProp);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
for (const propKey in newProps) {
|
|
235
|
+
const newProp = newProps[propKey];
|
|
236
|
+
const oldProp = oldProps[propKey];
|
|
237
|
+
if (newProps.hasOwnProperty(propKey) && newProp !== oldProp && (newProp != null || oldProp != null)) {
|
|
238
|
+
setProperty(instance, type, propKey, newProp, oldProp);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/reconciler/host-config.ts
|
|
244
|
+
var currentUpdatePriority = NoEventPriority;
|
|
245
|
+
var hostConfig = {
|
|
246
|
+
supportsMutation: true,
|
|
247
|
+
supportsPersistence: false,
|
|
248
|
+
supportsHydration: false,
|
|
249
|
+
createInstance(type, props, rootContainerInstance, hostContext) {
|
|
250
|
+
const id = getNextId(type);
|
|
251
|
+
const components = getComponentCatalogue();
|
|
252
|
+
if (!components[type]) {
|
|
253
|
+
throw new Error(`[Reconciler] Unknown component type: ${type}`);
|
|
254
|
+
}
|
|
255
|
+
return new components[type](id, {});
|
|
256
|
+
},
|
|
257
|
+
appendChild(parent, child) {
|
|
258
|
+
parent.add(child);
|
|
259
|
+
},
|
|
260
|
+
removeChild(parent, child) {
|
|
261
|
+
parent.remove(child.id);
|
|
262
|
+
},
|
|
263
|
+
insertBefore(parent, child, beforeChild) {
|
|
264
|
+
parent.insertBefore(child, beforeChild);
|
|
265
|
+
},
|
|
266
|
+
insertInContainerBefore(parent, child, beforeChild) {
|
|
267
|
+
parent.insertBefore(child, beforeChild);
|
|
268
|
+
},
|
|
269
|
+
removeChildFromContainer(parent, child) {
|
|
270
|
+
parent.remove(child.id);
|
|
271
|
+
},
|
|
272
|
+
prepareForCommit(containerInfo) {
|
|
273
|
+
return null;
|
|
274
|
+
},
|
|
275
|
+
resetAfterCommit(containerInfo) {
|
|
276
|
+
containerInfo.needsUpdate();
|
|
277
|
+
},
|
|
278
|
+
getRootHostContext(rootContainerInstance) {
|
|
279
|
+
return {};
|
|
280
|
+
},
|
|
281
|
+
getChildHostContext(parentHostContext, type, rootContainerInstance) {
|
|
282
|
+
return parentHostContext;
|
|
283
|
+
},
|
|
284
|
+
shouldSetTextContent(type, props) {
|
|
285
|
+
if (type === "text") {
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
return false;
|
|
289
|
+
},
|
|
290
|
+
createTextInstance(text, rootContainerInstance, hostContext) {
|
|
291
|
+
const components = getComponentCatalogue();
|
|
292
|
+
return new components["text"](getNextId("text"), {
|
|
293
|
+
content: text
|
|
294
|
+
});
|
|
295
|
+
},
|
|
296
|
+
scheduleTimeout: setTimeout,
|
|
297
|
+
cancelTimeout: clearTimeout,
|
|
298
|
+
noTimeout: -1,
|
|
299
|
+
shouldAttemptEagerTransition() {
|
|
300
|
+
return false;
|
|
301
|
+
},
|
|
302
|
+
finalizeInitialChildren(instance, type, props, rootContainerInstance, hostContext) {
|
|
303
|
+
setInitialProperties(instance, type, props);
|
|
304
|
+
return false;
|
|
305
|
+
},
|
|
306
|
+
commitMount(instance, type, props, internalInstanceHandle) {},
|
|
307
|
+
commitUpdate(instance, type, oldProps, newProps, internalInstanceHandle) {
|
|
308
|
+
updateProperties(instance, type, oldProps, newProps);
|
|
309
|
+
instance.needsUpdate();
|
|
310
|
+
},
|
|
311
|
+
commitTextUpdate(textInstance, oldText, newText) {
|
|
312
|
+
textInstance.content = newText;
|
|
313
|
+
textInstance.needsUpdate();
|
|
314
|
+
},
|
|
315
|
+
appendChildToContainer(container, child) {
|
|
316
|
+
container.add(child);
|
|
317
|
+
},
|
|
318
|
+
appendInitialChild(parent, child) {
|
|
319
|
+
parent.add(child);
|
|
320
|
+
},
|
|
321
|
+
hideInstance(instance) {
|
|
322
|
+
instance.visible = false;
|
|
323
|
+
instance.needsUpdate();
|
|
324
|
+
},
|
|
325
|
+
unhideInstance(instance, props) {
|
|
326
|
+
instance.visible = true;
|
|
327
|
+
instance.needsUpdate();
|
|
328
|
+
},
|
|
329
|
+
hideTextInstance(textInstance) {
|
|
330
|
+
textInstance.visible = false;
|
|
331
|
+
textInstance.needsUpdate();
|
|
332
|
+
},
|
|
333
|
+
unhideTextInstance(textInstance, text) {
|
|
334
|
+
textInstance.visible = true;
|
|
335
|
+
textInstance.needsUpdate();
|
|
336
|
+
},
|
|
337
|
+
clearContainer(container) {
|
|
338
|
+
const children = container.getChildren();
|
|
339
|
+
children.forEach((child) => container.remove(child.id));
|
|
340
|
+
},
|
|
341
|
+
setCurrentUpdatePriority(newPriority) {
|
|
342
|
+
currentUpdatePriority = newPriority;
|
|
343
|
+
},
|
|
344
|
+
getCurrentUpdatePriority: () => currentUpdatePriority,
|
|
345
|
+
resolveUpdatePriority() {
|
|
346
|
+
if (currentUpdatePriority !== NoEventPriority) {
|
|
347
|
+
return currentUpdatePriority;
|
|
348
|
+
}
|
|
349
|
+
return DefaultEventPriority;
|
|
350
|
+
},
|
|
351
|
+
maySuspendCommit() {
|
|
352
|
+
return false;
|
|
353
|
+
},
|
|
354
|
+
NotPendingTransition: null,
|
|
355
|
+
HostTransitionContext: createContext2(null),
|
|
356
|
+
resetFormInstance() {},
|
|
357
|
+
requestPostPaintCallback() {},
|
|
358
|
+
trackSchedulerEvent() {},
|
|
359
|
+
resolveEventType() {
|
|
360
|
+
return null;
|
|
361
|
+
},
|
|
362
|
+
resolveEventTimeStamp() {
|
|
363
|
+
return -1.1;
|
|
364
|
+
},
|
|
365
|
+
preloadInstance() {
|
|
366
|
+
return true;
|
|
367
|
+
},
|
|
368
|
+
startSuspendingCommit() {},
|
|
369
|
+
suspendInstance() {},
|
|
370
|
+
waitForCommitToBeReady() {
|
|
371
|
+
return null;
|
|
372
|
+
},
|
|
373
|
+
detachDeletedInstance(instance) {
|
|
374
|
+
if (!instance.parent) {
|
|
375
|
+
instance.destroy();
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
getPublicInstance(instance) {
|
|
379
|
+
return instance;
|
|
380
|
+
},
|
|
381
|
+
preparePortalMount(containerInfo) {},
|
|
382
|
+
isPrimaryRenderer: true,
|
|
383
|
+
getInstanceFromNode() {
|
|
384
|
+
return null;
|
|
385
|
+
},
|
|
386
|
+
beforeActiveInstanceBlur() {},
|
|
387
|
+
afterActiveInstanceBlur() {},
|
|
388
|
+
prepareScopeUpdate() {},
|
|
389
|
+
getInstanceFromScope() {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
// src/reconciler/reconciler.ts
|
|
395
|
+
var reconciler = ReactReconciler(hostConfig);
|
|
396
|
+
function _render(element, root) {
|
|
397
|
+
const container = reconciler.createContainer(root, ConcurrentRoot, null, false, null, "", console.error, console.error, console.error, console.error, null);
|
|
398
|
+
reconciler.updateContainer(element, container, null, () => {});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// src/reconciler/renderer.ts
|
|
402
|
+
var keyHandler = getKeyHandler();
|
|
403
|
+
async function render(node, rendererConfig = {}) {
|
|
404
|
+
const renderer = await createCliRenderer(rendererConfig);
|
|
405
|
+
_render(React.createElement(AppContext.Provider, { value: { keyHandler, renderer } }, node), renderer.root);
|
|
406
|
+
}
|
|
407
|
+
export {
|
|
408
|
+
useRenderer,
|
|
409
|
+
useOnResize,
|
|
410
|
+
useKeyboard,
|
|
411
|
+
useAppContext,
|
|
412
|
+
render,
|
|
413
|
+
getComponentCatalogue,
|
|
414
|
+
extend,
|
|
415
|
+
componentCatalogue,
|
|
416
|
+
baseComponents,
|
|
417
|
+
AppContext
|
|
418
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Fragment, jsxDEV } from "react/jsx-dev-runtime"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BoxProps, GroupProps, InputProps, SelectProps, TabSelectProps, TextProps } from "./src/types/components"
|
|
2
|
+
import type { ExtendedIntrinsicElements, OpenTUIComponents } from "./src/types/extend"
|
|
3
|
+
|
|
4
|
+
export namespace JSX {
|
|
5
|
+
interface Element extends React.ReactElement<any, any> {}
|
|
6
|
+
|
|
7
|
+
interface ElementClass {
|
|
8
|
+
render: any
|
|
9
|
+
}
|
|
10
|
+
interface ElementAttributesProperty {
|
|
11
|
+
props: {}
|
|
12
|
+
}
|
|
13
|
+
interface ElementChildrenAttribute {
|
|
14
|
+
children: {}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface IntrinsicElements extends ExtendedIntrinsicElements<OpenTUIComponents> {
|
|
18
|
+
box: BoxProps
|
|
19
|
+
group: GroupProps
|
|
20
|
+
input: InputProps
|
|
21
|
+
select: SelectProps
|
|
22
|
+
"tab-select": TabSelectProps
|
|
23
|
+
text: TextProps
|
|
24
|
+
}
|
|
25
|
+
}
|
package/jsx-runtime.d.ts
ADDED
package/jsx-runtime.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Fragment, jsx, jsxs } from "react/jsx-runtime"
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opentui/react",
|
|
3
|
+
"module": "index.js",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"types": "src/index.d.ts",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"version": "0.1.6",
|
|
8
|
+
"description": "React renderer for building terminal user interfaces using OpenTUI core",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/sst/opentui",
|
|
13
|
+
"directory": "packages/react"
|
|
14
|
+
},
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./src/index.d.ts",
|
|
18
|
+
"import": "./index.js",
|
|
19
|
+
"require": "./index.js"
|
|
20
|
+
},
|
|
21
|
+
"./renderer": {
|
|
22
|
+
"types": "./src/reconciler/renderer.d.ts",
|
|
23
|
+
"import": "./src/reconciler/renderer.js",
|
|
24
|
+
"require": "./src/reconciler/renderer.js"
|
|
25
|
+
},
|
|
26
|
+
"./jsx-runtime": {
|
|
27
|
+
"types": "./jsx-runtime.d.ts",
|
|
28
|
+
"import": "./jsx-runtime.js",
|
|
29
|
+
"require": "./jsx-runtime.js"
|
|
30
|
+
},
|
|
31
|
+
"./jsx-dev-runtime": {
|
|
32
|
+
"types": "./jsx-dev-runtime.d.ts",
|
|
33
|
+
"import": "./jsx-dev-runtime.js",
|
|
34
|
+
"require": "./jsx-dev-runtime.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@opentui/core": "0.1.6",
|
|
39
|
+
"react-reconciler": "^0.32.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/bun": "latest",
|
|
43
|
+
"@types/react-reconciler": "^0.32.0",
|
|
44
|
+
"prettier": "3.6.2"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": ">=19.0.0",
|
|
48
|
+
"typescript": "^5"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CliRenderer, KeyHandler } from "@opentui/core";
|
|
2
|
+
interface AppContext {
|
|
3
|
+
keyHandler: KeyHandler | null;
|
|
4
|
+
renderer: CliRenderer | null;
|
|
5
|
+
}
|
|
6
|
+
export declare const AppContext: import("react").Context<AppContext>;
|
|
7
|
+
export declare const useAppContext: () => AppContext;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BoxRenderable, GroupRenderable, InputRenderable, SelectRenderable, TabSelectRenderable, TextRenderable } from "@opentui/core";
|
|
2
|
+
import type { RenderableConstructor } from "../types/extend";
|
|
3
|
+
export declare const baseComponents: {
|
|
4
|
+
box: typeof BoxRenderable;
|
|
5
|
+
text: typeof TextRenderable;
|
|
6
|
+
group: typeof GroupRenderable;
|
|
7
|
+
input: typeof InputRenderable;
|
|
8
|
+
select: typeof SelectRenderable;
|
|
9
|
+
"tab-select": typeof TabSelectRenderable;
|
|
10
|
+
};
|
|
11
|
+
type ComponentCatalogue = Record<string, RenderableConstructor>;
|
|
12
|
+
export declare const componentCatalogue: ComponentCatalogue;
|
|
13
|
+
/**
|
|
14
|
+
* Extend the component catalogue with new renderable components
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* // Extend with an object of components
|
|
19
|
+
* extend({
|
|
20
|
+
* consoleButton: ConsoleButtonRenderable,
|
|
21
|
+
* customBox: CustomBoxRenderable
|
|
22
|
+
* })
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function extend<T extends ComponentCatalogue>(objects: T): void;
|
|
26
|
+
export declare function getComponentCatalogue(): ComponentCatalogue;
|
|
27
|
+
export type { ExtendedComponentProps, ExtendedIntrinsicElements, RenderableConstructor } from "../types/extend";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useRenderer: () => import("@opentui/core").CliRenderer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useOnResize: (callback: (width: number, height: number) => void) => import("@opentui/core").CliRenderer;
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./components";
|
|
2
|
+
export * from "./components/app";
|
|
3
|
+
export * from "./hooks/use-keyboard";
|
|
4
|
+
export * from "./hooks/use-renderer";
|
|
5
|
+
export * from "./hooks/use-resize";
|
|
6
|
+
export * from "./reconciler/renderer";
|
|
7
|
+
export * from "./types/extend";
|
|
8
|
+
export * from "./types/components";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { HostConfig } from "react-reconciler";
|
|
2
|
+
import type { Container, HostContext, Instance, Props, PublicInstance, TextInstance, Type } from "../types/host";
|
|
3
|
+
export declare const hostConfig: HostConfig<Type, Props, Container, Instance, TextInstance, unknown, // SuspenseInstance
|
|
4
|
+
unknown, // HydratableInstance
|
|
5
|
+
unknown, // FormInstance
|
|
6
|
+
PublicInstance, HostContext, unknown, // ChildSet
|
|
7
|
+
unknown, // TimeoutHandle
|
|
8
|
+
unknown, // NoTimeout
|
|
9
|
+
unknown>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RootRenderable } from "@opentui/core";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import ReactReconciler from "react-reconciler";
|
|
4
|
+
export declare const reconciler: ReactReconciler.Reconciler<RootRenderable, import("@opentui/core").Renderable, import("@opentui/core").TextRenderable, unknown, unknown, import("@opentui/core").Renderable>;
|
|
5
|
+
export declare function _render(element: React.ReactNode, root: RootRenderable): void;
|