110 lines
2.3 KiB
TypeScript
110 lines
2.3 KiB
TypeScript
/**
|
|
* Text input component with focus styling.
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { Box, Text } from 'ink';
|
|
import TextInput from './TextInput.js';
|
|
import { colors } from '../theme.js';
|
|
|
|
/**
|
|
* Props for the Input component.
|
|
*/
|
|
interface InputProps {
|
|
/** Current value */
|
|
value: string;
|
|
/** Change handler */
|
|
onChange: (value: string) => void;
|
|
/** Submit handler (Enter key) */
|
|
onSubmit?: (value: string) => void;
|
|
/** Placeholder text */
|
|
placeholder?: string;
|
|
/** Label shown above input */
|
|
label?: string;
|
|
/** Whether input is focused */
|
|
focus?: boolean;
|
|
/** Whether to mask input (for passwords) */
|
|
mask?: string;
|
|
/** Whether input is disabled */
|
|
disabled?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Text input component with label and focus styling.
|
|
*/
|
|
export function Input({
|
|
value,
|
|
onChange,
|
|
onSubmit,
|
|
placeholder,
|
|
label,
|
|
focus = true,
|
|
mask,
|
|
disabled = false,
|
|
}: InputProps): React.ReactElement {
|
|
const borderColor = focus ? colors.focus : colors.border;
|
|
|
|
return (
|
|
<Box flexDirection="column">
|
|
{label && (
|
|
<Text color={colors.text} bold>{label}</Text>
|
|
)}
|
|
<Box
|
|
borderStyle="single"
|
|
borderColor={borderColor}
|
|
paddingX={1}
|
|
>
|
|
{disabled ? (
|
|
<Text color={colors.textMuted}>{value || placeholder || ''}</Text>
|
|
) : (
|
|
<TextInput
|
|
value={value}
|
|
onChange={onChange}
|
|
onSubmit={onSubmit}
|
|
placeholder={placeholder}
|
|
focus={focus}
|
|
mask={mask}
|
|
/>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Multi-line text display (read-only, styled like input).
|
|
*/
|
|
interface TextDisplayProps {
|
|
/** Text content */
|
|
content: string;
|
|
/** Label shown above */
|
|
label?: string;
|
|
/** Whether to show border */
|
|
border?: boolean;
|
|
}
|
|
|
|
export function TextDisplay({
|
|
content,
|
|
label,
|
|
border = true
|
|
}: TextDisplayProps): React.ReactElement {
|
|
return (
|
|
<Box flexDirection="column">
|
|
{label && (
|
|
<Text color={colors.text} bold>{label}</Text>
|
|
)}
|
|
{border ? (
|
|
<Box
|
|
borderStyle="single"
|
|
borderColor={colors.border}
|
|
paddingX={1}
|
|
>
|
|
<Text>{content}</Text>
|
|
</Box>
|
|
) : (
|
|
<Text>{content}</Text>
|
|
)}
|
|
</Box>
|
|
);
|
|
}
|