@gridland/web 0.1.0

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,557 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
3
+ import { ReactNode, CSSProperties } from 'react';
4
+ import { EventEmitter } from 'events';
5
+
6
+ declare class RGBA {
7
+ buffer: Float32Array;
8
+ constructor(buffer: Float32Array);
9
+ static fromArray(array: Float32Array): RGBA;
10
+ static fromValues(r: number, g: number, b: number, a?: number): RGBA;
11
+ static fromInts(r: number, g: number, b: number, a?: number): RGBA;
12
+ static fromHex(hex: string): RGBA;
13
+ get r(): number;
14
+ set r(v: number);
15
+ get g(): number;
16
+ set g(v: number);
17
+ get b(): number;
18
+ set b(v: number);
19
+ get a(): number;
20
+ set a(v: number);
21
+ toInts(): [number, number, number, number];
22
+ map<R>(fn: (value: number) => R): R[];
23
+ toString(): string;
24
+ equals(other?: RGBA): boolean;
25
+ }
26
+
27
+ type CursorStyle = "block" | "line" | "underline";
28
+ type MousePointerStyle = "default" | "pointer" | "text" | "crosshair" | "move" | "not-allowed";
29
+ type WidthMethod$1 = "wcwidth" | "unicode";
30
+ interface CursorStyleOptions {
31
+ style?: CursorStyle;
32
+ blinking?: boolean;
33
+ color?: RGBA;
34
+ cursor?: MousePointerStyle;
35
+ }
36
+ interface RenderContext {
37
+ addToHitGrid: (x: number, y: number, width: number, height: number, id: number) => void;
38
+ pushHitGridScissorRect: (x: number, y: number, width: number, height: number) => void;
39
+ popHitGridScissorRect: () => void;
40
+ clearHitGridScissorRects: () => void;
41
+ width: number;
42
+ height: number;
43
+ requestRender: () => void;
44
+ setCursorPosition: (x: number, y: number, visible: boolean) => void;
45
+ setCursorStyle: (options: CursorStyleOptions) => void;
46
+ setCursorColor: (color: RGBA) => void;
47
+ setMousePointer: (shape: MousePointerStyle) => void;
48
+ widthMethod: WidthMethod$1;
49
+ capabilities: any | null;
50
+ requestLive: () => void;
51
+ dropLive: () => void;
52
+ hasSelection: boolean;
53
+ getSelection: () => any | null;
54
+ requestSelectionUpdate: () => void;
55
+ currentFocusedRenderable: any | null;
56
+ focusRenderable: (renderable: any) => void;
57
+ registerLifecyclePass: (renderable: any) => void;
58
+ unregisterLifecyclePass: (renderable: any) => void;
59
+ getLifecyclePasses: () => Set<any>;
60
+ keyInput: any;
61
+ _internalKeyInput: any;
62
+ clearSelection: () => void;
63
+ startSelection: (renderable: any, x: number, y: number) => void;
64
+ updateSelection: (currentRenderable: any | undefined, x: number, y: number, options?: {
65
+ finishDragging?: boolean;
66
+ }) => void;
67
+ on: (event: string, listener: (...args: any[]) => void) => any;
68
+ off: (event: string, listener: (...args: any[]) => void) => any;
69
+ emit: (event: string, ...args: any[]) => boolean;
70
+ removeAllListeners: (event?: string) => any;
71
+ }
72
+ interface CapturedSpan {
73
+ text: string;
74
+ fg: RGBA;
75
+ bg: RGBA;
76
+ attributes: number;
77
+ width: number;
78
+ }
79
+ interface CapturedLine {
80
+ spans: CapturedSpan[];
81
+ }
82
+
83
+ type WidthMethod = "wcwidth" | "unicode";
84
+ interface BorderDrawOptions {
85
+ x: number;
86
+ y: number;
87
+ width: number;
88
+ height: number;
89
+ borderStyle?: string;
90
+ customBorderChars?: Uint32Array;
91
+ border: boolean | string[];
92
+ borderColor: RGBA;
93
+ backgroundColor: RGBA;
94
+ shouldFill?: boolean;
95
+ title?: string;
96
+ titleAlignment?: "left" | "center" | "right";
97
+ }
98
+ declare class BrowserBuffer {
99
+ id: string;
100
+ respectAlpha: boolean;
101
+ private _width;
102
+ private _height;
103
+ private _widthMethod;
104
+ char: Uint32Array;
105
+ fg: Float32Array;
106
+ bg: Float32Array;
107
+ attributes: Uint32Array;
108
+ private scissorStack;
109
+ private opacityStack;
110
+ linkRegistry: Map<number, string>;
111
+ private nextLinkId;
112
+ constructor(width: number, height: number, options?: {
113
+ respectAlpha?: boolean;
114
+ id?: string;
115
+ widthMethod?: WidthMethod;
116
+ });
117
+ static create(width: number, height: number, widthMethod: WidthMethod, options?: {
118
+ respectAlpha?: boolean;
119
+ id?: string;
120
+ }): BrowserBuffer;
121
+ get width(): number;
122
+ get height(): number;
123
+ get widthMethod(): WidthMethod;
124
+ get ptr(): number;
125
+ get buffers(): {
126
+ char: Uint32Array<ArrayBufferLike>;
127
+ fg: Float32Array<ArrayBufferLike>;
128
+ bg: Float32Array<ArrayBufferLike>;
129
+ attributes: Uint32Array<ArrayBufferLike>;
130
+ };
131
+ setRespectAlpha(respectAlpha: boolean): void;
132
+ getNativeId(): string;
133
+ registerLink(url: string): number;
134
+ getLinkUrl(linkId: number): string | undefined;
135
+ private isInScissor;
136
+ private getCurrentOpacityMultiplier;
137
+ private applyOpacity;
138
+ clear(bg?: RGBA): void;
139
+ setCell(x: number, y: number, char: string, fgColor: RGBA, bgColor: RGBA, attr?: number): void;
140
+ setCellWithAlphaBlending(x: number, y: number, char: string, fgColor: RGBA, bgColor: RGBA, attr?: number): void;
141
+ drawChar(charCode: number, x: number, y: number, fgColor: RGBA, bgColor: RGBA, attr?: number): void;
142
+ drawText(text: string, x: number, y: number, fgColor: RGBA, bgColor?: RGBA, attr?: number, _selection?: {
143
+ start: number;
144
+ end: number;
145
+ bgColor?: RGBA;
146
+ fgColor?: RGBA;
147
+ } | null): void;
148
+ fillRect(x: number, y: number, width: number, height: number, bgColor: RGBA): void;
149
+ drawBox(options: BorderDrawOptions): void;
150
+ private getDefaultBorderChars;
151
+ pushScissorRect(x: number, y: number, width: number, height: number): void;
152
+ popScissorRect(): void;
153
+ clearScissorRects(): void;
154
+ pushOpacity(opacity: number): void;
155
+ popOpacity(): void;
156
+ getCurrentOpacity(): number;
157
+ clearOpacity(): void;
158
+ resize(width: number, height: number): void;
159
+ getSpanLines(): CapturedLine[];
160
+ drawTextBufferView(view: any, x: number, y: number): void;
161
+ drawTextBuffer(textBufferView: any, x: number, y: number): void;
162
+ drawFrameBuffer(destX: number, destY: number, frameBuffer: BrowserBuffer, sourceX?: number, sourceY?: number, sourceWidth?: number, sourceHeight?: number): void;
163
+ drawEditorView(editorView: any, x: number, y: number): void;
164
+ drawSuperSampleBuffer(): void;
165
+ drawPackedBuffer(): void;
166
+ drawGrayscaleBuffer(): void;
167
+ drawGrayscaleBufferSupersampled(): void;
168
+ drawGrid(): void;
169
+ encodeUnicode(_text: string): null;
170
+ freeUnicode(): void;
171
+ getRealCharBytes(): Uint8Array;
172
+ destroy(): void;
173
+ }
174
+
175
+ declare class BrowserKeyHandler extends EventEmitter {
176
+ constructor();
177
+ processInput(_data: string): boolean;
178
+ }
179
+ declare class BrowserInternalKeyHandler extends BrowserKeyHandler {
180
+ private renderableHandlers;
181
+ onInternal(event: string, handler: Function): void;
182
+ offInternal(event: string, handler: Function): void;
183
+ emit(event: string, ...args: any[]): boolean;
184
+ }
185
+ declare class BrowserRenderContext extends EventEmitter implements RenderContext {
186
+ private _width;
187
+ private _height;
188
+ private _widthMethod;
189
+ private _renderRequested;
190
+ private _onRenderRequest;
191
+ private _lifecyclePasses;
192
+ private _focusedRenderable;
193
+ keyInput: BrowserKeyHandler;
194
+ _internalKeyInput: BrowserInternalKeyHandler;
195
+ constructor(width: number, height: number, widthMethod?: WidthMethod$1);
196
+ get width(): number;
197
+ get height(): number;
198
+ get widthMethod(): WidthMethod$1;
199
+ get capabilities(): any;
200
+ get hasSelection(): boolean;
201
+ get currentFocusedRenderable(): any | null;
202
+ setOnRenderRequest(callback: () => void): void;
203
+ resize(width: number, height: number): void;
204
+ addToHitGrid(_x: number, _y: number, _width: number, _height: number, _id: number): void;
205
+ pushHitGridScissorRect(_x: number, _y: number, _width: number, _height: number): void;
206
+ popHitGridScissorRect(): void;
207
+ clearHitGridScissorRects(): void;
208
+ requestRender(): void;
209
+ setCursorPosition(_x: number, _y: number, _visible: boolean): void;
210
+ setCursorStyle(_options: CursorStyleOptions): void;
211
+ setCursorColor(_color: RGBA): void;
212
+ setMousePointer(_shape: MousePointerStyle): void;
213
+ requestLive(): void;
214
+ dropLive(): void;
215
+ getSelection(): any | null;
216
+ requestSelectionUpdate(): void;
217
+ focusRenderable(renderable: any): void;
218
+ registerLifecyclePass(renderable: any): void;
219
+ unregisterLifecyclePass(renderable: any): void;
220
+ getLifecyclePasses(): Set<any>;
221
+ clearSelection(): void;
222
+ startSelection(_renderable: any, _x: number, _y: number): void;
223
+ updateSelection(_currentRenderable: any | undefined, _x: number, _y: number, _options?: {
224
+ finishDragging?: boolean;
225
+ }): void;
226
+ }
227
+
228
+ interface SelectionRange {
229
+ startCol: number;
230
+ startRow: number;
231
+ endCol: number;
232
+ endRow: number;
233
+ }
234
+ declare class SelectionManager {
235
+ private _startCol;
236
+ private _startRow;
237
+ private _endCol;
238
+ private _endRow;
239
+ private _active;
240
+ private _selecting;
241
+ startSelection(col: number, row: number): void;
242
+ updateSelection(col: number, row: number): void;
243
+ endSelection(): void;
244
+ clearSelection(): void;
245
+ get active(): boolean;
246
+ get selecting(): boolean;
247
+ /** Returns the selection range normalized to reading order (top-left to bottom-right) */
248
+ getSelectedRange(): SelectionRange | null;
249
+ isSelected(col: number, row: number): boolean;
250
+ getSelectedText(buffer: BrowserBuffer): string;
251
+ }
252
+
253
+ interface CanvasPainterOptions {
254
+ fontFamily?: string;
255
+ fontSize?: number;
256
+ }
257
+ declare class CanvasPainter {
258
+ private cellWidth;
259
+ private cellHeight;
260
+ private fontFamily;
261
+ private fontSize;
262
+ private baselineOffset;
263
+ constructor(options?: CanvasPainterOptions);
264
+ measureCell(ctx: CanvasRenderingContext2D): {
265
+ width: number;
266
+ height: number;
267
+ };
268
+ getCellSize(): {
269
+ width: number;
270
+ height: number;
271
+ };
272
+ paint(ctx: CanvasRenderingContext2D, buffer: BrowserBuffer, selection?: SelectionManager): void;
273
+ }
274
+
275
+ declare class BrowserRenderer {
276
+ canvas: HTMLCanvasElement;
277
+ ctx2d: CanvasRenderingContext2D;
278
+ buffer: BrowserBuffer;
279
+ renderContext: BrowserRenderContext;
280
+ root: any;
281
+ painter: CanvasPainter;
282
+ selection: SelectionManager;
283
+ private cols;
284
+ private rows;
285
+ private cellWidth;
286
+ private cellHeight;
287
+ private rafId;
288
+ private lastTime;
289
+ private needsRender;
290
+ private isDragOver;
291
+ private cleanupListeners;
292
+ private mouseDownCell;
293
+ constructor(canvas: HTMLCanvasElement, cols: number, rows: number);
294
+ private pixelToCell;
295
+ private setupDomListeners;
296
+ start(): void;
297
+ stop(): void;
298
+ private loop;
299
+ resize(cols: number, rows: number): void;
300
+ private static PREVENT_DEFAULT_KEYS;
301
+ private static MODIFIER_KEYS;
302
+ private static KEY_MAP;
303
+ handleKeyDown(event: KeyboardEvent): void;
304
+ }
305
+
306
+ interface TUIProps {
307
+ children: ReactNode;
308
+ /** CSS styles for the outer container div */
309
+ style?: CSSProperties;
310
+ /** CSS class for the outer container div */
311
+ className?: string;
312
+ /** Font size in pixels (default: 14) */
313
+ fontSize?: number;
314
+ /** Font family (default: monospace stack) */
315
+ fontFamily?: string;
316
+ /** Auto-focus the canvas for keyboard input (default: true) */
317
+ autoFocus?: boolean;
318
+ /** Called when the renderer is ready */
319
+ onReady?: (renderer: BrowserRenderer) => void;
320
+ }
321
+ /**
322
+ * A single React component that renders TUI content to an HTML5 Canvas.
323
+ * Gridland is built on the opentui engine.
324
+ *
325
+ * Usage:
326
+ * ```tsx
327
+ * <TUI style={{ width: "100%", height: 400 }}>
328
+ * <box border borderStyle="rounded">
329
+ * <text>Hello from Gridland!</text>
330
+ * </box>
331
+ * </TUI>
332
+ * ```
333
+ *
334
+ * No dynamic imports, no wrapper chains. Just a component.
335
+ */
336
+ declare function TUI({ children, style, className, fontSize, fontFamily, autoFocus, onReady, }: TUIProps): react_jsx_runtime.JSX.Element;
337
+
338
+ interface MountOptions {
339
+ /** Number of columns (auto-calculated from canvas size if omitted) */
340
+ cols?: number;
341
+ /** Number of rows (auto-calculated from canvas size if omitted) */
342
+ rows?: number;
343
+ /** Font size in pixels (default: 14) */
344
+ fontSize?: number;
345
+ /** Font family (default: monospace stack) */
346
+ fontFamily?: string;
347
+ /** Listen for keyboard events on the canvas (default: true) */
348
+ keyboard?: boolean;
349
+ /** Auto-resize when canvas size changes (default: true) */
350
+ autoResize?: boolean;
351
+ }
352
+ interface MountResult {
353
+ renderer: BrowserRenderer;
354
+ unmount: () => void;
355
+ resize: (cols: number, rows: number) => void;
356
+ }
357
+ /**
358
+ * Imperative API to mount Gridland content into a canvas element.
359
+ *
360
+ * ```ts
361
+ * const canvas = document.getElementById("my-canvas") as HTMLCanvasElement
362
+ * const { unmount } = mountGridland(canvas, <App />)
363
+ * ```
364
+ */
365
+ declare function mountGridland(canvas: HTMLCanvasElement, element: ReactNode, options?: MountOptions): MountResult;
366
+
367
+ interface TextChunk {
368
+ __isChunk: true;
369
+ text: string;
370
+ fg?: RGBA;
371
+ bg?: RGBA;
372
+ attributes?: number;
373
+ link?: {
374
+ url: string;
375
+ };
376
+ }
377
+ interface StyledTextInput {
378
+ chunks: TextChunk[];
379
+ }
380
+ declare class BrowserTextBuffer {
381
+ private _text;
382
+ private _chunks;
383
+ private _defaultFg;
384
+ private _defaultBg;
385
+ private _defaultAttributes;
386
+ private _syntaxStyle;
387
+ private _tabWidth;
388
+ private _widthMethod;
389
+ constructor(widthMethod: WidthMethod);
390
+ static create(widthMethod: WidthMethod): BrowserTextBuffer;
391
+ get ptr(): number;
392
+ get length(): number;
393
+ get byteSize(): number;
394
+ setText(text: string): void;
395
+ append(text: string): void;
396
+ setStyledText(styledText: StyledTextInput): void;
397
+ getPlainText(): string;
398
+ getTextRange(startOffset: number, endOffset: number): string;
399
+ getLineCount(): number;
400
+ getChunks(): TextChunk[];
401
+ setDefaultFg(fg: RGBA | null): void;
402
+ setDefaultBg(bg: RGBA | null): void;
403
+ setDefaultAttributes(attributes: number | null): void;
404
+ resetDefaults(): void;
405
+ get defaultFg(): RGBA | null;
406
+ get defaultBg(): RGBA | null;
407
+ get defaultAttributes(): number;
408
+ setSyntaxStyle(style: any): void;
409
+ getSyntaxStyle(): any;
410
+ setTabWidth(width: number): void;
411
+ getTabWidth(): number;
412
+ addHighlightByCharRange(_highlight: any): void;
413
+ addHighlight(_lineIdx: number, _highlight: any): void;
414
+ removeHighlightsByRef(_hlRef: number): void;
415
+ clearLineHighlights(_lineIdx: number): void;
416
+ clearAllHighlights(): void;
417
+ getLineHighlights(_lineIdx: number): any[];
418
+ getHighlightCount(): number;
419
+ loadFile(_path: string): void;
420
+ clear(): void;
421
+ reset(): void;
422
+ destroy(): void;
423
+ }
424
+
425
+ interface VisibleLineChunk {
426
+ text: string;
427
+ fg: RGBA;
428
+ bg: RGBA;
429
+ attributes: number;
430
+ link?: {
431
+ url: string;
432
+ };
433
+ }
434
+ interface VisibleLine {
435
+ chunks: VisibleLineChunk[];
436
+ }
437
+ declare class BrowserTextBufferView {
438
+ private textBuffer;
439
+ private _wrapWidth;
440
+ private _wrapMode;
441
+ private _viewportX;
442
+ private _viewportY;
443
+ private _viewportWidth;
444
+ private _viewportHeight;
445
+ private _truncate;
446
+ private _selection;
447
+ private _selectionBg;
448
+ private _selectionFg;
449
+ constructor(textBuffer: BrowserTextBuffer);
450
+ static create(textBuffer: BrowserTextBuffer): BrowserTextBufferView;
451
+ get ptr(): number;
452
+ get lineInfo(): {
453
+ lineStarts: number[];
454
+ lineWidths: number[];
455
+ maxLineWidth: number;
456
+ lineSources: number[];
457
+ lineWraps: number[];
458
+ };
459
+ get logicalLineInfo(): {
460
+ lineStarts: number[];
461
+ lineWidths: number[];
462
+ maxLineWidth: number;
463
+ lineSources: number[];
464
+ lineWraps: number[];
465
+ };
466
+ setSelection(start: number, end: number, bgColor?: RGBA, fgColor?: RGBA): void;
467
+ updateSelection(end: number, bgColor?: RGBA, fgColor?: RGBA): void;
468
+ resetSelection(): void;
469
+ getSelection(): {
470
+ start: number;
471
+ end: number;
472
+ } | null;
473
+ hasSelection(): boolean;
474
+ setLocalSelection(_anchorX: number, _anchorY: number, _focusX: number, _focusY: number, _bgColor?: RGBA, _fgColor?: RGBA): boolean;
475
+ updateLocalSelection(_anchorX: number, _anchorY: number, _focusX: number, _focusY: number, _bgColor?: RGBA, _fgColor?: RGBA): boolean;
476
+ resetLocalSelection(): void;
477
+ getSelectedText(): string;
478
+ getPlainText(): string;
479
+ setWrapWidth(width: number | null): void;
480
+ setWrapMode(mode: "none" | "char" | "word"): void;
481
+ setViewportSize(width: number, height: number): void;
482
+ setViewport(x: number, y: number, width: number, height: number): void;
483
+ setTabIndicator(_indicator: string | number): void;
484
+ setTabIndicatorColor(_color: RGBA): void;
485
+ setTruncate(truncate: boolean): void;
486
+ private getAllWrappedLines;
487
+ private sliceChunks;
488
+ measureForDimensions(width: number, height: number): {
489
+ lineCount: number;
490
+ maxWidth: number;
491
+ } | null;
492
+ getVirtualLineCount(): number;
493
+ getVisibleLines(): VisibleLine[] | null;
494
+ destroy(): void;
495
+ }
496
+
497
+ declare class BrowserSyntaxStyle {
498
+ private _destroyed;
499
+ static create(): BrowserSyntaxStyle;
500
+ static fromTheme(_theme: any): BrowserSyntaxStyle;
501
+ static fromStyles(_styles: any): BrowserSyntaxStyle;
502
+ get ptr(): number;
503
+ registerStyle(_name: string, _style: any): number;
504
+ resolveStyleId(_name: string): number | null;
505
+ getStyleId(_name: string): number | null;
506
+ getStyleCount(): number;
507
+ clearNameCache(): void;
508
+ getStyle(_name: string): any;
509
+ mergeStyles(..._styleNames: string[]): {
510
+ attributes: number;
511
+ };
512
+ clearCache(): void;
513
+ getCacheSize(): number;
514
+ getAllStyles(): Map<string, any>;
515
+ getRegisteredNames(): string[];
516
+ destroy(): void;
517
+ }
518
+
519
+ interface BrowserRoot {
520
+ render(node: ReactNode): void;
521
+ unmount(): void;
522
+ }
523
+ declare function createBrowserRoot(renderer: BrowserRenderer): BrowserRoot;
524
+
525
+ interface DroppedFile {
526
+ name: string;
527
+ content: string;
528
+ type: string;
529
+ size: number;
530
+ }
531
+ declare function useFileDrop(callback: (file: DroppedFile) => void): {
532
+ isDragOver: boolean;
533
+ };
534
+
535
+ declare function usePaste(callback: (text: string) => void): void;
536
+
537
+ interface BrowserContextValue {
538
+ renderContext: BrowserRenderContext;
539
+ }
540
+ declare const BrowserContext: react.Context<BrowserContextValue | null>;
541
+ declare function useBrowserContext(): BrowserContextValue;
542
+
543
+ /**
544
+ * SSR-safe utilities for @gridland/web.
545
+ * These can be imported in any environment (Node.js, browser, edge).
546
+ */
547
+ /** Check if running in a browser environment */
548
+ declare function isBrowser(): boolean;
549
+ /** Check if canvas is supported */
550
+ declare function isCanvasSupported(): boolean;
551
+ /** Calculate grid dimensions from pixel dimensions and font size */
552
+ declare function calculateGridSize(widthPx: number, heightPx: number, cellWidth: number, cellHeight: number): {
553
+ cols: number;
554
+ rows: number;
555
+ };
556
+
557
+ export { type BorderDrawOptions, BrowserBuffer, BrowserContext, type BrowserContextValue, BrowserRenderContext, BrowserRenderer, type BrowserRoot, BrowserSyntaxStyle, BrowserTextBuffer, BrowserTextBufferView, CanvasPainter, type CanvasPainterOptions, type DroppedFile, type MountOptions, type MountResult, SelectionManager, type StyledTextInput, TUI, type TUIProps, type TextChunk, type VisibleLine, type VisibleLineChunk, type WidthMethod, calculateGridSize, createBrowserRoot, isBrowser, isCanvasSupported, mountGridland, useBrowserContext, useFileDrop, usePaste };