mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 21:05:51 +00:00
145 lines
3.2 KiB
TypeScript
145 lines
3.2 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
import React from 'react'
|
|
import type { Color, Styles, TextStyles } from '../core/styles.js'
|
|
|
|
type BaseProps = {
|
|
/**
|
|
* Change text color. Accepts a raw color value (rgb, hex, ansi).
|
|
*/
|
|
readonly color?: Color
|
|
|
|
/**
|
|
* Same as `color`, but for background.
|
|
*/
|
|
readonly backgroundColor?: Color
|
|
|
|
/**
|
|
* Make the text italic.
|
|
*/
|
|
readonly italic?: boolean
|
|
|
|
/**
|
|
* Make the text underlined.
|
|
*/
|
|
readonly underline?: boolean
|
|
|
|
/**
|
|
* Make the text crossed with a line.
|
|
*/
|
|
readonly strikethrough?: boolean
|
|
|
|
/**
|
|
* Inverse background and foreground colors.
|
|
*/
|
|
readonly inverse?: boolean
|
|
|
|
/**
|
|
* This property tells Ink to wrap or truncate text if its width is larger than container.
|
|
* If `wrap` is passed (by default), Ink will wrap text and split it into multiple lines.
|
|
* If `truncate-*` is passed, Ink will truncate text instead, which will result in one line of text with the rest cut off.
|
|
*/
|
|
readonly wrap?: Styles['textWrap']
|
|
|
|
readonly children?: ReactNode
|
|
}
|
|
|
|
/**
|
|
* Bold and dim are mutually exclusive in terminals.
|
|
* This type ensures you can use one or the other, but not both.
|
|
*/
|
|
type WeightProps =
|
|
| { bold?: never; dim?: never }
|
|
| { bold: boolean; dim?: never }
|
|
| { dim: boolean; bold?: never }
|
|
|
|
export type Props = BaseProps & WeightProps
|
|
|
|
const memoizedStylesForWrap: Record<NonNullable<Styles['textWrap']>, Styles> = {
|
|
wrap: {
|
|
flexGrow: 0,
|
|
flexShrink: 1,
|
|
flexDirection: 'row',
|
|
textWrap: 'wrap',
|
|
},
|
|
'wrap-trim': {
|
|
flexGrow: 0,
|
|
flexShrink: 1,
|
|
flexDirection: 'row',
|
|
textWrap: 'wrap-trim',
|
|
},
|
|
end: {
|
|
flexGrow: 0,
|
|
flexShrink: 1,
|
|
flexDirection: 'row',
|
|
textWrap: 'end',
|
|
},
|
|
middle: {
|
|
flexGrow: 0,
|
|
flexShrink: 1,
|
|
flexDirection: 'row',
|
|
textWrap: 'middle',
|
|
},
|
|
'truncate-end': {
|
|
flexGrow: 0,
|
|
flexShrink: 1,
|
|
flexDirection: 'row',
|
|
textWrap: 'truncate-end',
|
|
},
|
|
truncate: {
|
|
flexGrow: 0,
|
|
flexShrink: 1,
|
|
flexDirection: 'row',
|
|
textWrap: 'truncate',
|
|
},
|
|
'truncate-middle': {
|
|
flexGrow: 0,
|
|
flexShrink: 1,
|
|
flexDirection: 'row',
|
|
textWrap: 'truncate-middle',
|
|
},
|
|
'truncate-start': {
|
|
flexGrow: 0,
|
|
flexShrink: 1,
|
|
flexDirection: 'row',
|
|
textWrap: 'truncate-start',
|
|
},
|
|
} as const
|
|
|
|
/**
|
|
* This component can display text, and change its style to make it colorful, bold, underline, italic or strikethrough.
|
|
*/
|
|
export default function Text({
|
|
color,
|
|
backgroundColor,
|
|
bold,
|
|
dim,
|
|
italic = false,
|
|
underline = false,
|
|
strikethrough = false,
|
|
inverse = false,
|
|
wrap = 'wrap',
|
|
children,
|
|
}: Props): React.ReactNode {
|
|
if (children === undefined || children === null) {
|
|
return null
|
|
}
|
|
|
|
// Build textStyles object with only the properties that are set
|
|
const textStyles: TextStyles = {
|
|
...(color && { color }),
|
|
...(backgroundColor && { backgroundColor }),
|
|
...(dim && { dim }),
|
|
...(bold && { bold }),
|
|
...(italic && { italic }),
|
|
...(underline && { underline }),
|
|
...(strikethrough && { strikethrough }),
|
|
...(inverse && { inverse }),
|
|
}
|
|
|
|
return (
|
|
<ink-text style={memoizedStylesForWrap[wrap]} textStyles={textStyles}>
|
|
{children}
|
|
</ink-text>
|
|
)
|
|
}
|