@opentui/solid 0.0.0-20250908-4906ddad → 0.0.0-20250912-12c969f4

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.
@@ -0,0 +1,61 @@
1
+ export function useTimeline(timeline: any, initialValue: any, targetValue: any, options: any, startTime?: number): import("solid-js").Accessor<any>;
2
+ export function useTerminalDimensions(): import("solid-js").Accessor<{
3
+ width: any;
4
+ height: any;
5
+ }>;
6
+ export function useSelectionHandler(callback: any): void;
7
+ export function useRenderer(): any;
8
+ export function useKeyboard(callback: any): void;
9
+ export function useKeyHandler(callback: any): void;
10
+ export var use: <A, T>(fn: (element: any, arg: A) => T, element: any, arg: A) => T;
11
+ export var spread: <T>(node: any, accessor: (() => T) | T, skipChildren?: boolean) => void;
12
+ export var setProp: <T>(node: any, name: string, value: T, prev?: T | undefined) => T;
13
+ export function render(node: any, renderConfig?: {}): Promise<void>;
14
+ export function onResize(callback: any): void;
15
+ export var mergeProps: (...sources: unknown[]) => unknown;
16
+ export var memo: <T>(fn: () => T, equal: boolean) => () => T;
17
+ export var insertNode: (parent: any, node: any, anchor?: any) => void;
18
+ export var insert: <T>(parent: any, accessor: T | (() => T), marker?: any | null, initial?: any) => any;
19
+ export function getComponentCatalogue(): {
20
+ box: typeof BoxRenderable;
21
+ text: typeof TextRenderable;
22
+ input: typeof InputRenderable;
23
+ select: typeof SelectRenderable;
24
+ ascii_font: typeof ASCIIFontRenderable;
25
+ tab_select: typeof TabSelectRenderable;
26
+ scrollbox: typeof ScrollBoxRenderable;
27
+ span: typeof SpanRenderable;
28
+ };
29
+ export function extend(objects: any): void;
30
+ export var effect: <T>(fn: (prev?: T) => T, init?: T) => void;
31
+ export var createTextNode: (value: string) => any;
32
+ export var createElement: (tag: string) => any;
33
+ export function createComponentTimeline(options?: {}): Timeline;
34
+ export var createComponent: <T>(Comp: (props: T) => any, props: T) => any;
35
+ export namespace componentCatalogue {
36
+ export { BoxRenderable as box };
37
+ export { TextRenderable as text };
38
+ export { InputRenderable as input };
39
+ export { SelectRenderable as select };
40
+ export { ASCIIFontRenderable as ascii_font };
41
+ export { TabSelectRenderable as tab_select };
42
+ export { ScrollBoxRenderable as scrollbox };
43
+ export { SpanRenderable as span };
44
+ }
45
+ export namespace baseComponents { }
46
+ export var _render: (code: () => any, node: any) => () => void;
47
+ export var RendererContext: import("solid-js").Context<any>;
48
+ import { BoxRenderable } from "@opentui/core";
49
+ import { TextRenderable } from "@opentui/core";
50
+ import { InputRenderable } from "@opentui/core";
51
+ import { SelectRenderable } from "@opentui/core";
52
+ import { ASCIIFontRenderable } from "@opentui/core";
53
+ import { TabSelectRenderable } from "@opentui/core";
54
+ import { ScrollBoxRenderable } from "@opentui/core";
55
+ declare class SpanRenderable extends TextNodeRenderable {
56
+ constructor(_ctx: any, options: any);
57
+ _ctx: any;
58
+ }
59
+ import { Timeline } from "@opentui/core";
60
+ import { TextNodeRenderable } from "@opentui/core";
61
+ export {};
package/index.js CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  ScrollBoxRenderable,
11
11
  SelectRenderable,
12
12
  TabSelectRenderable,
13
+ TextNodeRenderable,
13
14
  TextRenderable
14
15
  } from "@opentui/core";
15
16
 
@@ -95,6 +96,13 @@ var useTimeline = (timeline, initialValue, targetValue, options, startTime = 0)
95
96
  };
96
97
 
97
98
  // src/elements/index.ts
99
+ class SpanRenderable extends TextNodeRenderable {
100
+ _ctx;
101
+ constructor(_ctx, options) {
102
+ super(options);
103
+ this._ctx = _ctx;
104
+ }
105
+ }
98
106
  var baseComponents = {
99
107
  box: BoxRenderable,
100
108
  text: TextRenderable,
@@ -102,7 +110,8 @@ var baseComponents = {
102
110
  select: SelectRenderable,
103
111
  ascii_font: ASCIIFontRenderable,
104
112
  tab_select: TabSelectRenderable,
105
- scrollbox: ScrollBoxRenderable
113
+ scrollbox: ScrollBoxRenderable,
114
+ span: SpanRenderable
106
115
  };
107
116
  var componentCatalogue = { ...baseComponents };
108
117
  function extend(objects) {
@@ -114,22 +123,24 @@ function getComponentCatalogue() {
114
123
 
115
124
  // src/reconciler.ts
116
125
  import {
126
+ BaseRenderable,
127
+ createTextAttributes,
117
128
  InputRenderable as InputRenderable2,
118
129
  InputRenderableEvents,
119
- Renderable as Renderable2,
130
+ isTextNodeRenderable,
131
+ parseColor,
132
+ Renderable,
133
+ RootTextNodeRenderable,
120
134
  SelectRenderable as SelectRenderable2,
121
135
  SelectRenderableEvents,
122
- StyledText,
123
136
  TabSelectRenderable as TabSelectRenderable2,
124
137
  TabSelectRenderableEvents,
125
- TextRenderable as TextRenderable3
138
+ TextNodeRenderable as TextNodeRenderable2,
139
+ TextRenderable as TextRenderable2
126
140
  } from "@opentui/core";
127
141
  import { useContext as useContext2 } from "solid-js";
128
142
  import { createRenderer } from "solid-js/universal";
129
143
 
130
- // src/elements/text-node.ts
131
- import { Renderable, TextRenderable as TextRenderable2 } from "@opentui/core";
132
-
133
144
  // src/utils/id-counter.ts
134
145
  var idCounter = new Map;
135
146
  function getNextId(elementType) {
@@ -148,216 +159,76 @@ var log = (...args) => {
148
159
  }
149
160
  };
150
161
 
151
- // src/elements/text-node.ts
152
- var GHOST_NODE_TAG = "text-ghost";
153
- var ChunkToTextNodeMap = new WeakMap;
154
- var isTextChunk = (node) => {
155
- return typeof node === "object" && "__isChunk" in node;
156
- };
157
-
158
- class TextNode {
159
- id;
160
- chunk;
161
- parent;
162
- textParent;
163
- constructor(chunk) {
164
- this.id = getNextId("text-node");
165
- this.chunk = chunk;
166
- ChunkToTextNodeMap.set(chunk, this);
167
- }
168
- replaceText(newChunk) {
169
- const textParent = this.textParent;
170
- if (!textParent) {
171
- log("No parent found for text node:", this.id);
172
- return;
173
- }
174
- textParent.content = textParent.content.replace(newChunk, this.chunk);
175
- this.chunk = newChunk;
176
- ChunkToTextNodeMap.set(newChunk, this);
177
- }
178
- static getTextNodeFromChunk(chunk) {
179
- return ChunkToTextNodeMap.get(chunk);
180
- }
181
- insert(parent, anchor) {
182
- if (!(parent instanceof Renderable)) {
183
- log("Attaching text node to parent text node, impossible");
184
- return;
185
- }
186
- let textParent;
187
- if (!(parent instanceof TextRenderable2)) {
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);
200
- }
201
- const anchorIndex = anchor ? styledText.chunks.indexOf(anchor.chunk) : -1;
202
- if (anchorIndex === -1) {
203
- log("anchor not found");
204
- styledText = styledText.insert(this.chunk);
205
- } else {
206
- styledText = styledText.insert(this.chunk, anchorIndex);
207
- }
208
- } else {
209
- const firstChunk = textParent.content.chunks[0];
210
- if (firstChunk && !ChunkToTextNodeMap.has(firstChunk)) {
211
- styledText = styledText.replace(this.chunk, firstChunk);
212
- } else {
213
- styledText = styledText.insert(this.chunk);
214
- }
215
- }
216
- textParent.content = styledText;
217
- textParent.visible = textParent.textLength !== 0;
218
- this.parent = parent;
219
- }
220
- remove(parent) {
221
- if (!(parent instanceof Renderable)) {
222
- ChunkToTextNodeMap.delete(this.chunk);
223
- return;
224
- }
225
- if (parent === this.textParent && parent instanceof TextRenderable2) {
226
- ChunkToTextNodeMap.delete(this.chunk);
227
- parent.content = parent.content.remove(this.chunk);
228
- return;
229
- }
230
- if (this.textParent) {
231
- ChunkToTextNodeMap.delete(this.chunk);
232
- let styledText = this.textParent.content;
233
- styledText = styledText.remove(this.chunk);
234
- if (styledText.chunks.length > 0) {
235
- this.textParent.content = styledText;
236
- } else {
237
- this.parent?.remove(this.textParent.id);
238
- process.nextTick(() => {
239
- if (!this.textParent)
240
- return;
241
- if (!this.textParent.parent) {
242
- this.textParent.destroyRecursively();
243
- }
244
- });
245
- }
246
- }
247
- }
248
- getOrCreateTextGhostNode(parent, anchor) {
249
- if (anchor instanceof TextNode && anchor.textParent) {
250
- return anchor.textParent;
251
- }
252
- const children = parent.getChildren();
253
- if (anchor instanceof Renderable) {
254
- const anchorIndex = children.findIndex((el) => el.id === anchor.id);
255
- const beforeAnchor = children[anchorIndex - 1];
256
- if (beforeAnchor instanceof GhostTextRenderable) {
257
- return beforeAnchor;
258
- }
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
- });
267
- insertNode(parent, ghostNode, anchor);
268
- return ghostNode;
269
- }
270
- }
271
-
272
- class GhostTextRenderable extends TextRenderable2 {
273
- constructor(ctx, options) {
274
- super(ctx, options);
275
- }
276
- static isGhostNode(node) {
277
- return node instanceof GhostTextRenderable;
162
+ // src/reconciler.ts
163
+ class TextNode extends TextNodeRenderable2 {
164
+ static fromString(text, options = {}) {
165
+ const node = new TextNode(options);
166
+ node.add(text);
167
+ return node;
278
168
  }
279
169
  }
280
-
281
- // src/reconciler.ts
282
170
  var logId = (node) => {
283
171
  if (!node)
284
172
  return;
285
- if (isTextChunk(node)) {
286
- return node.plainText;
287
- }
288
173
  return node.id;
289
174
  };
175
+ var getNodeChildren = (node) => {
176
+ let children;
177
+ if (node instanceof TextRenderable2) {
178
+ children = node.getTextChildren();
179
+ } else {
180
+ children = node.getChildren();
181
+ }
182
+ return children;
183
+ };
290
184
  function _insertNode(parent, node, anchor) {
291
185
  log("Inserting node:", logId(node), "into parent:", logId(parent), "with anchor:", logId(anchor), node instanceof TextNode);
292
- if (node instanceof StyledText) {
293
- log("Inserting styled text:", node.toString());
294
- for (const chunk of node.chunks) {
295
- _insertNode(parent, _createTextNode(chunk), anchor);
186
+ if (isTextNodeRenderable(node)) {
187
+ if (!(parent instanceof TextRenderable2) && !isTextNodeRenderable(parent)) {
188
+ log(`Text must have a <text> as a parent: ${parent.id} above ${node.id}`);
296
189
  return;
297
190
  }
298
191
  }
299
- if (isTextChunk(node)) {
300
- _insertNode(parent, _createTextNode(node), anchor);
192
+ if (!(parent instanceof BaseRenderable)) {
193
+ log("[INSERT]", "Tried to mount a non base renderable");
301
194
  return;
302
195
  }
303
- if (node instanceof TextNode) {
304
- return node.insert(parent, anchor);
305
- }
306
- if (!(parent instanceof Renderable2)) {
196
+ if (!anchor) {
197
+ parent.add(node);
307
198
  return;
308
199
  }
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 {
322
- parent.add(node);
200
+ const children = getNodeChildren(parent);
201
+ const anchorIndex = children.findIndex((el) => el.id === anchor.id);
202
+ if (anchorIndex === -1) {
203
+ log("[INSERT]", "Could not find anchor", logId(parent), logId(anchor), "[children]", ...children.map((c) => c.id));
323
204
  }
205
+ parent.add(node, anchorIndex);
324
206
  }
325
207
  function _removeNode(parent, node) {
326
208
  log("Removing node:", logId(node), "from parent:", logId(parent));
327
- if (isTextChunk(node)) {
328
- const textNode = TextNode.getTextNodeFromChunk(node);
329
- if (textNode) {
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);
209
+ parent.remove(node.id);
210
+ process.nextTick(() => {
211
+ if (node instanceof Renderable && !node.parent) {
212
+ node.destroyRecursively();
213
+ return;
338
214
  }
339
- }
340
- if (node instanceof TextNode) {
341
- return node.remove(parent);
342
- }
343
- if (parent instanceof Renderable2 && node instanceof Renderable2) {
344
- parent.remove(node.id);
345
- process.nextTick(() => {
346
- if (!node.parent) {
347
- node.destroyRecursively();
348
- }
349
- });
350
- }
215
+ });
351
216
  }
352
217
  function _createTextNode(value) {
353
218
  log("Creating text node:", value);
354
- const chunk = value && isTextChunk(value) ? value : {
355
- __isChunk: true,
356
- text: new TextEncoder().encode(`${value}`),
357
- plainText: `${value}`
358
- };
359
- const textNode = new TextNode(chunk);
360
- return textNode;
219
+ const id = getNextId("text-node");
220
+ if (typeof value === "number") {
221
+ value = value.toString();
222
+ }
223
+ return TextNode.fromString(value, { id });
224
+ }
225
+ function _getParentNode(childNode) {
226
+ log("Getting parent of node:", logId(childNode));
227
+ let parent = childNode.parent ?? undefined;
228
+ if (parent instanceof RootTextNodeRenderable) {
229
+ parent = parent.textParent ?? undefined;
230
+ }
231
+ return parent;
361
232
  }
362
233
  var {
363
234
  render: _render,
@@ -391,24 +262,11 @@ var {
391
262
  createTextNode: _createTextNode,
392
263
  replaceText(textNode, value) {
393
264
  log("Replacing text:", value, "in node:", logId(textNode));
394
- if (textNode instanceof Renderable2)
265
+ if (!(textNode instanceof TextNode))
395
266
  return;
396
- if (isTextChunk(textNode)) {
397
- console.warn("Cannot replace text on text chunk", logId(textNode));
398
- return;
399
- }
400
- const newChunk = {
401
- __isChunk: true,
402
- text: new TextEncoder().encode(value),
403
- plainText: value
404
- };
405
- textNode.replaceText(newChunk);
267
+ textNode.replace(value, 0);
406
268
  },
407
269
  setProperty(node, name, value, prev) {
408
- if (node instanceof TextNode || isTextChunk(node)) {
409
- console.warn("Cannot set property on text node:", logId(node));
410
- return;
411
- }
412
270
  if (name.startsWith("on:")) {
413
271
  const eventName = name.slice(3);
414
272
  if (value) {
@@ -419,8 +277,19 @@ var {
419
277
  }
420
278
  return;
421
279
  }
280
+ if (isTextNodeRenderable(node)) {
281
+ if (name !== "style") {
282
+ return;
283
+ }
284
+ node.attributes |= createTextAttributes(value);
285
+ node.fg = value.fg ? parseColor(value.fg) : node.fg;
286
+ node.bg = value.bg ? parseColor(value.bg) : node.bg;
287
+ return;
288
+ }
422
289
  switch (name) {
423
290
  case "focused":
291
+ if (!(node instanceof Renderable))
292
+ return;
424
293
  if (value) {
425
294
  node.focus();
426
295
  } else {
@@ -503,37 +372,10 @@ var {
503
372
  },
504
373
  insertNode: _insertNode,
505
374
  removeNode: _removeNode,
506
- getParentNode(childNode) {
507
- log("Getting parent of node:", logId(childNode));
508
- let node = childNode;
509
- if (isTextChunk(childNode)) {
510
- const parentTextNode = TextNode.getTextNodeFromChunk(childNode);
511
- if (!parentTextNode)
512
- return;
513
- node = parentTextNode;
514
- }
515
- const parent = node.parent;
516
- if (!parent) {
517
- log("No parent found for node:", logId(node));
518
- return;
519
- }
520
- log("Parent found:", logId(parent), "for node:", logId(node));
521
- return parent;
522
- },
375
+ getParentNode: _getParentNode,
523
376
  getFirstChild(node) {
524
377
  log("Getting first child of node:", logId(node));
525
- if (node instanceof TextRenderable3) {
526
- const chunk = node.content.chunks[0];
527
- if (chunk) {
528
- return TextNode.getTextNodeFromChunk(chunk);
529
- } else {
530
- return;
531
- }
532
- }
533
- if (node instanceof TextNode || isTextChunk(node)) {
534
- return;
535
- }
536
- const firstChild = node.getChildren()[0];
378
+ const firstChild = getNodeChildren(node)[0];
537
379
  if (!firstChild) {
538
380
  log("No first child found for node:", logId(node));
539
381
  return;
@@ -543,34 +385,12 @@ var {
543
385
  },
544
386
  getNextSibling(node) {
545
387
  log("Getting next sibling of node:", logId(node));
546
- if (isTextChunk(node)) {
547
- console.warn("Cannot get next sibling of text chunk");
548
- return;
549
- }
550
- const parent = node.parent;
388
+ const parent = _getParentNode(node);
551
389
  if (!parent) {
552
390
  log("No parent found for node:", logId(node));
553
391
  return;
554
392
  }
555
- if (node instanceof TextNode) {
556
- if (parent instanceof TextRenderable3) {
557
- const siblings2 = parent.content.chunks;
558
- const index2 = siblings2.indexOf(node.chunk);
559
- if (index2 === -1 || index2 === siblings2.length - 1) {
560
- log("No next sibling found for node:", logId(node));
561
- return;
562
- }
563
- const nextSibling2 = siblings2[index2 + 1];
564
- if (!nextSibling2) {
565
- log("Next sibling is null for node:", logId(node));
566
- return;
567
- }
568
- return TextNode.getTextNodeFromChunk(nextSibling2);
569
- }
570
- console.warn("Text parent is not a text node:", logId(node));
571
- return;
572
- }
573
- const siblings = parent.getChildren();
393
+ const siblings = getNodeChildren(node);
574
394
  const index = siblings.indexOf(node);
575
395
  if (index === -1 || index === siblings.length - 1) {
576
396
  log("No next sibling found for node:", logId(node));
package/jsx-runtime.d.ts CHANGED
@@ -5,24 +5,29 @@ import type {
5
5
  ExtendedIntrinsicElements,
6
6
  InputProps,
7
7
  OpenTUIComponents,
8
+ ScrollBoxProps,
8
9
  SelectProps,
10
+ SpanProps,
9
11
  TabSelectProps,
10
12
  TextProps,
11
13
  } from "./src/types/elements"
14
+ import type { DomNode } from "./dist"
12
15
 
13
16
  declare namespace JSX {
14
17
  // Replace Node with Renderable
15
- type Element = Renderable | ArrayElement | (string & {}) | number | boolean | null | undefined
18
+ type Element = DomNode | ArrayElement | string | number | boolean | null | undefined
16
19
 
17
- interface ArrayElement extends Array<Element> {}
20
+ type ArrayElement = Array<Element>
18
21
 
19
22
  interface IntrinsicElements extends ExtendedIntrinsicElements<OpenTUIComponents> {
20
23
  box: BoxProps
21
24
  text: TextProps
25
+ span: SpanProps
22
26
  input: InputProps
23
27
  select: SelectProps
24
28
  ascii_font: AsciiFontProps
25
29
  tab_select: TabSelectProps
30
+ scrollbox: ScrollBoxProps
26
31
  }
27
32
 
28
33
  interface ElementChildrenAttribute {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "type": "module",
7
- "version": "0.0.0-20250908-4906ddad",
7
+ "version": "0.0.0-20250912-12c969f4",
8
8
  "description": "SolidJS renderer for OpenTUI",
9
9
  "license": "MIT",
10
10
  "repository": {
@@ -25,7 +25,7 @@
25
25
  "./jsx-dev-runtime": "./jsx-runtime.d.ts"
26
26
  },
27
27
  "dependencies": {
28
- "@opentui/core": "0.0.0-20250908-4906ddad",
28
+ "@opentui/core": "0.0.0-20250912-12c969f4",
29
29
  "babel-plugin-module-resolver": "5.0.2",
30
30
  "@babel/core": "7.28.0",
31
31
  "@babel/preset-typescript": "7.27.1",
@@ -14,6 +14,12 @@ const solidTransformPlugin: BunPlugin = {
14
14
  const code = await file.text()
15
15
  return { contents: code, loader: "js" }
16
16
  })
17
+ build.onLoad({ filter: /\/node_modules\/solid-js\/store\/dist\/server\.js$/ }, async (args) => {
18
+ const path = args.path.replace("server.js", "store.js")
19
+ const file = Bun.file(path)
20
+ const code = await file.text()
21
+ return { contents: code, loader: "js" }
22
+ })
17
23
  build.onLoad({ filter: /\.(js|ts)x$/ }, async (args) => {
18
24
  const file = Bun.file(args.path)
19
25
  const code = await file.text()
@@ -1,6 +1,10 @@
1
- import { ASCIIFontRenderable, BoxRenderable, InputRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextRenderable } from "@opentui/core";
1
+ import { ASCIIFontRenderable, BoxRenderable, InputRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextNodeRenderable, TextRenderable, type RenderContext, type TextNodeOptions } from "@opentui/core";
2
2
  import type { RenderableConstructor } from "../types/elements";
3
3
  export * from "./hooks";
4
+ declare class SpanRenderable extends TextNodeRenderable {
5
+ private readonly _ctx;
6
+ constructor(_ctx: RenderContext, options: TextNodeOptions);
7
+ }
4
8
  export declare const baseComponents: {
5
9
  box: typeof BoxRenderable;
6
10
  text: typeof TextRenderable;
@@ -9,6 +13,7 @@ export declare const baseComponents: {
9
13
  ascii_font: typeof ASCIIFontRenderable;
10
14
  tab_select: typeof TabSelectRenderable;
11
15
  scrollbox: typeof ScrollBoxRenderable;
16
+ span: typeof SpanRenderable;
12
17
  };
13
18
  type ComponentCatalogue = Record<string, RenderableConstructor>;
14
19
  export declare const componentCatalogue: ComponentCatalogue;
@@ -1,4 +1,3 @@
1
- import { Renderable, type TextChunk } from "@opentui/core";
2
- import { TextNode } from "./elements/text-node";
3
- export type DomNode = Renderable | TextNode | TextChunk;
4
- export declare const _render: (code: () => DomNode, node: DomNode) => () => void, effect: <T>(fn: (prev?: T) => T, init?: T) => void, memo: <T>(fn: () => T, equal: boolean) => () => T, createComponent: <T>(Comp: (props: T) => DomNode, props: T) => DomNode, createElement: (tag: string) => DomNode, createTextNode: (value: string) => DomNode, insertNode: (parent: DomNode, node: DomNode, anchor?: DomNode | undefined) => void, insert: <T>(parent: any, accessor: T | (() => T), marker?: any | null, initial?: any) => DomNode, spread: <T>(node: any, accessor: (() => T) | T, skipChildren?: boolean) => void, setProp: <T>(node: DomNode, name: string, value: T, prev?: T | undefined) => T, mergeProps: (...sources: unknown[]) => unknown, use: <A, T>(fn: (element: DomNode, arg: A) => T, element: DomNode, arg: A) => T;
1
+ import { BaseRenderable } from "@opentui/core";
2
+ export type DomNode = BaseRenderable;
3
+ export declare const _render: (code: () => BaseRenderable, node: BaseRenderable) => () => void, effect: <T>(fn: (prev?: T) => T, init?: T) => void, memo: <T>(fn: () => T, equal: boolean) => () => T, createComponent: <T>(Comp: (props: T) => BaseRenderable, props: T) => BaseRenderable, createElement: (tag: string) => BaseRenderable, createTextNode: (value: string) => BaseRenderable, insertNode: (parent: BaseRenderable, node: BaseRenderable, anchor?: BaseRenderable | undefined) => void, insert: <T>(parent: any, accessor: T | (() => T), marker?: any | null, initial?: any) => BaseRenderable, spread: <T>(node: any, accessor: (() => T) | T, skipChildren?: boolean) => void, setProp: <T>(node: BaseRenderable, name: string, value: T, prev?: T | undefined) => T, mergeProps: (...sources: unknown[]) => unknown, use: <A, T>(fn: (element: BaseRenderable, arg: A) => T, element: BaseRenderable, arg: A) => T;
@@ -1,5 +1,6 @@
1
- import type { ASCIIFontOptions, ASCIIFontRenderable, BoxOptions, BoxRenderable, InputRenderable, InputRenderableOptions, Renderable, RenderableOptions, RenderContext, ScrollBoxOptions, ScrollBoxRenderable, SelectOption, SelectRenderable, SelectRenderableOptions, StyledText, TabSelectOption, TabSelectRenderable, TabSelectRenderableOptions, TextChunk, TextOptions, TextRenderable } from "@opentui/core";
2
- import type { JSX, Ref } from "solid-js";
1
+ import type { ASCIIFontOptions, ASCIIFontRenderable, BaseRenderable, BoxOptions, BoxRenderable, InputRenderable, InputRenderableOptions, RenderableOptions, RenderContext, ScrollBoxOptions, ScrollBoxRenderable, SelectOption, SelectRenderable, SelectRenderableOptions, TabSelectOption, TabSelectRenderable, TabSelectRenderableOptions, TextNodeRenderable, TextOptions, TextRenderable } from "@opentui/core";
2
+ import type { Ref } from "solid-js";
3
+ import type { JSX } from "../../jsx-runtime";
3
4
  /** Properties that should not be included in the style prop */
4
5
  export type NonStyledProps = "id" | "buffered" | "live" | "enableLayout" | "selectable" | "renderAfter" | "renderBefore" | `on${string}`;
5
6
  /** Solid-specific props for all components */
@@ -7,7 +8,7 @@ export type ElementProps<TRenderable = unknown> = {
7
8
  ref?: Ref<TRenderable>;
8
9
  };
9
10
  /** Base type for any renderable constructor */
10
- export type RenderableConstructor<TRenderable extends Renderable = Renderable> = new (ctx: RenderContext, options: any) => TRenderable;
11
+ export type RenderableConstructor<TRenderable extends BaseRenderable = BaseRenderable> = new (ctx: RenderContext, options: any) => TRenderable;
11
12
  /** Extract the options type from a renderable constructor */
12
13
  type ExtractRenderableOptions<TConstructor> = TConstructor extends new (ctx: RenderContext, options: infer TOptions) => any ? TOptions : never;
13
14
  /** Extract the renderable type from a constructor */
@@ -19,13 +20,16 @@ type ContainerProps<TOptions> = TOptions & {
19
20
  children?: JSX.Element;
20
21
  };
21
22
  /** Smart component props that automatically determine excluded properties */
22
- type ComponentProps<TOptions extends RenderableOptions<TRenderable>, TRenderable extends Renderable> = TOptions & {
23
+ type ComponentProps<TOptions extends RenderableOptions<TRenderable>, TRenderable extends BaseRenderable> = TOptions & {
23
24
  style?: Partial<Omit<TOptions, GetNonStyledProperties<RenderableConstructor<TRenderable>>>>;
24
25
  } & ElementProps<TRenderable>;
25
26
  /** Valid text content types for Text component children */
26
- type TextChildren = (string & {}) | number | boolean | null | undefined;
27
+ type TextChildren = string | number | boolean | null | undefined | JSX.Element;
27
28
  export type TextProps = ComponentProps<TextOptions, TextRenderable> & {
28
- children?: TextChildren | StyledText | TextChunk | Array<TextChildren | StyledText | TextChunk>;
29
+ children?: TextChildren | Array<TextChildren>;
30
+ };
31
+ export type SpanProps = ComponentProps<{}, TextNodeRenderable> & {
32
+ children?: TextChildren | Array<TextChildren>;
29
33
  };
30
34
  export type BoxProps = ComponentProps<ContainerProps<BoxOptions>, BoxRenderable>;
31
35
  export type InputProps = ComponentProps<InputRenderableOptions, InputRenderable> & {
@@ -47,6 +51,8 @@ export type TabSelectProps = ComponentProps<TabSelectRenderableOptions, TabSelec
47
51
  };
48
52
  export type ScrollBoxProps = ComponentProps<ContainerProps<ScrollBoxOptions>, ScrollBoxRenderable> & {
49
53
  focused?: boolean;
54
+ stickyScroll?: boolean;
55
+ stickyStart?: "bottom" | "top" | "left" | "right";
50
56
  };
51
57
  /** Convert renderable constructor to component props with proper style exclusions */
52
58
  export type ExtendedComponentProps<TConstructor extends RenderableConstructor, TOptions = ExtractRenderableOptions<TConstructor>> = TOptions & {
@@ -1,48 +0,0 @@
1
- import { Renderable, TextRenderable, type RenderContext, type TextChunk, type TextOptions } from "@opentui/core";
2
- import { type DomNode } from "../reconciler";
3
- export declare const isTextChunk: (node: any) => node is TextChunk;
4
- /**
5
- * Represents a text node in the SolidJS reconciler.
6
- */
7
- export declare class TextNode {
8
- id: string;
9
- chunk: TextChunk;
10
- parent?: Renderable;
11
- textParent?: TextRenderable | GhostTextRenderable;
12
- constructor(chunk: TextChunk);
13
- /**
14
- * Replaces the current text chunk with a new one.
15
- * @param newChunk The new text chunk to replace with.
16
- */
17
- replaceText(newChunk: TextChunk): void;
18
- /**
19
- * Retrieves the TextNode associated with a given TextChunk.
20
- * @param chunk The text chunk to look up.
21
- * @returns The associated TextNode or undefined if not found.
22
- */
23
- static getTextNodeFromChunk(chunk: TextChunk): TextNode | undefined;
24
- /**
25
- * Inserts this text node into the DOM structure.
26
- * @param parent The parent DOM node.
27
- * @param anchor The anchor node for positioning.
28
- */
29
- insert(parent: DomNode, anchor?: DomNode): void;
30
- /**
31
- * Removes this text node from the DOM structure.
32
- * @param parent The parent DOM node.
33
- */
34
- remove(parent: DomNode): void;
35
- /**
36
- * Gets or creates a ghost text node for rendering text content.
37
- * @param parent The parent renderable.
38
- * @param anchor The anchor node for positioning.
39
- * @returns The text renderable ghost node.
40
- * @private
41
- */
42
- private getOrCreateTextGhostNode;
43
- }
44
- declare class GhostTextRenderable extends TextRenderable {
45
- constructor(ctx: RenderContext, options: TextOptions);
46
- static isGhostNode(node: DomNode): node is GhostTextRenderable;
47
- }
48
- export {};