@opentui/react 0.1.52 → 0.1.54

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 CHANGED
@@ -49,23 +49,68 @@ For optimal TypeScript support, configure your `tsconfig.json`:
49
49
  }
50
50
  ```
51
51
 
52
+ ## Table of Contents
53
+
54
+ - [Core Concepts](#core-concepts)
55
+ - [Components](#components)
56
+ - [Styling](#styling)
57
+ - [API Reference](#api-reference)
58
+ - [createRoot(renderer)](#createrootrenderer)
59
+ - [render(element, config?)](#renderelement-config-deprecated)
60
+ - [Hooks](#hooks)
61
+ - [useRenderer()](#userenderer)
62
+ - [useKeyboard(handler, options?)](#usekeyboardhandler-options)
63
+ - [useOnResize(callback)](#useonresizecallback)
64
+ - [useTerminalDimensions()](#useterminaldimensions)
65
+ - [useTimeline(options?)](#usetimelineoptions)
66
+ - [Components](#components-1)
67
+ - [Layout & Display Components](#layout--display-components)
68
+ - [Text Component](#text-component)
69
+ - [Box Component](#box-component)
70
+ - [Scrollbox Component](#scrollbox-component)
71
+ - [ASCII Font Component](#ascii-font-component)
72
+ - [Input Components](#input-components)
73
+ - [Input Component](#input-component)
74
+ - [Textarea Component](#textarea-component)
75
+ - [Select Component](#select-component)
76
+ - [Code & Diff Components](#code--diff-components)
77
+ - [Code Component](#code-component)
78
+ - [Line Number Component](#line-number-component)
79
+ - [Diff Component](#diff-component)
80
+ - [Examples](#examples)
81
+ - [Login Form](#login-form)
82
+ - [Counter with Timer](#counter-with-timer)
83
+ - [System Monitor Animation](#system-monitor-animation)
84
+ - [Styled Text Showcase](#styled-text-showcase)
85
+ - [Component Extension](#component-extension)
86
+
52
87
  ## Core Concepts
53
88
 
54
89
  ### Components
55
90
 
56
91
  OpenTUI React provides several built-in components that map to OpenTUI core renderables:
57
92
 
93
+ **Layout & Display:**
94
+
58
95
  - **`<text>`** - Display text with styling
59
96
  - **`<box>`** - Container with borders and layout
97
+ - **`<scrollbox>`** - A scrollable box
98
+ - **`<ascii-font>`** - Display ASCII art text with different font styles
99
+
100
+ **Input Components:**
101
+
60
102
  - **`<input>`** - Text input field
61
103
  - **`<textarea>`** - Multi-line text input field
62
- - **`<code>`** - Code block with syntax highlighting
63
104
  - **`<select>`** - Selection dropdown
64
- - **`<scrollbox>`** - A scrollable box
65
105
  - **`<tab-select>`** - Tab-based selection
66
- - **`<ascii-font>`** - Display ASCII art text with different font styles
67
106
 
68
- Helpers:
107
+ **Code & Diff Components:**
108
+
109
+ - **`<code>`** - Code block with syntax highlighting
110
+ - **`<line-number>`** - Code display with line numbers, diff highlights, and diagnostics
111
+ - **`<diff>`** - Unified or split diff viewer with syntax highlighting
112
+
113
+ **Helpers:**
69
114
 
70
115
  - **`<span>`, `<strong>`, `<em>`, `<u>`, `<b>`, `<i>`, `<br>`** - Text modifiers (_must be used inside of the text component_)
71
116
 
@@ -135,7 +180,7 @@ function App() {
135
180
  }
136
181
  ```
137
182
 
138
- #### `useKeyboard(handler)`
183
+ #### `useKeyboard(handler, options?)`
139
184
 
140
185
  Handle keyboard events.
141
186
 
@@ -153,6 +198,46 @@ function App() {
153
198
  }
154
199
  ```
155
200
 
201
+ **Parameters:**
202
+
203
+ - `handler`: Callback function that receives a `KeyEvent` object
204
+ - `options?`: Optional configuration object:
205
+ - `release?`: Boolean to include key release events (default: `false`)
206
+
207
+ By default, only receives press events (including key repeats with `repeated: true`). Set `options.release` to `true` to also receive release events.
208
+
209
+ **Example with release events:**
210
+
211
+ ```tsx
212
+ import { useKeyboard } from "@opentui/react"
213
+ import { useState } from "react"
214
+
215
+ function App() {
216
+ const [pressedKeys, setPressedKeys] = useState<Set<string>>(new Set())
217
+
218
+ useKeyboard(
219
+ (event) => {
220
+ setPressedKeys((keys) => {
221
+ const newKeys = new Set(keys)
222
+ if (event.eventType === "release") {
223
+ newKeys.delete(event.name)
224
+ } else {
225
+ newKeys.add(event.name)
226
+ }
227
+ return newKeys
228
+ })
229
+ },
230
+ { release: true },
231
+ )
232
+
233
+ return (
234
+ <box>
235
+ <text>Currently pressed: {Array.from(pressedKeys).join(", ") || "none"}</text>
236
+ </box>
237
+ )
238
+ }
239
+ ```
240
+
156
241
  #### `useOnResize(callback)`
157
242
 
158
243
  Handle terminal resize events.
@@ -255,7 +340,9 @@ function App() {
255
340
 
256
341
  ## Components
257
342
 
258
- ### Text Component
343
+ ### Layout & Display Components
344
+
345
+ #### Text Component
259
346
 
260
347
  Display text with rich formatting.
261
348
 
@@ -280,7 +367,7 @@ function App() {
280
367
  }
281
368
  ```
282
369
 
283
- ### Box Component
370
+ #### Box Component
284
371
 
285
372
  Container with borders and layout capabilities.
286
373
 
@@ -316,7 +403,109 @@ function App() {
316
403
  }
317
404
  ```
318
405
 
319
- ### Input Component
406
+ #### Scrollbox Component
407
+
408
+ A scrollable box.
409
+
410
+ ```tsx
411
+ function App() {
412
+ return (
413
+ <scrollbox
414
+ style={{
415
+ rootOptions: {
416
+ backgroundColor: "#24283b",
417
+ },
418
+ wrapperOptions: {
419
+ backgroundColor: "#1f2335",
420
+ },
421
+ viewportOptions: {
422
+ backgroundColor: "#1a1b26",
423
+ },
424
+ contentOptions: {
425
+ backgroundColor: "#16161e",
426
+ },
427
+ scrollbarOptions: {
428
+ showArrows: true,
429
+ trackOptions: {
430
+ foregroundColor: "#7aa2f7",
431
+ backgroundColor: "#414868",
432
+ },
433
+ },
434
+ }}
435
+ focused
436
+ >
437
+ {Array.from({ length: 1000 }).map((_, i) => (
438
+ <box
439
+ key={i}
440
+ style={{ width: "100%", padding: 1, marginBottom: 1, backgroundColor: i % 2 === 0 ? "#292e42" : "#2f3449" }}
441
+ >
442
+ <text content={`Box ${i}`} />
443
+ </box>
444
+ ))}
445
+ </scrollbox>
446
+ )
447
+ }
448
+ ```
449
+
450
+ #### ASCII Font Component
451
+
452
+ Display ASCII art text with different font styles.
453
+
454
+ ```tsx
455
+ import { useState } from "react"
456
+
457
+ function App() {
458
+ const text = "ASCII"
459
+ const [font, setFont] = useState<"block" | "shade" | "slick" | "tiny">("tiny")
460
+
461
+ return (
462
+ <box style={{ border: true, paddingLeft: 1, paddingRight: 1 }}>
463
+ <box
464
+ style={{
465
+ height: 8,
466
+ border: true,
467
+ marginBottom: 1,
468
+ }}
469
+ >
470
+ <select
471
+ focused
472
+ onChange={(_, option) => setFont(option?.value)}
473
+ showScrollIndicator
474
+ options={[
475
+ {
476
+ name: "Tiny",
477
+ description: "Tiny font",
478
+ value: "tiny",
479
+ },
480
+ {
481
+ name: "Block",
482
+ description: "Block font",
483
+ value: "block",
484
+ },
485
+ {
486
+ name: "Slick",
487
+ description: "Slick font",
488
+ value: "slick",
489
+ },
490
+ {
491
+ name: "Shade",
492
+ description: "Shade font",
493
+ value: "shade",
494
+ },
495
+ ]}
496
+ style={{ flexGrow: 1 }}
497
+ />
498
+ </box>
499
+
500
+ <ascii-font text={text} font={font} />
501
+ </box>
502
+ )
503
+ }
504
+ ```
505
+
506
+ ### Input Components
507
+
508
+ #### Input Component
320
509
 
321
510
  Text input field with event handling.
322
511
 
@@ -339,7 +528,7 @@ function App() {
339
528
  }
340
529
  ```
341
530
 
342
- ### Textarea Component
531
+ #### Textarea Component
343
532
 
344
533
  ```tsx
345
534
  import type { TextareaRenderable } from "@opentui/core"
@@ -368,38 +557,7 @@ function App() {
368
557
  }
369
558
  ```
370
559
 
371
- ### Code Component
372
-
373
- ```tsx
374
- import { RGBA, SyntaxStyle } from "@opentui/core"
375
-
376
- const syntaxStyle = SyntaxStyle.fromStyles({
377
- keyword: { fg: RGBA.fromHex("#ff6b6b"), bold: true }, // red, bold
378
- string: { fg: RGBA.fromHex("#51cf66") }, // green
379
- comment: { fg: RGBA.fromHex("#868e96"), italic: true }, // gray, italic
380
- number: { fg: RGBA.fromHex("#ffd43b") }, // yellow
381
- default: { fg: RGBA.fromHex("#ffffff") }, // white
382
- })
383
-
384
- const codeExample = `function hello() {
385
- // This is a comment
386
-
387
- const message = "Hello, world!"
388
- const count = 42
389
-
390
- return message + " " + count
391
- }`
392
-
393
- function App() {
394
- return (
395
- <box style={{ border: true, flexGrow: 1 }}>
396
- <code content={codeExample} filetype="javascript" syntaxStyle={syntaxStyle} />
397
- </box>
398
- )
399
- }
400
- ```
401
-
402
- ### Select Component
560
+ #### Select Component
403
561
 
404
562
  Dropdown selection component.
405
563
 
@@ -432,106 +590,101 @@ function App() {
432
590
  }
433
591
  ```
434
592
 
435
- ### Scrollbox Component
593
+ ### Code & Diff Components
436
594
 
437
- A scrollable box.
595
+ #### Code Component
438
596
 
439
597
  ```tsx
598
+ import { RGBA, SyntaxStyle } from "@opentui/core"
599
+
600
+ const syntaxStyle = SyntaxStyle.fromStyles({
601
+ keyword: { fg: RGBA.fromHex("#ff6b6b"), bold: true }, // red, bold
602
+ string: { fg: RGBA.fromHex("#51cf66") }, // green
603
+ comment: { fg: RGBA.fromHex("#868e96"), italic: true }, // gray, italic
604
+ number: { fg: RGBA.fromHex("#ffd43b") }, // yellow
605
+ default: { fg: RGBA.fromHex("#ffffff") }, // white
606
+ })
607
+
608
+ const codeExample = `function hello() {
609
+ // This is a comment
610
+
611
+ const message = "Hello, world!"
612
+ const count = 42
613
+
614
+ return message + " " + count
615
+ }`
616
+
440
617
  function App() {
441
618
  return (
442
- <scrollbox
443
- style={{
444
- rootOptions: {
445
- backgroundColor: "#24283b",
446
- },
447
- wrapperOptions: {
448
- backgroundColor: "#1f2335",
449
- },
450
- viewportOptions: {
451
- backgroundColor: "#1a1b26",
452
- },
453
- contentOptions: {
454
- backgroundColor: "#16161e",
455
- },
456
- scrollbarOptions: {
457
- showArrows: true,
458
- trackOptions: {
459
- foregroundColor: "#7aa2f7",
460
- backgroundColor: "#414868",
461
- },
462
- },
463
- }}
464
- focused
465
- >
466
- {Array.from({ length: 1000 }).map((_, i) => (
467
- <box
468
- key={i}
469
- style={{ width: "100%", padding: 1, marginBottom: 1, backgroundColor: i % 2 === 0 ? "#292e42" : "#2f3449" }}
470
- >
471
- <text content={`Box ${i}`} />
472
- </box>
473
- ))}
474
- </scrollbox>
619
+ <box style={{ border: true, flexGrow: 1 }}>
620
+ <code content={codeExample} filetype="javascript" syntaxStyle={syntaxStyle} />
621
+ </box>
475
622
  )
476
623
  }
477
624
  ```
478
625
 
479
- ### ASCII Font Component
626
+ #### Line Number Component
480
627
 
481
- Display ASCII art text with different font styles.
628
+ Display code with line numbers, and optionally add diff highlights or diagnostic indicators.
482
629
 
483
630
  ```tsx
484
- import { useState } from "react"
631
+ import type { LineNumberRenderable } from "@opentui/core"
632
+ import { RGBA, SyntaxStyle } from "@opentui/core"
633
+ import { useEffect, useRef } from "react"
485
634
 
486
635
  function App() {
487
- const text = "ASCII"
488
- const [font, setFont] = useState<"block" | "shade" | "slick" | "tiny">("tiny")
636
+ const lineNumberRef = useRef<LineNumberRenderable>(null)
637
+
638
+ const syntaxStyle = SyntaxStyle.fromStyles({
639
+ keyword: { fg: RGBA.fromHex("#C792EA") },
640
+ string: { fg: RGBA.fromHex("#C3E88D") },
641
+ number: { fg: RGBA.fromHex("#F78C6C") },
642
+ default: { fg: RGBA.fromHex("#A6ACCD") },
643
+ })
644
+
645
+ const codeContent = `function fibonacci(n: number): number {
646
+ if (n <= 1) return n
647
+ return fibonacci(n - 1) + fibonacci(n - 2)
648
+ }
649
+
650
+ console.log(fibonacci(10))`
651
+
652
+ useEffect(() => {
653
+ // Add diff highlight - line was added
654
+ lineNumberRef.current?.setLineColor(1, "#1a4d1a")
655
+ lineNumberRef.current?.setLineSign(1, { after: " +", afterColor: "#22c55e" })
656
+
657
+ // Add diagnostic indicator
658
+ lineNumberRef.current?.setLineSign(4, { before: "⚠️", beforeColor: "#f59e0b" })
659
+ }, [])
489
660
 
490
661
  return (
491
- <box style={{ border: true, paddingLeft: 1, paddingRight: 1 }}>
492
- <box
493
- style={{
494
- height: 8,
495
- border: true,
496
- marginBottom: 1,
497
- }}
662
+ <box style={{ border: true, flexGrow: 1 }}>
663
+ <line-number
664
+ ref={lineNumberRef}
665
+ fg="#6b7280"
666
+ bg="#161b22"
667
+ minWidth={3}
668
+ paddingRight={1}
669
+ showLineNumbers={true}
670
+ width="100%"
671
+ height="100%"
498
672
  >
499
- <select
500
- focused
501
- onChange={(_, option) => setFont(option?.value)}
502
- showScrollIndicator
503
- options={[
504
- {
505
- name: "Tiny",
506
- description: "Tiny font",
507
- value: "tiny",
508
- },
509
- {
510
- name: "Block",
511
- description: "Block font",
512
- value: "block",
513
- },
514
- {
515
- name: "Slick",
516
- description: "Slick font",
517
- value: "slick",
518
- },
519
- {
520
- name: "Shade",
521
- description: "Shade font",
522
- value: "shade",
523
- },
524
- ]}
525
- style={{ flexGrow: 1 }}
526
- />
527
- </box>
528
-
529
- <ascii-font text={text} font={font} />
673
+ <code content={codeContent} filetype="typescript" syntaxStyle={syntaxStyle} width="100%" height="100%" />
674
+ </line-number>
530
675
  </box>
531
676
  )
532
677
  }
533
678
  ```
534
679
 
680
+ For a more complete example with interactive diff highlights and diagnostics, see [`examples/line-number.tsx`](examples/line-number.tsx).
681
+
682
+ #### Diff Component
683
+
684
+ Display unified or split-view diffs with syntax highlighting, customizable themes, and line number support. Supports multiple view modes (unified/split), word wrapping, and theme customization.
685
+
686
+ For a complete interactive example with theme switching and keybindings, see [`examples/diff.tsx`](examples/diff.tsx).
687
+
535
688
  ## Examples
536
689
 
537
690
  ### Login Form
package/index.js CHANGED
@@ -4,7 +4,9 @@ import {
4
4
  ASCIIFontRenderable,
5
5
  BoxRenderable,
6
6
  CodeRenderable,
7
+ DiffRenderable,
7
8
  InputRenderable,
9
+ LineNumberRenderable,
8
10
  ScrollBoxRenderable,
9
11
  SelectRenderable,
10
12
  TabSelectRenderable,
@@ -71,12 +73,14 @@ var baseComponents = {
71
73
  box: BoxRenderable,
72
74
  text: TextRenderable,
73
75
  code: CodeRenderable,
76
+ diff: DiffRenderable,
74
77
  input: InputRenderable,
75
78
  select: SelectRenderable,
76
79
  textarea: TextareaRenderable,
77
80
  scrollbox: ScrollBoxRenderable,
78
81
  "ascii-font": ASCIIFontRenderable,
79
82
  "tab-select": TabSelectRenderable,
83
+ "line-number": LineNumberRenderable,
80
84
  span: SpanRenderable,
81
85
  br: LineBreakRenderable,
82
86
  b: BoldSpanRenderable,
@@ -118,15 +122,21 @@ function useEffectEvent(handler) {
118
122
  }
119
123
 
120
124
  // src/hooks/use-keyboard.ts
121
- var useKeyboard = (handler) => {
125
+ var useKeyboard = (handler, options = { release: false }) => {
122
126
  const { keyHandler } = useAppContext();
123
127
  const stableHandler = useEffectEvent(handler);
124
128
  useEffect(() => {
125
129
  keyHandler?.on("keypress", stableHandler);
130
+ if (options?.release) {
131
+ keyHandler?.on("keyrelease", stableHandler);
132
+ }
126
133
  return () => {
127
134
  keyHandler?.off("keypress", stableHandler);
135
+ if (options?.release) {
136
+ keyHandler?.off("keyrelease", stableHandler);
137
+ }
128
138
  };
129
- }, [keyHandler]);
139
+ }, [keyHandler, options.release]);
130
140
  };
131
141
  // src/hooks/use-renderer.ts
132
142
  var useRenderer = () => {
@@ -3,9 +3,11 @@ import type {
3
3
  AsciiFontProps,
4
4
  BoxProps,
5
5
  CodeProps,
6
+ DiffProps,
6
7
  ExtendedIntrinsicElements,
7
8
  InputProps,
8
9
  LineBreakProps,
10
+ LineNumberProps,
9
11
  OpenTUIComponents,
10
12
  ScrollBoxProps,
11
13
  SelectProps,
@@ -37,12 +39,14 @@ export namespace JSX {
37
39
  text: TextProps
38
40
  span: SpanProps
39
41
  code: CodeProps
42
+ diff: DiffProps
40
43
  input: InputProps
41
44
  textarea: TextareaProps
42
45
  select: SelectProps
43
46
  scrollbox: ScrollBoxProps
44
47
  "ascii-font": AsciiFontProps
45
48
  "tab-select": TabSelectProps
49
+ "line-number": LineNumberProps
46
50
  // Text modifiers
47
51
  b: SpanProps
48
52
  i: SpanProps
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.52",
7
+ "version": "0.1.54",
8
8
  "description": "React renderer for building terminal user interfaces using OpenTUI core",
9
9
  "license": "MIT",
10
10
  "repository": {
@@ -40,7 +40,7 @@
40
40
  }
41
41
  },
42
42
  "dependencies": {
43
- "@opentui/core": "0.1.52",
43
+ "@opentui/core": "0.1.54",
44
44
  "react-reconciler": "^0.32.0"
45
45
  },
46
46
  "devDependencies": {
@@ -1,16 +1,18 @@
1
- import { ASCIIFontRenderable, BoxRenderable, CodeRenderable, InputRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextareaRenderable, TextRenderable } from "@opentui/core";
1
+ import { ASCIIFontRenderable, BoxRenderable, CodeRenderable, DiffRenderable, InputRenderable, LineNumberRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextareaRenderable, TextRenderable } from "@opentui/core";
2
2
  import type { RenderableConstructor } from "../types/components";
3
3
  import { BoldSpanRenderable, ItalicSpanRenderable, LineBreakRenderable, SpanRenderable, UnderlineSpanRenderable } from "./text";
4
4
  export declare const baseComponents: {
5
5
  box: typeof BoxRenderable;
6
6
  text: typeof TextRenderable;
7
7
  code: typeof CodeRenderable;
8
+ diff: typeof DiffRenderable;
8
9
  input: typeof InputRenderable;
9
10
  select: typeof SelectRenderable;
10
11
  textarea: typeof TextareaRenderable;
11
12
  scrollbox: typeof ScrollBoxRenderable;
12
13
  "ascii-font": typeof ASCIIFontRenderable;
13
14
  "tab-select": typeof TabSelectRenderable;
15
+ "line-number": typeof LineNumberRenderable;
14
16
  span: typeof SpanRenderable;
15
17
  br: typeof LineBreakRenderable;
16
18
  b: typeof BoldSpanRenderable;
@@ -1,2 +1,22 @@
1
1
  import type { KeyEvent } from "@opentui/core";
2
- export declare const useKeyboard: (handler: (key: KeyEvent) => void) => void;
2
+ export interface UseKeyboardOptions {
3
+ /** Include release events - callback receives events with eventType: "release" */
4
+ release?: boolean;
5
+ }
6
+ /**
7
+ * Subscribe to keyboard events.
8
+ *
9
+ * By default, only receives press events (including key repeats with `repeated: true`).
10
+ * Use `options.release` to also receive release events.
11
+ *
12
+ * @example
13
+ * // Basic press handling (includes repeats)
14
+ * useKeyboard((e) => console.log(e.name, e.repeated ? "(repeat)" : ""))
15
+ *
16
+ * // With release events
17
+ * useKeyboard((e) => {
18
+ * if (e.eventType === "release") keys.delete(e.name)
19
+ * else keys.add(e.name)
20
+ * }, { release: true })
21
+ */
22
+ export declare const useKeyboard: (handler: (key: KeyEvent) => void, options?: UseKeyboardOptions) => void;
@@ -53,7 +53,9 @@ import {
53
53
  ASCIIFontRenderable,
54
54
  BoxRenderable,
55
55
  CodeRenderable,
56
+ DiffRenderable,
56
57
  InputRenderable,
58
+ LineNumberRenderable,
57
59
  ScrollBoxRenderable,
58
60
  SelectRenderable,
59
61
  TabSelectRenderable,
@@ -120,12 +122,14 @@ var baseComponents = {
120
122
  box: BoxRenderable,
121
123
  text: TextRenderable,
122
124
  code: CodeRenderable,
125
+ diff: DiffRenderable,
123
126
  input: InputRenderable,
124
127
  select: SelectRenderable,
125
128
  textarea: TextareaRenderable,
126
129
  scrollbox: ScrollBoxRenderable,
127
130
  "ascii-font": ASCIIFontRenderable,
128
131
  "tab-select": TabSelectRenderable,
132
+ "line-number": LineNumberRenderable,
129
133
  span: SpanRenderable,
130
134
  br: LineBreakRenderable,
131
135
  b: BoldSpanRenderable,
@@ -57,7 +57,9 @@ import {
57
57
  ASCIIFontRenderable,
58
58
  BoxRenderable,
59
59
  CodeRenderable,
60
+ DiffRenderable,
60
61
  InputRenderable,
62
+ LineNumberRenderable,
61
63
  ScrollBoxRenderable,
62
64
  SelectRenderable,
63
65
  TabSelectRenderable,
@@ -124,12 +126,14 @@ var baseComponents = {
124
126
  box: BoxRenderable,
125
127
  text: TextRenderable,
126
128
  code: CodeRenderable,
129
+ diff: DiffRenderable,
127
130
  input: InputRenderable,
128
131
  select: SelectRenderable,
129
132
  textarea: TextareaRenderable,
130
133
  scrollbox: ScrollBoxRenderable,
131
134
  "ascii-font": ASCIIFontRenderable,
132
135
  "tab-select": TabSelectRenderable,
136
+ "line-number": LineNumberRenderable,
133
137
  span: SpanRenderable,
134
138
  br: LineBreakRenderable,
135
139
  b: BoldSpanRenderable,
@@ -1,4 +1,4 @@
1
- import type { ASCIIFontOptions, ASCIIFontRenderable, BaseRenderable, BoxOptions, BoxRenderable, CodeOptions, CodeRenderable, InputRenderable, InputRenderableOptions, 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, 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}`;
@@ -43,6 +43,7 @@ export type TextareaProps = ComponentProps<TextareaOptions, TextareaRenderable>
43
43
  focused?: boolean;
44
44
  };
45
45
  export type CodeProps = ComponentProps<CodeOptions, CodeRenderable>;
46
+ export type DiffProps = ComponentProps<DiffRenderableOptions, DiffRenderable>;
46
47
  export type SelectProps = ComponentProps<SelectRenderableOptions, SelectRenderable> & {
47
48
  focused?: boolean;
48
49
  onChange?: (index: number, option: SelectOption | null) => void;
@@ -57,6 +58,9 @@ export type TabSelectProps = ComponentProps<TabSelectRenderableOptions, TabSelec
57
58
  onChange?: (index: number, option: TabSelectOption | null) => void;
58
59
  onSelect?: (index: number, option: TabSelectOption | null) => void;
59
60
  };
61
+ export type LineNumberProps = ComponentProps<ContainerProps<LineNumberOptions>, LineNumberRenderable> & {
62
+ focused?: boolean;
63
+ };
60
64
  /** Convert renderable constructor to component props with proper style exclusions */
61
65
  export type ExtendedComponentProps<TConstructor extends RenderableConstructor, TOptions = ExtractRenderableOptions<TConstructor>> = TOptions & {
62
66
  children?: React.ReactNode;