Socket
Socket
Sign inDemoInstall

ink

Package Overview
Dependencies
48
Maintainers
2
Versions
75
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.1.0 to 4.2.0

build/parse-keypress.d.ts

150

build/components/Box.d.ts

@@ -5,155 +5,9 @@ import React from 'react';

import { type DOMElement } from '../dom.js';
export type Props = Except<Styles, 'textWrap'> & {
/**
* Size of the gap between an element's columns.
*
* @default 0
*/
readonly columnGap?: number;
/**
* Size of the gap between element's rows.
*
* @default 0
*/
readonly rowGap?: number;
/**
* Size of the gap between an element's columns and rows. Shorthand for `columnGap` and `rowGap`.
*
* @default 0
*/
readonly gap?: number;
/**
* Margin on all sides. Equivalent to setting `marginTop`, `marginBottom`, `marginLeft` and `marginRight`.
*
* @default 0
*/
readonly margin?: number;
/**
* Horizontal margin. Equivalent to setting `marginLeft` and `marginRight`.
*
* @default 0
*/
readonly marginX?: number;
/**
* Vertical margin. Equivalent to setting `marginTop` and `marginBottom`.
*
* @default 0
*/
readonly marginY?: number;
/**
* Padding on all sides. Equivalent to setting `paddingTop`, `paddingBottom`, `paddingLeft` and `paddingRight`.
*
* @default 0
*/
readonly padding?: number;
/**
* Horizontal padding. Equivalent to setting `paddingLeft` and `paddingRight`.
*
* @default 0
*/
readonly paddingX?: number;
/**
* Vertical padding. Equivalent to setting `paddingTop` and `paddingBottom`.
*
* @default 0
*/
readonly paddingY?: number;
/**
* Behavior for an element's overflow in both directions.
*
* @default 'visible'
*/
readonly overflow?: 'visible' | 'hidden';
/**
* Behavior for an element's overflow in horizontal direction.
*
* @default 'visible'
*/
readonly overflowX?: 'visible' | 'hidden';
/**
* Behavior for an element's overflow in vertical direction.
*
* @default 'visible'
*/
readonly overflowY?: 'visible' | 'hidden';
};
export type Props = Except<Styles, 'textWrap'>;
/**
* `<Box>` is an essential Ink component to build your layout. It's like `<div style="display: flex">` in the browser.
*/
declare const Box: React.ForwardRefExoticComponent<Except<Styles, "textWrap"> & {
/**
* Size of the gap between an element's columns.
*
* @default 0
*/
readonly columnGap?: number | undefined;
/**
* Size of the gap between element's rows.
*
* @default 0
*/
readonly rowGap?: number | undefined;
/**
* Size of the gap between an element's columns and rows. Shorthand for `columnGap` and `rowGap`.
*
* @default 0
*/
readonly gap?: number | undefined;
/**
* Margin on all sides. Equivalent to setting `marginTop`, `marginBottom`, `marginLeft` and `marginRight`.
*
* @default 0
*/
readonly margin?: number | undefined;
/**
* Horizontal margin. Equivalent to setting `marginLeft` and `marginRight`.
*
* @default 0
*/
readonly marginX?: number | undefined;
/**
* Vertical margin. Equivalent to setting `marginTop` and `marginBottom`.
*
* @default 0
*/
readonly marginY?: number | undefined;
/**
* Padding on all sides. Equivalent to setting `paddingTop`, `paddingBottom`, `paddingLeft` and `paddingRight`.
*
* @default 0
*/
readonly padding?: number | undefined;
/**
* Horizontal padding. Equivalent to setting `paddingLeft` and `paddingRight`.
*
* @default 0
*/
readonly paddingX?: number | undefined;
/**
* Vertical padding. Equivalent to setting `paddingTop` and `paddingBottom`.
*
* @default 0
*/
readonly paddingY?: number | undefined;
/**
* Behavior for an element's overflow in both directions.
*
* @default 'visible'
*/
readonly overflow?: "visible" | "hidden" | undefined;
/**
* Behavior for an element's overflow in horizontal direction.
*
* @default 'visible'
*/
readonly overflowX?: "visible" | "hidden" | undefined;
/**
* Behavior for an element's overflow in vertical direction.
*
* @default 'visible'
*/
readonly overflowY?: "visible" | "hidden" | undefined;
} & {
declare const Box: React.ForwardRefExoticComponent<Props & {
children?: React.ReactNode;
} & React.RefAttributes<DOMElement>>;
export default Box;

@@ -1,2 +0,1 @@

/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
import React, { forwardRef } from 'react';

@@ -7,18 +6,7 @@ /**

const Box = forwardRef(({ children, ...style }, ref) => {
const transformedStyle = {
...style,
columnGap: style.columnGap || style.gap || 0,
rowGap: style.rowGap || style.gap || 0,
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,
overflowX: style.overflowX || style.overflow || 'visible',
overflowY: style.overflowY || style.overflow || 'visible'
};
return (React.createElement("ink-box", { ref: ref, style: transformedStyle }, children));
return (React.createElement("ink-box", { ref: ref, style: {
...style,
overflowX: style.overflowX ?? style.overflow ?? 'visible',
overflowY: style.overflowY ?? style.overflow ?? 'visible'
} }, children));
});

@@ -25,0 +13,0 @@ Box.displayName = 'Box';

// eslint-disable-next-line n/file-extension-in-import
import Yoga from 'yoga-wasm-web/auto';
import measureText from './measure-text.js';
import applyStyles from './styles.js';
import wrapText from './wrap-text.js';

@@ -73,5 +72,2 @@ import squashTextNodes from './squash-text-nodes.js';

node.style = style;
if (node.yogaNode) {
applyStyles(node.yogaNode, style);
}
};

@@ -78,0 +74,0 @@ export const createTextNode = (text) => {

import { useEffect } from 'react';
import { isUpperCase } from 'is-upper-case';
import parseKeypress, { nonAlphanumericKeys } from '../parse-keypress.js';
import useStdin from './use-stdin.js';

@@ -44,43 +46,37 @@ /**

const handleData = (data) => {
let input = String(data);
const keypress = parseKeypress(data);
const key = {
upArrow: input === '\u001B[A',
downArrow: input === '\u001B[B',
leftArrow: input === '\u001B[D',
rightArrow: input === '\u001B[C',
pageDown: input === '\u001B[6~',
pageUp: input === '\u001B[5~',
return: input === '\r',
escape: input === '\u001B',
ctrl: false,
shift: false,
tab: input === '\t' || input === '\u001B[Z',
backspace: input === '\u0008',
delete: input === '\u007F' || input === '\u001B[3~',
meta: false
upArrow: keypress.name === 'up',
downArrow: keypress.name === 'down',
leftArrow: keypress.name === 'left',
rightArrow: keypress.name === 'right',
pageDown: keypress.name === 'pagedown',
pageUp: keypress.name === 'pageup',
return: keypress.name === 'return',
escape: keypress.name === 'escape',
ctrl: keypress.ctrl,
shift: keypress.shift,
tab: keypress.name === 'tab',
backspace: keypress.name === 'backspace',
delete: keypress.name === 'delete',
// `parseKeypress` parses \u001B\u001B[A (meta + up arrow) as meta = false
// but with option = true, so we need to take this into account here
// to avoid breaking changes in Ink.
// TODO(vadimdemedes): consider removing this in the next major version.
meta: keypress.meta || keypress.name === 'escape' || keypress.option
};
// Copied from `keypress` module
if (input <= '\u001A' && !key.return) {
// 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;
let input = keypress.ctrl ? keypress.name : keypress.sequence;
if (nonAlphanumericKeys.includes(keypress.name)) {
input = '';
}
// Strip meta if it's still remaining after `parseKeypress`
// TODO(vadimdemedes): remove this in the next major version.
if (input.startsWith('\u001B')) {
input = input.slice(1);
key.meta = true;
}
const isLatinUppercase = input >= 'A' && input <= 'Z';
const isCyrillicUppercase = input >= 'А' && input <= 'Я';
if (input.length === 1 && (isLatinUppercase || isCyrillicUppercase)) {
if (input.length === 1 &&
typeof input[0] === 'string' &&
isUpperCase(input[0])) {
key.shift = true;
}
// Shift+Tab
if (key.tab && input === '[Z') {
key.shift = true;
}
if (key.tab || key.backspace || key.delete) {
input = '';
}
// If app is not supposed to exit on Ctrl+C, then let input listener handle it

@@ -87,0 +83,0 @@ if (!(input === 'c' && key.ctrl) || !internal_exitOnCtrlC) {

@@ -7,2 +7,3 @@ import process from 'node:process';

import { createTextNode, appendChildNode, insertBeforeNode, removeChildNode, setStyle, setTextNodeValue, createNode, setAttribute } from './dom.js';
import applyStyles from './styles.js';
// We need to conditionally perform devtools connection to avoid

@@ -30,2 +31,28 @@ // accidentally breaking other third-party code.

}
const diff = (before, after) => {
if (before === after) {
return;
}
if (!before) {
return after;
}
const changed = {};
let isChanged = false;
for (const key of Object.keys(before)) {
const isDeleted = after ? !Object.hasOwnProperty.call(after, key) : true;
if (isDeleted) {
changed[key] = undefined;
isChanged = true;
}
}
if (after) {
for (const key of Object.keys(after)) {
if (after[key] !== before[key]) {
changed[key] = after[key];
isChanged = true;
}
}
}
return isChanged ? changed : undefined;
};
const cleanupYogaNode = (node) => {

@@ -83,2 +110,5 @@ node?.unsetMeasureFunc();

setStyle(node, value);
if (node.yogaNode) {
applyStyles(node.yogaNode, value);
}
continue;

@@ -154,65 +184,29 @@ }

}
const updatePayload = {};
const keys = Object.keys(newProps);
for (const key of keys) {
if (newProps[key] !== oldProps[key]) {
const isStyle = key === 'style' &&
typeof newProps['style'] === 'object' &&
typeof oldProps['style'] === 'object';
if (isStyle) {
const newStyle = newProps['style'];
const oldStyle = oldProps['style'];
const styleKeys = Object.keys(newStyle);
for (const styleKey of styleKeys) {
// Always include `borderColor` and `borderStyle` to ensure border is rendered,
// and `overflowX` and `overflowY` to ensure content is clipped,
// otherwise resulting `updatePayload` may not contain them
// if they weren't changed during this update
if (styleKey === 'borderStyle' || styleKey === 'borderColor') {
if (typeof updatePayload['style'] !== 'object') {
// Linter didn't like `= {} as Style`
const style = {};
updatePayload['style'] = style;
}
updatePayload['style'].borderStyle =
newStyle.borderStyle;
updatePayload['style'].borderColor =
newStyle.borderColor;
updatePayload['style'].overflowX = newStyle.overflowX;
updatePayload['style'].overflowY = newStyle.overflowY;
}
if (newStyle[styleKey] !== oldStyle[styleKey]) {
if (typeof updatePayload['style'] !== 'object') {
// Linter didn't like `= {} as Style`
const style = {};
updatePayload['style'] = style;
}
updatePayload['style'][styleKey] = newStyle[styleKey];
}
}
const props = diff(oldProps, newProps);
const style = diff(oldProps['style'], newProps['style']);
if (!props && !style) {
return null;
}
return { props, style };
},
commitUpdate(node, { props, style }) {
if (props) {
for (const [key, value] of Object.entries(props)) {
if (key === 'style') {
setStyle(node, value);
continue;
}
updatePayload[key] = newProps[key];
if (key === 'internal_transform') {
node.internal_transform = value;
continue;
}
if (key === 'internal_static') {
node.internal_static = true;
continue;
}
setAttribute(node, key, value);
}
}
return updatePayload;
},
commitUpdate(node, updatePayload) {
for (const [key, value] of Object.entries(updatePayload)) {
if (key === 'children') {
continue;
}
if (key === 'style') {
setStyle(node, value);
continue;
}
if (key === 'internal_transform') {
node.internal_transform = value;
continue;
}
if (key === 'internal_static') {
node.internal_static = true;
continue;
}
setAttribute(node, key, value);
if (style && node.yogaNode) {
applyStyles(node.yogaNode, style);
}

@@ -219,0 +213,0 @@ },

import cliBoxes from 'cli-boxes';
import colorize from './colorize.js';
const renderBorder = (x, y, node, output) => {
if (typeof node.style.borderStyle === 'string') {
if (node.style.borderStyle) {
const width = node.yogaNode.getComputedWidth();
const height = node.yogaNode.getComputedHeight();
const color = node.style.borderColor;
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: [] });
output.write(x, y + 1, verticalBorder, { transformers: [] });
output.write(x + width - 1, y + 1, verticalBorder, { transformers: [] });
output.write(x, y + height - 1, bottomBorder, { transformers: [] });
const box = typeof node.style.borderStyle === 'string'
? cliBoxes[node.style.borderStyle]
: node.style.borderStyle;
const topBorderColor = node.style.borderTopColor ?? node.style.borderColor;
const bottomBorderColor = node.style.borderBottomColor ?? node.style.borderColor;
const leftBorderColor = node.style.borderLeftColor ?? node.style.borderColor;
const rightBorderColor = node.style.borderRightColor ?? node.style.borderColor;
const showTopBorder = node.style.borderTop !== false;
const showBottomBorder = node.style.borderBottom !== false;
const showLeftBorder = node.style.borderLeft !== false;
const showRightBorder = node.style.borderRight !== false;
const contentWidth = width - (showLeftBorder ? 1 : 0) - (showRightBorder ? 1 : 0);
const topBorder = showTopBorder
? colorize((showLeftBorder ? box.topLeft : '') +
box.top.repeat(contentWidth) +
(showRightBorder ? box.topRight : ''), topBorderColor, 'foreground')
: undefined;
let verticalBorderHeight = height;
if (showTopBorder) {
verticalBorderHeight -= 1;
}
if (showBottomBorder) {
verticalBorderHeight -= 1;
}
const leftBorder = (colorize(box.left, leftBorderColor, 'foreground') + '\n').repeat(verticalBorderHeight);
const rightBorder = (colorize(box.right, rightBorderColor, 'foreground') + '\n').repeat(verticalBorderHeight);
const bottomBorder = showBottomBorder
? colorize((showLeftBorder ? box.bottomLeft : '') +
box.bottom.repeat(contentWidth) +
(showRightBorder ? box.bottomRight : ''), bottomBorderColor, 'foreground')
: undefined;
const offsetY = showTopBorder ? 1 : 0;
if (topBorder) {
output.write(x, y, topBorder, { transformers: [] });
}
if (showLeftBorder) {
output.write(x, y + offsetY, leftBorder, { transformers: [] });
}
if (showRightBorder) {
output.write(x + width - 1, y + offsetY, rightBorder, {
transformers: []
});
}
if (bottomBorder) {
output.write(x, y + height - 1, bottomBorder, { transformers: [] });
}
}

@@ -17,0 +54,0 @@ };

@@ -61,4 +61,4 @@ import widestLine from 'widest-line';

renderBorder(x, y, node, output);
const clipHorizontally = node.style.overflowX === 'hidden';
const clipVertically = node.style.overflowY === 'hidden';
const clipHorizontally = node.style.overflowX === 'hidden' || node.style.overflow === 'hidden';
const clipVertically = node.style.overflowY === 'hidden' || node.style.overflow === 'hidden';
if (clipHorizontally || clipVertically) {

@@ -65,0 +65,0 @@ const x1 = clipHorizontally

@@ -1,2 +0,2 @@

import { type Boxes } from 'cli-boxes';
import { type Boxes, type BoxStyle } from 'cli-boxes';
import { type LiteralUnion } from 'type-fest';

@@ -9,10 +9,26 @@ import { type ForegroundColorName } from 'chalk';

/**
* Gap between element's columns.
* Size of the gap between an element's columns.
*/
readonly columnGap?: number;
/**
* Gap between element's rows.
* Size of the gap between element's rows.
*/
readonly rowGap?: number;
/**
* Size of the gap between an element's columns and rows. Shorthand for `columnGap` and `rowGap`.
*/
readonly gap?: number;
/**
* Margin on all sides. Equivalent to setting `marginTop`, `marginBottom`, `marginLeft` and `marginRight`.
*/
readonly margin?: number;
/**
* Horizontal margin. Equivalent to setting `marginLeft` and `marginRight`.
*/
readonly marginX?: number;
/**
* Vertical margin. Equivalent to setting `marginTop` and `marginBottom`.
*/
readonly marginY?: number;
/**
* Top margin.

@@ -34,2 +50,14 @@ */

/**
* Padding on all sides. Equivalent to setting `paddingTop`, `paddingBottom`, `paddingLeft` and `paddingRight`.
*/
readonly padding?: number;
/**
* Horizontal padding. Equivalent to setting `paddingLeft` and `paddingRight`.
*/
readonly paddingX?: number;
/**
* Vertical padding. Equivalent to setting `paddingTop` and `paddingBottom`.
*/
readonly paddingY?: number;
/**
* Top padding.

@@ -116,10 +144,62 @@ */

*/
readonly borderStyle?: keyof Boxes;
readonly borderStyle?: keyof Boxes | BoxStyle;
/**
* Determines whether top border is visible.
*
* @default true
*/
readonly borderTop?: boolean;
/**
* Determines whether bottom border is visible.
*
* @default true
*/
readonly borderBottom?: boolean;
/**
* Determines whether left border is visible.
*
* @default true
*/
readonly borderLeft?: boolean;
/**
* Determines whether right border is visible.
*
* @default true
*/
readonly borderRight?: boolean;
/**
* Change border color.
* Accepts the same values as `color` in <Text> component.
* Shorthand for setting `borderTopColor`, `borderRightColor`, `borderBottomColor` and `borderLeftColor`.
*/
readonly borderColor?: LiteralUnion<ForegroundColorName, string>;
/**
* Change top border color.
* Accepts the same values as `color` in `Text` component.
*/
readonly borderTopColor?: LiteralUnion<ForegroundColorName, string>;
/**
* Change bottom border color.
* Accepts the same values as `color` in `Text` component.
*/
readonly borderBottomColor?: LiteralUnion<ForegroundColorName, string>;
/**
* Change left border color.
* Accepts the same values as `color` in `Text` component.
*/
readonly borderLeftColor?: LiteralUnion<ForegroundColorName, string>;
/**
* Change right border color.
* Accepts the same values as `color` in `Text` component.
*/
readonly borderRightColor?: LiteralUnion<ForegroundColorName, string>;
/**
* Behavior for an element's overflow in both directions.
*
* @default 'visible'
*/
readonly overflow?: 'visible' | 'hidden';
/**
* Behavior for an element's overflow in horizontal direction.
*
* @default 'visible'
*/

@@ -129,2 +209,4 @@ readonly overflowX?: 'visible' | 'hidden';

* Behavior for an element's overflow in vertical direction.
*
* @default 'visible'
*/

@@ -131,0 +213,0 @@ readonly overflowY?: 'visible' | 'hidden';

@@ -11,2 +11,11 @@ // eslint-disable-next-line n/file-extension-in-import

const applyMarginStyles = (node, style) => {
if ('margin' in style) {
node.setMargin(Yoga.EDGE_ALL, style.margin ?? 0);
}
if ('marginX' in style) {
node.setMargin(Yoga.EDGE_HORIZONTAL, style.marginX ?? 0);
}
if ('marginY' in style) {
node.setMargin(Yoga.EDGE_VERTICAL, style.marginY ?? 0);
}
if ('marginLeft' in style) {

@@ -26,2 +35,11 @@ node.setMargin(Yoga.EDGE_START, style.marginLeft || 0);

const applyPaddingStyles = (node, style) => {
if ('padding' in style) {
node.setPadding(Yoga.EDGE_ALL, style.padding ?? 0);
}
if ('paddingX' in style) {
node.setPadding(Yoga.EDGE_HORIZONTAL, style.paddingX ?? 0);
}
if ('paddingY' in style) {
node.setPadding(Yoga.EDGE_VERTICAL, style.paddingY ?? 0);
}
if ('paddingLeft' in style) {

@@ -177,10 +195,21 @@ node.setPadding(Yoga.EDGE_LEFT, style.paddingLeft || 0);

if ('borderStyle' in style) {
const borderWidth = typeof style.borderStyle === 'string' ? 1 : 0;
node.setBorder(Yoga.EDGE_TOP, borderWidth);
node.setBorder(Yoga.EDGE_BOTTOM, borderWidth);
node.setBorder(Yoga.EDGE_LEFT, borderWidth);
node.setBorder(Yoga.EDGE_RIGHT, borderWidth);
const borderWidth = style.borderStyle ? 1 : 0;
if (style.borderTop !== false) {
node.setBorder(Yoga.EDGE_TOP, borderWidth);
}
if (style.borderBottom !== false) {
node.setBorder(Yoga.EDGE_BOTTOM, borderWidth);
}
if (style.borderLeft !== false) {
node.setBorder(Yoga.EDGE_LEFT, borderWidth);
}
if (style.borderRight !== false) {
node.setBorder(Yoga.EDGE_RIGHT, borderWidth);
}
}
};
const applyGapStyles = (node, style) => {
if ('gap' in style) {
node.setGap(Yoga.GUTTER_ALL, style.gap ?? 0);
}
if ('columnGap' in style) {

@@ -187,0 +216,0 @@ node.setGap(Yoga.GUTTER_COLUMN, style.columnGap ?? 0);

{
"name": "ink",
"version": "4.1.0",
"version": "4.2.0",
"description": "React for CLI",

@@ -21,2 +21,3 @@ "license": "MIT",

"scripts": {
"dev": "tsc --watch",
"build": "tsc",

@@ -55,2 +56,4 @@ "prepare": "npm run build",

"is-ci": "^3.0.1",
"is-lower-case": "^2.0.2",
"is-upper-case": "^2.0.2",
"lodash": "^4.17.21",

@@ -152,2 +155,5 @@ "patch-console": "^2.0.0",

},
"ignores": [
"src/parse-keypress.ts"
],
"overrides": [

@@ -154,0 +160,0 @@ {

@@ -171,3 +171,3 @@ [![](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md)

<details><summary>Manual setup</summary>
<details><summary>Manual JavaScript setup</summary>
<p>

@@ -185,13 +185,3 @@ Ink requires the same Babel setup as you would do for regular React-based apps in the browser.

{
"presets": [
"@babel/preset-react",
[
"@babel/preset-env",
{
"targets": {
"node": true
}
}
]
]
"presets": ["@babel/preset-react"]
}

@@ -614,3 +604,3 @@ ```

```jsx
<Box gap={1}>
<Box columnGap={1}>
<Text>A</Text>

@@ -630,3 +620,3 @@ <Text>B</Text>

```jsx
<Box flexDirection="column" gap={1}>
<Box flexDirection="column" rowGap={1}>
<Text>A</Text>

@@ -936,3 +926,3 @@ <Text>B</Text>

Type: `string`\
Allowed values: `single` `double` `round` `bold` `singleDouble` `doubleSingle` `classic`
Allowed values: `single` `double` `round` `bold` `singleDouble` `doubleSingle` `classic` | `BoxStyle`

@@ -981,4 +971,23 @@ Add a border with a specified style.

See example in [examples/borders](examples/borders/borders.js).
Alternatively, pass a custom border style like so:
```jsx
<Box
borderStyle={{
topLeft: '↘',
top: '↓',
topRight: '↙',
left: '→',
bottomLeft: '↗',
bottom: '↑',
bottomRight: '↖',
right: '←'
}}
>
<Text>Custom</Text>
</Box>
```
See example in [examples/borders](examples/borders/borders.tsx).
##### borderColor

@@ -989,3 +998,3 @@

Change border color.
Accepts the same values as [`color`](#color) in `<Text>` component.
Shorthand for setting `borderTopColor`, `borderRightColor`, `borderBottomColor` and `borderLeftColor`.

@@ -1000,2 +1009,95 @@ ```jsx

##### borderTopColor
Type: `string`
Change top border color.
Accepts the same values as [`color`](#color) in `<Text>` component.
```jsx
<Box borderStyle="round" borderTopColor="green">
<Text>Hello world</Text>
</Box>
```
##### borderRightColor
Type: `string`
Change right border color.
Accepts the same values as [`color`](#color) in `<Text>` component.
```jsx
<Box borderStyle="round" borderRightColor="green">
<Text>Hello world</Text>
</Box>
```
##### borderRightColor
Type: `string`
Change right border color.
Accepts the same values as [`color`](#color) in `<Text>` component.
```jsx
<Box borderStyle="round" borderRightColor="green">
<Text>Hello world</Text>
</Box>
```
##### borderBottomColor
Type: `string`
Change bottom border color.
Accepts the same values as [`color`](#color) in `<Text>` component.
```jsx
<Box borderStyle="round" borderBottomColor="green">
<Text>Hello world</Text>
</Box>
```
##### borderLeftColor
Type: `string`
Change left border color.
Accepts the same values as [`color`](#color) in `<Text>` component.
```jsx
<Box borderStyle="round" borderLeftColor="green">
<Text>Hello world</Text>
</Box>
```
##### borderTop
Type: `boolean`\
Default: `true`
Determines whether top border is visible.
##### borderRight
Type: `boolean`\
Default: `true`
Determines whether right border is visible.
##### borderBottom
Type: `boolean`\
Default: `true`
Determines whether bottom border is visible.
##### borderLeft
Type: `boolean`\
Default: `true`
Determines whether left border is visible.
### `<Newline>`

@@ -1144,3 +1246,3 @@

See [examples/static](examples/static/static.js) for an example usage of `<Static>` component.
See [examples/static](examples/static/static.tsx) for an example usage of `<Static>` component.

@@ -1235,3 +1337,3 @@ #### items

However, if user pastes text and it's more than one character, the callback will be called only once and the whole string will be passed as `input`.
You can find a full example of using `useInput` at [examples/use-input](examples/use-input/use-input.js).
You can find a full example of using `useInput` at [examples/use-input](examples/use-input/use-input.tsx).

@@ -1519,3 +1621,3 @@ ```jsx

See additional usage example in [examples/use-stdout](examples/use-stdout/use-stdout.js).
See additional usage example in [examples/use-stdout](examples/use-stdout/use-stdout.tsx).

@@ -1613,3 +1715,3 @@ ### useStderr()

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).
See example in [examples/use-focus](examples/use-focus/use-focus.tsx) and [examples/use-focus-with-id](examples/use-focus-with-id/use-focus-with-id.tsx).

@@ -1616,0 +1718,0 @@ ### useFocusManager()

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc