mirror of
https://github.com/codeaashu/claude-code.git
synced 2026-04-08 22:28:48 +03:00
claude-code
This commit is contained in:
93
web/lib/ink-compat/color-mapping.ts
Normal file
93
web/lib/ink-compat/color-mapping.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Maps Ink/ANSI color values to CSS color strings.
|
||||
*
|
||||
* Ink Color types:
|
||||
* RGBColor = `rgb(${number},${number},${number})`
|
||||
* HexColor = `#${string}`
|
||||
* Ansi256Color = `ansi256(${number})`
|
||||
* AnsiColor = `ansi:black` | `ansi:red` | ...
|
||||
*/
|
||||
|
||||
// Standard ANSI 16-color palette mapped to CSS hex values
|
||||
const ANSI_COLORS: Record<string, string> = {
|
||||
black: '#000000',
|
||||
red: '#cc0000',
|
||||
green: '#4e9a06',
|
||||
yellow: '#c4a000',
|
||||
blue: '#3465a4',
|
||||
magenta: '#75507b',
|
||||
cyan: '#06989a',
|
||||
white: '#d3d7cf',
|
||||
blackBright: '#555753',
|
||||
redBright: '#ef2929',
|
||||
greenBright: '#8ae234',
|
||||
yellowBright: '#fce94f',
|
||||
blueBright: '#729fcf',
|
||||
magentaBright: '#ad7fa8',
|
||||
cyanBright: '#34e2e2',
|
||||
whiteBright: '#eeeeec',
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an index in the xterm 256-color palette to a CSS hex color string.
|
||||
*/
|
||||
function ansi256ToHex(index: number): string {
|
||||
// 0–15: standard palette
|
||||
if (index < 16) {
|
||||
const names = [
|
||||
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white',
|
||||
'blackBright', 'redBright', 'greenBright', 'yellowBright',
|
||||
'blueBright', 'magentaBright', 'cyanBright', 'whiteBright',
|
||||
]
|
||||
return ANSI_COLORS[names[index]!] ?? '#000000'
|
||||
}
|
||||
|
||||
// 232–255: grayscale ramp
|
||||
if (index >= 232) {
|
||||
const level = (index - 232) * 10 + 8
|
||||
const hex = level.toString(16).padStart(2, '0')
|
||||
return `#${hex}${hex}${hex}`
|
||||
}
|
||||
|
||||
// 16–231: 6×6×6 color cube
|
||||
const i = index - 16
|
||||
const b = i % 6
|
||||
const g = Math.floor(i / 6) % 6
|
||||
const r = Math.floor(i / 36)
|
||||
const toChannel = (v: number) => (v === 0 ? 0 : v * 40 + 55)
|
||||
const rh = toChannel(r).toString(16).padStart(2, '0')
|
||||
const gh = toChannel(g).toString(16).padStart(2, '0')
|
||||
const bh = toChannel(b).toString(16).padStart(2, '0')
|
||||
return `#${rh}${gh}${bh}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Ink Color string (or theme-resolved raw color) to a CSS color string.
|
||||
* Returns `undefined` if `color` is undefined/empty.
|
||||
*/
|
||||
export function inkColorToCSS(color: string | undefined): string | undefined {
|
||||
if (!color) return undefined
|
||||
|
||||
// Pass through hex colors
|
||||
if (color.startsWith('#')) return color
|
||||
|
||||
// Normalise `rgb(r,g,b)` → `rgb(r, g, b)` (browsers accept both, but clean)
|
||||
if (color.startsWith('rgb(')) {
|
||||
return color.replace(/\s+/g, '')
|
||||
}
|
||||
|
||||
// ansi256(N)
|
||||
const ansi256Match = color.match(/^ansi256\((\d+)\)$/)
|
||||
if (ansi256Match) {
|
||||
return ansi256ToHex(parseInt(ansi256Match[1]!, 10))
|
||||
}
|
||||
|
||||
// ansi:name
|
||||
if (color.startsWith('ansi:')) {
|
||||
const name = color.slice(5)
|
||||
return ANSI_COLORS[name] ?? color
|
||||
}
|
||||
|
||||
// Unknown format — return as-is (browser may understand it)
|
||||
return color
|
||||
}
|
||||
Reference in New Issue
Block a user