Files
codeaashu-claude-code/web/lib/ink-compat/color-mapping.ts
ashutoshpythoncs@gmail.com b564857c0b claude-code
2026-03-31 18:58:05 +05:30

94 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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 {
// 015: 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'
}
// 232255: grayscale ramp
if (index >= 232) {
const level = (index - 232) * 10 + 8
const hex = level.toString(16).padStart(2, '0')
return `#${hex}${hex}${hex}`
}
// 16231: 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
}