UNPKG

@shopify/cli-kit

Version:

A set of utilities, interfaces, and models that are common across all the platform features

87 lines 3.55 kB
/* eslint-disable no-nested-ternary */ import { shouldDisplayColors } from '../../../../public/node/output.js'; import React, { useEffect, useState } from 'react'; import { Text, useInput } from 'ink'; import chalk from 'chalk'; import figures from 'figures'; const TextInput = ({ value: originalValue, defaultValue = '', onChange, placeholder = '', noColor = !shouldDisplayColors(), color = noColor ? undefined : 'cyan', password = false, focus = true, }) => { const [cursorOffset, setCursorOffset] = useState((originalValue || '').length); // if the updated value is shorter than the last one we need to reset the cursor useEffect(() => { setCursorOffset((previousOffset) => { const newValue = originalValue || ''; if (previousOffset > newValue.length - 1) { return newValue.length; } return previousOffset; }); }, [originalValue]); const value = password ? '*'.repeat(originalValue.length) : originalValue; let renderedValue; const renderPlaceholder = (value) => { return chalk.inverse(value[0]) + chalk.dim(value.slice(1)); }; const cursorChar = figures.square; const defaultCursor = React.createElement(Text, { backgroundColor: color }, cursorChar); const placeholderText = defaultValue.length > 0 ? defaultValue : placeholder.length > 0 ? placeholder : ''; const renderedPlaceholder = placeholderText.length > 0 ? renderPlaceholder(placeholderText) : defaultCursor; // render cursor renderedValue = value .split('') .map((char, index) => { if (index === cursorOffset) { return noColor ? cursorChar : chalk.inverse(char); } else { return char; } }) .join(''); if (cursorOffset === value.length) { renderedValue = (React.createElement(Text, null, renderedValue, defaultCursor)); } useInput((input, key) => { if (key.upArrow || key.downArrow || (key.ctrl && input === 'c') || (key.shift && key.tab) || key.return) { return; } else if (key.tab) { if (originalValue.length === 0 && placeholderText) { onChange(placeholderText); setCursorOffset(placeholderText.length); return; } } let nextCursorOffset = cursorOffset; let nextValue = originalValue; if (key.leftArrow) { if (cursorOffset > 0) { nextCursorOffset--; } } else if (key.rightArrow) { if (cursorOffset < originalValue.length) { nextCursorOffset++; } } else if (key.backspace || key.delete) { if (cursorOffset > 0) { nextValue = originalValue.slice(0, cursorOffset - 1) + originalValue.slice(cursorOffset, originalValue.length); nextCursorOffset--; } } else { nextValue = originalValue.slice(0, cursorOffset) + input + originalValue.slice(cursorOffset, originalValue.length); nextCursorOffset += input.length; } setCursorOffset(nextCursorOffset); if (nextValue !== originalValue) { onChange(nextValue); } }, { isActive: focus }); return React.createElement(Text, { color: color }, value.length > 0 ? renderedValue : renderedPlaceholder); }; export { TextInput }; //# sourceMappingURL=TextInput.js.map