ink-form
Version:
Complex user-friendly form component for React Ink
62 lines (61 loc) • 2.72 kB
JavaScript
import React from 'react';
import { Box, Text, useInput } from 'ink';
import TextInput from 'ink-text-input';
const FLOAT_REGEX = /^-?((\d+)|(\d*\.\d+))$/;
const INTEGER_REGEX = /^-?\d+$/;
export const NumberFieldRenderer = props => {
const regex = props.isFloat ? FLOAT_REGEX : INTEGER_REGEX;
const parse = props.isFloat ? parseFloat : parseInt;
const change = (value) => {
if (regex.test(value)) {
props.onClearError();
const asNumber = Math.round(parse(value) * 100000) / 100000;
if (props.field.min !== undefined && props.field.min > asNumber) {
props.onError(`"${value}" too small, must be above or equal to ${props.field.min}.`);
props.onChange(value);
return;
}
else if (props.field.max !== undefined && props.field.max < asNumber) {
props.onError(`"${value}" too big, must be below or equal to ${props.field.max}.`);
props.onChange(value);
return;
}
else {
props.onChange(asNumber);
}
}
else {
props.onError(`"${value}" is not an ${props.isFloat ? 'float' : 'integer'}.`);
props.onChange(value);
}
};
useInput((input, key) => {
if (typeof props.value === 'number') {
if (key.upArrow) {
change('' + ((props.value ?? 0) + (props.field.step ?? 1)));
}
else if (key.downArrow) {
change('' + ((props.value ?? 0) - (props.field.step ?? 1)));
}
}
else {
if (key.upArrow || key.downArrow) {
change('' + ((props.field.min ?? 0) <= 0 && (props.field.max ?? 0) >= 0 ? 0 : props.field.min ?? props.field.max));
}
}
});
return (React.createElement(Box, { borderStyle: 'round', width: "100%", flexDirection: "column" },
React.createElement(Box, null,
React.createElement(TextInput, { value: '' + (props.value ?? ''), onChange: value => {
if (regex.test(value)) {
props.onClearError();
change(value);
}
else {
props.onError(`"${value}" is not an ${props.isFloat ? 'float' : 'integer'}.`);
props.onChange(value);
}
}, placeholder: props.field.placeholder, onSubmit: () => props.onSetEditingField(undefined) })),
React.createElement(Box, null,
React.createElement(Text, { dimColor: true }, "Press UP/DOWN to increase or decrease the value."))));
};