ink 6.6.0 → 6.8.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.
- package/build/ansi-tokenizer.d.ts +38 -0
- package/build/ansi-tokenizer.js +316 -0
- package/build/ansi-tokenizer.js.map +1 -0
- package/build/components/App.d.ts +8 -49
- package/build/components/App.js +293 -228
- package/build/components/App.js.map +1 -1
- package/build/components/AppContext.d.ts +5 -1
- package/build/components/AppContext.js.map +1 -1
- package/build/components/Cursor.d.ts +83 -0
- package/build/components/Cursor.js +53 -0
- package/build/components/Cursor.js.map +1 -0
- package/build/components/CursorContext.d.ts +11 -0
- package/build/components/CursorContext.js +8 -0
- package/build/components/CursorContext.js.map +1 -0
- package/build/components/ErrorBoundary.d.ts +18 -0
- package/build/components/ErrorBoundary.js +23 -0
- package/build/components/ErrorBoundary.js.map +1 -0
- package/build/cursor-helpers.d.ts +38 -0
- package/build/cursor-helpers.js +56 -0
- package/build/cursor-helpers.js.map +1 -0
- package/build/dom.js +5 -4
- package/build/dom.js.map +1 -1
- package/build/hooks/use-cursor.d.ts +12 -0
- package/build/hooks/use-cursor.js +29 -0
- package/build/hooks/use-cursor.js.map +1 -0
- package/build/hooks/use-input.d.ts +30 -0
- package/build/hooks/use-input.js +31 -2
- package/build/hooks/use-input.js.map +1 -1
- package/build/index.d.ts +6 -0
- package/build/index.js +3 -0
- package/build/index.js.map +1 -1
- package/build/ink.d.ts +39 -3
- package/build/ink.js +377 -49
- package/build/ink.js.map +1 -1
- package/build/input-parser.d.ts +7 -0
- package/build/input-parser.js +154 -0
- package/build/input-parser.js.map +1 -0
- package/build/kitty-keyboard.d.ts +23 -0
- package/build/kitty-keyboard.js +32 -0
- package/build/kitty-keyboard.js.map +1 -0
- package/build/layout.d.ts +7 -0
- package/build/layout.js +33 -0
- package/build/layout.js.map +1 -0
- package/build/log-update.d.ts +6 -1
- package/build/log-update.js +163 -40
- package/build/log-update.js.map +1 -1
- package/build/output.d.ts +1 -0
- package/build/output.js +38 -5
- package/build/output.js.map +1 -1
- package/build/parse-keypress.d.ts +8 -0
- package/build/parse-keypress.js +270 -2
- package/build/parse-keypress.js.map +1 -1
- package/build/reconciler.js +23 -3
- package/build/reconciler.js.map +1 -1
- package/build/render-to-string.d.ts +38 -0
- package/build/render-to-string.js +115 -0
- package/build/render-to-string.js.map +1 -0
- package/build/render.d.ts +34 -1
- package/build/render.js +7 -2
- package/build/render.js.map +1 -1
- package/build/sanitize-ansi.d.ts +2 -0
- package/build/sanitize-ansi.js +27 -0
- package/build/sanitize-ansi.js.map +1 -0
- package/build/squash-text-nodes.js +2 -1
- package/build/squash-text-nodes.js.map +1 -1
- package/build/utils.d.ts +2 -0
- package/build/utils.js +4 -0
- package/build/utils.js.map +1 -0
- package/build/write-synchronized.d.ts +4 -0
- package/build/write-synchronized.js +7 -0
- package/build/write-synchronized.js.map +1 -0
- package/package.json +27 -21
- package/readme.md +292 -14
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React, { type RefObject } from 'react';
|
|
2
|
+
import { type DOMElement, type CursorAnchorMode } from '../dom.js';
|
|
3
|
+
export type Props = {
|
|
4
|
+
/**
|
|
5
|
+
Optional reference to anchor cursor coordinates to a different element.
|
|
6
|
+
|
|
7
|
+
By default, `anchorRef` uses `anchor="textEnd"` behavior to follow the rendered end of that element's text, including wrapping and wide characters.
|
|
8
|
+
|
|
9
|
+
Use this for inputs where the cursor should stay at the visible end of text.
|
|
10
|
+
|
|
11
|
+
If `anchorRef` is set but currently unresolved, Ink hides the cursor for that frame unless `anchor="flow"` is used.
|
|
12
|
+
|
|
13
|
+
If multiple `<Cursor>` components are rendered in one frame, the last rendered one controls terminal cursor position.
|
|
14
|
+
*/
|
|
15
|
+
readonly anchorRef?: RefObject<DOMElement | null>;
|
|
16
|
+
/**
|
|
17
|
+
Anchor mode used to resolve cursor coordinates.
|
|
18
|
+
|
|
19
|
+
- `'flow'`: Anchor to `<Cursor />` position in layout flow.
|
|
20
|
+
Use this when you place `<Cursor />` exactly where it should appear.
|
|
21
|
+
|
|
22
|
+
- `'origin'`: Anchor to content origin (top-left) of `anchorRef` or parent when no `anchorRef` is provided.
|
|
23
|
+
Use this for manual `x/y` positioning.
|
|
24
|
+
|
|
25
|
+
- `'textEnd'`: Anchor to rendered end of text for `anchorRef` or parent when no `anchorRef` is provided.
|
|
26
|
+
Use this when cursor should follow wrapped text.
|
|
27
|
+
|
|
28
|
+
Defaults to `'flow'` when `anchorRef` is omitted and `'textEnd'` when `anchorRef` is provided.
|
|
29
|
+
|
|
30
|
+
`'flow'` is the default without `anchorRef` to avoid coupling cursor position to surrounding sibling text changes.
|
|
31
|
+
*/
|
|
32
|
+
readonly anchor?: CursorAnchorMode;
|
|
33
|
+
/**
|
|
34
|
+
Horizontal offset from resolved anchor position.
|
|
35
|
+
*/
|
|
36
|
+
readonly x?: number;
|
|
37
|
+
/**
|
|
38
|
+
Vertical offset from resolved anchor position.
|
|
39
|
+
*/
|
|
40
|
+
readonly y?: number;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
Declaratively position the terminal cursor relative to a container.
|
|
44
|
+
|
|
45
|
+
Use this component when building reusable inputs where absolute root coordinates are inconvenient.
|
|
46
|
+
|
|
47
|
+
`<Cursor>` must not be rendered inside `<Text>`.
|
|
48
|
+
|
|
49
|
+
@example
|
|
50
|
+
```jsx
|
|
51
|
+
import {Box, Cursor, Text} from 'ink';
|
|
52
|
+
import {useRef} from 'react';
|
|
53
|
+
|
|
54
|
+
const prompt = '> ';
|
|
55
|
+
const value = 'hello';
|
|
56
|
+
|
|
57
|
+
const Example = () => {
|
|
58
|
+
return (
|
|
59
|
+
<Box flexDirection="row">
|
|
60
|
+
<Text>{prompt}</Text>
|
|
61
|
+
<Text>{value}</Text>
|
|
62
|
+
<Cursor />
|
|
63
|
+
</Box>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```jsx
|
|
69
|
+
const ExampleWithAnchor = () => {
|
|
70
|
+
const lineReference = useRef();
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<Box flexDirection="column">
|
|
74
|
+
<Box ref={lineReference}>
|
|
75
|
+
<Text>{`${prompt}${value}`}</Text>
|
|
76
|
+
</Box>
|
|
77
|
+
<Cursor anchorRef={lineReference} />
|
|
78
|
+
</Box>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
*/
|
|
83
|
+
export default function Cursor({ anchorRef, anchor, x, y }: Props): React.JSX.Element;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
Declaratively position the terminal cursor relative to a container.
|
|
4
|
+
|
|
5
|
+
Use this component when building reusable inputs where absolute root coordinates are inconvenient.
|
|
6
|
+
|
|
7
|
+
`<Cursor>` must not be rendered inside `<Text>`.
|
|
8
|
+
|
|
9
|
+
@example
|
|
10
|
+
```jsx
|
|
11
|
+
import {Box, Cursor, Text} from 'ink';
|
|
12
|
+
import {useRef} from 'react';
|
|
13
|
+
|
|
14
|
+
const prompt = '> ';
|
|
15
|
+
const value = 'hello';
|
|
16
|
+
|
|
17
|
+
const Example = () => {
|
|
18
|
+
return (
|
|
19
|
+
<Box flexDirection="row">
|
|
20
|
+
<Text>{prompt}</Text>
|
|
21
|
+
<Text>{value}</Text>
|
|
22
|
+
<Cursor />
|
|
23
|
+
</Box>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```jsx
|
|
29
|
+
const ExampleWithAnchor = () => {
|
|
30
|
+
const lineReference = useRef();
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Box flexDirection="column">
|
|
34
|
+
<Box ref={lineReference}>
|
|
35
|
+
<Text>{`${prompt}${value}`}</Text>
|
|
36
|
+
</Box>
|
|
37
|
+
<Cursor anchorRef={lineReference} />
|
|
38
|
+
</Box>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
*/
|
|
43
|
+
export default function Cursor({ anchorRef, anchor, x = 0, y = 0 }) {
|
|
44
|
+
const normalizedAnchorReference = anchorRef ?? undefined;
|
|
45
|
+
const normalizedAnchor = anchor ?? (normalizedAnchorReference ? 'textEnd' : 'flow');
|
|
46
|
+
return (React.createElement("ink-cursor", { internal_cursor: {
|
|
47
|
+
anchorRef: normalizedAnchorReference,
|
|
48
|
+
anchor: normalizedAnchor,
|
|
49
|
+
x,
|
|
50
|
+
y,
|
|
51
|
+
} }));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=Cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Cursor.js","sourceRoot":"","sources":["../../src/components/Cursor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuB,MAAM,OAAO,CAAC;AAmD5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCE;AACF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAQ;IACtE,MAAM,yBAAyB,GAC9B,SAAS,IAAI,SAAS,CAAC;IACxB,MAAM,gBAAgB,GACrB,MAAM,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAE5D,OAAO,CACN,oCACC,eAAe,EAAE;YAChB,SAAS,EAAE,yBAAyB;YACpC,MAAM,EAAE,gBAAgB;YACxB,CAAC;YACD,CAAC;SACD,GACA,CACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type CursorPosition } from '../log-update.js';
|
|
2
|
+
export type Props = {
|
|
3
|
+
/**
|
|
4
|
+
Set the cursor position relative to the Ink output.
|
|
5
|
+
|
|
6
|
+
Pass `undefined` to hide the cursor.
|
|
7
|
+
*/
|
|
8
|
+
readonly setCursorPosition: (position: CursorPosition | undefined) => void;
|
|
9
|
+
};
|
|
10
|
+
declare const CursorContext: import("react").Context<Props>;
|
|
11
|
+
export default CursorContext;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3
|
+
const CursorContext = createContext({
|
|
4
|
+
setCursorPosition() { },
|
|
5
|
+
});
|
|
6
|
+
CursorContext.displayName = 'InternalCursorContext';
|
|
7
|
+
export default CursorContext;
|
|
8
|
+
//# sourceMappingURL=CursorContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CursorContext.js","sourceRoot":"","sources":["../../src/components/CursorContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AAYpC,gEAAgE;AAChE,MAAM,aAAa,GAAG,aAAa,CAAQ;IAC1C,iBAAiB,KAAI,CAAC;CACtB,CAAC,CAAC;AAEH,aAAa,CAAC,WAAW,GAAG,uBAAuB,CAAC;AAEpD,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React, { PureComponent, type ReactNode } from 'react';
|
|
2
|
+
type Props = {
|
|
3
|
+
readonly children: ReactNode;
|
|
4
|
+
readonly onError: (error: Error) => void;
|
|
5
|
+
};
|
|
6
|
+
type State = {
|
|
7
|
+
readonly error?: Error;
|
|
8
|
+
};
|
|
9
|
+
export default class ErrorBoundary extends PureComponent<Props, State> {
|
|
10
|
+
static displayName: string;
|
|
11
|
+
static getDerivedStateFromError(error: Error): {
|
|
12
|
+
error: Error;
|
|
13
|
+
};
|
|
14
|
+
state: State;
|
|
15
|
+
componentDidCatch(error: Error): void;
|
|
16
|
+
render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { PureComponent } from 'react';
|
|
2
|
+
import ErrorOverview from './ErrorOverview.js';
|
|
3
|
+
// Error boundary must be a class component since getDerivedStateFromError
|
|
4
|
+
// and componentDidCatch are not available as hooks
|
|
5
|
+
export default class ErrorBoundary extends PureComponent {
|
|
6
|
+
static displayName = 'InternalErrorBoundary';
|
|
7
|
+
static getDerivedStateFromError(error) {
|
|
8
|
+
return { error };
|
|
9
|
+
}
|
|
10
|
+
state = {
|
|
11
|
+
error: undefined,
|
|
12
|
+
};
|
|
13
|
+
componentDidCatch(error) {
|
|
14
|
+
this.props.onError(error);
|
|
15
|
+
}
|
|
16
|
+
render() {
|
|
17
|
+
if (this.state.error) {
|
|
18
|
+
return React.createElement(ErrorOverview, { error: this.state.error });
|
|
19
|
+
}
|
|
20
|
+
return this.props.children;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=ErrorBoundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.js","sourceRoot":"","sources":["../../src/components/ErrorBoundary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,aAAa,EAAiB,MAAM,OAAO,CAAC;AAC3D,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAW/C,0EAA0E;AAC1E,mDAAmD;AACnD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,aAA2B;IACrE,MAAM,CAAC,WAAW,GAAG,uBAAuB,CAAC;IAE7C,MAAM,CAAC,wBAAwB,CAAC,KAAY;QAC3C,OAAO,EAAC,KAAK,EAAC,CAAC;IAChB,CAAC;IAEQ,KAAK,GAAU;QACvB,KAAK,EAAE,SAAS;KAChB,CAAC;IAEO,iBAAiB,CAAC,KAAY;QACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAEQ,MAAM;QACd,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,oBAAC,aAAa,IAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAI,CAAC;QACnD,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC5B,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type CursorPosition = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
};
|
|
5
|
+
declare const showCursorEscape = "\u001B[?25h";
|
|
6
|
+
declare const hideCursorEscape = "\u001B[?25l";
|
|
7
|
+
export { showCursorEscape, hideCursorEscape };
|
|
8
|
+
/**
|
|
9
|
+
Compare two cursor positions. Returns true if they differ.
|
|
10
|
+
*/
|
|
11
|
+
export declare const cursorPositionChanged: (a: CursorPosition | undefined, b: CursorPosition | undefined) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
Build escape sequence to move cursor from bottom of output to the target position and show it.
|
|
14
|
+
Assumes cursor is at (col 0, line visibleLineCount) — i.e. just after the last output line.
|
|
15
|
+
*/
|
|
16
|
+
export declare const buildCursorSuffix: (visibleLineCount: number, cursorPosition: CursorPosition | undefined) => string;
|
|
17
|
+
/**
|
|
18
|
+
Build escape sequence to move cursor from previousCursorPosition back to the bottom of output.
|
|
19
|
+
This must be done before eraseLines or any operation that assumes cursor is at the bottom.
|
|
20
|
+
*/
|
|
21
|
+
export declare const buildReturnToBottom: (previousLineCount: number, previousCursorPosition: CursorPosition | undefined) => string;
|
|
22
|
+
export type CursorOnlyInput = {
|
|
23
|
+
cursorWasShown: boolean;
|
|
24
|
+
previousLineCount: number;
|
|
25
|
+
previousCursorPosition: CursorPosition | undefined;
|
|
26
|
+
visibleLineCount: number;
|
|
27
|
+
cursorPosition: CursorPosition | undefined;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
Build the escape sequence for cursor-only updates (output unchanged, cursor moved).
|
|
31
|
+
Hides cursor if it was previously shown, returns to bottom, then repositions.
|
|
32
|
+
*/
|
|
33
|
+
export declare const buildCursorOnlySequence: (input: CursorOnlyInput) => string;
|
|
34
|
+
/**
|
|
35
|
+
Build the prefix that hides cursor and returns to bottom before erasing or rewriting.
|
|
36
|
+
Returns empty string if cursor was not shown.
|
|
37
|
+
*/
|
|
38
|
+
export declare const buildReturnToBottomPrefix: (cursorWasShown: boolean, previousLineCount: number, previousCursorPosition: CursorPosition | undefined) => string;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import ansiEscapes from 'ansi-escapes';
|
|
2
|
+
const showCursorEscape = '\u001B[?25h';
|
|
3
|
+
const hideCursorEscape = '\u001B[?25l';
|
|
4
|
+
export { showCursorEscape, hideCursorEscape };
|
|
5
|
+
/**
|
|
6
|
+
Compare two cursor positions. Returns true if they differ.
|
|
7
|
+
*/
|
|
8
|
+
export const cursorPositionChanged = (a, b) => a?.x !== b?.x || a?.y !== b?.y;
|
|
9
|
+
/**
|
|
10
|
+
Build escape sequence to move cursor from bottom of output to the target position and show it.
|
|
11
|
+
Assumes cursor is at (col 0, line visibleLineCount) — i.e. just after the last output line.
|
|
12
|
+
*/
|
|
13
|
+
export const buildCursorSuffix = (visibleLineCount, cursorPosition) => {
|
|
14
|
+
if (!cursorPosition) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
const moveUp = visibleLineCount - cursorPosition.y;
|
|
18
|
+
return ((moveUp > 0 ? ansiEscapes.cursorUp(moveUp) : '') +
|
|
19
|
+
ansiEscapes.cursorTo(cursorPosition.x) +
|
|
20
|
+
showCursorEscape);
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
Build escape sequence to move cursor from previousCursorPosition back to the bottom of output.
|
|
24
|
+
This must be done before eraseLines or any operation that assumes cursor is at the bottom.
|
|
25
|
+
*/
|
|
26
|
+
export const buildReturnToBottom = (previousLineCount, previousCursorPosition) => {
|
|
27
|
+
if (!previousCursorPosition) {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
// PreviousLineCount includes trailing newline, so visible lines = previousLineCount - 1
|
|
31
|
+
// cursor is at previousCursorPosition.y, need to go to line (previousLineCount - 1)
|
|
32
|
+
const down = previousLineCount - 1 - previousCursorPosition.y;
|
|
33
|
+
return ((down > 0 ? ansiEscapes.cursorDown(down) : '') + ansiEscapes.cursorTo(0));
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
Build the escape sequence for cursor-only updates (output unchanged, cursor moved).
|
|
37
|
+
Hides cursor if it was previously shown, returns to bottom, then repositions.
|
|
38
|
+
*/
|
|
39
|
+
export const buildCursorOnlySequence = (input) => {
|
|
40
|
+
const hidePrefix = input.cursorWasShown ? hideCursorEscape : '';
|
|
41
|
+
const returnToBottom = buildReturnToBottom(input.previousLineCount, input.previousCursorPosition);
|
|
42
|
+
const cursorSuffix = buildCursorSuffix(input.visibleLineCount, input.cursorPosition);
|
|
43
|
+
return hidePrefix + returnToBottom + cursorSuffix;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
Build the prefix that hides cursor and returns to bottom before erasing or rewriting.
|
|
47
|
+
Returns empty string if cursor was not shown.
|
|
48
|
+
*/
|
|
49
|
+
export const buildReturnToBottomPrefix = (cursorWasShown, previousLineCount, previousCursorPosition) => {
|
|
50
|
+
if (!cursorWasShown) {
|
|
51
|
+
return '';
|
|
52
|
+
}
|
|
53
|
+
return (hideCursorEscape +
|
|
54
|
+
buildReturnToBottom(previousLineCount, previousCursorPosition));
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=cursor-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-helpers.js","sourceRoot":"","sources":["../src/cursor-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,cAAc,CAAC;AAOvC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AACvC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAEvC,OAAO,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,CAAC;AAE5C;;EAEE;AACF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACpC,CAA6B,EAC7B,CAA6B,EACnB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAE7C;;;EAGE;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAChC,gBAAwB,EACxB,cAA0C,EACjC,EAAE;IACX,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,CAAC,CAAC,CAAC;IACnD,OAAO,CACN,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;QACtC,gBAAgB,CAChB,CAAC;AACH,CAAC,CAAC;AAEF;;;EAGE;AACF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAClC,iBAAyB,EACzB,sBAAkD,EACzC,EAAE;IACX,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACX,CAAC;IAED,wFAAwF;IACxF,oFAAoF;IACpF,MAAM,IAAI,GAAG,iBAAiB,GAAG,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC;IAC9D,OAAO,CACN,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CACxE,CAAC;AACH,CAAC,CAAC;AAUF;;;EAGE;AACF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,KAAsB,EAAU,EAAE;IACzE,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,MAAM,cAAc,GAAG,mBAAmB,CACzC,KAAK,CAAC,iBAAiB,EACvB,KAAK,CAAC,sBAAsB,CAC5B,CAAC;IACF,MAAM,YAAY,GAAG,iBAAiB,CACrC,KAAK,CAAC,gBAAgB,EACtB,KAAK,CAAC,cAAc,CACpB,CAAC;IACF,OAAO,UAAU,GAAG,cAAc,GAAG,YAAY,CAAC;AACnD,CAAC,CAAC;AAEF;;;EAGE;AACF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACxC,cAAuB,EACvB,iBAAyB,EACzB,sBAAkD,EACzC,EAAE;IACX,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO,CACN,gBAAgB;QAChB,mBAAmB,CAAC,iBAAiB,EAAE,sBAAsB,CAAC,CAC9D,CAAC;AACH,CAAC,CAAC"}
|
package/build/dom.js
CHANGED
|
@@ -42,11 +42,12 @@ export const insertBeforeNode = (node, newChildNode, beforeChildNode) => {
|
|
|
42
42
|
if (newChildNode.yogaNode) {
|
|
43
43
|
node.yogaNode?.insertChild(newChildNode.yogaNode, index);
|
|
44
44
|
}
|
|
45
|
-
return;
|
|
46
45
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
else {
|
|
47
|
+
node.childNodes.push(newChildNode);
|
|
48
|
+
if (newChildNode.yogaNode) {
|
|
49
|
+
node.yogaNode?.insertChild(newChildNode.yogaNode, node.yogaNode.getChildCount());
|
|
50
|
+
}
|
|
50
51
|
}
|
|
51
52
|
if (node.nodeName === 'ink-text' || node.nodeName === 'ink-virtual-text') {
|
|
52
53
|
markNodeAsDirty(node);
|
package/build/dom.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"AAAA,OAAO,IAA6B,MAAM,aAAa,CAAC;AACxD,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAE5C,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,eAAe,MAAM,wBAAwB,CAAC;AAoFrD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAAsB,EAAc,EAAE;IAChE,MAAM,IAAI,GAAe;QACxB,QAAQ;QACR,KAAK,EAAE,EAAE;QACT,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,EAAE;QACd,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,QAAQ,KAAK,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QAC1E,gEAAgE;QAChE,sBAAsB,EAAE,EAAE;KAC1B,CAAC;IAEF,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC9B,IAAgB,EAChB,SAAqB,EACd,EAAE;IACT,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;QAC1B,eAAe,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAClD,CAAC;IAED,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEhC,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACxB,IAAI,CAAC,QAAQ,EAAE,WAAW,CACzB,SAAS,CAAC,QAAQ,EAClB,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAC7B,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,IAAI,IAAI,CAAC,QAAQ,KAAK,kBAAkB,EAAE,CAAC;QAC1E,eAAe,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;AACF,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,IAAgB,EAChB,YAAqB,EACrB,eAAwB,EACjB,EAAE;IACT,IAAI,YAAY,CAAC,UAAU,EAAE,CAAC;QAC7B,eAAe,CAAC,YAAY,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACxD,CAAC;IAED,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC;IAE/B,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACvD,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAChB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;QAC/C,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC1D,CAAC;
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CursorPosition } from '../log-update.js';
|
|
2
|
+
/**
|
|
3
|
+
`useCursor` is a React hook that lets you control the terminal cursor position.
|
|
4
|
+
|
|
5
|
+
Setting a cursor position makes the cursor visible at the specified coordinates (relative to the Ink output origin). This is useful for IME (Input Method Editor) support, where the composing character is displayed at the cursor location.
|
|
6
|
+
|
|
7
|
+
Pass `undefined` to hide the cursor.
|
|
8
|
+
*/
|
|
9
|
+
declare const useCursor: () => {
|
|
10
|
+
setCursorPosition: (position: CursorPosition | undefined) => void;
|
|
11
|
+
};
|
|
12
|
+
export default useCursor;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useContext, useRef, useCallback, useInsertionEffect } from 'react';
|
|
2
|
+
import CursorContext from '../components/CursorContext.js';
|
|
3
|
+
/**
|
|
4
|
+
`useCursor` is a React hook that lets you control the terminal cursor position.
|
|
5
|
+
|
|
6
|
+
Setting a cursor position makes the cursor visible at the specified coordinates (relative to the Ink output origin). This is useful for IME (Input Method Editor) support, where the composing character is displayed at the cursor location.
|
|
7
|
+
|
|
8
|
+
Pass `undefined` to hide the cursor.
|
|
9
|
+
*/
|
|
10
|
+
const useCursor = () => {
|
|
11
|
+
const context = useContext(CursorContext);
|
|
12
|
+
const positionRef = useRef(undefined);
|
|
13
|
+
const setCursorPosition = useCallback((position) => {
|
|
14
|
+
positionRef.current = position;
|
|
15
|
+
}, []);
|
|
16
|
+
// Propagate cursor position to log-update only during commit phase.
|
|
17
|
+
// useInsertionEffect runs before resetAfterCommit (which triggers onRender),
|
|
18
|
+
// and does NOT run for abandoned concurrent renders (e.g. suspended components).
|
|
19
|
+
// This prevents cursor state from leaking across render boundaries.
|
|
20
|
+
useInsertionEffect(() => {
|
|
21
|
+
context.setCursorPosition(positionRef.current);
|
|
22
|
+
return () => {
|
|
23
|
+
context.setCursorPosition(undefined);
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
return { setCursorPosition };
|
|
27
|
+
};
|
|
28
|
+
export default useCursor;
|
|
29
|
+
//# sourceMappingURL=use-cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-cursor.js","sourceRoot":"","sources":["../../src/hooks/use-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAC,MAAM,OAAO,CAAC;AAC1E,OAAO,aAAa,MAAM,gCAAgC,CAAC;AAG3D;;;;;;EAME;AACF,MAAM,SAAS,GAAG,GAAG,EAAE;IACtB,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,MAAM,CAA6B,SAAS,CAAC,CAAC;IAElE,MAAM,iBAAiB,GAAG,WAAW,CACpC,CAAC,QAAoC,EAAE,EAAE;QACxC,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAChC,CAAC,EACD,EAAE,CACF,CAAC;IAEF,oEAAoE;IACpE,6EAA6E;IAC7E,iFAAiF;IACjF,oEAAoE;IACpE,kBAAkB,CAAC,GAAG,EAAE;QACvB,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC/C,OAAO,GAAG,EAAE;YACX,OAAO,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,EAAC,iBAAiB,EAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -66,6 +66,36 @@ export type Key = {
|
|
|
66
66
|
[Meta key](https://en.wikipedia.org/wiki/Meta_key) was pressed.
|
|
67
67
|
*/
|
|
68
68
|
meta: boolean;
|
|
69
|
+
/**
|
|
70
|
+
Super key (Cmd on Mac, Win on Windows) was pressed.
|
|
71
|
+
|
|
72
|
+
Only available with kitty keyboard protocol.
|
|
73
|
+
*/
|
|
74
|
+
super: boolean;
|
|
75
|
+
/**
|
|
76
|
+
Hyper key was pressed.
|
|
77
|
+
|
|
78
|
+
Only available with kitty keyboard protocol.
|
|
79
|
+
*/
|
|
80
|
+
hyper: boolean;
|
|
81
|
+
/**
|
|
82
|
+
Caps Lock is active.
|
|
83
|
+
|
|
84
|
+
Only available with kitty keyboard protocol.
|
|
85
|
+
*/
|
|
86
|
+
capsLock: boolean;
|
|
87
|
+
/**
|
|
88
|
+
Num Lock is active.
|
|
89
|
+
|
|
90
|
+
Only available with kitty keyboard protocol.
|
|
91
|
+
*/
|
|
92
|
+
numLock: boolean;
|
|
93
|
+
/**
|
|
94
|
+
Event type for key events.
|
|
95
|
+
|
|
96
|
+
Only available with kitty keyboard protocol.
|
|
97
|
+
*/
|
|
98
|
+
eventType?: 'press' | 'repeat' | 'release';
|
|
69
99
|
};
|
|
70
100
|
type Handler = (input: string, key: Key) => void;
|
|
71
101
|
type Options = {
|
package/build/hooks/use-input.js
CHANGED
|
@@ -62,9 +62,38 @@ const useInput = (inputHandler, options = {}) => {
|
|
|
62
62
|
// to avoid breaking changes in Ink.
|
|
63
63
|
// TODO(vadimdemedes): consider removing this in the next major version.
|
|
64
64
|
meta: keypress.meta || keypress.name === 'escape' || keypress.option,
|
|
65
|
+
// Kitty keyboard protocol modifiers
|
|
66
|
+
super: keypress.super ?? false,
|
|
67
|
+
hyper: keypress.hyper ?? false,
|
|
68
|
+
capsLock: keypress.capsLock ?? false,
|
|
69
|
+
numLock: keypress.numLock ?? false,
|
|
70
|
+
eventType: keypress.eventType,
|
|
65
71
|
};
|
|
66
|
-
let input
|
|
67
|
-
if (
|
|
72
|
+
let input;
|
|
73
|
+
if (keypress.isKittyProtocol) {
|
|
74
|
+
// Use text-as-codepoints field for printable keys (needed when
|
|
75
|
+
// reportAllKeysAsEscapeCodes flag is enabled), suppress non-printable
|
|
76
|
+
if (keypress.isPrintable) {
|
|
77
|
+
input = keypress.text ?? keypress.name;
|
|
78
|
+
}
|
|
79
|
+
else if (keypress.ctrl && keypress.name.length === 1) {
|
|
80
|
+
// Ctrl+letter via codepoint 1-26 form: not printable text, but
|
|
81
|
+
// the letter name must flow through so handlers (e.g. exitOnCtrlC
|
|
82
|
+
// checking `input === 'c' && key.ctrl`) still work.
|
|
83
|
+
input = keypress.name;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
input = '';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else if (keypress.ctrl) {
|
|
90
|
+
input = keypress.name;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
input = keypress.sequence;
|
|
94
|
+
}
|
|
95
|
+
if (!keypress.isKittyProtocol &&
|
|
96
|
+
nonAlphanumericKeys.includes(keypress.name)) {
|
|
68
97
|
input = '';
|
|
69
98
|
}
|
|
70
99
|
// Strip meta if it's still remaining after `parseKeypress`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-input.js","sourceRoot":"","sources":["../../src/hooks/use-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAChC,OAAO,aAAa,EAAE,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AACxE,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,QAAQ,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-input.js","sourceRoot":"","sources":["../../src/hooks/use-input.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type { RenderOptions, Instance } from './render.js';
|
|
2
2
|
export { default as render } from './render.js';
|
|
3
|
+
export type { RenderToStringOptions } from './render-to-string.js';
|
|
4
|
+
export { default as renderToString } from './render-to-string.js';
|
|
3
5
|
export type { Props as BoxProps } from './components/Box.js';
|
|
4
6
|
export { default as Box } from './components/Box.js';
|
|
5
7
|
export type { Props as TextProps } from './components/Text.js';
|
|
@@ -24,5 +26,9 @@ export { default as useStderr } from './hooks/use-stderr.js';
|
|
|
24
26
|
export { default as useFocus } from './hooks/use-focus.js';
|
|
25
27
|
export { default as useFocusManager } from './hooks/use-focus-manager.js';
|
|
26
28
|
export { default as useIsScreenReaderEnabled } from './hooks/use-is-screen-reader-enabled.js';
|
|
29
|
+
export { default as useCursor } from './hooks/use-cursor.js';
|
|
30
|
+
export type { CursorPosition } from './log-update.js';
|
|
27
31
|
export { default as measureElement } from './measure-element.js';
|
|
28
32
|
export type { DOMElement } from './dom.js';
|
|
33
|
+
export { kittyFlags, kittyModifiers } from './kitty-keyboard.js';
|
|
34
|
+
export type { KittyKeyboardOptions, KittyFlagName } from './kitty-keyboard.js';
|
package/build/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as render } from './render.js';
|
|
2
|
+
export { default as renderToString } from './render-to-string.js';
|
|
2
3
|
export { default as Box } from './components/Box.js';
|
|
3
4
|
export { default as Text } from './components/Text.js';
|
|
4
5
|
export { default as Static } from './components/Static.js';
|
|
@@ -13,5 +14,7 @@ export { default as useStderr } from './hooks/use-stderr.js';
|
|
|
13
14
|
export { default as useFocus } from './hooks/use-focus.js';
|
|
14
15
|
export { default as useFocusManager } from './hooks/use-focus-manager.js';
|
|
15
16
|
export { default as useIsScreenReaderEnabled } from './hooks/use-is-screen-reader-enabled.js';
|
|
17
|
+
export { default as useCursor } from './hooks/use-cursor.js';
|
|
16
18
|
export { default as measureElement } from './measure-element.js';
|
|
19
|
+
export { kittyFlags, kittyModifiers } from './kitty-keyboard.js';
|
|
17
20
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAC,OAAO,IAAI,GAAG,EAAC,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,sBAAsB,CAAC;AAMrD,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAC,OAAO,IAAI,OAAO,EAAC,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAC,OAAO,IAAI,wBAAwB,EAAC,MAAM,yCAAyC,CAAC;AAC5F,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAAC,OAAO,IAAI,GAAG,EAAC,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,sBAAsB,CAAC;AAMrD,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAC,OAAO,IAAI,OAAO,EAAC,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAC,OAAO,IAAI,wBAAwB,EAAC,MAAM,yCAAyC,CAAC;AAC5F,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAC,UAAU,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAC"}
|
package/build/ink.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
+
import { type CursorPosition } from './log-update.js';
|
|
3
|
+
import { type KittyKeyboardOptions } from './kitty-keyboard.js';
|
|
2
4
|
/**
|
|
3
5
|
Performance metrics for a render operation.
|
|
4
6
|
*/
|
|
@@ -17,38 +19,72 @@ export type Options = {
|
|
|
17
19
|
patchConsole: boolean;
|
|
18
20
|
onRender?: (metrics: RenderMetrics) => void;
|
|
19
21
|
isScreenReaderEnabled?: boolean;
|
|
20
|
-
waitUntilExit?: () => Promise<
|
|
22
|
+
waitUntilExit?: () => Promise<unknown>;
|
|
21
23
|
maxFps?: number;
|
|
22
24
|
incrementalRendering?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
Enable React Concurrent Rendering mode.
|
|
27
|
+
|
|
28
|
+
When enabled:
|
|
29
|
+
- Suspense boundaries work correctly with async data
|
|
30
|
+
- `useTransition` and `useDeferredValue` are fully functional
|
|
31
|
+
- Updates can be interrupted for higher priority work
|
|
32
|
+
|
|
33
|
+
Note: Concurrent mode changes the timing of renders. Some tests may need to use `act()` to properly await updates. The `concurrent` option only takes effect on the first render for a given stdout. If you need to change the rendering mode, call `unmount()` first.
|
|
34
|
+
|
|
35
|
+
@default false
|
|
36
|
+
@experimental
|
|
37
|
+
*/
|
|
38
|
+
concurrent?: boolean;
|
|
39
|
+
kittyKeyboard?: KittyKeyboardOptions;
|
|
23
40
|
};
|
|
24
41
|
export default class Ink {
|
|
42
|
+
/**
|
|
43
|
+
Whether this instance is using concurrent rendering mode.
|
|
44
|
+
*/
|
|
45
|
+
readonly isConcurrent: boolean;
|
|
25
46
|
private readonly options;
|
|
26
47
|
private readonly log;
|
|
48
|
+
private cursorPosition;
|
|
27
49
|
private readonly throttledLog;
|
|
28
50
|
private readonly isScreenReaderEnabled;
|
|
29
51
|
private isUnmounted;
|
|
52
|
+
private isUnmounting;
|
|
30
53
|
private lastOutput;
|
|
54
|
+
private lastOutputToRender;
|
|
31
55
|
private lastOutputHeight;
|
|
32
56
|
private lastTerminalWidth;
|
|
33
57
|
private readonly container;
|
|
34
58
|
private readonly rootNode;
|
|
35
59
|
private fullStaticOutput;
|
|
36
60
|
private exitPromise?;
|
|
61
|
+
private exitResult;
|
|
62
|
+
private beforeExitHandler?;
|
|
37
63
|
private restoreConsole?;
|
|
38
64
|
private readonly unsubscribeResize?;
|
|
65
|
+
private readonly throttledOnRender?;
|
|
66
|
+
private hasPendingThrottledRender;
|
|
67
|
+
private kittyProtocolEnabled;
|
|
68
|
+
private cancelKittyDetection?;
|
|
39
69
|
constructor(options: Options);
|
|
40
70
|
getTerminalWidth: () => number;
|
|
41
71
|
resized: () => void;
|
|
42
|
-
resolveExitPromise: () => void;
|
|
72
|
+
resolveExitPromise: (result?: unknown) => void;
|
|
43
73
|
rejectExitPromise: (reason?: Error) => void;
|
|
44
74
|
unsubscribeExit: () => void;
|
|
75
|
+
handleAppExit: (errorOrResult?: unknown) => void;
|
|
76
|
+
setCursorPosition: (position: CursorPosition | undefined) => void;
|
|
77
|
+
restoreLastOutput: () => void;
|
|
45
78
|
calculateLayout: () => void;
|
|
46
79
|
onRender: () => void;
|
|
47
80
|
render(node: ReactNode): void;
|
|
48
81
|
writeToStdout(data: string): void;
|
|
49
82
|
writeToStderr(data: string): void;
|
|
50
83
|
unmount(error?: Error | number | null): void;
|
|
51
|
-
waitUntilExit(): Promise<
|
|
84
|
+
waitUntilExit(): Promise<unknown>;
|
|
52
85
|
clear(): void;
|
|
53
86
|
patchConsole(): void;
|
|
87
|
+
private initKittyKeyboard;
|
|
88
|
+
private confirmKittySupport;
|
|
89
|
+
private enableKittyProtocol;
|
|
54
90
|
}
|