diff --git a/index.d.ts b/index.d.ts index 2d769a7..b3d54c0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -183,6 +183,14 @@ export interface ChalkInstance extends ChalkFunction { */ hex: (color: string) => this; + /** + Use a [Select/Set Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters) (SGR) [color code number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) to set text color. + + 30 <= code && code < 38 || 90 <= code && code < 98 + For example, 31 for red, 91 for redBright. + */ + ansi: (code: number) => this; + /** Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color. */ @@ -207,6 +215,14 @@ export interface ChalkInstance extends ChalkFunction { */ bgHex: (color: string) => this; + /** + Use a [Select/Set Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters) (SGR) [color code number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) to set background color. + 30 <= code && code < 38 || 90 <= code && code < 98 + For example, 31 for red, 91 for redBright. + Use the foreground code, not the background code (for example, not 41, nor 101). + */ + bgAnsi: (code: number) => this; + /** Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color. */ diff --git a/index.test-d.ts b/index.test-d.ts index 45299d6..0f41ecc 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -43,9 +43,11 @@ expectType(chalk`Works with numbers {bold.red ${1}}`); // -- Color methods -- expectAssignable(chalk.rgb(0, 0, 0)); expectAssignable(chalk.hex('#DEADED')); +expectAssignable(chalk.ansi(30)); expectAssignable(chalk.ansi256(0)); expectAssignable(chalk.bgRgb(0, 0, 0)); expectAssignable(chalk.bgHex('#DEADED')); +expectAssignable(chalk.bgAnsi(30)); expectAssignable(chalk.bgAnsi256(0)); // -- Modifiers -- diff --git a/package.json b/package.json index 203b04e..2509b62 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "text" ], "dependencies": { - "ansi-styles": "^6.0.0", + "ansi-styles": "^6.1.0", "supports-color": "^9.0.0" }, "devDependencies": { diff --git a/readme.md b/readme.md index ed9b312..e7ce95e 100644 --- a/readme.md +++ b/readme.md @@ -298,6 +298,7 @@ The following color models can be used: - [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')` - [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')` +- [`ansi`](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) - Example: `chalk.ansi(31).bgAnsi(93)('red on yellowBright')` - [`ansi256`](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) - Example: `chalk.bgAnsi256(194)('Honeydew, more or less')` ## Browser support diff --git a/source/index.js b/source/index.js index 79bdabc..c81da1c 100644 --- a/source/index.js +++ b/source/index.js @@ -11,8 +11,8 @@ const {isArray} = Array; // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = [ - 'ansi256', - 'ansi256', + 'ansi', + 'ansi', 'ansi256', 'ansi16m' ]; @@ -74,7 +74,15 @@ styles.visible = { const getModelAnsi = (model, level, type, ...arguments_) => { if (model === 'rgb') { - return level === 'ansi16m' ? ansiStyles[type].ansi16m(...arguments_) : ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_)); + if (level === 'ansi16m') { + return ansiStyles[type].ansi16m(...arguments_); + } + + if (level === 'ansi256') { + return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_)); + } + + return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_)); } if (model === 'hex') { @@ -84,7 +92,7 @@ const getModelAnsi = (model, level, type, ...arguments_) => { return ansiStyles[type](...arguments_); }; -const usedModels = ['rgb', 'hex', 'ansi256']; +const usedModels = ['rgb', 'hex', 'ansi256', 'ansi']; for (const model of usedModels) { styles[model] = { diff --git a/test/chalk.js b/test/chalk.js index 035ad30..adc1aed 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -93,6 +93,11 @@ test('line breaks should open and close colors with CRLF', t => { t.is(chalk.grey('hello\r\nworld'), '\u001B[90mhello\u001B[39m\r\n\u001B[90mworld\u001B[39m'); }); +test('properly convert RGB to 16 colors on basic color terminals', t => { + t.is(new Chalk({level: 1}).hex('#FF0000')('hello'), '\u001B[91mhello\u001B[39m'); + t.is(new Chalk({level: 1}).bgHex('#FF0000')('hello'), '\u001B[101mhello\u001B[49m'); +}); + test('properly convert RGB to 256 colors on basic color terminals', t => { t.is(new Chalk({level: 2}).hex('#FF0000')('hello'), '\u001B[38;5;196mhello\u001B[39m'); t.is(new Chalk({level: 2}).bgHex('#FF0000')('hello'), '\u001B[48;5;196mhello\u001B[49m');