Comparing version 3.2.0 to 4.0.0
@@ -1,3 +0,3 @@ | ||
declare type ColorType = 'foreground' | 'background'; | ||
declare const _default: (str: string, color: string | undefined, type: ColorType) => string; | ||
export default _default; | ||
type ColorType = 'foreground' | 'background'; | ||
declare const colorize: (str: string, color: string | undefined, type: ColorType) => string; | ||
export default colorize; |
@@ -1,53 +0,48 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
import chalk from 'chalk'; | ||
const rgbRegex = /^rgb\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/; | ||
const ansiRegex = /^ansi256\(\s?(\d+)\s?\)$/; | ||
const isNamedColor = (color) => { | ||
return color in chalk; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const chalk_1 = __importDefault(require("chalk")); | ||
const RGB_LIKE_REGEX = /^(rgb|hsl|hsv|hwb)\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/; | ||
const ANSI_REGEX = /^(ansi|ansi256)\(\s?(\d+)\s?\)$/; | ||
const getMethod = (name, type) => { | ||
if (type === 'foreground') { | ||
return name; | ||
} | ||
return 'bg' + name[0].toUpperCase() + name.slice(1); | ||
}; | ||
exports.default = (str, color, type) => { | ||
const colorize = (str, color, type) => { | ||
if (!color) { | ||
return str; | ||
} | ||
if (color in chalk_1.default) { | ||
const method = getMethod(color, type); | ||
return chalk_1.default[method](str); | ||
if (isNamedColor(color)) { | ||
if (type === 'foreground') { | ||
return chalk[color](str); | ||
} | ||
const methodName = `bg${color[0].toUpperCase() + color.slice(1)}`; | ||
return chalk[methodName](str); | ||
} | ||
if (color.startsWith('#')) { | ||
const method = getMethod('hex', type); | ||
return chalk_1.default[method](color)(str); | ||
return type === 'foreground' | ||
? chalk.hex(color)(str) | ||
: chalk.bgHex(color)(str); | ||
} | ||
if (color.startsWith('ansi')) { | ||
const matches = ANSI_REGEX.exec(color); | ||
if (color.startsWith('ansi256')) { | ||
const matches = ansiRegex.exec(color); | ||
if (!matches) { | ||
return str; | ||
} | ||
const method = getMethod(matches[1], type); | ||
const value = Number(matches[2]); | ||
return chalk_1.default[method](value)(str); | ||
const value = Number(matches[1]); | ||
return type === 'foreground' | ||
? chalk.ansi256(value)(str) | ||
: chalk.bgAnsi256(value)(str); | ||
} | ||
const isRgbLike = color.startsWith('rgb') || | ||
color.startsWith('hsl') || | ||
color.startsWith('hsv') || | ||
color.startsWith('hwb'); | ||
if (isRgbLike) { | ||
const matches = RGB_LIKE_REGEX.exec(color); | ||
if (color.startsWith('rgb')) { | ||
const matches = rgbRegex.exec(color); | ||
if (!matches) { | ||
return str; | ||
} | ||
const method = getMethod(matches[1], type); | ||
const firstValue = Number(matches[2]); | ||
const secondValue = Number(matches[3]); | ||
const thirdValue = Number(matches[4]); | ||
return chalk_1.default[method](firstValue, secondValue, thirdValue)(str); | ||
const firstValue = Number(matches[1]); | ||
const secondValue = Number(matches[2]); | ||
const thirdValue = Number(matches[3]); | ||
return type === 'foreground' | ||
? chalk.rgb(firstValue, secondValue, thirdValue)(str) | ||
: chalk.bgRgb(firstValue, secondValue, thirdValue)(str); | ||
} | ||
return str; | ||
}; | ||
export default colorize; | ||
//# sourceMappingURL=colorize.js.map |
@@ -1,4 +0,4 @@ | ||
/// <reference types="node" /> | ||
import { PureComponent, ReactNode } from 'react'; | ||
interface Props { | ||
/// <reference types="node" resolution-mode="require"/> | ||
import { PureComponent, type ReactNode } from 'react'; | ||
type Props = { | ||
readonly children: ReactNode; | ||
@@ -12,4 +12,4 @@ readonly stdin: NodeJS.ReadStream; | ||
readonly onExit: (error?: Error) => void; | ||
} | ||
interface State { | ||
}; | ||
type State = { | ||
readonly isFocusEnabled: boolean; | ||
@@ -19,9 +19,12 @@ readonly activeFocusId?: string; | ||
readonly error?: Error; | ||
} | ||
interface Focusable { | ||
}; | ||
type Focusable = { | ||
readonly id: string; | ||
readonly isActive: boolean; | ||
} | ||
}; | ||
export default class App extends PureComponent<Props, State> { | ||
static displayName: string; | ||
static getDerivedStateFromError(error: Error): { | ||
error: Error; | ||
}; | ||
state: { | ||
@@ -34,5 +37,2 @@ isFocusEnabled: boolean; | ||
rawModeEnabledCount: number; | ||
static getDerivedStateFromError(error: Error): { | ||
error: Error; | ||
}; | ||
isRawModeSupported(): boolean; | ||
@@ -45,3 +45,3 @@ render(): JSX.Element; | ||
handleInput: (input: string) => void; | ||
handleExit: (error?: Error | undefined) => void; | ||
handleExit: (error?: Error) => void; | ||
enableFocus: () => void; | ||
@@ -48,0 +48,0 @@ disableFocus: () => void; |
@@ -1,227 +0,281 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ | ||
const react_1 = __importStar(require("react")); | ||
const cli_cursor_1 = __importDefault(require("cli-cursor")); | ||
const AppContext_1 = __importDefault(require("./AppContext")); | ||
const StdinContext_1 = __importDefault(require("./StdinContext")); | ||
const StdoutContext_1 = __importDefault(require("./StdoutContext")); | ||
const StderrContext_1 = __importDefault(require("./StderrContext")); | ||
const FocusContext_1 = __importDefault(require("./FocusContext")); | ||
const ErrorOverview_1 = __importDefault(require("./ErrorOverview")); | ||
const TAB = '\t'; | ||
const SHIFT_TAB = '\u001B[Z'; | ||
const ESC = '\u001B'; | ||
import process from 'node:process'; | ||
import React, { PureComponent } from 'react'; | ||
import cliCursor from 'cli-cursor'; | ||
import AppContext from './AppContext.js'; | ||
import StdinContext from './StdinContext.js'; | ||
import StdoutContext from './StdoutContext.js'; | ||
import StderrContext from './StderrContext.js'; | ||
import FocusContext from './FocusContext.js'; | ||
import ErrorOverview from './ErrorOverview.js'; | ||
const tab = '\t'; | ||
const shiftTab = '\u001B[Z'; | ||
const escape = '\u001B'; | ||
// Root component for all Ink apps | ||
// It renders stdin and stdout contexts, so that children can access them if needed | ||
// It also handles Ctrl+C exiting and cursor visibility | ||
class App extends react_1.PureComponent { | ||
export default class App extends PureComponent { | ||
constructor() { | ||
super(...arguments); | ||
this.state = { | ||
isFocusEnabled: true, | ||
activeFocusId: undefined, | ||
focusables: [], | ||
error: undefined | ||
}; | ||
Object.defineProperty(this, "state", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: { | ||
isFocusEnabled: true, | ||
activeFocusId: undefined, | ||
focusables: [], | ||
error: undefined | ||
} | ||
}); | ||
// Count how many components enabled raw mode to avoid disabling | ||
// raw mode until all components don't need it anymore | ||
this.rawModeEnabledCount = 0; | ||
this.handleSetRawMode = (isEnabled) => { | ||
const { stdin } = this.props; | ||
if (!this.isRawModeSupported()) { | ||
if (stdin === process.stdin) { | ||
throw new Error('Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported'); | ||
Object.defineProperty(this, "rawModeEnabledCount", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: 0 | ||
}); | ||
Object.defineProperty(this, "handleSetRawMode", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (isEnabled) => { | ||
const { stdin } = this.props; | ||
if (!this.isRawModeSupported()) { | ||
if (stdin === process.stdin) { | ||
throw new Error('Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported'); | ||
} | ||
else { | ||
throw new Error('Raw mode is not supported on the stdin provided to Ink.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported'); | ||
} | ||
} | ||
else { | ||
throw new Error('Raw mode is not supported on the stdin provided to Ink.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported'); | ||
stdin.setEncoding('utf8'); | ||
if (isEnabled) { | ||
// Ensure raw mode is enabled only once | ||
if (this.rawModeEnabledCount === 0) { | ||
stdin.addListener('data', this.handleInput); | ||
stdin.resume(); | ||
stdin.setRawMode(true); | ||
} | ||
this.rawModeEnabledCount++; | ||
return; | ||
} | ||
// Disable raw mode only when no components left that are using it | ||
if (--this.rawModeEnabledCount === 0) { | ||
stdin.setRawMode(false); | ||
stdin.removeListener('data', this.handleInput); | ||
stdin.pause(); | ||
} | ||
} | ||
stdin.setEncoding('utf8'); | ||
if (isEnabled) { | ||
// Ensure raw mode is enabled only once | ||
if (this.rawModeEnabledCount === 0) { | ||
stdin.addListener('data', this.handleInput); | ||
stdin.resume(); | ||
stdin.setRawMode(true); | ||
}); | ||
Object.defineProperty(this, "handleInput", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (input) => { | ||
// Exit on Ctrl+C | ||
// eslint-disable-next-line unicorn/no-hex-escape | ||
if (input === '\x03' && this.props.exitOnCtrlC) { | ||
this.handleExit(); | ||
} | ||
this.rawModeEnabledCount++; | ||
return; | ||
// Reset focus when there's an active focused component on Esc | ||
if (input === escape && this.state.activeFocusId) { | ||
this.setState({ | ||
activeFocusId: undefined | ||
}); | ||
} | ||
if (this.state.isFocusEnabled && this.state.focusables.length > 0) { | ||
if (input === tab) { | ||
this.focusNext(); | ||
} | ||
if (input === shiftTab) { | ||
this.focusPrevious(); | ||
} | ||
} | ||
} | ||
// Disable raw mode only when no components left that are using it | ||
if (--this.rawModeEnabledCount === 0) { | ||
stdin.setRawMode(false); | ||
stdin.removeListener('data', this.handleInput); | ||
stdin.pause(); | ||
}); | ||
Object.defineProperty(this, "handleExit", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (error) => { | ||
if (this.isRawModeSupported()) { | ||
this.handleSetRawMode(false); | ||
} | ||
this.props.onExit(error); | ||
} | ||
}; | ||
this.handleInput = (input) => { | ||
// Exit on Ctrl+C | ||
// eslint-disable-next-line unicorn/no-hex-escape | ||
if (input === '\x03' && this.props.exitOnCtrlC) { | ||
this.handleExit(); | ||
}); | ||
Object.defineProperty(this, "enableFocus", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: () => { | ||
this.setState({ | ||
isFocusEnabled: true | ||
}); | ||
} | ||
// Reset focus when there's an active focused component on Esc | ||
if (input === ESC && this.state.activeFocusId) { | ||
}); | ||
Object.defineProperty(this, "disableFocus", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: () => { | ||
this.setState({ | ||
activeFocusId: undefined | ||
isFocusEnabled: false | ||
}); | ||
} | ||
if (this.state.isFocusEnabled && this.state.focusables.length > 0) { | ||
if (input === TAB) { | ||
this.focusNext(); | ||
} | ||
if (input === SHIFT_TAB) { | ||
this.focusPrevious(); | ||
} | ||
}); | ||
Object.defineProperty(this, "focus", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (id) => { | ||
this.setState(previousState => { | ||
const hasFocusableId = previousState.focusables.some(focusable => focusable?.id === id); | ||
if (!hasFocusableId) { | ||
return previousState; | ||
} | ||
return { activeFocusId: id }; | ||
}); | ||
} | ||
}; | ||
this.handleExit = (error) => { | ||
if (this.isRawModeSupported()) { | ||
this.handleSetRawMode(false); | ||
}); | ||
Object.defineProperty(this, "focusNext", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: () => { | ||
this.setState(previousState => { | ||
const firstFocusableId = previousState.focusables[0]?.id; | ||
const nextFocusableId = this.findNextFocusable(previousState); | ||
return { | ||
activeFocusId: nextFocusableId ?? firstFocusableId | ||
}; | ||
}); | ||
} | ||
this.props.onExit(error); | ||
}; | ||
this.enableFocus = () => { | ||
this.setState({ | ||
isFocusEnabled: true | ||
}); | ||
}; | ||
this.disableFocus = () => { | ||
this.setState({ | ||
isFocusEnabled: false | ||
}); | ||
}; | ||
this.focus = (id) => { | ||
this.setState(previousState => { | ||
const hasFocusableId = previousState.focusables.some(focusable => (focusable === null || focusable === void 0 ? void 0 : focusable.id) === id); | ||
if (!hasFocusableId) { | ||
return previousState; | ||
} | ||
return { activeFocusId: id }; | ||
}); | ||
}; | ||
this.focusNext = () => { | ||
this.setState(previousState => { | ||
var _a; | ||
const firstFocusableId = (_a = previousState.focusables[0]) === null || _a === void 0 ? void 0 : _a.id; | ||
const nextFocusableId = this.findNextFocusable(previousState); | ||
return { | ||
activeFocusId: nextFocusableId || firstFocusableId | ||
}; | ||
}); | ||
}; | ||
this.focusPrevious = () => { | ||
this.setState(previousState => { | ||
var _a; | ||
const lastFocusableId = (_a = previousState.focusables[previousState.focusables.length - 1]) === null || _a === void 0 ? void 0 : _a.id; | ||
const previousFocusableId = this.findPreviousFocusable(previousState); | ||
return { | ||
activeFocusId: previousFocusableId || lastFocusableId | ||
}; | ||
}); | ||
}; | ||
this.addFocusable = (id, { autoFocus }) => { | ||
this.setState(previousState => { | ||
let nextFocusId = previousState.activeFocusId; | ||
if (!nextFocusId && autoFocus) { | ||
nextFocusId = id; | ||
} | ||
return { | ||
activeFocusId: nextFocusId, | ||
focusables: [ | ||
...previousState.focusables, | ||
{ | ||
id, | ||
isActive: true | ||
} | ||
] | ||
}; | ||
}); | ||
}; | ||
this.removeFocusable = (id) => { | ||
this.setState(previousState => ({ | ||
activeFocusId: previousState.activeFocusId === id | ||
? undefined | ||
: previousState.activeFocusId, | ||
focusables: previousState.focusables.filter(focusable => { | ||
return focusable.id !== id; | ||
}) | ||
})); | ||
}; | ||
this.activateFocusable = (id) => { | ||
this.setState(previousState => ({ | ||
focusables: previousState.focusables.map(focusable => { | ||
if (focusable.id !== id) { | ||
return focusable; | ||
} | ||
}); | ||
Object.defineProperty(this, "focusPrevious", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: () => { | ||
this.setState(previousState => { | ||
const lastFocusableId = previousState.focusables[previousState.focusables.length - 1]?.id; | ||
const previousFocusableId = this.findPreviousFocusable(previousState); | ||
return { | ||
id, | ||
isActive: true | ||
activeFocusId: previousFocusableId ?? lastFocusableId | ||
}; | ||
}) | ||
})); | ||
}; | ||
this.deactivateFocusable = (id) => { | ||
this.setState(previousState => ({ | ||
activeFocusId: previousState.activeFocusId === id | ||
? undefined | ||
: previousState.activeFocusId, | ||
focusables: previousState.focusables.map(focusable => { | ||
if (focusable.id !== id) { | ||
return focusable; | ||
}); | ||
} | ||
}); | ||
Object.defineProperty(this, "addFocusable", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (id, { autoFocus }) => { | ||
this.setState(previousState => { | ||
let nextFocusId = previousState.activeFocusId; | ||
if (!nextFocusId && autoFocus) { | ||
nextFocusId = id; | ||
} | ||
return { | ||
id, | ||
isActive: false | ||
activeFocusId: nextFocusId, | ||
focusables: [ | ||
...previousState.focusables, | ||
{ | ||
id, | ||
isActive: true | ||
} | ||
] | ||
}; | ||
}) | ||
})); | ||
}; | ||
this.findNextFocusable = (state) => { | ||
var _a; | ||
const activeIndex = state.focusables.findIndex(focusable => { | ||
return focusable.id === state.activeFocusId; | ||
}); | ||
for (let index = activeIndex + 1; index < state.focusables.length; index++) { | ||
if ((_a = state.focusables[index]) === null || _a === void 0 ? void 0 : _a.isActive) { | ||
return state.focusables[index].id; | ||
}); | ||
} | ||
}); | ||
Object.defineProperty(this, "removeFocusable", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (id) => { | ||
this.setState(previousState => ({ | ||
activeFocusId: previousState.activeFocusId === id | ||
? undefined | ||
: previousState.activeFocusId, | ||
focusables: previousState.focusables.filter(focusable => { | ||
return focusable.id !== id; | ||
}) | ||
})); | ||
} | ||
}); | ||
Object.defineProperty(this, "activateFocusable", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (id) => { | ||
this.setState(previousState => ({ | ||
focusables: previousState.focusables.map(focusable => { | ||
if (focusable.id !== id) { | ||
return focusable; | ||
} | ||
return { | ||
id, | ||
isActive: true | ||
}; | ||
}) | ||
})); | ||
} | ||
}); | ||
Object.defineProperty(this, "deactivateFocusable", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (id) => { | ||
this.setState(previousState => ({ | ||
activeFocusId: previousState.activeFocusId === id | ||
? undefined | ||
: previousState.activeFocusId, | ||
focusables: previousState.focusables.map(focusable => { | ||
if (focusable.id !== id) { | ||
return focusable; | ||
} | ||
return { | ||
id, | ||
isActive: false | ||
}; | ||
}) | ||
})); | ||
} | ||
}); | ||
Object.defineProperty(this, "findNextFocusable", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (state) => { | ||
const activeIndex = state.focusables.findIndex(focusable => { | ||
return focusable.id === state.activeFocusId; | ||
}); | ||
for (let index = activeIndex + 1; index < state.focusables.length; index++) { | ||
const focusable = state.focusables[index]; | ||
if (focusable?.isActive) { | ||
return focusable.id; | ||
} | ||
} | ||
return undefined; | ||
} | ||
return undefined; | ||
}; | ||
this.findPreviousFocusable = (state) => { | ||
var _a; | ||
const activeIndex = state.focusables.findIndex(focusable => { | ||
return focusable.id === state.activeFocusId; | ||
}); | ||
for (let index = activeIndex - 1; index >= 0; index--) { | ||
if ((_a = state.focusables[index]) === null || _a === void 0 ? void 0 : _a.isActive) { | ||
return state.focusables[index].id; | ||
}); | ||
Object.defineProperty(this, "findPreviousFocusable", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: (state) => { | ||
const activeIndex = state.focusables.findIndex(focusable => { | ||
return focusable.id === state.activeFocusId; | ||
}); | ||
for (let index = activeIndex - 1; index >= 0; index--) { | ||
const focusable = state.focusables[index]; | ||
if (focusable?.isActive) { | ||
return focusable.id; | ||
} | ||
} | ||
return undefined; | ||
} | ||
return undefined; | ||
}; | ||
}); | ||
} | ||
@@ -236,20 +290,41 @@ static getDerivedStateFromError(error) { | ||
render() { | ||
return (react_1.default.createElement(AppContext_1.default.Provider, { value: { | ||
return (React.createElement(AppContext.Provider | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
, { | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
value: { | ||
exit: this.handleExit | ||
} }, | ||
react_1.default.createElement(StdinContext_1.default.Provider, { value: { | ||
React.createElement(StdinContext.Provider | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
, { | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
value: { | ||
stdin: this.props.stdin, | ||
setRawMode: this.handleSetRawMode, | ||
isRawModeSupported: this.isRawModeSupported(), | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
internal_exitOnCtrlC: this.props.exitOnCtrlC | ||
} }, | ||
react_1.default.createElement(StdoutContext_1.default.Provider, { value: { | ||
React.createElement(StdoutContext.Provider | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
, { | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
value: { | ||
stdout: this.props.stdout, | ||
write: this.props.writeToStdout | ||
} }, | ||
react_1.default.createElement(StderrContext_1.default.Provider, { value: { | ||
React.createElement(StderrContext.Provider | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
, { | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
value: { | ||
stderr: this.props.stderr, | ||
write: this.props.writeToStderr | ||
} }, | ||
react_1.default.createElement(FocusContext_1.default.Provider, { value: { | ||
React.createElement(FocusContext.Provider | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
, { | ||
// eslint-disable-next-line react/jsx-no-constructed-context-values | ||
value: { | ||
activeId: this.state.activeFocusId, | ||
@@ -265,9 +340,9 @@ add: this.addFocusable, | ||
focus: this.focus | ||
} }, this.state.error ? (react_1.default.createElement(ErrorOverview_1.default, { error: this.state.error })) : (this.props.children))))))); | ||
} }, this.state.error ? (React.createElement(ErrorOverview, { error: this.state.error })) : (this.props.children))))))); | ||
} | ||
componentDidMount() { | ||
cli_cursor_1.default.hide(this.props.stdout); | ||
cliCursor.hide(this.props.stdout); | ||
} | ||
componentWillUnmount() { | ||
cli_cursor_1.default.show(this.props.stdout); | ||
cliCursor.show(this.props.stdout); | ||
// ignore calling setRawMode on an handle stdin it cannot be called | ||
@@ -282,4 +357,8 @@ if (this.isRawModeSupported()) { | ||
} | ||
exports.default = App; | ||
App.displayName = 'InternalApp'; | ||
Object.defineProperty(App, "displayName", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: 'InternalApp' | ||
}); | ||
//# sourceMappingURL=App.js.map |
/// <reference types="react" /> | ||
export interface Props { | ||
export type Props = { | ||
/** | ||
@@ -7,3 +7,3 @@ * Exit (unmount) the whole Ink app. | ||
readonly exit: (error?: Error) => void; | ||
} | ||
}; | ||
/** | ||
@@ -10,0 +10,0 @@ * `AppContext` is a React context, which exposes a method to manually exit the app (unmount). |
@@ -1,12 +0,11 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
import { createContext } from 'react'; | ||
/** | ||
* `AppContext` is a React context, which exposes a method to manually exit the app (unmount). | ||
*/ | ||
const AppContext = react_1.createContext({ | ||
exit: () => { } | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const AppContext = createContext({ | ||
exit() { } | ||
}); | ||
AppContext.displayName = 'InternalAppContext'; | ||
exports.default = AppContext; | ||
export default AppContext; | ||
//# sourceMappingURL=AppContext.js.map |
import React from 'react'; | ||
import { Except } from 'type-fest'; | ||
import { Styles } from '../styles'; | ||
import { DOMElement } from '../dom'; | ||
export declare type Props = Except<Styles, 'textWrap'> & { | ||
import { type Except } from 'type-fest'; | ||
import { type Styles } from '../styles.js'; | ||
import { type DOMElement } from '../dom.js'; | ||
export type Props = Except<Styles, 'textWrap'> & { | ||
/** | ||
@@ -46,3 +46,3 @@ * Margin on all sides. Equivalent to setting `marginTop`, `marginBottom`, `marginLeft` and `marginRight`. | ||
*/ | ||
declare const Box: React.ForwardRefExoticComponent<Pick<Styles, "position" | "marginLeft" | "marginRight" | "marginTop" | "marginBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "paddingBottom" | "flexGrow" | "flexShrink" | "flexDirection" | "flexBasis" | "alignItems" | "alignSelf" | "justifyContent" | "width" | "height" | "minWidth" | "minHeight" | "display" | "borderStyle" | "borderColor"> & { | ||
declare const Box: React.ForwardRefExoticComponent<Except<Styles, "textWrap"> & { | ||
/** | ||
@@ -49,0 +49,0 @@ * Margin on all sides. Equivalent to setting `marginTop`, `marginBottom`, `marginLeft` and `marginRight`. |
@@ -1,42 +0,19 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ | ||
const react_1 = __importStar(require("react")); | ||
import React, { forwardRef } from 'react'; | ||
/** | ||
* `<Box>` is an essential Ink component to build your layout. It's like `<div style="display: flex">` in the browser. | ||
*/ | ||
const Box = react_1.forwardRef((_a, ref) => { | ||
var { children } = _a, style = __rest(_a, ["children"]); | ||
const transformedStyle = Object.assign(Object.assign({}, style), { marginLeft: style.marginLeft || style.marginX || style.margin || 0, marginRight: style.marginRight || style.marginX || style.margin || 0, marginTop: style.marginTop || style.marginY || style.margin || 0, marginBottom: style.marginBottom || style.marginY || style.margin || 0, paddingLeft: style.paddingLeft || style.paddingX || style.padding || 0, paddingRight: style.paddingRight || style.paddingX || style.padding || 0, paddingTop: style.paddingTop || style.paddingY || style.padding || 0, paddingBottom: style.paddingBottom || style.paddingY || style.padding || 0 }); | ||
return (react_1.default.createElement("ink-box", { ref: ref, style: transformedStyle }, children)); | ||
const Box = forwardRef(({ children, ...style }, ref) => { | ||
const transformedStyle = { | ||
...style, | ||
marginLeft: style.marginLeft || style.marginX || style.margin || 0, | ||
marginRight: style.marginRight || style.marginX || style.margin || 0, | ||
marginTop: style.marginTop || style.marginY || style.margin || 0, | ||
marginBottom: style.marginBottom || style.marginY || style.margin || 0, | ||
paddingLeft: style.paddingLeft || style.paddingX || style.padding || 0, | ||
paddingRight: style.paddingRight || style.paddingX || style.padding || 0, | ||
paddingTop: style.paddingTop || style.paddingY || style.padding || 0, | ||
paddingBottom: style.paddingBottom || style.paddingY || style.padding || 0 | ||
}; | ||
return (React.createElement("ink-box", { ref: ref, style: transformedStyle }, children)); | ||
}); | ||
@@ -49,3 +26,3 @@ Box.displayName = 'Box'; | ||
}; | ||
exports.default = Box; | ||
export default Box; | ||
//# sourceMappingURL=Box.js.map |
@@ -1,6 +0,6 @@ | ||
import { FC } from 'react'; | ||
interface Props { | ||
/// <reference types="react" /> | ||
type Props = { | ||
readonly error: Error; | ||
} | ||
declare const ErrorOverview: FC<Props>; | ||
export default ErrorOverview; | ||
}; | ||
export default function ErrorOverview({ error }: Props): JSX.Element; | ||
export {}; |
@@ -1,43 +0,26 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
import * as fs from 'node:fs'; | ||
import { cwd } from 'node:process'; | ||
import React from 'react'; | ||
import StackUtils from 'stack-utils'; | ||
import codeExcerpt from 'code-excerpt'; | ||
import Box from './Box.js'; | ||
import Text from './Text.js'; | ||
// Error's source file is reported as file:///home/user/file.js | ||
// This function removes the file://[cwd] part | ||
const cleanupPath = (path) => { | ||
return path?.replace(`file://${cwd()}/`, ''); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fs = __importStar(require("fs")); | ||
const react_1 = __importDefault(require("react")); | ||
const stack_utils_1 = __importDefault(require("stack-utils")); | ||
const code_excerpt_1 = __importDefault(require("code-excerpt")); | ||
const Box_1 = __importDefault(require("./Box")); | ||
const Text_1 = __importDefault(require("./Text")); | ||
const stackUtils = new stack_utils_1.default({ | ||
cwd: process.cwd(), | ||
internals: stack_utils_1.default.nodeInternals() | ||
const stackUtils = new StackUtils({ | ||
cwd: cwd(), | ||
internals: StackUtils.nodeInternals() | ||
}); | ||
const ErrorOverview = ({ error }) => { | ||
export default function ErrorOverview({ error }) { | ||
const stack = error.stack ? error.stack.split('\n').slice(1) : undefined; | ||
const origin = stack ? stackUtils.parseLine(stack[0]) : undefined; | ||
const filePath = cleanupPath(origin?.file); | ||
let excerpt; | ||
let lineWidth = 0; | ||
if ((origin === null || origin === void 0 ? void 0 : origin.file) && (origin === null || origin === void 0 ? void 0 : origin.line) && fs.existsSync(origin.file)) { | ||
const sourceCode = fs.readFileSync(origin.file, 'utf8'); | ||
excerpt = code_excerpt_1.default(sourceCode, origin.line); | ||
if (filePath && origin?.line && fs.existsSync(filePath)) { | ||
const sourceCode = fs.readFileSync(filePath, 'utf8'); | ||
excerpt = codeExcerpt(sourceCode, origin.line); | ||
if (excerpt) { | ||
@@ -49,14 +32,14 @@ for (const { line } of excerpt) { | ||
} | ||
return (react_1.default.createElement(Box_1.default, { flexDirection: "column", padding: 1 }, | ||
react_1.default.createElement(Box_1.default, null, | ||
react_1.default.createElement(Text_1.default, { backgroundColor: "red", color: "white" }, | ||
return (React.createElement(Box, { flexDirection: "column", padding: 1 }, | ||
React.createElement(Box, null, | ||
React.createElement(Text, { backgroundColor: "red", color: "white" }, | ||
' ', | ||
"ERROR", | ||
' '), | ||
react_1.default.createElement(Text_1.default, null, | ||
React.createElement(Text, null, | ||
" ", | ||
error.message)), | ||
origin && (react_1.default.createElement(Box_1.default, { marginTop: 1 }, | ||
react_1.default.createElement(Text_1.default, { dimColor: true }, | ||
origin.file, | ||
origin && filePath && (React.createElement(Box, { marginTop: 1 }, | ||
React.createElement(Text, { dimColor: true }, | ||
filePath, | ||
":", | ||
@@ -66,9 +49,9 @@ origin.line, | ||
origin.column))), | ||
origin && excerpt && (react_1.default.createElement(Box_1.default, { marginTop: 1, flexDirection: "column" }, excerpt.map(({ line, value }) => (react_1.default.createElement(Box_1.default, { key: line }, | ||
react_1.default.createElement(Box_1.default, { width: lineWidth + 1 }, | ||
react_1.default.createElement(Text_1.default, { dimColor: line !== origin.line, backgroundColor: line === origin.line ? 'red' : undefined, color: line === origin.line ? 'white' : undefined }, | ||
origin && excerpt && (React.createElement(Box, { marginTop: 1, flexDirection: "column" }, excerpt.map(({ line, value }) => (React.createElement(Box, { key: line }, | ||
React.createElement(Box, { width: lineWidth + 1 }, | ||
React.createElement(Text, { dimColor: line !== origin.line, backgroundColor: line === origin.line ? 'red' : undefined, color: line === origin.line ? 'white' : undefined }, | ||
String(line).padStart(lineWidth, ' '), | ||
":")), | ||
react_1.default.createElement(Text_1.default, { key: line, backgroundColor: line === origin.line ? 'red' : undefined, color: line === origin.line ? 'white' : undefined }, ' ' + value)))))), | ||
error.stack && (react_1.default.createElement(Box_1.default, { marginTop: 1, flexDirection: "column" }, error.stack | ||
React.createElement(Text, { key: line, backgroundColor: line === origin.line ? 'red' : undefined, color: line === origin.line ? 'white' : undefined }, ' ' + value)))))), | ||
error.stack && (React.createElement(Box, { marginTop: 1, flexDirection: "column" }, error.stack | ||
.split('\n') | ||
@@ -80,13 +63,13 @@ .slice(1) | ||
if (!parsedLine) { | ||
return (react_1.default.createElement(Box_1.default, { key: line }, | ||
react_1.default.createElement(Text_1.default, { dimColor: true }, "- "), | ||
react_1.default.createElement(Text_1.default, { dimColor: true, bold: true }, line))); | ||
return (React.createElement(Box, { key: line }, | ||
React.createElement(Text, { dimColor: true }, "- "), | ||
React.createElement(Text, { dimColor: true, bold: true }, line))); | ||
} | ||
return (react_1.default.createElement(Box_1.default, { key: line }, | ||
react_1.default.createElement(Text_1.default, { dimColor: true }, "- "), | ||
react_1.default.createElement(Text_1.default, { dimColor: true, bold: true }, parsedLine.function), | ||
react_1.default.createElement(Text_1.default, { dimColor: true, color: "gray" }, | ||
return (React.createElement(Box, { key: line }, | ||
React.createElement(Text, { dimColor: true }, "- "), | ||
React.createElement(Text, { dimColor: true, bold: true }, parsedLine.function), | ||
React.createElement(Text, { dimColor: true, color: "gray" }, | ||
' ', | ||
"(", | ||
parsedLine.file, | ||
cleanupPath(parsedLine.file) ?? '', | ||
":", | ||
@@ -98,4 +81,3 @@ parsedLine.line, | ||
}))))); | ||
}; | ||
exports.default = ErrorOverview; | ||
} | ||
//# sourceMappingURL=ErrorOverview.js.map |
/// <reference types="react" /> | ||
export interface Props { | ||
export type Props = { | ||
readonly activeId?: string; | ||
@@ -15,4 +15,4 @@ readonly add: (id: string, options: { | ||
readonly focus: (id: string) => void; | ||
} | ||
}; | ||
declare const FocusContext: import("react").Context<Props>; | ||
export default FocusContext; |
@@ -1,18 +0,17 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const FocusContext = react_1.createContext({ | ||
import { createContext } from 'react'; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const FocusContext = createContext({ | ||
activeId: undefined, | ||
add: () => { }, | ||
remove: () => { }, | ||
activate: () => { }, | ||
deactivate: () => { }, | ||
enableFocus: () => { }, | ||
disableFocus: () => { }, | ||
focusNext: () => { }, | ||
focusPrevious: () => { }, | ||
focus: () => { } | ||
add() { }, | ||
remove() { }, | ||
activate() { }, | ||
deactivate() { }, | ||
enableFocus() { }, | ||
disableFocus() { }, | ||
focusNext() { }, | ||
focusPrevious() { }, | ||
focus() { } | ||
}); | ||
FocusContext.displayName = 'InternalFocusContext'; | ||
exports.default = FocusContext; | ||
export default FocusContext; | ||
//# sourceMappingURL=FocusContext.js.map |
@@ -1,3 +0,3 @@ | ||
import { FC } from 'react'; | ||
export interface Props { | ||
/// <reference types="react" /> | ||
export type Props = { | ||
/** | ||
@@ -9,7 +9,6 @@ * Number of newlines to insert. | ||
readonly count?: number; | ||
} | ||
}; | ||
/** | ||
* Adds one or more newline (\n) characters. Must be used within <Text> components. | ||
*/ | ||
declare const Newline: FC<Props>; | ||
export default Newline; | ||
export default function Newline({ count }: Props): JSX.Element; |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = __importDefault(require("react")); | ||
import React from 'react'; | ||
/** | ||
* Adds one or more newline (\n) characters. Must be used within <Text> components. | ||
*/ | ||
const Newline = ({ count = 1 }) => (react_1.default.createElement("ink-text", null, '\n'.repeat(count))); | ||
Newline.displayName = 'Newline'; | ||
exports.default = Newline; | ||
export default function Newline({ count = 1 }) { | ||
return React.createElement("ink-text", null, '\n'.repeat(count)); | ||
} | ||
//# sourceMappingURL=Newline.js.map |
@@ -1,2 +0,2 @@ | ||
import { FC } from 'react'; | ||
/// <reference types="react" /> | ||
/** | ||
@@ -6,3 +6,2 @@ * A flexible space that expands along the major axis of its containing layout. | ||
*/ | ||
declare const Spacer: FC; | ||
export default Spacer; | ||
export default function Spacer(): JSX.Element; |
@@ -1,8 +0,3 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = __importDefault(require("react")); | ||
const Box_1 = __importDefault(require("./Box")); | ||
import React from 'react'; | ||
import Box from './Box.js'; | ||
/** | ||
@@ -12,5 +7,5 @@ * A flexible space that expands along the major axis of its containing layout. | ||
*/ | ||
const Spacer = () => react_1.default.createElement(Box_1.default, { flexGrow: 1 }); | ||
Spacer.displayName = 'Spacer'; | ||
exports.default = Spacer; | ||
export default function Spacer() { | ||
return React.createElement(Box, { flexGrow: 1 }); | ||
} | ||
//# sourceMappingURL=Spacer.js.map |
@@ -1,4 +0,4 @@ | ||
import { ReactNode } from 'react'; | ||
import { Styles } from '../styles'; | ||
export interface Props<T> { | ||
import { type ReactNode } from 'react'; | ||
import { type Styles } from '../styles.js'; | ||
export type Props<T> = { | ||
/** | ||
@@ -18,3 +18,3 @@ * Array of items of any type to render using a function you pass as a component child. | ||
readonly children: (item: T, index: number) => ReactNode; | ||
} | ||
}; | ||
/** | ||
@@ -32,6 +32,2 @@ * `<Static>` component permanently renders its output above everything else. | ||
*/ | ||
declare const Static: { | ||
<T>(props: Props<T>): JSX.Element; | ||
displayName: string; | ||
}; | ||
export default Static; | ||
export default function Static<T>(props: Props<T>): JSX.Element; |
@@ -1,23 +0,2 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = __importStar(require("react")); | ||
import React, { useMemo, useState, useLayoutEffect } from 'react'; | ||
/** | ||
@@ -35,9 +14,9 @@ * `<Static>` component permanently renders its output above everything else. | ||
*/ | ||
const Static = (props) => { | ||
export default function Static(props) { | ||
const { items, children: render, style: customStyle } = props; | ||
const [index, setIndex] = react_1.useState(0); | ||
const itemsToRender = react_1.useMemo(() => { | ||
const [index, setIndex] = useState(0); | ||
const itemsToRender = useMemo(() => { | ||
return items.slice(index); | ||
}, [items, index]); | ||
react_1.useLayoutEffect(() => { | ||
useLayoutEffect(() => { | ||
setIndex(items.length); | ||
@@ -48,9 +27,9 @@ }, [items.length]); | ||
}); | ||
const style = react_1.useMemo(() => (Object.assign({ position: 'absolute', flexDirection: 'column' }, customStyle)), [customStyle]); | ||
return (react_1.default.createElement("ink-box", { | ||
// @ts-ignore | ||
internal_static: true, style: style }, children)); | ||
}; | ||
Static.displayName = 'Static'; | ||
exports.default = Static; | ||
const style = useMemo(() => ({ | ||
position: 'absolute', | ||
flexDirection: 'column', | ||
...customStyle | ||
}), [customStyle]); | ||
return (React.createElement("ink-box", { internal_static: true, style: style }, children)); | ||
} | ||
//# sourceMappingURL=Static.js.map |
@@ -1,8 +0,8 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" resolution-mode="require"/> | ||
/// <reference types="react" /> | ||
export interface Props { | ||
export type Props = { | ||
/** | ||
* Stderr stream passed to `render()` in `options.stderr` or `process.stderr` by default. | ||
*/ | ||
readonly stderr?: NodeJS.WriteStream; | ||
readonly stderr: NodeJS.WriteStream; | ||
/** | ||
@@ -14,3 +14,3 @@ * Write any string to stderr, while preserving Ink's output. | ||
readonly write: (data: string) => void; | ||
} | ||
}; | ||
/** | ||
@@ -17,0 +17,0 @@ * `StderrContext` is a React context, which exposes stderr stream. |
@@ -1,13 +0,13 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
import process from 'node:process'; | ||
import { createContext } from 'react'; | ||
/** | ||
* `StderrContext` is a React context, which exposes stderr stream. | ||
*/ | ||
const StderrContext = react_1.createContext({ | ||
stderr: undefined, | ||
write: () => { } | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const StderrContext = createContext({ | ||
stderr: process.stderr, | ||
write() { } | ||
}); | ||
StderrContext.displayName = 'InternalStderrContext'; | ||
exports.default = StderrContext; | ||
export default StderrContext; | ||
//# sourceMappingURL=StderrContext.js.map |
@@ -1,8 +0,8 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" resolution-mode="require"/> | ||
/// <reference types="react" /> | ||
export interface Props { | ||
export type Props = { | ||
/** | ||
* Stdin stream passed to `render()` in `options.stdin` or `process.stdin` by default. Useful if your app needs to handle user input. | ||
*/ | ||
readonly stdin?: NodeJS.ReadStream; | ||
readonly stdin: NodeJS.ReadStream; | ||
/** | ||
@@ -18,3 +18,3 @@ * Ink exposes this function via own `<StdinContext>` to be able to handle Ctrl+C, that's why you should use Ink's `setRawMode` instead of `process.stdin.setRawMode`. | ||
readonly internal_exitOnCtrlC: boolean; | ||
} | ||
}; | ||
/** | ||
@@ -21,0 +21,0 @@ * `StdinContext` is a React context, which exposes input stream. |
@@ -1,15 +0,16 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
import process from 'node:process'; | ||
import { createContext } from 'react'; | ||
/** | ||
* `StdinContext` is a React context, which exposes input stream. | ||
*/ | ||
const StdinContext = react_1.createContext({ | ||
stdin: undefined, | ||
setRawMode: () => { }, | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const StdinContext = createContext({ | ||
stdin: process.stdin, | ||
setRawMode() { }, | ||
isRawModeSupported: false, | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
internal_exitOnCtrlC: true | ||
}); | ||
StdinContext.displayName = 'InternalStdinContext'; | ||
exports.default = StdinContext; | ||
export default StdinContext; | ||
//# sourceMappingURL=StdinContext.js.map |
@@ -1,8 +0,8 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" resolution-mode="require"/> | ||
/// <reference types="react" /> | ||
export interface Props { | ||
export type Props = { | ||
/** | ||
* Stdout stream passed to `render()` in `options.stdout` or `process.stdout` by default. | ||
*/ | ||
readonly stdout?: NodeJS.WriteStream; | ||
readonly stdout: NodeJS.WriteStream; | ||
/** | ||
@@ -14,3 +14,3 @@ * Write any string to stdout, while preserving Ink's output. | ||
readonly write: (data: string) => void; | ||
} | ||
}; | ||
/** | ||
@@ -17,0 +17,0 @@ * `StdoutContext` is a React context, which exposes stdout stream, where Ink renders your app. |
@@ -1,13 +0,13 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
import process from 'node:process'; | ||
import { createContext } from 'react'; | ||
/** | ||
* `StdoutContext` is a React context, which exposes stdout stream, where Ink renders your app. | ||
*/ | ||
const StdoutContext = react_1.createContext({ | ||
stdout: undefined, | ||
write: () => { } | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const StdoutContext = createContext({ | ||
stdout: process.stdout, | ||
write() { } | ||
}); | ||
StdoutContext.displayName = 'InternalStdoutContext'; | ||
exports.default = StdoutContext; | ||
export default StdoutContext; | ||
//# sourceMappingURL=StdoutContext.js.map |
@@ -1,14 +0,14 @@ | ||
import { FC, ReactNode } from 'react'; | ||
import { ForegroundColor } from 'chalk'; | ||
import { Styles } from '../styles'; | ||
import { LiteralUnion } from 'type-fest'; | ||
export interface Props { | ||
import { type ReactNode } from 'react'; | ||
import { type ForegroundColorName } from 'chalk'; | ||
import { type LiteralUnion } from 'type-fest'; | ||
import { type Styles } from '../styles.js'; | ||
export type Props = { | ||
/** | ||
* Change text color. Ink uses chalk under the hood, so all its functionality is supported. | ||
*/ | ||
readonly color?: LiteralUnion<typeof ForegroundColor, string>; | ||
readonly color?: LiteralUnion<ForegroundColorName, string>; | ||
/** | ||
* Same as `color`, but for background. | ||
*/ | ||
readonly backgroundColor?: LiteralUnion<typeof ForegroundColor, string>; | ||
readonly backgroundColor?: LiteralUnion<ForegroundColorName, string>; | ||
/** | ||
@@ -45,7 +45,6 @@ * Dim the color (emit a small amount of light). | ||
readonly children?: ReactNode; | ||
} | ||
}; | ||
/** | ||
* This component can display text, and change its style to make it colorful, bold, underline, italic or strikethrough. | ||
*/ | ||
declare const Text: FC<Props>; | ||
export default Text; | ||
export default function Text({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children }: Props): JSX.Element | null; |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = __importDefault(require("react")); | ||
const chalk_1 = __importDefault(require("chalk")); | ||
const colorize_1 = __importDefault(require("../colorize")); | ||
import React from 'react'; | ||
import chalk from 'chalk'; | ||
import colorize from '../colorize.js'; | ||
/** | ||
* This component can display text, and change its style to make it colorful, bold, underline, italic or strikethrough. | ||
*/ | ||
const Text = ({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children }) => { | ||
export default function Text({ color, backgroundColor, dimColor = false, bold = false, italic = false, underline = false, strikethrough = false, inverse = false, wrap = 'wrap', children }) { | ||
if (children === undefined || children === null) { | ||
@@ -18,39 +13,29 @@ return null; | ||
if (dimColor) { | ||
children = chalk_1.default.dim(children); | ||
children = chalk.dim(children); | ||
} | ||
if (color) { | ||
children = colorize_1.default(children, color, 'foreground'); | ||
children = colorize(children, color, 'foreground'); | ||
} | ||
if (backgroundColor) { | ||
children = colorize_1.default(children, backgroundColor, 'background'); | ||
children = colorize(children, backgroundColor, 'background'); | ||
} | ||
if (bold) { | ||
children = chalk_1.default.bold(children); | ||
children = chalk.bold(children); | ||
} | ||
if (italic) { | ||
children = chalk_1.default.italic(children); | ||
children = chalk.italic(children); | ||
} | ||
if (underline) { | ||
children = chalk_1.default.underline(children); | ||
children = chalk.underline(children); | ||
} | ||
if (strikethrough) { | ||
children = chalk_1.default.strikethrough(children); | ||
children = chalk.strikethrough(children); | ||
} | ||
if (inverse) { | ||
children = chalk_1.default.inverse(children); | ||
children = chalk.inverse(children); | ||
} | ||
return children; | ||
}; | ||
return (react_1.default.createElement("ink-text", { style: { flexGrow: 0, flexShrink: 1, flexDirection: 'row', textWrap: wrap }, internal_transform: transform }, children)); | ||
}; | ||
Text.displayName = 'Text'; | ||
Text.defaultProps = { | ||
dimColor: false, | ||
bold: false, | ||
italic: false, | ||
underline: false, | ||
strikethrough: false, | ||
wrap: 'wrap' | ||
}; | ||
exports.default = Text; | ||
return (React.createElement("ink-text", { style: { flexGrow: 0, flexShrink: 1, flexDirection: 'row', textWrap: wrap }, internal_transform: transform }, children)); | ||
} | ||
//# sourceMappingURL=Text.js.map |
@@ -1,3 +0,3 @@ | ||
import { FC, ReactNode } from 'react'; | ||
export interface Props { | ||
import { type ReactNode } from 'react'; | ||
export type Props = { | ||
/** | ||
@@ -8,3 +8,3 @@ * Function which transforms children output. It accepts children and must return transformed children too. | ||
readonly children?: ReactNode; | ||
} | ||
}; | ||
/** | ||
@@ -16,3 +16,2 @@ * Transform a string representation of React components before they are written to output. | ||
*/ | ||
declare const Transform: FC<Props>; | ||
export default Transform; | ||
export default function Transform({ children, transform }: Props): JSX.Element | null; |
@@ -1,7 +0,2 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = __importDefault(require("react")); | ||
import React from 'react'; | ||
/** | ||
@@ -13,10 +8,8 @@ * Transform a string representation of React components before they are written to output. | ||
*/ | ||
const Transform = ({ children, transform }) => { | ||
export default function Transform({ children, transform }) { | ||
if (children === undefined || children === null) { | ||
return null; | ||
} | ||
return (react_1.default.createElement("ink-text", { style: { flexGrow: 0, flexShrink: 1, flexDirection: 'row' }, internal_transform: transform }, children)); | ||
}; | ||
Transform.displayName = 'Transform'; | ||
exports.default = Transform; | ||
return (React.createElement("ink-text", { style: { flexGrow: 0, flexShrink: 1, flexDirection: 'row' }, internal_transform: transform }, children)); | ||
} | ||
//# sourceMappingURL=Transform.js.map |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// Ignoring missing types error to avoid adding another dependency for this hack to work | ||
// @ts-ignore | ||
const ws_1 = __importDefault(require("ws")); | ||
import ws from 'ws'; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const customGlobal = global; | ||
// These things must exist before importing `react-devtools-core` | ||
if (!customGlobal.WebSocket) { | ||
customGlobal.WebSocket = ws_1.default; | ||
customGlobal.WebSocket = ws; | ||
} | ||
@@ -14,0 +9,0 @@ if (!customGlobal.window) { |
@@ -1,1 +0,1 @@ | ||
import './devtools-window-polyfill'; | ||
import './devtools-window-polyfill.js'; |
@@ -1,8 +0,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// eslint-disable-next-line import/no-unassigned-import | ||
require("./devtools-window-polyfill"); | ||
// @ts-ignore | ||
const react_devtools_core_1 = require("react-devtools-core"); | ||
react_devtools_core_1.connectToDevTools(); | ||
import './devtools-window-polyfill.js'; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-expect-error | ||
import devtools from 'react-devtools-core'; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
devtools.connectToDevTools(); | ||
//# sourceMappingURL=devtools.js.map |
/// <reference types="yoga-layout" /> | ||
import Yoga from 'yoga-layout-prebuilt'; | ||
import { Styles } from './styles'; | ||
import { OutputTransformer } from './render-node-to-output'; | ||
interface InkNode { | ||
parentNode: DOMElement | null; | ||
import { type Styles } from './styles.js'; | ||
import { type OutputTransformer } from './render-node-to-output.js'; | ||
type InkNode = { | ||
parentNode: DOMElement | undefined; | ||
yogaNode?: Yoga.YogaNode; | ||
internal_static?: boolean; | ||
style: Styles; | ||
} | ||
export declare const TEXT_NAME = "#text"; | ||
export declare type TextName = '#text'; | ||
export declare type ElementNames = 'ink-root' | 'ink-box' | 'ink-text' | 'ink-virtual-text'; | ||
export declare type NodeNames = ElementNames | TextName; | ||
export declare type DOMElement = { | ||
}; | ||
export type TextName = '#text'; | ||
export type ElementNames = 'ink-root' | 'ink-box' | 'ink-text' | 'ink-virtual-text'; | ||
export type NodeNames = ElementNames | TextName; | ||
export type DOMElement = { | ||
nodeName: ElementNames; | ||
attributes: { | ||
[key: string]: DOMNodeAttribute; | ||
}; | ||
attributes: Record<string, DOMNodeAttribute>; | ||
childNodes: DOMNode[]; | ||
internal_transform?: OutputTransformer; | ||
isStaticDirty?: boolean; | ||
staticNode?: any; | ||
staticNode?: DOMElement; | ||
onRender?: () => void; | ||
onImmediateRender?: () => void; | ||
} & InkNode; | ||
export declare type TextNode = { | ||
export type TextNode = { | ||
nodeName: TextName; | ||
nodeValue: string; | ||
} & InkNode; | ||
export declare type DOMNode<T = { | ||
export type DOMNode<T = { | ||
nodeName: NodeNames; | ||
@@ -36,3 +33,3 @@ }> = T extends { | ||
} ? U extends '#text' ? TextNode : DOMElement : never; | ||
export declare type DOMNodeAttribute = boolean | string | number; | ||
export type DOMNodeAttribute = boolean | string | number; | ||
export declare const createNode: (nodeName: ElementNames) => DOMElement; | ||
@@ -39,0 +36,0 @@ export declare const appendChildNode: (node: DOMElement, childNode: DOMElement) => void; |
@@ -1,15 +0,7 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.setTextNodeValue = exports.createTextNode = exports.setStyle = exports.setAttribute = exports.removeChildNode = exports.insertBeforeNode = exports.appendChildNode = exports.createNode = exports.TEXT_NAME = void 0; | ||
const yoga_layout_prebuilt_1 = __importDefault(require("yoga-layout-prebuilt")); | ||
const measure_text_1 = __importDefault(require("./measure-text")); | ||
const styles_1 = __importDefault(require("./styles")); | ||
const wrap_text_1 = __importDefault(require("./wrap-text")); | ||
const squash_text_nodes_1 = __importDefault(require("./squash-text-nodes")); | ||
exports.TEXT_NAME = '#text'; | ||
exports.createNode = (nodeName) => { | ||
var _a; | ||
import Yoga from 'yoga-layout-prebuilt'; | ||
import measureText from './measure-text.js'; | ||
import applyStyles from './styles.js'; | ||
import wrapText from './wrap-text.js'; | ||
import squashTextNodes from './squash-text-nodes.js'; | ||
export const createNode = (nodeName) => { | ||
const node = { | ||
@@ -20,14 +12,13 @@ nodeName, | ||
childNodes: [], | ||
parentNode: null, | ||
yogaNode: nodeName === 'ink-virtual-text' ? undefined : yoga_layout_prebuilt_1.default.Node.create() | ||
parentNode: undefined, | ||
yogaNode: nodeName === 'ink-virtual-text' ? undefined : Yoga.Node.create() | ||
}; | ||
if (nodeName === 'ink-text') { | ||
(_a = node.yogaNode) === null || _a === void 0 ? void 0 : _a.setMeasureFunc(measureTextNode.bind(null, node)); | ||
node.yogaNode?.setMeasureFunc(measureTextNode.bind(null, node)); | ||
} | ||
return node; | ||
}; | ||
exports.appendChildNode = (node, childNode) => { | ||
var _a; | ||
export const appendChildNode = (node, childNode) => { | ||
if (childNode.parentNode) { | ||
exports.removeChildNode(childNode.parentNode, childNode); | ||
removeChildNode(childNode.parentNode, childNode); | ||
} | ||
@@ -37,3 +28,3 @@ childNode.parentNode = node; | ||
if (childNode.yogaNode) { | ||
(_a = node.yogaNode) === null || _a === void 0 ? void 0 : _a.insertChild(childNode.yogaNode, node.yogaNode.getChildCount()); | ||
node.yogaNode?.insertChild(childNode.yogaNode, node.yogaNode.getChildCount()); | ||
} | ||
@@ -44,6 +35,5 @@ if (node.nodeName === 'ink-text' || node.nodeName === 'ink-virtual-text') { | ||
}; | ||
exports.insertBeforeNode = (node, newChildNode, beforeChildNode) => { | ||
var _a, _b; | ||
export const insertBeforeNode = (node, newChildNode, beforeChildNode) => { | ||
if (newChildNode.parentNode) { | ||
exports.removeChildNode(newChildNode.parentNode, newChildNode); | ||
removeChildNode(newChildNode.parentNode, newChildNode); | ||
} | ||
@@ -55,3 +45,3 @@ newChildNode.parentNode = node; | ||
if (newChildNode.yogaNode) { | ||
(_a = node.yogaNode) === null || _a === void 0 ? void 0 : _a.insertChild(newChildNode.yogaNode, index); | ||
node.yogaNode?.insertChild(newChildNode.yogaNode, index); | ||
} | ||
@@ -62,3 +52,3 @@ return; | ||
if (newChildNode.yogaNode) { | ||
(_b = node.yogaNode) === null || _b === void 0 ? void 0 : _b.insertChild(newChildNode.yogaNode, node.yogaNode.getChildCount()); | ||
node.yogaNode?.insertChild(newChildNode.yogaNode, node.yogaNode.getChildCount()); | ||
} | ||
@@ -69,8 +59,7 @@ if (node.nodeName === 'ink-text' || node.nodeName === 'ink-virtual-text') { | ||
}; | ||
exports.removeChildNode = (node, removeNode) => { | ||
var _a, _b; | ||
export const removeChildNode = (node, removeNode) => { | ||
if (removeNode.yogaNode) { | ||
(_b = (_a = removeNode.parentNode) === null || _a === void 0 ? void 0 : _a.yogaNode) === null || _b === void 0 ? void 0 : _b.removeChild(removeNode.yogaNode); | ||
removeNode.parentNode?.yogaNode?.removeChild(removeNode.yogaNode); | ||
} | ||
removeNode.parentNode = null; | ||
removeNode.parentNode = undefined; | ||
const index = node.childNodes.indexOf(removeNode); | ||
@@ -84,12 +73,12 @@ if (index >= 0) { | ||
}; | ||
exports.setAttribute = (node, key, value) => { | ||
export const setAttribute = (node, key, value) => { | ||
node.attributes[key] = value; | ||
}; | ||
exports.setStyle = (node, style) => { | ||
export const setStyle = (node, style) => { | ||
node.style = style; | ||
if (node.yogaNode) { | ||
styles_1.default(node.yogaNode, style); | ||
applyStyles(node.yogaNode, style); | ||
} | ||
}; | ||
exports.createTextNode = (text) => { | ||
export const createTextNode = (text) => { | ||
const node = { | ||
@@ -99,12 +88,11 @@ nodeName: '#text', | ||
yogaNode: undefined, | ||
parentNode: null, | ||
parentNode: undefined, | ||
style: {} | ||
}; | ||
exports.setTextNodeValue(node, text); | ||
setTextNodeValue(node, text); | ||
return node; | ||
}; | ||
const measureTextNode = function (node, width) { | ||
var _a, _b; | ||
const text = node.nodeName === '#text' ? node.nodeValue : squash_text_nodes_1.default(node); | ||
const dimensions = measure_text_1.default(text); | ||
const text = node.nodeName === '#text' ? node.nodeValue : squashTextNodes(node); | ||
const dimensions = measureText(text); | ||
// Text fits into container, no need to wrap | ||
@@ -119,12 +107,11 @@ if (dimensions.width <= width) { | ||
} | ||
const textWrap = (_b = (_a = node.style) === null || _a === void 0 ? void 0 : _a.textWrap) !== null && _b !== void 0 ? _b : 'wrap'; | ||
const wrappedText = wrap_text_1.default(text, width, textWrap); | ||
return measure_text_1.default(wrappedText); | ||
const textWrap = node.style?.textWrap ?? 'wrap'; | ||
const wrappedText = wrapText(text, width, textWrap); | ||
return measureText(wrappedText); | ||
}; | ||
const findClosestYogaNode = (node) => { | ||
var _a; | ||
if (!node || !node.parentNode) { | ||
if (!node?.parentNode) { | ||
return undefined; | ||
} | ||
return (_a = node.yogaNode) !== null && _a !== void 0 ? _a : findClosestYogaNode(node.parentNode); | ||
return node.yogaNode ?? findClosestYogaNode(node.parentNode); | ||
}; | ||
@@ -134,5 +121,5 @@ const markNodeAsDirty = (node) => { | ||
const yogaNode = findClosestYogaNode(node); | ||
yogaNode === null || yogaNode === void 0 ? void 0 : yogaNode.markDirty(); | ||
yogaNode?.markDirty(); | ||
}; | ||
exports.setTextNodeValue = (node, text) => { | ||
export const setTextNodeValue = (node, text) => { | ||
if (typeof text !== 'string') { | ||
@@ -139,0 +126,0 @@ text = String(text); |
import Yoga from 'yoga-layout-prebuilt'; | ||
declare const _default: (yogaNode: Yoga.YogaNode) => number; | ||
export default _default; | ||
declare const getMaxWidth: (yogaNode: Yoga.YogaNode) => number; | ||
export default getMaxWidth; |
@@ -1,14 +0,10 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const yoga_layout_prebuilt_1 = __importDefault(require("yoga-layout-prebuilt")); | ||
exports.default = (yogaNode) => { | ||
import Yoga from 'yoga-layout-prebuilt'; | ||
const getMaxWidth = (yogaNode) => { | ||
return (yogaNode.getComputedWidth() - | ||
yogaNode.getComputedPadding(yoga_layout_prebuilt_1.default.EDGE_LEFT) - | ||
yogaNode.getComputedPadding(yoga_layout_prebuilt_1.default.EDGE_RIGHT) - | ||
yogaNode.getComputedBorder(yoga_layout_prebuilt_1.default.EDGE_LEFT) - | ||
yogaNode.getComputedBorder(yoga_layout_prebuilt_1.default.EDGE_RIGHT)); | ||
yogaNode.getComputedPadding(Yoga.EDGE_LEFT) - | ||
yogaNode.getComputedPadding(Yoga.EDGE_RIGHT) - | ||
yogaNode.getComputedBorder(Yoga.EDGE_LEFT) - | ||
yogaNode.getComputedBorder(Yoga.EDGE_RIGHT)); | ||
}; | ||
export default getMaxWidth; | ||
//# sourceMappingURL=get-max-width.js.map |
/** | ||
* `useApp` is a React hook, which exposes a method to manually exit the app (unmount). | ||
*/ | ||
declare const useApp: () => import("../components/AppContext").Props; | ||
declare const useApp: () => import("../components/AppContext.js").Props; | ||
export default useApp; |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const AppContext_1 = __importDefault(require("../components/AppContext")); | ||
import { useContext } from 'react'; | ||
import AppContext from '../components/AppContext.js'; | ||
/** | ||
* `useApp` is a React hook, which exposes a method to manually exit the app (unmount). | ||
*/ | ||
const useApp = () => react_1.useContext(AppContext_1.default); | ||
exports.default = useApp; | ||
const useApp = () => useContext(AppContext); | ||
export default useApp; | ||
//# sourceMappingURL=use-app.js.map |
@@ -1,3 +0,3 @@ | ||
import { Props } from '../components/FocusContext'; | ||
interface Output { | ||
import { type Props } from '../components/FocusContext.js'; | ||
type Output = { | ||
/** | ||
@@ -28,3 +28,3 @@ * Enable focus management for all components. | ||
focus: Props['focus']; | ||
} | ||
}; | ||
/** | ||
@@ -31,0 +31,0 @@ * This hook exposes methods to enable or disable focus management for all |
@@ -1,8 +0,3 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const FocusContext_1 = __importDefault(require("../components/FocusContext")); | ||
import { useContext } from 'react'; | ||
import FocusContext from '../components/FocusContext.js'; | ||
/** | ||
@@ -13,3 +8,3 @@ * This hook exposes methods to enable or disable focus management for all | ||
const useFocusManager = () => { | ||
const focusContext = react_1.useContext(FocusContext_1.default); | ||
const focusContext = useContext(FocusContext); | ||
return { | ||
@@ -23,3 +18,3 @@ enableFocus: focusContext.enableFocus, | ||
}; | ||
exports.default = useFocusManager; | ||
export default useFocusManager; | ||
//# sourceMappingURL=use-focus-manager.js.map |
@@ -1,2 +0,2 @@ | ||
interface Input { | ||
type Input = { | ||
/** | ||
@@ -14,4 +14,4 @@ * Enable or disable this component's focus, while still maintaining its position in the list of focusable components. | ||
id?: string; | ||
} | ||
interface Output { | ||
}; | ||
type Output = { | ||
/** | ||
@@ -25,3 +25,3 @@ * Determines whether this component is focused or not. | ||
focus: (id: string) => void; | ||
} | ||
}; | ||
/** | ||
@@ -28,0 +28,0 @@ * Component that uses `useFocus` hook becomes "focusable" to Ink, |
@@ -1,9 +0,4 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const FocusContext_1 = __importDefault(require("../components/FocusContext")); | ||
const use_stdin_1 = __importDefault(require("./use-stdin")); | ||
import { useEffect, useContext, useMemo } from 'react'; | ||
import FocusContext from '../components/FocusContext.js'; | ||
import useStdin from './use-stdin.js'; | ||
/** | ||
@@ -18,8 +13,8 @@ * Component that uses `useFocus` hook becomes "focusable" to Ink, | ||
const useFocus = ({ isActive = true, autoFocus = false, id: customId } = {}) => { | ||
const { isRawModeSupported, setRawMode } = use_stdin_1.default(); | ||
const { activeId, add, remove, activate, deactivate, focus } = react_1.useContext(FocusContext_1.default); | ||
const id = react_1.useMemo(() => { | ||
return customId !== null && customId !== void 0 ? customId : Math.random().toString().slice(2, 7); | ||
const { isRawModeSupported, setRawMode } = useStdin(); | ||
const { activeId, add, remove, activate, deactivate, focus } = useContext(FocusContext); | ||
const id = useMemo(() => { | ||
return customId ?? Math.random().toString().slice(2, 7); | ||
}, [customId]); | ||
react_1.useEffect(() => { | ||
useEffect(() => { | ||
add(id, { autoFocus }); | ||
@@ -30,3 +25,3 @@ return () => { | ||
}, [id, autoFocus]); | ||
react_1.useEffect(() => { | ||
useEffect(() => { | ||
if (isActive) { | ||
@@ -39,3 +34,3 @@ activate(id); | ||
}, [isActive, id]); | ||
react_1.useEffect(() => { | ||
useEffect(() => { | ||
if (!isRawModeSupported || !isActive) { | ||
@@ -54,3 +49,3 @@ return; | ||
}; | ||
exports.default = useFocus; | ||
export default useFocus; | ||
//# sourceMappingURL=use-focus.js.map |
/** | ||
* Handy information about a key that was pressed. | ||
*/ | ||
export interface Key { | ||
export type Key = { | ||
/** | ||
@@ -61,5 +61,5 @@ * Up arrow key was pressed. | ||
meta: boolean; | ||
} | ||
declare type Handler = (input: string, key: Key) => void; | ||
interface Options { | ||
}; | ||
type Handler = (input: string, key: Key) => void; | ||
type Options = { | ||
/** | ||
@@ -72,3 +72,3 @@ * Enable or disable capturing of user input. | ||
isActive?: boolean; | ||
} | ||
}; | ||
/** | ||
@@ -75,0 +75,0 @@ * This hook is used for handling user input. |
@@ -1,8 +0,3 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const use_stdin_1 = __importDefault(require("./use-stdin")); | ||
import { useEffect } from 'react'; | ||
import useStdin from './use-stdin.js'; | ||
/** | ||
@@ -33,4 +28,5 @@ * This hook is used for handling user input. | ||
const useInput = (inputHandler, options = {}) => { | ||
const { stdin, setRawMode, internal_exitOnCtrlC } = use_stdin_1.default(); | ||
react_1.useEffect(() => { | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const { stdin, setRawMode, internal_exitOnCtrlC } = useStdin(); | ||
useEffect(() => { | ||
if (options.isActive === false) { | ||
@@ -44,3 +40,3 @@ return; | ||
}, [options.isActive, setRawMode]); | ||
react_1.useEffect(() => { | ||
useEffect(() => { | ||
if (options.isActive === false) { | ||
@@ -69,3 +65,6 @@ return; | ||
if (input <= '\u001A' && !key.return) { | ||
input = String.fromCharCode(input.charCodeAt(0) + 'a'.charCodeAt(0) - 1); | ||
// eslint-disable-next-line unicorn/prefer-code-point | ||
input = String.fromCharCode( | ||
// eslint-disable-next-line unicorn/prefer-code-point | ||
input.charCodeAt(0) + 'a'.charCodeAt(0) - 1); | ||
key.ctrl = true; | ||
@@ -94,9 +93,9 @@ } | ||
}; | ||
stdin === null || stdin === void 0 ? void 0 : stdin.on('data', handleData); | ||
stdin?.on('data', handleData); | ||
return () => { | ||
stdin === null || stdin === void 0 ? void 0 : stdin.off('data', handleData); | ||
stdin?.off('data', handleData); | ||
}; | ||
}, [options.isActive, stdin, internal_exitOnCtrlC, inputHandler]); | ||
}; | ||
exports.default = useInput; | ||
export default useInput; | ||
//# sourceMappingURL=use-input.js.map |
/** | ||
* `useStderr` is a React hook, which exposes stderr stream. | ||
*/ | ||
declare const useStderr: () => import("../components/StderrContext").Props; | ||
declare const useStderr: () => import("../components/StderrContext.js").Props; | ||
export default useStderr; |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const StderrContext_1 = __importDefault(require("../components/StderrContext")); | ||
import { useContext } from 'react'; | ||
import StderrContext from '../components/StderrContext.js'; | ||
/** | ||
* `useStderr` is a React hook, which exposes stderr stream. | ||
*/ | ||
const useStderr = () => react_1.useContext(StderrContext_1.default); | ||
exports.default = useStderr; | ||
const useStderr = () => useContext(StderrContext); | ||
export default useStderr; | ||
//# sourceMappingURL=use-stderr.js.map |
/** | ||
* `useStdin` is a React hook, which exposes stdin stream. | ||
*/ | ||
declare const useStdin: () => import("../components/StdinContext").Props; | ||
declare const useStdin: () => import("../components/StdinContext.js").Props; | ||
export default useStdin; |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const StdinContext_1 = __importDefault(require("../components/StdinContext")); | ||
import { useContext } from 'react'; | ||
import StdinContext from '../components/StdinContext.js'; | ||
/** | ||
* `useStdin` is a React hook, which exposes stdin stream. | ||
*/ | ||
const useStdin = () => react_1.useContext(StdinContext_1.default); | ||
exports.default = useStdin; | ||
const useStdin = () => useContext(StdinContext); | ||
export default useStdin; | ||
//# sourceMappingURL=use-stdin.js.map |
/** | ||
* `useStdout` is a React hook, which exposes stdout stream. | ||
*/ | ||
declare const useStdout: () => import("../components/StdoutContext").Props; | ||
declare const useStdout: () => import("../components/StdoutContext.js").Props; | ||
export default useStdout; |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("react"); | ||
const StdoutContext_1 = __importDefault(require("../components/StdoutContext")); | ||
import { useContext } from 'react'; | ||
import StdoutContext from '../components/StdoutContext.js'; | ||
/** | ||
* `useStdout` is a React hook, which exposes stdout stream. | ||
*/ | ||
const useStdout = () => react_1.useContext(StdoutContext_1.default); | ||
exports.default = useStdout; | ||
const useStdout = () => useContext(StdoutContext); | ||
export default useStdout; | ||
//# sourceMappingURL=use-stdout.js.map |
@@ -1,20 +0,27 @@ | ||
export { default as render, RenderOptions, Instance } from './render'; | ||
export { default as Box, Props as BoxProps } from './components/Box'; | ||
export { default as Text, Props as TextProps } from './components/Text'; | ||
export { Props as AppProps } from './components/AppContext'; | ||
export { Props as StdinProps } from './components/StdinContext'; | ||
export { Props as StdoutProps } from './components/StdoutContext'; | ||
export { Props as StderrProps } from './components/StderrContext'; | ||
export { default as Static, Props as StaticProps } from './components/Static'; | ||
export { default as Transform, Props as TransformProps } from './components/Transform'; | ||
export { default as Newline, Props as NewlineProps } from './components/Newline'; | ||
export { default as Spacer } from './components/Spacer'; | ||
export { default as useInput, Key } from './hooks/use-input'; | ||
export { default as useApp } from './hooks/use-app'; | ||
export { default as useStdin } from './hooks/use-stdin'; | ||
export { default as useStdout } from './hooks/use-stdout'; | ||
export { default as useStderr } from './hooks/use-stderr'; | ||
export { default as useFocus } from './hooks/use-focus'; | ||
export { default as useFocusManager } from './hooks/use-focus-manager'; | ||
export { default as measureElement } from './measure-element'; | ||
export { DOMElement } from './dom'; | ||
export type { RenderOptions, Instance } from './render.js'; | ||
export { default as render } from './render.js'; | ||
export type { Props as BoxProps } from './components/Box.js'; | ||
export { default as Box } from './components/Box.js'; | ||
export type { Props as TextProps } from './components/Text.js'; | ||
export { default as Text } from './components/Text.js'; | ||
export type { Props as AppProps } from './components/AppContext.js'; | ||
export type { Props as StdinProps } from './components/StdinContext.js'; | ||
export type { Props as StdoutProps } from './components/StdoutContext.js'; | ||
export type { Props as StderrProps } from './components/StderrContext.js'; | ||
export type { Props as StaticProps } from './components/Static.js'; | ||
export { default as Static } from './components/Static.js'; | ||
export type { Props as TransformProps } from './components/Transform.js'; | ||
export { default as Transform } from './components/Transform.js'; | ||
export type { Props as NewlineProps } from './components/Newline.js'; | ||
export { default as Newline } from './components/Newline.js'; | ||
export { default as Spacer } from './components/Spacer.js'; | ||
export type { Key } from './hooks/use-input.js'; | ||
export { default as useInput } from './hooks/use-input.js'; | ||
export { default as useApp } from './hooks/use-app.js'; | ||
export { default as useStdin } from './hooks/use-stdin.js'; | ||
export { default as useStdout } from './hooks/use-stdout.js'; | ||
export { default as useStderr } from './hooks/use-stderr.js'; | ||
export { default as useFocus } from './hooks/use-focus.js'; | ||
export { default as useFocusManager } from './hooks/use-focus-manager.js'; | ||
export { default as measureElement } from './measure-element.js'; | ||
export type { DOMElement } from './dom.js'; |
@@ -1,33 +0,16 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var render_1 = require("./render"); | ||
Object.defineProperty(exports, "render", { enumerable: true, get: function () { return render_1.default; } }); | ||
var Box_1 = require("./components/Box"); | ||
Object.defineProperty(exports, "Box", { enumerable: true, get: function () { return Box_1.default; } }); | ||
var Text_1 = require("./components/Text"); | ||
Object.defineProperty(exports, "Text", { enumerable: true, get: function () { return Text_1.default; } }); | ||
var Static_1 = require("./components/Static"); | ||
Object.defineProperty(exports, "Static", { enumerable: true, get: function () { return Static_1.default; } }); | ||
var Transform_1 = require("./components/Transform"); | ||
Object.defineProperty(exports, "Transform", { enumerable: true, get: function () { return Transform_1.default; } }); | ||
var Newline_1 = require("./components/Newline"); | ||
Object.defineProperty(exports, "Newline", { enumerable: true, get: function () { return Newline_1.default; } }); | ||
var Spacer_1 = require("./components/Spacer"); | ||
Object.defineProperty(exports, "Spacer", { enumerable: true, get: function () { return Spacer_1.default; } }); | ||
var use_input_1 = require("./hooks/use-input"); | ||
Object.defineProperty(exports, "useInput", { enumerable: true, get: function () { return use_input_1.default; } }); | ||
var use_app_1 = require("./hooks/use-app"); | ||
Object.defineProperty(exports, "useApp", { enumerable: true, get: function () { return use_app_1.default; } }); | ||
var use_stdin_1 = require("./hooks/use-stdin"); | ||
Object.defineProperty(exports, "useStdin", { enumerable: true, get: function () { return use_stdin_1.default; } }); | ||
var use_stdout_1 = require("./hooks/use-stdout"); | ||
Object.defineProperty(exports, "useStdout", { enumerable: true, get: function () { return use_stdout_1.default; } }); | ||
var use_stderr_1 = require("./hooks/use-stderr"); | ||
Object.defineProperty(exports, "useStderr", { enumerable: true, get: function () { return use_stderr_1.default; } }); | ||
var use_focus_1 = require("./hooks/use-focus"); | ||
Object.defineProperty(exports, "useFocus", { enumerable: true, get: function () { return use_focus_1.default; } }); | ||
var use_focus_manager_1 = require("./hooks/use-focus-manager"); | ||
Object.defineProperty(exports, "useFocusManager", { enumerable: true, get: function () { return use_focus_manager_1.default; } }); | ||
var measure_element_1 = require("./measure-element"); | ||
Object.defineProperty(exports, "measureElement", { enumerable: true, get: function () { return measure_element_1.default; } }); | ||
export { default as render } from './render.js'; | ||
export { default as Box } from './components/Box.js'; | ||
export { default as Text } from './components/Text.js'; | ||
export { default as Static } from './components/Static.js'; | ||
export { default as Transform } from './components/Transform.js'; | ||
export { default as Newline } from './components/Newline.js'; | ||
export { default as Spacer } from './components/Spacer.js'; | ||
export { default as useInput } from './hooks/use-input.js'; | ||
export { default as useApp } from './hooks/use-app.js'; | ||
export { default as useStdin } from './hooks/use-stdin.js'; | ||
export { default as useStdout } from './hooks/use-stdout.js'; | ||
export { default as useStderr } from './hooks/use-stderr.js'; | ||
export { default as useFocus } from './hooks/use-focus.js'; | ||
export { default as useFocusManager } from './hooks/use-focus-manager.js'; | ||
export { default as measureElement } from './measure-element.js'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,4 +0,4 @@ | ||
/// <reference types="node" /> | ||
import { ReactNode } from 'react'; | ||
export interface Options { | ||
/// <reference types="node" resolution-mode="require"/> | ||
import { type ReactNode } from 'react'; | ||
export type Options = { | ||
stdout: NodeJS.WriteStream; | ||
@@ -11,3 +11,3 @@ stdin: NodeJS.ReadStream; | ||
waitUntilExit?: () => Promise<void>; | ||
} | ||
}; | ||
export default class Ink { | ||
@@ -14,0 +14,0 @@ private readonly options; |
263
build/ink.js
@@ -1,89 +0,155 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = __importDefault(require("react")); | ||
const lodash_1 = require("lodash"); | ||
const log_update_1 = __importDefault(require("./log-update")); | ||
const ansi_escapes_1 = __importDefault(require("ansi-escapes")); | ||
const is_ci_1 = __importDefault(require("is-ci")); | ||
const auto_bind_1 = __importDefault(require("auto-bind")); | ||
const reconciler_1 = __importDefault(require("./reconciler")); | ||
const renderer_1 = __importDefault(require("./renderer")); | ||
const signal_exit_1 = __importDefault(require("signal-exit")); | ||
const patch_console_1 = __importDefault(require("patch-console")); | ||
const dom = __importStar(require("./dom")); | ||
const instances_1 = __importDefault(require("./instances")); | ||
const App_1 = __importDefault(require("./components/App")); | ||
const isCI = process.env.CI === 'false' ? false : is_ci_1.default; | ||
import process from 'node:process'; | ||
import React from 'react'; | ||
import { throttle } from 'lodash-es'; | ||
import ansiEscapes from 'ansi-escapes'; | ||
import originalIsCi from 'is-ci'; | ||
import autoBind from 'auto-bind'; | ||
import signalExit from 'signal-exit'; | ||
import patchConsole from 'patch-console'; | ||
import reconciler from './reconciler.js'; | ||
import render from './renderer.js'; | ||
import * as dom from './dom.js'; | ||
import logUpdate from './log-update.js'; | ||
import instances from './instances.js'; | ||
import App from './components/App.js'; | ||
const isCi = process.env['CI'] === 'false' ? false : originalIsCi; | ||
const noop = () => { }; | ||
class Ink { | ||
export default class Ink { | ||
constructor(options) { | ||
this.resolveExitPromise = () => { }; | ||
this.rejectExitPromise = () => { }; | ||
this.unsubscribeExit = () => { }; | ||
this.onRender = () => { | ||
if (this.isUnmounted) { | ||
return; | ||
} | ||
const { output, outputHeight, staticOutput } = renderer_1.default(this.rootNode, | ||
// The 'columns' property can be undefined or 0 when not using a TTY. | ||
// In that case we fall back to 80. | ||
this.options.stdout.columns || 80); | ||
// If <Static> output isn't empty, it means new children have been added to it | ||
const hasStaticOutput = staticOutput && staticOutput !== '\n'; | ||
if (this.options.debug) { | ||
Object.defineProperty(this, "options", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "log", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "throttledLog", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
// Ignore last render after unmounting a tree to prevent empty output before exit | ||
Object.defineProperty(this, "isUnmounted", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "lastOutput", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "container", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "rootNode", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
// This variable is used only in debug mode to store full static output | ||
// so that it's rerendered every time, not just new static parts, like in non-debug mode | ||
Object.defineProperty(this, "fullStaticOutput", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "exitPromise", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "restoreConsole", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "unsubscribeResize", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "resolveExitPromise", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: () => { } | ||
}); | ||
Object.defineProperty(this, "rejectExitPromise", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: () => { } | ||
}); | ||
Object.defineProperty(this, "unsubscribeExit", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: () => { } | ||
}); | ||
Object.defineProperty(this, "onRender", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: () => { | ||
if (this.isUnmounted) { | ||
return; | ||
} | ||
const { output, outputHeight, staticOutput } = render(this.rootNode, | ||
// The 'columns' property can be undefined or 0 when not using a TTY. | ||
// In that case we fall back to 80. | ||
this.options.stdout.columns || 80); | ||
// If <Static> output isn't empty, it means new children have been added to it | ||
const hasStaticOutput = staticOutput && staticOutput !== '\n'; | ||
if (this.options.debug) { | ||
if (hasStaticOutput) { | ||
this.fullStaticOutput += staticOutput; | ||
} | ||
this.options.stdout.write(this.fullStaticOutput + output); | ||
return; | ||
} | ||
if (isCi) { | ||
if (hasStaticOutput) { | ||
this.options.stdout.write(staticOutput); | ||
} | ||
this.lastOutput = output; | ||
return; | ||
} | ||
if (hasStaticOutput) { | ||
this.fullStaticOutput += staticOutput; | ||
} | ||
this.options.stdout.write(this.fullStaticOutput + output); | ||
return; | ||
} | ||
if (isCI) { | ||
if (outputHeight >= this.options.stdout.rows) { | ||
this.options.stdout.write(ansiEscapes.clearTerminal + this.fullStaticOutput + output); | ||
this.lastOutput = output; | ||
return; | ||
} | ||
// To ensure static output is cleanly rendered before main output, clear main output first | ||
if (hasStaticOutput) { | ||
this.log.clear(); | ||
this.options.stdout.write(staticOutput); | ||
this.log(output); | ||
} | ||
if (!hasStaticOutput && output !== this.lastOutput) { | ||
this.throttledLog(output); | ||
} | ||
this.lastOutput = output; | ||
return; | ||
} | ||
if (hasStaticOutput) { | ||
this.fullStaticOutput += staticOutput; | ||
} | ||
if (outputHeight >= this.options.stdout.rows) { | ||
this.options.stdout.write(ansi_escapes_1.default.clearTerminal + this.fullStaticOutput + output); | ||
this.lastOutput = output; | ||
return; | ||
} | ||
// To ensure static output is cleanly rendered before main output, clear main output first | ||
if (hasStaticOutput) { | ||
this.log.clear(); | ||
this.options.stdout.write(staticOutput); | ||
this.log(output); | ||
} | ||
if (!hasStaticOutput && output !== this.lastOutput) { | ||
this.throttledLog(output); | ||
} | ||
this.lastOutput = output; | ||
}; | ||
auto_bind_1.default(this); | ||
}); | ||
autoBind(this); | ||
this.options = options; | ||
@@ -93,3 +159,3 @@ this.rootNode = dom.createNode('ink-root'); | ||
? this.onRender | ||
: lodash_1.throttle(this.onRender, 32, { | ||
: throttle(this.onRender, 32, { | ||
leading: true, | ||
@@ -99,6 +165,6 @@ trailing: true | ||
this.rootNode.onImmediateRender = this.onRender; | ||
this.log = log_update_1.default.create(options.stdout); | ||
this.log = logUpdate.create(options.stdout); | ||
this.throttledLog = options.debug | ||
? this.log | ||
: lodash_1.throttle(this.log, undefined, { | ||
: throttle(this.log, undefined, { | ||
leading: true, | ||
@@ -114,9 +180,10 @@ trailing: true | ||
this.fullStaticOutput = ''; | ||
this.container = reconciler_1.default.createContainer(this.rootNode, | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
this.container = reconciler.createContainer(this.rootNode, | ||
// Legacy mode | ||
0, false, null); | ||
0, null, false, null, 'id', () => { }, null); | ||
// Unmount when process exits | ||
this.unsubscribeExit = signal_exit_1.default(this.unmount, { alwaysLast: false }); | ||
if (process.env.DEV === 'true') { | ||
reconciler_1.default.injectIntoDevTools({ | ||
this.unsubscribeExit = signalExit(this.unmount, { alwaysLast: false }); | ||
if (process.env['DEV'] === 'true') { | ||
reconciler.injectIntoDevTools({ | ||
bundleType: 0, | ||
@@ -132,3 +199,3 @@ // Reporting React DOM's version, not Ink's | ||
} | ||
if (!isCI) { | ||
if (!isCi) { | ||
options.stdout.on('resize', this.onRender); | ||
@@ -141,4 +208,4 @@ this.unsubscribeResize = () => { | ||
render(node) { | ||
const tree = (react_1.default.createElement(App_1.default, { stdin: this.options.stdin, stdout: this.options.stdout, stderr: this.options.stderr, writeToStdout: this.writeToStdout, writeToStderr: this.writeToStderr, exitOnCtrlC: this.options.exitOnCtrlC, onExit: this.unmount }, node)); | ||
reconciler_1.default.updateContainer(tree, this.container, null, noop); | ||
const tree = (React.createElement(App, { stdin: this.options.stdin, stdout: this.options.stdout, stderr: this.options.stderr, writeToStdout: this.writeToStdout, writeToStderr: this.writeToStderr, exitOnCtrlC: this.options.exitOnCtrlC, onExit: this.unmount }, node)); | ||
reconciler.updateContainer(tree, this.container, null, noop); | ||
} | ||
@@ -153,3 +220,3 @@ writeToStdout(data) { | ||
} | ||
if (isCI) { | ||
if (isCi) { | ||
this.options.stdout.write(data); | ||
@@ -171,3 +238,3 @@ return; | ||
} | ||
if (isCI) { | ||
if (isCi) { | ||
this.options.stderr.write(data); | ||
@@ -180,2 +247,3 @@ return; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/ban-types | ||
unmount(error) { | ||
@@ -195,3 +263,3 @@ if (this.isUnmounted) { | ||
// only render last frame of non-static output | ||
if (isCI) { | ||
if (isCi) { | ||
this.options.stdout.write(this.lastOutput + '\n'); | ||
@@ -203,4 +271,4 @@ } | ||
this.isUnmounted = true; | ||
reconciler_1.default.updateContainer(null, this.container, null, noop); | ||
instances_1.default.delete(this.options.stdout); | ||
reconciler.updateContainer(null, this.container, null, noop); | ||
instances.delete(this.options.stdout); | ||
if (error instanceof Error) { | ||
@@ -213,3 +281,3 @@ this.rejectExitPromise(error); | ||
} | ||
waitUntilExit() { | ||
async waitUntilExit() { | ||
if (!this.exitPromise) { | ||
@@ -224,3 +292,3 @@ this.exitPromise = new Promise((resolve, reject) => { | ||
clear() { | ||
if (!isCI && !this.options.debug) { | ||
if (!isCi && !this.options.debug) { | ||
this.log.clear(); | ||
@@ -233,3 +301,3 @@ } | ||
} | ||
this.restoreConsole = patch_console_1.default((stream, data) => { | ||
this.restoreConsole = patchConsole((stream, data) => { | ||
if (stream === 'stdout') { | ||
@@ -247,3 +315,2 @@ this.writeToStdout(data); | ||
} | ||
exports.default = Ink; | ||
//# sourceMappingURL=ink.js.map |
@@ -1,2 +0,4 @@ | ||
declare const _default: WeakMap<object, any>; | ||
export default _default; | ||
/// <reference types="node" resolution-mode="require"/> | ||
import type Ink from './ink.js'; | ||
declare const instances: WeakMap<NodeJS.WriteStream, Ink>; | ||
export default instances; |
@@ -1,3 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// Store all instances of Ink (instance.js) to ensure that consecutive render() calls | ||
@@ -8,3 +6,4 @@ // use the same instance of Ink and don't create a new one | ||
// but instance.js should delete itself from the map on unmount | ||
exports.default = new WeakMap(); | ||
const instances = new WeakMap(); | ||
export default instances; | ||
//# sourceMappingURL=instances.js.map |
@@ -1,9 +0,8 @@ | ||
/// <reference types="node" /> | ||
import { Writable } from 'stream'; | ||
export interface LogUpdate { | ||
import { type Writable } from 'node:stream'; | ||
export type LogUpdate = { | ||
clear: () => void; | ||
done: () => void; | ||
(str: string): void; | ||
} | ||
declare const _default: { | ||
}; | ||
declare const logUpdate: { | ||
create: (stream: Writable, { showCursor }?: { | ||
@@ -13,2 +12,2 @@ showCursor?: boolean | undefined; | ||
}; | ||
export default _default; | ||
export default logUpdate; |
@@ -1,8 +0,3 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ansi_escapes_1 = __importDefault(require("ansi-escapes")); | ||
const cli_cursor_1 = __importDefault(require("cli-cursor")); | ||
import ansiEscapes from 'ansi-escapes'; | ||
import cliCursor from 'cli-cursor'; | ||
const create = (stream, { showCursor = false } = {}) => { | ||
@@ -14,3 +9,3 @@ let previousLineCount = 0; | ||
if (!showCursor && !hasHiddenCursor) { | ||
cli_cursor_1.default.hide(); | ||
cliCursor.hide(); | ||
hasHiddenCursor = true; | ||
@@ -23,7 +18,7 @@ } | ||
previousOutput = output; | ||
stream.write(ansi_escapes_1.default.eraseLines(previousLineCount) + output); | ||
stream.write(ansiEscapes.eraseLines(previousLineCount) + output); | ||
previousLineCount = output.split('\n').length; | ||
}; | ||
render.clear = () => { | ||
stream.write(ansi_escapes_1.default.eraseLines(previousLineCount)); | ||
stream.write(ansiEscapes.eraseLines(previousLineCount)); | ||
previousOutput = ''; | ||
@@ -36,3 +31,3 @@ previousLineCount = 0; | ||
if (!showCursor) { | ||
cli_cursor_1.default.show(); | ||
cliCursor.show(); | ||
hasHiddenCursor = false; | ||
@@ -43,3 +38,4 @@ } | ||
}; | ||
exports.default = { create }; | ||
const logUpdate = { create }; | ||
export default logUpdate; | ||
//# sourceMappingURL=log-update.js.map |
@@ -1,3 +0,3 @@ | ||
import { DOMElement } from './dom'; | ||
interface Output { | ||
import { type DOMElement } from './dom.js'; | ||
type Output = { | ||
/** | ||
@@ -11,7 +11,7 @@ * Element width. | ||
height: number; | ||
} | ||
declare const _default: (node: DOMElement) => Output; | ||
}; | ||
/** | ||
* Measure the dimensions of a particular `<Box>` element. | ||
*/ | ||
export default _default; | ||
declare const measureElement: (node: DOMElement) => Output; | ||
export default measureElement; |
@@ -1,13 +0,9 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* Measure the dimensions of a particular `<Box>` element. | ||
*/ | ||
exports.default = (node) => { | ||
var _a, _b, _c, _d; | ||
return ({ | ||
width: (_b = (_a = node.yogaNode) === null || _a === void 0 ? void 0 : _a.getComputedWidth()) !== null && _b !== void 0 ? _b : 0, | ||
height: (_d = (_c = node.yogaNode) === null || _c === void 0 ? void 0 : _c.getComputedHeight()) !== null && _d !== void 0 ? _d : 0 | ||
}); | ||
}; | ||
const measureElement = (node) => ({ | ||
width: node.yogaNode?.getComputedWidth() ?? 0, | ||
height: node.yogaNode?.getComputedHeight() ?? 0 | ||
}); | ||
export default measureElement; | ||
//# sourceMappingURL=measure-element.js.map |
@@ -1,6 +0,6 @@ | ||
interface Output { | ||
type Output = { | ||
width: number; | ||
height: number; | ||
} | ||
declare const _default: (text: string) => Output; | ||
export default _default; | ||
}; | ||
declare const measureText: (text: string) => Output; | ||
export default measureText; |
@@ -1,9 +0,4 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const widest_line_1 = __importDefault(require("widest-line")); | ||
import widestLine from 'widest-line'; | ||
const cache = {}; | ||
exports.default = (text) => { | ||
const measureText = (text) => { | ||
if (text.length === 0) { | ||
@@ -15,6 +10,7 @@ return { | ||
} | ||
if (cache[text]) { | ||
return cache[text]; | ||
const cachedDimensions = cache[text]; | ||
if (cachedDimensions) { | ||
return cachedDimensions; | ||
} | ||
const width = widest_line_1.default(text); | ||
const width = widestLine(text); | ||
const height = text.split('\n').length; | ||
@@ -24,2 +20,3 @@ cache[text] = { width, height }; | ||
}; | ||
export default measureText; | ||
//# sourceMappingURL=measure-text.js.map |
@@ -1,2 +0,2 @@ | ||
import { OutputTransformer } from './render-node-to-output'; | ||
import { type OutputTransformer } from './render-node-to-output.js'; | ||
/** | ||
@@ -10,6 +10,6 @@ * "Virtual" output class | ||
*/ | ||
interface Options { | ||
type Options = { | ||
width: number; | ||
height: number; | ||
} | ||
}; | ||
export default class Output { | ||
@@ -16,0 +16,0 @@ width: number; |
@@ -1,12 +0,24 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const slice_ansi_1 = __importDefault(require("slice-ansi")); | ||
const string_width_1 = __importDefault(require("string-width")); | ||
class Output { | ||
import sliceAnsi from 'slice-ansi'; | ||
import stringWidth from 'string-width'; | ||
export default class Output { | ||
constructor(options) { | ||
Object.defineProperty(this, "width", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "height", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
// Initialize output array with a specific set of rows, so that margin/padding at the bottom is preserved | ||
this.writes = []; | ||
Object.defineProperty(this, "writes", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: [] | ||
}); | ||
const { width, height } = options; | ||
@@ -38,3 +50,3 @@ this.width = width; | ||
} | ||
const width = string_width_1.default(line); | ||
const width = stringWidth(line); | ||
for (const transformer of transformers) { | ||
@@ -44,10 +56,9 @@ line = transformer(line); | ||
output[y + offsetY] = | ||
slice_ansi_1.default(currentLine, 0, x) + | ||
sliceAnsi(currentLine, 0, x) + | ||
line + | ||
slice_ansi_1.default(currentLine, x + width); | ||
sliceAnsi(currentLine, x + width); | ||
offsetY++; | ||
} | ||
} | ||
// eslint-disable-next-line unicorn/prefer-trim-start-end | ||
const generatedOutput = output.map(line => line.trimRight()).join('\n'); | ||
const generatedOutput = output.map(line => line.trimEnd()).join('\n'); | ||
return { | ||
@@ -59,3 +70,2 @@ output: generatedOutput, | ||
} | ||
exports.default = Output; | ||
//# sourceMappingURL=output.js.map |
import createReconciler from 'react-reconciler'; | ||
import { TextNode, DOMElement } from './dom'; | ||
import { type TextNode, type DOMElement } from './dom.js'; | ||
declare const _default: createReconciler.Reconciler<DOMElement, DOMElement, TextNode, DOMElement, unknown>; | ||
export default _default; |
@@ -1,26 +0,33 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const scheduler_1 = require("scheduler"); | ||
const react_reconciler_1 = __importDefault(require("react-reconciler")); | ||
const yoga_layout_prebuilt_1 = __importDefault(require("yoga-layout-prebuilt")); | ||
const dom_1 = require("./dom"); | ||
import process from 'node:process'; | ||
import createReconciler from 'react-reconciler'; | ||
import { DefaultEventPriority } from 'react-reconciler/constants.js'; | ||
import Yoga from 'yoga-layout-prebuilt'; | ||
import { createTextNode, appendChildNode, insertBeforeNode, removeChildNode, setStyle, setTextNodeValue, createNode, setAttribute } from './dom.js'; | ||
// We need to conditionally perform devtools connection to avoid | ||
// accidentally breaking other third-party code. | ||
// See https://github.com/vadimdemedes/ink/issues/384 | ||
if (process.env.DEV === 'true') { | ||
// eslint-disable-next-line import/no-unassigned-import | ||
require('./devtools'); | ||
if (process.env['DEV'] === 'true') { | ||
try { | ||
await import('./devtools.js'); | ||
// eslint-disable-next-line @typescript-eslint/no-implicit-any-catch | ||
} | ||
catch (error) { | ||
if (error.code === 'MODULE_NOT_FOUND') { | ||
console.warn(` | ||
Debugging with React Devtools requires \`react-devtools-core\` dependency to be installed. | ||
$ npm install --save-dev react-devtools-core | ||
`.trim() + '\n'); | ||
} | ||
else { | ||
// eslint-disable-next-line @typescript-eslint/no-throw-literal | ||
throw error; | ||
} | ||
} | ||
} | ||
const cleanupYogaNode = (node) => { | ||
node === null || node === void 0 ? void 0 : node.unsetMeasureFunc(); | ||
node === null || node === void 0 ? void 0 : node.freeRecursive(); | ||
node?.unsetMeasureFunc(); | ||
node?.freeRecursive(); | ||
}; | ||
exports.default = react_reconciler_1.default({ | ||
// @ts-ignore | ||
schedulePassiveEffects: scheduler_1.unstable_scheduleCallback, | ||
cancelPassiveEffects: scheduler_1.unstable_cancelCallback, | ||
now: Date.now, | ||
export default createReconciler({ | ||
getRootHostContext: () => ({ | ||
@@ -32,4 +39,3 @@ isInsideText: false | ||
clearContainer: () => false, | ||
shouldDeprioritizeSubtree: () => false, | ||
resetAfterCommit: rootNode => { | ||
resetAfterCommit(rootNode) { | ||
// Since renders are throttled at the instance level and <Static> component children | ||
@@ -49,3 +55,3 @@ // are rendered only once and then get deleted, we need an escape hatch to | ||
}, | ||
getChildHostContext: (parentHostContext, type) => { | ||
getChildHostContext(parentHostContext, type) { | ||
const previousIsInsideText = parentHostContext.isInsideText; | ||
@@ -59,3 +65,3 @@ const isInsideText = type === 'ink-text' || type === 'ink-virtual-text'; | ||
shouldSetTextContent: () => false, | ||
createInstance: (originalType, newProps, _root, hostContext) => { | ||
createInstance(originalType, newProps, _root, hostContext) { | ||
if (hostContext.isInsideText && originalType === 'ink-box') { | ||
@@ -67,3 +73,3 @@ throw new Error(`<Box> can’t be nested inside <Text> component`); | ||
: originalType; | ||
const node = dom_1.createNode(type); | ||
const node = createNode(type); | ||
for (const [key, value] of Object.entries(newProps)) { | ||
@@ -73,43 +79,42 @@ if (key === 'children') { | ||
} | ||
else if (key === 'style') { | ||
dom_1.setStyle(node, value); | ||
if (key === 'style') { | ||
setStyle(node, value); | ||
continue; | ||
} | ||
else if (key === 'internal_transform') { | ||
if (key === 'internal_transform') { | ||
node.internal_transform = value; | ||
continue; | ||
} | ||
else if (key === 'internal_static') { | ||
if (key === 'internal_static') { | ||
node.internal_static = true; | ||
continue; | ||
} | ||
else { | ||
dom_1.setAttribute(node, key, value); | ||
} | ||
setAttribute(node, key, value); | ||
} | ||
return node; | ||
}, | ||
createTextInstance: (text, _root, hostContext) => { | ||
createTextInstance(text, _root, hostContext) { | ||
if (!hostContext.isInsideText) { | ||
throw new Error(`Text string "${text}" must be rendered inside <Text> component`); | ||
} | ||
return dom_1.createTextNode(text); | ||
return createTextNode(text); | ||
}, | ||
resetTextContent: () => { }, | ||
hideTextInstance: node => { | ||
dom_1.setTextNodeValue(node, ''); | ||
resetTextContent() { }, | ||
hideTextInstance(node) { | ||
setTextNodeValue(node, ''); | ||
}, | ||
unhideTextInstance: (node, text) => { | ||
dom_1.setTextNodeValue(node, text); | ||
unhideTextInstance(node, text) { | ||
setTextNodeValue(node, text); | ||
}, | ||
getPublicInstance: instance => instance, | ||
hideInstance: node => { | ||
var _a; | ||
(_a = node.yogaNode) === null || _a === void 0 ? void 0 : _a.setDisplay(yoga_layout_prebuilt_1.default.DISPLAY_NONE); | ||
hideInstance(node) { | ||
node.yogaNode?.setDisplay(Yoga.DISPLAY_NONE); | ||
}, | ||
unhideInstance: node => { | ||
var _a; | ||
(_a = node.yogaNode) === null || _a === void 0 ? void 0 : _a.setDisplay(yoga_layout_prebuilt_1.default.DISPLAY_FLEX); | ||
unhideInstance(node) { | ||
node.yogaNode?.setDisplay(Yoga.DISPLAY_FLEX); | ||
}, | ||
appendInitialChild: dom_1.appendChildNode, | ||
appendChild: dom_1.appendChildNode, | ||
insertBefore: dom_1.insertBeforeNode, | ||
finalizeInitialChildren: (node, _type, _props, rootNode) => { | ||
appendInitialChild: appendChildNode, | ||
appendChild: appendChildNode, | ||
insertBefore: insertBeforeNode, | ||
finalizeInitialChildren(node, _type, _props, rootNode) { | ||
if (node.internal_static) { | ||
@@ -123,10 +128,23 @@ rootNode.isStaticDirty = true; | ||
}, | ||
isPrimaryRenderer: true, | ||
supportsMutation: true, | ||
appendChildToContainer: dom_1.appendChildNode, | ||
insertInContainerBefore: dom_1.insertBeforeNode, | ||
removeChildFromContainer: (node, removeNode) => { | ||
dom_1.removeChildNode(node, removeNode); | ||
supportsPersistence: false, | ||
supportsHydration: false, | ||
scheduleTimeout: setTimeout, | ||
cancelTimeout: clearTimeout, | ||
noTimeout: -1, | ||
getCurrentEventPriority: () => DefaultEventPriority, | ||
beforeActiveInstanceBlur() { }, | ||
afterActiveInstanceBlur() { }, | ||
detachDeletedInstance() { }, | ||
getInstanceFromNode: () => null, | ||
prepareScopeUpdate() { }, | ||
getInstanceFromScope: () => null, | ||
appendChildToContainer: appendChildNode, | ||
insertInContainerBefore: insertBeforeNode, | ||
removeChildFromContainer(node, removeNode) { | ||
removeChildNode(node, removeNode); | ||
cleanupYogaNode(removeNode.yogaNode); | ||
}, | ||
prepareUpdate: (node, _type, oldProps, newProps, rootNode) => { | ||
prepareUpdate(node, _type, oldProps, newProps, rootNode) { | ||
if (node.internal_static) { | ||
@@ -140,7 +158,7 @@ rootNode.isStaticDirty = true; | ||
const isStyle = key === 'style' && | ||
typeof newProps.style === 'object' && | ||
typeof oldProps.style === 'object'; | ||
typeof newProps['style'] === 'object' && | ||
typeof oldProps['style'] === 'object'; | ||
if (isStyle) { | ||
const newStyle = newProps.style; | ||
const oldStyle = oldProps.style; | ||
const newStyle = newProps['style']; | ||
const oldStyle = oldProps['style']; | ||
const styleKeys = Object.keys(newStyle); | ||
@@ -152,17 +170,19 @@ for (const styleKey of styleKeys) { | ||
if (styleKey === 'borderStyle' || styleKey === 'borderColor') { | ||
if (typeof updatePayload.style !== 'object') { | ||
if (typeof updatePayload['style'] !== 'object') { | ||
// Linter didn't like `= {} as Style` | ||
const style = {}; | ||
updatePayload.style = style; | ||
updatePayload['style'] = style; | ||
} | ||
updatePayload.style.borderStyle = newStyle.borderStyle; | ||
updatePayload.style.borderColor = newStyle.borderColor; | ||
updatePayload['style'].borderStyle = | ||
newStyle.borderStyle; | ||
updatePayload['style'].borderColor = | ||
newStyle.borderColor; | ||
} | ||
if (newStyle[styleKey] !== oldStyle[styleKey]) { | ||
if (typeof updatePayload.style !== 'object') { | ||
if (typeof updatePayload['style'] !== 'object') { | ||
// Linter didn't like `= {} as Style` | ||
const style = {}; | ||
updatePayload.style = style; | ||
updatePayload['style'] = style; | ||
} | ||
updatePayload.style[styleKey] = newStyle[styleKey]; | ||
updatePayload['style'][styleKey] = newStyle[styleKey]; | ||
} | ||
@@ -177,3 +197,3 @@ } | ||
}, | ||
commitUpdate: (node, updatePayload) => { | ||
commitUpdate(node, updatePayload) { | ||
for (const [key, value] of Object.entries(updatePayload)) { | ||
@@ -183,21 +203,22 @@ if (key === 'children') { | ||
} | ||
else if (key === 'style') { | ||
dom_1.setStyle(node, value); | ||
if (key === 'style') { | ||
setStyle(node, value); | ||
continue; | ||
} | ||
else if (key === 'internal_transform') { | ||
if (key === 'internal_transform') { | ||
node.internal_transform = value; | ||
continue; | ||
} | ||
else if (key === 'internal_static') { | ||
if (key === 'internal_static') { | ||
node.internal_static = true; | ||
continue; | ||
} | ||
else { | ||
dom_1.setAttribute(node, key, value); | ||
} | ||
setAttribute(node, key, value); | ||
} | ||
}, | ||
commitTextUpdate: (node, _oldText, newText) => { | ||
dom_1.setTextNodeValue(node, newText); | ||
commitTextUpdate(node, _oldText, newText) { | ||
setTextNodeValue(node, newText); | ||
}, | ||
removeChild: (node, removeNode) => { | ||
dom_1.removeChildNode(node, removeNode); | ||
removeChild(node, removeNode) { | ||
removeChildNode(node, removeNode); | ||
cleanupYogaNode(removeNode.yogaNode); | ||
@@ -204,0 +225,0 @@ } |
@@ -1,4 +0,4 @@ | ||
import { DOMNode } from './dom'; | ||
import Output from './output'; | ||
declare const _default: (x: number, y: number, node: DOMNode, output: Output) => void; | ||
export default _default; | ||
import { type DOMNode } from './dom.js'; | ||
import type Output from './output.js'; | ||
declare const renderBorder: (x: number, y: number, node: DOMNode, output: Output) => void; | ||
export default renderBorder; |
@@ -1,9 +0,4 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const cli_boxes_1 = __importDefault(require("cli-boxes")); | ||
const colorize_1 = __importDefault(require("./colorize")); | ||
exports.default = (x, y, node, output) => { | ||
import cliBoxes from 'cli-boxes'; | ||
import colorize from './colorize.js'; | ||
const renderBorder = (x, y, node, output) => { | ||
if (typeof node.style.borderStyle === 'string') { | ||
@@ -13,6 +8,6 @@ const width = node.yogaNode.getComputedWidth(); | ||
const color = node.style.borderColor; | ||
const box = cli_boxes_1.default[node.style.borderStyle]; | ||
const topBorder = colorize_1.default(box.topLeft + box.horizontal.repeat(width - 2) + box.topRight, color, 'foreground'); | ||
const verticalBorder = (colorize_1.default(box.vertical, color, 'foreground') + '\n').repeat(height - 2); | ||
const bottomBorder = colorize_1.default(box.bottomLeft + box.horizontal.repeat(width - 2) + box.bottomRight, color, 'foreground'); | ||
const box = cliBoxes[node.style.borderStyle]; | ||
const topBorder = colorize(box.topLeft + box.top.repeat(width - 2) + box.topRight, color, 'foreground'); | ||
const verticalBorder = (colorize(box.left, color, 'foreground') + '\n').repeat(height - 2); | ||
const bottomBorder = colorize(box.bottomLeft + box.bottom.repeat(width - 2) + box.bottomRight, color, 'foreground'); | ||
output.write(x, y, topBorder, { transformers: [] }); | ||
@@ -24,2 +19,3 @@ output.write(x, y + 1, verticalBorder, { transformers: [] }); | ||
}; | ||
export default renderBorder; | ||
//# sourceMappingURL=render-border.js.map |
@@ -1,4 +0,4 @@ | ||
import { DOMElement } from './dom'; | ||
import Output from './output'; | ||
export declare type OutputTransformer = (s: string) => string; | ||
import { type DOMElement } from './dom.js'; | ||
import type Output from './output.js'; | ||
export type OutputTransformer = (s: string) => string; | ||
declare const renderNodeToOutput: (node: DOMElement, output: Output, options: { | ||
@@ -5,0 +5,0 @@ offsetX?: number; |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const yoga_layout_prebuilt_1 = __importDefault(require("yoga-layout-prebuilt")); | ||
const widest_line_1 = __importDefault(require("widest-line")); | ||
const indent_string_1 = __importDefault(require("indent-string")); | ||
const wrap_text_1 = __importDefault(require("./wrap-text")); | ||
const get_max_width_1 = __importDefault(require("./get-max-width")); | ||
const squash_text_nodes_1 = __importDefault(require("./squash-text-nodes")); | ||
const render_border_1 = __importDefault(require("./render-border")); | ||
import Yoga from 'yoga-layout-prebuilt'; | ||
import widestLine from 'widest-line'; | ||
import indentString from 'indent-string'; | ||
import wrapText from './wrap-text.js'; | ||
import getMaxWidth from './get-max-width.js'; | ||
import squashTextNodes from './squash-text-nodes.js'; | ||
import renderBorder from './render-border.js'; | ||
// If parent container is `<Box>`, text nodes will be treated as separate nodes in | ||
@@ -20,8 +15,7 @@ // the tree and will have their own coordinates in the layout. | ||
const applyPaddingToText = (node, text) => { | ||
var _a; | ||
const yogaNode = (_a = node.childNodes[0]) === null || _a === void 0 ? void 0 : _a.yogaNode; | ||
const yogaNode = node.childNodes[0]?.yogaNode; | ||
if (yogaNode) { | ||
const offsetX = yogaNode.getComputedLeft(); | ||
const offsetY = yogaNode.getComputedTop(); | ||
text = '\n'.repeat(offsetY) + indent_string_1.default(text, offsetX); | ||
text = '\n'.repeat(offsetY) + indentString(text, offsetX); | ||
} | ||
@@ -32,3 +26,2 @@ return text; | ||
const renderNodeToOutput = (node, output, options) => { | ||
var _a; | ||
const { offsetX = 0, offsetY = 0, transformers = [], skipStaticElements } = options; | ||
@@ -40,3 +33,3 @@ if (skipStaticElements && node.internal_static) { | ||
if (yogaNode) { | ||
if (yogaNode.getDisplay() === yoga_layout_prebuilt_1.default.DISPLAY_NONE) { | ||
if (yogaNode.getDisplay() === Yoga.DISPLAY_NONE) { | ||
return; | ||
@@ -54,9 +47,9 @@ } | ||
if (node.nodeName === 'ink-text') { | ||
let text = squash_text_nodes_1.default(node); | ||
let text = squashTextNodes(node); | ||
if (text.length > 0) { | ||
const currentWidth = widest_line_1.default(text); | ||
const maxWidth = get_max_width_1.default(yogaNode); | ||
const currentWidth = widestLine(text); | ||
const maxWidth = getMaxWidth(yogaNode); | ||
if (currentWidth > maxWidth) { | ||
const textWrap = (_a = node.style.textWrap) !== null && _a !== void 0 ? _a : 'wrap'; | ||
text = wrap_text_1.default(text, maxWidth, textWrap); | ||
const textWrap = node.style.textWrap ?? 'wrap'; | ||
text = wrapText(text, maxWidth, textWrap); | ||
} | ||
@@ -69,3 +62,3 @@ text = applyPaddingToText(node, text); | ||
if (node.nodeName === 'ink-box') { | ||
render_border_1.default(x, y, node, output); | ||
renderBorder(x, y, node, output); | ||
} | ||
@@ -84,3 +77,3 @@ if (node.nodeName === 'ink-root' || node.nodeName === 'ink-box') { | ||
}; | ||
exports.default = renderNodeToOutput; | ||
export default renderNodeToOutput; | ||
//# sourceMappingURL=render-node-to-output.js.map |
@@ -1,5 +0,5 @@ | ||
/// <reference types="node" /> | ||
import { ReactElement } from 'react'; | ||
import Ink from './ink'; | ||
export interface RenderOptions { | ||
/// <reference types="node" resolution-mode="require"/> | ||
import { type ReactElement } from 'react'; | ||
import Ink from './ink.js'; | ||
export type RenderOptions = { | ||
/** | ||
@@ -40,4 +40,4 @@ * Output stream where app will be rendered. | ||
patchConsole?: boolean; | ||
} | ||
export interface Instance { | ||
}; | ||
export type Instance = { | ||
/** | ||
@@ -60,4 +60,4 @@ * Replace previous root node with a new one or update props of the current root node. | ||
clear: () => void; | ||
} | ||
declare type RenderFunction = <Props, K extends NodeJS.WriteStream | RenderOptions>(tree: ReactElement<Props>, options?: K) => Instance; | ||
}; | ||
type RenderFunction = <Props, K extends NodeJS.WriteStream | RenderOptions>(tree: ReactElement<Props>, options?: K) => Instance; | ||
/** | ||
@@ -64,0 +64,0 @@ * Mount a component and render the output. |
@@ -1,9 +0,5 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ink_1 = __importDefault(require("./ink")); | ||
const instances_1 = __importDefault(require("./instances")); | ||
const stream_1 = require("stream"); | ||
import { Stream } from 'node:stream'; | ||
import process from 'node:process'; | ||
import Ink from './ink.js'; | ||
import instances from './instances.js'; | ||
/** | ||
@@ -13,16 +9,26 @@ * Mount a component and render the output. | ||
const render = (node, options) => { | ||
const inkOptions = Object.assign({ stdout: process.stdout, stdin: process.stdin, stderr: process.stderr, debug: false, exitOnCtrlC: true, patchConsole: true }, getOptions(options)); | ||
const instance = getInstance(inkOptions.stdout, () => new ink_1.default(inkOptions)); | ||
const inkOptions = { | ||
stdout: process.stdout, | ||
stdin: process.stdin, | ||
stderr: process.stderr, | ||
debug: false, | ||
exitOnCtrlC: true, | ||
patchConsole: true, | ||
...getOptions(options) | ||
}; | ||
const instance = getInstance(inkOptions.stdout, () => new Ink(inkOptions)); | ||
instance.render(node); | ||
return { | ||
rerender: instance.render, | ||
unmount: () => instance.unmount(), | ||
unmount() { | ||
instance.unmount(); | ||
}, | ||
waitUntilExit: instance.waitUntilExit, | ||
cleanup: () => instances_1.default.delete(inkOptions.stdout), | ||
cleanup: () => instances.delete(inkOptions.stdout), | ||
clear: instance.clear | ||
}; | ||
}; | ||
exports.default = render; | ||
export default render; | ||
const getOptions = (stdout = {}) => { | ||
if (stdout instanceof stream_1.Stream) { | ||
if (stdout instanceof Stream) { | ||
return { | ||
@@ -36,9 +42,6 @@ stdout, | ||
const getInstance = (stdout, createInstance) => { | ||
let instance; | ||
if (instances_1.default.has(stdout)) { | ||
instance = instances_1.default.get(stdout); | ||
} | ||
else { | ||
let instance = instances.get(stdout); | ||
if (!instance) { | ||
instance = createInstance(); | ||
instances_1.default.set(stdout, instance); | ||
instances.set(stdout, instance); | ||
} | ||
@@ -45,0 +48,0 @@ return instance; |
@@ -1,8 +0,8 @@ | ||
import { DOMElement } from './dom'; | ||
interface Result { | ||
import { type DOMElement } from './dom.js'; | ||
type Result = { | ||
output: string; | ||
outputHeight: number; | ||
staticOutput: string; | ||
} | ||
declare const _default: (node: DOMElement, terminalWidth: number) => Result; | ||
export default _default; | ||
}; | ||
declare const renderer: (node: DOMElement, terminalWidth: number) => Result; | ||
export default renderer; |
@@ -1,26 +0,20 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const yoga_layout_prebuilt_1 = __importDefault(require("yoga-layout-prebuilt")); | ||
const render_node_to_output_1 = __importDefault(require("./render-node-to-output")); | ||
const output_1 = __importDefault(require("./output")); | ||
exports.default = (node, terminalWidth) => { | ||
var _a; | ||
import Yoga from 'yoga-layout-prebuilt'; | ||
import renderNodeToOutput from './render-node-to-output.js'; | ||
import Output from './output.js'; | ||
const renderer = (node, terminalWidth) => { | ||
node.yogaNode.setWidth(terminalWidth); | ||
if (node.yogaNode) { | ||
node.yogaNode.calculateLayout(undefined, undefined, yoga_layout_prebuilt_1.default.DIRECTION_LTR); | ||
const output = new output_1.default({ | ||
node.yogaNode.calculateLayout(undefined, undefined, Yoga.DIRECTION_LTR); | ||
const output = new Output({ | ||
width: node.yogaNode.getComputedWidth(), | ||
height: node.yogaNode.getComputedHeight() | ||
}); | ||
render_node_to_output_1.default(node, output, { skipStaticElements: true }); | ||
renderNodeToOutput(node, output, { skipStaticElements: true }); | ||
let staticOutput; | ||
if ((_a = node.staticNode) === null || _a === void 0 ? void 0 : _a.yogaNode) { | ||
staticOutput = new output_1.default({ | ||
if (node.staticNode?.yogaNode) { | ||
staticOutput = new Output({ | ||
width: node.staticNode.yogaNode.getComputedWidth(), | ||
height: node.staticNode.yogaNode.getComputedHeight() | ||
}); | ||
render_node_to_output_1.default(node.staticNode, staticOutput, { | ||
renderNodeToOutput(node.staticNode, staticOutput, { | ||
skipStaticElements: false | ||
@@ -44,2 +38,3 @@ }); | ||
}; | ||
export default renderer; | ||
//# sourceMappingURL=renderer.js.map |
@@ -1,3 +0,3 @@ | ||
import { DOMElement } from './dom'; | ||
import { type DOMElement } from './dom.js'; | ||
declare const squashTextNodes: (node: DOMElement) => string; | ||
export default squashTextNodes; |
@@ -1,3 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// Squashing text nodes allows to combine multiple text nodes into one and write | ||
@@ -34,3 +32,3 @@ // to `Output` instance only once. For example, <Text>hello{' '}world</Text> | ||
}; | ||
exports.default = squashTextNodes; | ||
export default squashTextNodes; | ||
//# sourceMappingURL=squash-text-nodes.js.map |
@@ -1,6 +0,6 @@ | ||
import { YogaNode } from 'yoga-layout-prebuilt'; | ||
import { Boxes } from 'cli-boxes'; | ||
import { LiteralUnion } from 'type-fest'; | ||
import { ForegroundColor } from 'chalk'; | ||
export interface Styles { | ||
import { type YogaNode } from 'yoga-layout-prebuilt'; | ||
import { type Boxes } from 'cli-boxes'; | ||
import { type LiteralUnion } from 'type-fest'; | ||
import { type ForegroundColorName } from 'chalk'; | ||
export type Styles = { | ||
readonly textWrap?: 'wrap' | 'end' | 'middle' | 'truncate-end' | 'truncate' | 'truncate-middle' | 'truncate-start'; | ||
@@ -106,5 +106,5 @@ readonly position?: 'absolute' | 'relative'; | ||
*/ | ||
readonly borderColor?: LiteralUnion<typeof ForegroundColor, string>; | ||
} | ||
declare const _default: (node: YogaNode, style?: Styles) => void; | ||
export default _default; | ||
readonly borderColor?: LiteralUnion<ForegroundColorName, string>; | ||
}; | ||
declare const styles: (node: YogaNode, style?: Styles) => void; | ||
export default styles; |
@@ -1,13 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ | ||
const yoga_layout_prebuilt_1 = __importDefault(require("yoga-layout-prebuilt")); | ||
import Yoga from 'yoga-layout-prebuilt'; | ||
const applyPositionStyles = (node, style) => { | ||
if ('position' in style) { | ||
node.setPositionType(style.position === 'absolute' | ||
? yoga_layout_prebuilt_1.default.POSITION_TYPE_ABSOLUTE | ||
: yoga_layout_prebuilt_1.default.POSITION_TYPE_RELATIVE); | ||
? Yoga.POSITION_TYPE_ABSOLUTE | ||
: Yoga.POSITION_TYPE_RELATIVE); | ||
} | ||
@@ -17,12 +12,12 @@ }; | ||
if ('marginLeft' in style) { | ||
node.setMargin(yoga_layout_prebuilt_1.default.EDGE_START, style.marginLeft || 0); | ||
node.setMargin(Yoga.EDGE_START, style.marginLeft || 0); | ||
} | ||
if ('marginRight' in style) { | ||
node.setMargin(yoga_layout_prebuilt_1.default.EDGE_END, style.marginRight || 0); | ||
node.setMargin(Yoga.EDGE_END, style.marginRight || 0); | ||
} | ||
if ('marginTop' in style) { | ||
node.setMargin(yoga_layout_prebuilt_1.default.EDGE_TOP, style.marginTop || 0); | ||
node.setMargin(Yoga.EDGE_TOP, style.marginTop || 0); | ||
} | ||
if ('marginBottom' in style) { | ||
node.setMargin(yoga_layout_prebuilt_1.default.EDGE_BOTTOM, style.marginBottom || 0); | ||
node.setMargin(Yoga.EDGE_BOTTOM, style.marginBottom || 0); | ||
} | ||
@@ -32,18 +27,17 @@ }; | ||
if ('paddingLeft' in style) { | ||
node.setPadding(yoga_layout_prebuilt_1.default.EDGE_LEFT, style.paddingLeft || 0); | ||
node.setPadding(Yoga.EDGE_LEFT, style.paddingLeft || 0); | ||
} | ||
if ('paddingRight' in style) { | ||
node.setPadding(yoga_layout_prebuilt_1.default.EDGE_RIGHT, style.paddingRight || 0); | ||
node.setPadding(Yoga.EDGE_RIGHT, style.paddingRight || 0); | ||
} | ||
if ('paddingTop' in style) { | ||
node.setPadding(yoga_layout_prebuilt_1.default.EDGE_TOP, style.paddingTop || 0); | ||
node.setPadding(Yoga.EDGE_TOP, style.paddingTop || 0); | ||
} | ||
if ('paddingBottom' in style) { | ||
node.setPadding(yoga_layout_prebuilt_1.default.EDGE_BOTTOM, style.paddingBottom || 0); | ||
node.setPadding(Yoga.EDGE_BOTTOM, style.paddingBottom || 0); | ||
} | ||
}; | ||
const applyFlexStyles = (node, style) => { | ||
var _a; | ||
if ('flexGrow' in style) { | ||
node.setFlexGrow((_a = style.flexGrow) !== null && _a !== void 0 ? _a : 0); | ||
node.setFlexGrow(style.flexGrow ?? 0); | ||
} | ||
@@ -55,12 +49,12 @@ if ('flexShrink' in style) { | ||
if (style.flexDirection === 'row') { | ||
node.setFlexDirection(yoga_layout_prebuilt_1.default.FLEX_DIRECTION_ROW); | ||
node.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); | ||
} | ||
if (style.flexDirection === 'row-reverse') { | ||
node.setFlexDirection(yoga_layout_prebuilt_1.default.FLEX_DIRECTION_ROW_REVERSE); | ||
node.setFlexDirection(Yoga.FLEX_DIRECTION_ROW_REVERSE); | ||
} | ||
if (style.flexDirection === 'column') { | ||
node.setFlexDirection(yoga_layout_prebuilt_1.default.FLEX_DIRECTION_COLUMN); | ||
node.setFlexDirection(Yoga.FLEX_DIRECTION_COLUMN); | ||
} | ||
if (style.flexDirection === 'column-reverse') { | ||
node.setFlexDirection(yoga_layout_prebuilt_1.default.FLEX_DIRECTION_COLUMN_REVERSE); | ||
node.setFlexDirection(Yoga.FLEX_DIRECTION_COLUMN_REVERSE); | ||
} | ||
@@ -77,3 +71,3 @@ } | ||
// This should be replaced with node.setFlexBasisAuto() when new Yoga release is out | ||
node.setFlexBasis(NaN); | ||
node.setFlexBasis(Number.NaN); | ||
} | ||
@@ -83,12 +77,12 @@ } | ||
if (style.alignItems === 'stretch' || !style.alignItems) { | ||
node.setAlignItems(yoga_layout_prebuilt_1.default.ALIGN_STRETCH); | ||
node.setAlignItems(Yoga.ALIGN_STRETCH); | ||
} | ||
if (style.alignItems === 'flex-start') { | ||
node.setAlignItems(yoga_layout_prebuilt_1.default.ALIGN_FLEX_START); | ||
node.setAlignItems(Yoga.ALIGN_FLEX_START); | ||
} | ||
if (style.alignItems === 'center') { | ||
node.setAlignItems(yoga_layout_prebuilt_1.default.ALIGN_CENTER); | ||
node.setAlignItems(Yoga.ALIGN_CENTER); | ||
} | ||
if (style.alignItems === 'flex-end') { | ||
node.setAlignItems(yoga_layout_prebuilt_1.default.ALIGN_FLEX_END); | ||
node.setAlignItems(Yoga.ALIGN_FLEX_END); | ||
} | ||
@@ -98,12 +92,12 @@ } | ||
if (style.alignSelf === 'auto' || !style.alignSelf) { | ||
node.setAlignSelf(yoga_layout_prebuilt_1.default.ALIGN_AUTO); | ||
node.setAlignSelf(Yoga.ALIGN_AUTO); | ||
} | ||
if (style.alignSelf === 'flex-start') { | ||
node.setAlignSelf(yoga_layout_prebuilt_1.default.ALIGN_FLEX_START); | ||
node.setAlignSelf(Yoga.ALIGN_FLEX_START); | ||
} | ||
if (style.alignSelf === 'center') { | ||
node.setAlignSelf(yoga_layout_prebuilt_1.default.ALIGN_CENTER); | ||
node.setAlignSelf(Yoga.ALIGN_CENTER); | ||
} | ||
if (style.alignSelf === 'flex-end') { | ||
node.setAlignSelf(yoga_layout_prebuilt_1.default.ALIGN_FLEX_END); | ||
node.setAlignSelf(Yoga.ALIGN_FLEX_END); | ||
} | ||
@@ -113,15 +107,15 @@ } | ||
if (style.justifyContent === 'flex-start' || !style.justifyContent) { | ||
node.setJustifyContent(yoga_layout_prebuilt_1.default.JUSTIFY_FLEX_START); | ||
node.setJustifyContent(Yoga.JUSTIFY_FLEX_START); | ||
} | ||
if (style.justifyContent === 'center') { | ||
node.setJustifyContent(yoga_layout_prebuilt_1.default.JUSTIFY_CENTER); | ||
node.setJustifyContent(Yoga.JUSTIFY_CENTER); | ||
} | ||
if (style.justifyContent === 'flex-end') { | ||
node.setJustifyContent(yoga_layout_prebuilt_1.default.JUSTIFY_FLEX_END); | ||
node.setJustifyContent(Yoga.JUSTIFY_FLEX_END); | ||
} | ||
if (style.justifyContent === 'space-between') { | ||
node.setJustifyContent(yoga_layout_prebuilt_1.default.JUSTIFY_SPACE_BETWEEN); | ||
node.setJustifyContent(Yoga.JUSTIFY_SPACE_BETWEEN); | ||
} | ||
if (style.justifyContent === 'space-around') { | ||
node.setJustifyContent(yoga_layout_prebuilt_1.default.JUSTIFY_SPACE_AROUND); | ||
node.setJustifyContent(Yoga.JUSTIFY_SPACE_AROUND); | ||
} | ||
@@ -131,3 +125,2 @@ } | ||
const applyDimensionStyles = (node, style) => { | ||
var _a, _b; | ||
if ('width' in style) { | ||
@@ -160,3 +153,3 @@ if (typeof style.width === 'number') { | ||
else { | ||
node.setMinWidth((_a = style.minWidth) !== null && _a !== void 0 ? _a : 0); | ||
node.setMinWidth(style.minWidth ?? 0); | ||
} | ||
@@ -169,3 +162,3 @@ } | ||
else { | ||
node.setMinHeight((_b = style.minHeight) !== null && _b !== void 0 ? _b : 0); | ||
node.setMinHeight(style.minHeight ?? 0); | ||
} | ||
@@ -176,3 +169,3 @@ } | ||
if ('display' in style) { | ||
node.setDisplay(style.display === 'flex' ? yoga_layout_prebuilt_1.default.DISPLAY_FLEX : yoga_layout_prebuilt_1.default.DISPLAY_NONE); | ||
node.setDisplay(style.display === 'flex' ? Yoga.DISPLAY_FLEX : Yoga.DISPLAY_NONE); | ||
} | ||
@@ -183,9 +176,9 @@ }; | ||
const borderWidth = typeof style.borderStyle === 'string' ? 1 : 0; | ||
node.setBorder(yoga_layout_prebuilt_1.default.EDGE_TOP, borderWidth); | ||
node.setBorder(yoga_layout_prebuilt_1.default.EDGE_BOTTOM, borderWidth); | ||
node.setBorder(yoga_layout_prebuilt_1.default.EDGE_LEFT, borderWidth); | ||
node.setBorder(yoga_layout_prebuilt_1.default.EDGE_RIGHT, borderWidth); | ||
node.setBorder(Yoga.EDGE_TOP, borderWidth); | ||
node.setBorder(Yoga.EDGE_BOTTOM, borderWidth); | ||
node.setBorder(Yoga.EDGE_LEFT, borderWidth); | ||
node.setBorder(Yoga.EDGE_RIGHT, borderWidth); | ||
} | ||
}; | ||
exports.default = (node, style = {}) => { | ||
const styles = (node, style = {}) => { | ||
applyPositionStyles(node, style); | ||
@@ -199,2 +192,3 @@ applyMarginStyles(node, style); | ||
}; | ||
export default styles; | ||
//# sourceMappingURL=styles.js.map |
@@ -1,3 +0,3 @@ | ||
import { Styles } from './styles'; | ||
declare const _default: (text: string, maxWidth: number, wrapType: Styles['textWrap']) => string; | ||
export default _default; | ||
import { type Styles } from './styles.js'; | ||
declare const wrapText: (text: string, maxWidth: number, wrapType: Styles['textWrap']) => string; | ||
export default wrapText; |
@@ -1,17 +0,13 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const wrap_ansi_1 = __importDefault(require("wrap-ansi")); | ||
const cli_truncate_1 = __importDefault(require("cli-truncate")); | ||
import wrapAnsi from 'wrap-ansi'; | ||
import cliTruncate from 'cli-truncate'; | ||
const cache = {}; | ||
exports.default = (text, maxWidth, wrapType) => { | ||
const wrapText = (text, maxWidth, wrapType) => { | ||
const cacheKey = text + String(maxWidth) + String(wrapType); | ||
if (cache[cacheKey]) { | ||
return cache[cacheKey]; | ||
const cachedText = cache[cacheKey]; | ||
if (cachedText) { | ||
return cachedText; | ||
} | ||
let wrappedText = text; | ||
if (wrapType === 'wrap') { | ||
wrappedText = wrap_ansi_1.default(text, maxWidth, { | ||
wrappedText = wrapAnsi(text, maxWidth, { | ||
trim: false, | ||
@@ -29,3 +25,3 @@ hard: true | ||
} | ||
wrappedText = cli_truncate_1.default(text, maxWidth, { position }); | ||
wrappedText = cliTruncate(text, maxWidth, { position }); | ||
} | ||
@@ -35,2 +31,3 @@ cache[cacheKey] = wrappedText; | ||
}; | ||
export default wrapText; | ||
//# sourceMappingURL=wrap-text.js.map |
152
package.json
{ | ||
"name": "ink", | ||
"version": "3.2.0", | ||
"version": "4.0.0", | ||
"description": "React for CLI", | ||
@@ -8,10 +8,13 @@ "license": "MIT", | ||
"author": { | ||
"name": "vdemedes", | ||
"email": "vdemedes@gmail.com", | ||
"name": "Vadim Demedes", | ||
"email": "vadimdemedes@hey.com", | ||
"url": "https://github.com/vadimdemedes" | ||
}, | ||
"main": "build", | ||
"types": "build/index.d.ts", | ||
"type": "module", | ||
"exports": { | ||
"types": "./build/index.d.ts", | ||
"default": "./build/index.js" | ||
}, | ||
"engines": { | ||
"node": ">=10" | ||
"node": ">=14.16" | ||
}, | ||
@@ -21,3 +24,5 @@ "scripts": { | ||
"prepare": "npm run build", | ||
"test": "tsc --noEmit && xo && FORCE_COLOR=true ava" | ||
"test": "tsc --noEmit && xo && FORCE_COLOR=true ava", | ||
"example": "NODE_NO_WARNINGS=1 node --loader ts-node/esm", | ||
"benchmark": "NODE_NO_WARNINGS=1 node --loader ts-node/esm" | ||
}, | ||
@@ -42,33 +47,35 @@ "files": [ | ||
"dependencies": { | ||
"ansi-escapes": "^4.2.1", | ||
"auto-bind": "4.0.0", | ||
"chalk": "^4.1.0", | ||
"cli-boxes": "^2.2.0", | ||
"cli-cursor": "^3.1.0", | ||
"cli-truncate": "^2.1.0", | ||
"code-excerpt": "^3.0.0", | ||
"indent-string": "^4.0.0", | ||
"is-ci": "^2.0.0", | ||
"lodash": "^4.17.20", | ||
"patch-console": "^1.0.0", | ||
"react-devtools-core": "^4.19.1", | ||
"react-reconciler": "^0.26.2", | ||
"scheduler": "^0.20.2", | ||
"signal-exit": "^3.0.2", | ||
"slice-ansi": "^3.0.0", | ||
"stack-utils": "^2.0.2", | ||
"string-width": "^4.2.2", | ||
"ansi-escapes": "^6.0.0", | ||
"auto-bind": "^5.0.1", | ||
"chalk": "^5.2.0", | ||
"cli-boxes": "^3.0.0", | ||
"cli-cursor": "^4.0.0", | ||
"cli-truncate": "^3.1.0", | ||
"code-excerpt": "^4.0.0", | ||
"indent-string": "^5.0.0", | ||
"is-ci": "^3.0.1", | ||
"lodash-es": "^4.17.21", | ||
"patch-console": "^2.0.0", | ||
"react-reconciler": "^0.29.0", | ||
"scheduler": "^0.23.0", | ||
"signal-exit": "^3.0.7", | ||
"slice-ansi": "^5.0.0", | ||
"stack-utils": "^2.0.6", | ||
"string-width": "^5.1.2", | ||
"type-fest": "^0.12.0", | ||
"widest-line": "^3.1.0", | ||
"wrap-ansi": "^6.2.0", | ||
"ws": "^7.5.5", | ||
"widest-line": "^4.0.1", | ||
"wrap-ansi": "^8.1.0", | ||
"ws": "^8.12.0", | ||
"yoga-layout-prebuilt": "^1.9.6" | ||
}, | ||
"devDependencies": { | ||
"@sindresorhus/tsconfig": "0.7.0", | ||
"@faker-js/faker": "^7.6.0", | ||
"@sindresorhus/tsconfig": "3.0.1", | ||
"@types/benchmark": "^2.1.2", | ||
"@types/is-ci": "^2.0.0", | ||
"@types/lodash": "^4.14.161", | ||
"@types/lodash-es": "^4.17.6", | ||
"@types/ms": "^0.7.31", | ||
"@types/node": "*", | ||
"@types/react": "^17.0.27", | ||
"@types/react-reconciler": "^0.26.4", | ||
"@types/react": "^18.0.0", | ||
"@types/react-reconciler": "^0.28.2", | ||
"@types/scheduler": "^0.16.2", | ||
@@ -80,29 +87,26 @@ "@types/signal-exit": "^3.0.0", | ||
"@types/wrap-ansi": "^3.0.0", | ||
"@types/ws": "^8.5.4", | ||
"@vdemedes/prettier-config": "^1.0.1", | ||
"ava": "^3.5.0", | ||
"babel-eslint": "^10.0.1", | ||
"benchmark": "^2.1.4", | ||
"boxen": "^4.2.0", | ||
"chance": "^1.1.6", | ||
"delay": "^4.1.0", | ||
"eslint-config-xo": "0.29.1", | ||
"eslint-config-xo-react": "^0.22.0", | ||
"eslint-plugin-prettier": "^3.1.2", | ||
"eslint-plugin-react": "^7.18.0", | ||
"eslint-plugin-react-hooks": "^2.3.0", | ||
"import-jsx": "3.1.0", | ||
"ms": "^2.1.1", | ||
"node-pty": "^0.9.0", | ||
"p-queue": "^6.2.1", | ||
"ava": "^5.1.1", | ||
"boxen": "^7.0.1", | ||
"delay": "^5.0.0", | ||
"eslint-config-xo-react": "^0.27.0", | ||
"eslint-plugin-react": "^7.32.2", | ||
"eslint-plugin-react-hooks": "^4.6.0", | ||
"ms": "^2.1.3", | ||
"node-pty": "0.10.1", | ||
"p-queue": "^7.3.4", | ||
"prettier": "^2.0.4", | ||
"react": "^17.0.2", | ||
"sinon": "^8.1.1", | ||
"react": "^18.0.0", | ||
"react-devtools-core": "^4.19.1", | ||
"sinon": "^12.0.1", | ||
"strip-ansi": "^6.0.0", | ||
"ts-node": "7.0.0", | ||
"typescript": "^3.8.3", | ||
"xo": "^0.28.0" | ||
"ts-node": "10.9.1", | ||
"typescript": "^4.9.4", | ||
"xo": "^0.53.0" | ||
}, | ||
"peerDependencies": { | ||
"@types/react": ">=16.8.0", | ||
"react": ">=16.8.0" | ||
"@types/react": ">=18.0.0", | ||
"react": ">=18.0.0", | ||
"react-devtools-core": "^4.19.1" | ||
}, | ||
@@ -112,11 +116,20 @@ "peerDependenciesMeta": { | ||
"optional": true | ||
}, | ||
"react-devtools-core": { | ||
"optional": true | ||
} | ||
}, | ||
"ava": { | ||
"extensions": [ | ||
"ts", | ||
"tsx" | ||
"workerThreads": false, | ||
"files": [ | ||
"test/**/*", | ||
"!test/helpers/**/*", | ||
"!test/fixtures/**/*" | ||
], | ||
"require": [ | ||
"ts-node/register/transpile-only" | ||
"extensions": { | ||
"ts": "module", | ||
"tsx": "module" | ||
}, | ||
"nodeArguments": [ | ||
"--loader=ts-node/esm" | ||
] | ||
@@ -135,3 +148,8 @@ }, | ||
"react/state-in-constructor": "off", | ||
"react/jsx-indent": "off" | ||
"react/jsx-indent": "off", | ||
"react/prop-types": "off", | ||
"unicorn/import-index": "off", | ||
"import/no-useless-path-segments": "off", | ||
"react-hooks/exhaustive-deps": "off", | ||
"complexity": "off" | ||
}, | ||
@@ -156,11 +174,12 @@ "overrides": [ | ||
"unicorn/filename-case": "off", | ||
"react/prop-types": "off", | ||
"react/default-props-match-prop-types": "off", | ||
"unicorn/prevent-abbreviations": "off", | ||
"react/require-default-props": "warn", | ||
"react/require-default-props": "off", | ||
"react/jsx-curly-brace-presence": "off", | ||
"@typescript-eslint/no-empty-function": "warn", | ||
"@typescript-eslint/no-empty-function": "off", | ||
"@typescript-eslint/promise-function-async": "warn", | ||
"@typescript-eslint/explicit-function-return": "off", | ||
"@typescript-eslint/explicit-function-return-type": "off" | ||
"@typescript-eslint/explicit-function-return-type": "off", | ||
"dot-notation": "off", | ||
"react/boolean-prop-naming": "off" | ||
} | ||
@@ -170,6 +189,7 @@ }, | ||
"files": [ | ||
"examples/**/*.js" | ||
"examples/**/*.{ts,tsx}", | ||
"benchmark/**/*.{ts,tsx}" | ||
], | ||
"rules": { | ||
"react/prop-types": "off" | ||
"import/no-unassigned-import": "off" | ||
} | ||
@@ -176,0 +196,0 @@ } |
140
readme.md
@@ -1,9 +0,13 @@ | ||
<h1 align="center"> | ||
[![](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) | ||
--- | ||
<div align="center"> | ||
<br> | ||
<br> | ||
<img width="200" alt="Ink" src="media/logo.png"> | ||
<img width="240" alt="Ink" src="media/logo.png"> | ||
<br> | ||
<br> | ||
<br> | ||
</h1> | ||
</div> | ||
@@ -23,9 +27,36 @@ > React for CLIs. Build and test your CLI output using components. | ||
**Note:** This is documentation for Ink 3. If you're looking for docs on Ink 2, check out [this release](https://github.com/vadimdemedes/ink/tree/v2.7.1). There's also a [migration guide](migrate.md) from Ink 2 available. | ||
**Note:** This is documentation for Ink 4. If you're looking for docs on Ink 3, check out [this release](https://github.com/vadimdemedes/ink/tree/v3.2.0). | ||
--- | ||
<div align="center"> | ||
<p> | ||
<p> | ||
<sup> | ||
<a href="https://opencollective.com/vadimdemedes">My open source work is supported by the community ❤️</a> | ||
</sup> | ||
</p> | ||
<sup>Special thanks to:</sup> | ||
<br> | ||
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=ink&utm_source=github"> | ||
<div> | ||
<img src="https://vadimdemedes.com/github/workos.svg" width="200" alt="WorkOS"> | ||
</div> | ||
<b>Your app, enterprise-ready.</b> | ||
<div> | ||
<sub>Start selling to enterprise customers with just a few lines of code.</sub> | ||
<br> | ||
<sup>Add Single Sign-On (and more) in minutes instead of months.</sup> | ||
</div> | ||
</a> | ||
</p> | ||
<br> | ||
<br> | ||
</div> | ||
## Install | ||
```sh | ||
npm install ink react | ||
``` | ||
$ npm install ink react | ||
``` | ||
@@ -64,2 +95,3 @@ ## Usage | ||
- [Cloudflare's Wrangler](https://github.com/cloudflare/wrangler2) - The CLI for Cloudflare Workers. | ||
- [Gatsby](https://www.gatsbyjs.org) - Gatsby is a modern web framework for blazing fast websites. | ||
@@ -71,7 +103,8 @@ - [tap](https://node-tap.org) - A Test-Anything-Protocol library for JavaScript. | ||
- [Prisma](https://www.prisma.io) - The unified data layer for modern applications. | ||
- [Wallace](https://www.projectwallace.com) - Pretty CSS analytics on the CLI. | ||
- [Wallace](https://www.projectwallace.com) - Pretty CSS analytics. | ||
- [Blitz](https://blitzjs.com) - The Fullstack React Framework. | ||
- [New York Times](https://github.com/nytimes/kyt) - NYT uses Ink `kyt` - a toolkit that encapsulates and manages the configuration for web apps. | ||
- [tink](https://github.com/npm/tink) - Next-generation runtime and package manager. | ||
- [loki](https://github.com/oblador/loki) - Visual Regression Testing for Storybook. | ||
- [Inkle](https://github.com/jrr/inkle) - Wordle game. | ||
- [loki](https://github.com/oblador/loki) - Visual regression testing for Storybook. | ||
- [Bit](https://github.com/teambit/bit) - Build, distribute and collaborate on components. | ||
@@ -81,17 +114,21 @@ - [Remirror](https://github.com/remirror/remirror) - Your friendly, world-class editor toolkit. | ||
- [Splash](https://github.com/Shopify/polaris-react/tree/master/scripts/splash) - Observe the splash zone of a change across the Shopify's [Polaris](https://polaris.shopify.com) component library. | ||
- [emoj](https://github.com/sindresorhus/emoj) - Find relevant emoji on the command-line. | ||
- [emma](https://github.com/maticzav/emma-cli) - Terminal assistant to find and install npm packages. | ||
- [emoj](https://github.com/sindresorhus/emoj) - Find relevant emojis. | ||
- [emma](https://github.com/maticzav/emma-cli) - Find and install npm packages. | ||
- [swiff](https://github.com/simple-integrated-marketing/swiff) - Multi-environment command line tools for time-saving web developers. | ||
- [share](https://github.com/marionebl/share-cli) - Quickly share files from your command line. | ||
- [share](https://github.com/marionebl/share-cli) - Quickly share files. | ||
- [Kubelive](https://github.com/ameerthehacker/kubelive) - CLI for Kubernetes to provide live data about the cluster and its resources. | ||
- [changelog-view](https://github.com/jdeniau/changelog-view) - Tool view changelog in console. | ||
- [cfpush](https://github.com/mamachanko/cfpush) - An interactive Cloud Foundry tutorial in your terminal. | ||
- [startd](https://github.com/mgrip/startd) - Turn your React component into a web app from the command-line. | ||
- [wiki-cli](https://github.com/hexrcs/wiki-cli) - Search Wikipedia and read summaries directly in your terminal. | ||
- [changelog-view](https://github.com/jdeniau/changelog-view) - View changelogs. | ||
- [cfpush](https://github.com/mamachanko/cfpush) - An interactive Cloud Foundry tutorial. | ||
- [startd](https://github.com/mgrip/startd) - Turn your React component into a web app. | ||
- [wiki-cli](https://github.com/hexrcs/wiki-cli) - Search Wikipedia and read summaries. | ||
- [garson](https://github.com/goliney/garson) - Build interactive config-based command-line interfaces. | ||
- [git-contrib-calendar](https://github.com/giannisp/git-contrib-calendar) - Display a contributions calendar for any git repository. | ||
- [gitgud](https://github.com/GitGud-org/GitGud) - An interactive command-line GUI for Git. | ||
- [Autarky](https://github.com/pranshuchittora/autarky) - An interactive CLI to find and delete old `node_modules` directories in order to free up disk space. | ||
- [Autarky](https://github.com/pranshuchittora/autarky) - Find and delete old `node_modules` directories in order to free up disk space. | ||
- [fast-cli](https://github.com/sindresorhus/fast-cli) - Test your download and upload speed. | ||
- [tasuku](https://github.com/privatenumber/tasuku) - Minimal task runner. | ||
- [mnswpr](https://github.com/mordv/mnswpr) - Minesweeper game. | ||
- [lrn](https://github.com/krychu/lrn) - Learning by repetition. | ||
- [turdle](https://github.com/mynameisankit/turdle) - Wordle game. | ||
- [Shopify CLI](https://github.com/Shopify/cli) - Build apps, themes, and storefronts for Shopify. | ||
@@ -127,13 +164,11 @@ ## Contents | ||
```sh | ||
npx create-ink-app my-ink-cli | ||
``` | ||
$ mkdir my-ink-cli | ||
$ cd my-ink-cli | ||
$ npx create-ink-app | ||
``` | ||
Alternatively, create a TypeScript project: | ||
```sh | ||
npx create-ink-app --typescript my-ink-cli | ||
``` | ||
$ npx create-ink-app --typescript | ||
``` | ||
@@ -147,5 +182,5 @@ <details><summary>Manual setup</summary> | ||
```sh | ||
npm install --save-dev @babel/preset-react | ||
``` | ||
$ npm install --save-dev @babel/preset-react | ||
``` | ||
@@ -181,13 +216,13 @@ ```json | ||
```sh | ||
npx babel source.js -o cli.js | ||
``` | ||
$ npx babel source.js -o cli.js | ||
``` | ||
Now you can run `cli.js` with Node.js: | ||
```sh | ||
node cli | ||
``` | ||
$ node cli | ||
``` | ||
If you don't like transpiling files during development, you can use [import-jsx](https://github.com/vadimdemedes/import-jsx) to `require()` a JSX file and transpile it on the fly. | ||
If you don't like transpiling files during development, you can use [import-jsx](https://github.com/vadimdemedes/import-jsx) or [@esbuild-kit/esm-loader](https://github.com/esbuild-kit/esm-loader) to `import` a JSX file and transpile it on the fly. | ||
@@ -717,3 +752,3 @@ </p> | ||
Default: `auto`\ | ||
Allowed vales: `auto` `flex-start` `center` `flex-end` | ||
Allowed values: `auto` `flex-start` `center` `flex-end` | ||
@@ -1346,3 +1381,3 @@ See [align-self](https://css-tricks.com/almanac/properties/a/align-self/). | ||
const Example = () => { | ||
const {stdout} = useStdout; | ||
const {stdout} = useStdout(); | ||
@@ -1473,3 +1508,3 @@ return … | ||
See example in [examples/use-focus](examples/use-focus/use-focus.js) and [examples/use-focus-with-id](examples/use-focus/use-focus-with-id.js). | ||
See example in [examples/use-focus](examples/use-focus/use-focus.js) and [examples/use-focus-with-id](examples/use-focus-with-id/use-focus-with-id.js). | ||
@@ -1760,11 +1795,11 @@ ### useFocusManager() | ||
```sh | ||
DEV=true my-cli | ||
``` | ||
$ DEV=true my-cli | ||
``` | ||
Then, start React Devtools itself: | ||
```sh | ||
npx react-devtools | ||
``` | ||
$ npx react-devtools | ||
``` | ||
@@ -1781,12 +1816,12 @@ After it starts up, you should see the component tree of your CLI. | ||
- [ink-select-input](https://github.com/vadimdemedes/ink-select-input) - Select (dropdown) input. | ||
- [ink-link](https://github.com/sindresorhus/ink-link) - Link component. | ||
- [ink-gradient](https://github.com/sindresorhus/ink-gradient) - Gradient color component. | ||
- [ink-big-text](https://github.com/sindresorhus/ink-big-text) - Awesome text component. | ||
- [ink-link](https://github.com/sindresorhus/ink-link) - Link. | ||
- [ink-gradient](https://github.com/sindresorhus/ink-gradient) - Gradient color. | ||
- [ink-big-text](https://github.com/sindresorhus/ink-big-text) - Awesome text. | ||
- [ink-image](https://github.com/kevva/ink-image) - Display images inside the terminal. | ||
- [ink-tab](https://github.com/jdeniau/ink-tab) - Tab component. | ||
- [ink-color-pipe](https://github.com/LitoMore/ink-color-pipe) - Create color text with simpler style strings in Ink. | ||
- [ink-tab](https://github.com/jdeniau/ink-tab) - Tab. | ||
- [ink-color-pipe](https://github.com/LitoMore/ink-color-pipe) - Create color text with simpler style strings. | ||
- [ink-multi-select](https://github.com/karaggeorge/ink-multi-select) - Select one or more values from a list | ||
- [ink-divider](https://github.com/JureSotosek/ink-divider) - A divider component. | ||
- [ink-progress-bar](https://github.com/brigand/ink-progress-bar) - Configurable component for rendering progress bars. | ||
- [ink-table](https://github.com/maticzav/ink-table) - Table component. | ||
- [ink-divider](https://github.com/JureSotosek/ink-divider) - A divider. | ||
- [ink-progress-bar](https://github.com/brigand/ink-progress-bar) - Progress bar. | ||
- [ink-table](https://github.com/maticzav/ink-table) - Table. | ||
- [ink-ascii](https://github.com/hexrcs/ink-ascii) - Awesome text component with more font choices, based on Figlet. | ||
@@ -1797,4 +1832,4 @@ - [ink-markdown](https://github.com/cameronhunter/ink-markdown) - Render syntax highlighted Markdown. | ||
- [ink-syntax-highlight](https://github.com/vsashyn/ink-syntax-highlight) - Code syntax highlighting. | ||
- [ink-form](https://github.com/lukasbach/ink-form) - Form component. | ||
- [ink-task-list](https://github.com/privatenumber/ink-task-list) - Task list component. | ||
- [ink-form](https://github.com/lukasbach/ink-form) - Form. | ||
- [ink-task-list](https://github.com/privatenumber/ink-task-list) - Task list. | ||
@@ -1807,10 +1842,17 @@ ## Useful Hooks | ||
The [`examples`](/examples) directory contains a set of real examples. You can run them with: | ||
```bash | ||
npm run example examples/[example name] | ||
# e.g. npm run example examples/borders | ||
``` | ||
- [Jest](examples/jest/jest.js) - Implementation of basic Jest UI [(live demo)](https://ink-jest-demo.vadimdemedes.repl.run/). | ||
- [Counter](examples/counter/counter.js) - Simple counter that increments every 100ms [(live demo)](https://ink-counter-demo.vadimdemedes.repl.run/). | ||
- [Form with Validation](https://github.com/final-form/rff-cli-example) - Manage form state using [Final Form](https://github.com/final-form/final-form#-final-form). | ||
- [Form with validation](https://github.com/final-form/rff-cli-example) - Manage form state using [Final Form](https://github.com/final-form/final-form#-final-form). | ||
- [Borders](examples/borders/borders.js) - Add borders to `<Box>` component. | ||
- [Suspense](examples/suspense/suspense.js) - Use React Suspense. | ||
- [Table](examples/table/table.js) - Render a table with multiple columns and rows. | ||
- [Focus Management](examples/use-focus/use-focus.js) - Use `useFocus` hook to manage focus between components. | ||
- [User Input](examples/use-input/use-input.js) - Listen to user input. | ||
- [Focus management](examples/use-focus/use-focus.js) - Use `useFocus` hook to manage focus between components. | ||
- [User input](examples/use-input/use-input.js) - Listen to user input. | ||
- [Write to stdout](examples/use-stdout/use-stdout.js) - Write to stdout bypassing main Ink output. | ||
@@ -1817,0 +1859,0 @@ - [Write to stderr](examples/use-stderr/use-stderr.js) - Write to stderr bypassing main Ink output. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
34
1853
4
Yes
227592
3072
+ Addedlodash-es@^4.17.21
+ Addedansi-escapes@6.2.1(transitive)
+ Addedansi-regex@6.1.0(transitive)
+ Addedansi-styles@6.2.1(transitive)
+ Addedauto-bind@5.0.1(transitive)
+ Addedchalk@5.3.0(transitive)
+ Addedci-info@3.9.0(transitive)
+ Addedcli-boxes@3.0.0(transitive)
+ Addedcli-cursor@4.0.0(transitive)
+ Addedcli-truncate@3.1.0(transitive)
+ Addedcode-excerpt@4.0.0(transitive)
+ Addedconvert-to-spaces@2.0.1(transitive)
+ Addedeastasianwidth@0.2.0(transitive)
+ Addedemoji-regex@9.2.2(transitive)
+ Addedindent-string@5.0.0(transitive)
+ Addedis-ci@3.0.1(transitive)
+ Addedis-fullwidth-code-point@4.0.0(transitive)
+ Addedlodash-es@4.17.21(transitive)
+ Addedpatch-console@2.0.0(transitive)
+ Addedreact-reconciler@0.29.2(transitive)
+ Addedrestore-cursor@4.0.0(transitive)
+ Addedscheduler@0.23.2(transitive)
+ Addedslice-ansi@5.0.0(transitive)
+ Addedstring-width@5.1.2(transitive)
+ Addedstrip-ansi@7.1.0(transitive)
+ Addedwidest-line@4.0.1(transitive)
+ Addedwrap-ansi@8.1.0(transitive)
+ Addedws@8.18.0(transitive)
- Removedlodash@^4.17.20
- Removedreact-devtools-core@^4.19.1
- Removedansi-escapes@4.3.2(transitive)
- Removedansi-regex@5.0.1(transitive)
- Removedansi-styles@4.3.0(transitive)
- Removedastral-regex@2.0.0(transitive)
- Removedauto-bind@4.0.0(transitive)
- Removedchalk@4.1.2(transitive)
- Removedci-info@2.0.0(transitive)
- Removedcli-boxes@2.2.1(transitive)
- Removedcli-cursor@3.1.0(transitive)
- Removedcli-truncate@2.1.0(transitive)
- Removedcode-excerpt@3.0.0(transitive)
- Removedcolor-convert@2.0.1(transitive)
- Removedcolor-name@1.1.4(transitive)
- Removedconvert-to-spaces@1.0.2(transitive)
- Removedemoji-regex@8.0.0(transitive)
- Removedhas-flag@4.0.0(transitive)
- Removedindent-string@4.0.0(transitive)
- Removedis-ci@2.0.0(transitive)
- Removedis-fullwidth-code-point@3.0.0(transitive)
- Removedlodash@4.17.21(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedpatch-console@1.0.0(transitive)
- Removedreact@17.0.2(transitive)
- Removedreact-reconciler@0.26.2(transitive)
- Removedrestore-cursor@3.1.0(transitive)
- Removedscheduler@0.20.2(transitive)
- Removedslice-ansi@3.0.0(transitive)
- Removedstring-width@4.2.3(transitive)
- Removedstrip-ansi@6.0.1(transitive)
- Removedsupports-color@7.2.0(transitive)
- Removedtype-fest@0.21.3(transitive)
- Removedwidest-line@3.1.0(transitive)
- Removedwrap-ansi@6.2.0(transitive)
Updatedansi-escapes@^6.0.0
Updatedauto-bind@^5.0.1
Updatedchalk@^5.2.0
Updatedcli-boxes@^3.0.0
Updatedcli-cursor@^4.0.0
Updatedcli-truncate@^3.1.0
Updatedcode-excerpt@^4.0.0
Updatedindent-string@^5.0.0
Updatedis-ci@^3.0.1
Updatedpatch-console@^2.0.0
Updatedreact-reconciler@^0.29.0
Updatedscheduler@^0.23.0
Updatedsignal-exit@^3.0.7
Updatedslice-ansi@^5.0.0
Updatedstack-utils@^2.0.6
Updatedstring-width@^5.1.2
Updatedwidest-line@^4.0.1
Updatedwrap-ansi@^8.1.0
Updatedws@^8.12.0