Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
6.6 kB · 231 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232import chalk from 'chalk'import cliBoxes, { type Boxes, type BoxStyle } from 'cli-boxes'import { applyColor } from './colorize.js'import type { DOMNode } from './dom.js'import type Output from './output.js'import { stringWidth } from './stringWidth.js'import type { Color } from './styles.js'
export type BorderTextOptions = { content: string // Pre-rendered string with ANSI color codes position: 'top' | 'bottom' align: 'start' | 'end' | 'center' offset?: number // Only used with 'start' or 'end' alignment. Number of characters from the edge.}
export const CUSTOM_BORDER_STYLES = { dashed: { top: '╌', left: '╎', right: '╎', bottom: '╌', // there aren't any line-drawing characters for dashes unfortunately topLeft: ' ', topRight: ' ', bottomLeft: ' ', bottomRight: ' ', },} as const
export type BorderStyle = | keyof Boxes | keyof typeof CUSTOM_BORDER_STYLES | BoxStyle
function embedTextInBorder( borderLine: string, text: string, align: 'start' | 'end' | 'center', offset: number = 0, borderChar: string,): [before: string, text: string, after: string] { const textLength = stringWidth(text) const borderLength = borderLine.length
if (textLength >= borderLength - 2) { return ['', text.substring(0, borderLength), ''] }
let position: number if (align === 'center') { position = Math.floor((borderLength - textLength) / 2) } else if (align === 'start') { position = offset + 1 // +1 to account for corner character } else { // align === 'end' position = borderLength - textLength - offset - 1 // -1 for corner character }
// Ensure position is valid position = Math.max(1, Math.min(position, borderLength - textLength - 1))
const before = borderLine.substring(0, 1) + borderChar.repeat(position - 1) const after = borderChar.repeat(borderLength - position - textLength - 1) + borderLine.substring(borderLength - 1)
return [before, text, after]}
function styleBorderLine( line: string, color: Color | undefined, dim: boolean | undefined,): string { let styled = applyColor(line, color) if (dim) { styled = chalk.dim(styled) } return styled}
const renderBorder = ( x: number, y: number, node: DOMNode, output: Output,): void => { if (node.style.borderStyle) { const width = Math.floor(node.yogaNode!.getComputedWidth()) const height = Math.floor(node.yogaNode!.getComputedHeight()) const box = typeof node.style.borderStyle === 'string' ? (CUSTOM_BORDER_STYLES[ node.style.borderStyle as keyof typeof CUSTOM_BORDER_STYLES ] ?? cliBoxes[node.style.borderStyle as keyof Boxes]) : 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 dimTopBorderColor = node.style.borderTopDimColor ?? node.style.borderDimColor
const dimBottomBorderColor = node.style.borderBottomDimColor ?? node.style.borderDimColor
const dimLeftBorderColor = node.style.borderLeftDimColor ?? node.style.borderDimColor
const dimRightBorderColor = node.style.borderRightDimColor ?? node.style.borderDimColor
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 = Math.max( 0, width - (showLeftBorder ? 1 : 0) - (showRightBorder ? 1 : 0), )
const topBorderLine = showTopBorder ? (showLeftBorder ? box.topLeft : '') + box.top.repeat(contentWidth) + (showRightBorder ? box.topRight : '') : ''
// Handle text in top border let topBorder: string | undefined if (showTopBorder && node.style.borderText?.position === 'top') { const [before, text, after] = embedTextInBorder( topBorderLine, node.style.borderText.content, node.style.borderText.align, node.style.borderText.offset, box.top, ) topBorder = styleBorderLine(before, topBorderColor, dimTopBorderColor) + text + styleBorderLine(after, topBorderColor, dimTopBorderColor) } else if (showTopBorder) { topBorder = styleBorderLine( topBorderLine, topBorderColor, dimTopBorderColor, ) }
let verticalBorderHeight = height
if (showTopBorder) { verticalBorderHeight -= 1 }
if (showBottomBorder) { verticalBorderHeight -= 1 }
verticalBorderHeight = Math.max(0, verticalBorderHeight)
let leftBorder = (applyColor(box.left, leftBorderColor) + '\n').repeat( verticalBorderHeight, )
if (dimLeftBorderColor) { leftBorder = chalk.dim(leftBorder) }
let rightBorder = (applyColor(box.right, rightBorderColor) + '\n').repeat( verticalBorderHeight, )
if (dimRightBorderColor) { rightBorder = chalk.dim(rightBorder) }
const bottomBorderLine = showBottomBorder ? (showLeftBorder ? box.bottomLeft : '') + box.bottom.repeat(contentWidth) + (showRightBorder ? box.bottomRight : '') : ''
// Handle text in bottom border let bottomBorder: string | undefined if (showBottomBorder && node.style.borderText?.position === 'bottom') { const [before, text, after] = embedTextInBorder( bottomBorderLine, node.style.borderText.content, node.style.borderText.align, node.style.borderText.offset, box.bottom, ) bottomBorder = styleBorderLine(before, bottomBorderColor, dimBottomBorderColor) + text + styleBorderLine(after, bottomBorderColor, dimBottomBorderColor) } else if (showBottomBorder) { bottomBorder = styleBorderLine( bottomBorderLine, bottomBorderColor, dimBottomBorderColor, ) }
const offsetY = showTopBorder ? 1 : 0
if (topBorder) { output.write(x, y, topBorder) }
if (showLeftBorder) { output.write(x, y + offsetY, leftBorder) }
if (showRightBorder) { output.write(x + width - 1, y + offsetY, rightBorder) }
if (bottomBorder) { output.write(x, y + height - 1, bottomBorder) } }}
export default renderBorder