Skip to content

Commit

Permalink
feat: add ansis.isSupported() method to detect color support
Browse files Browse the repository at this point in the history
  • Loading branch information
webdiscus committed Apr 24, 2024
1 parent c1ef85e commit 7400c8a
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change log

## 3.2.0 (2024-04-24)

- feat: add `ansis.isSupported()` method to detect color support

## 3.1.1 (2024-04-15)

- fix: interpret FORCE_COLOR=false or FORCE_COLOR=0 as force disable colors\
Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ hex('#E0115F').bold.underline('Hello TrueColor!')

- Quality is first, test coverage 100%.
- Ansis has a lot of useful [features](#features), compare with [other libraries](#compare).
- Ansis is one of the smallest, 3.4 KB only.
- Ansis is one of the smallest, 3.5 KB only.
- Ansis is one of the [fastest](#benchmark).
- Ansis is stable, continuously developing and improving.
- Ansis is open for your [feature requests](https://github.com/webdiscus/ansis/issues).
Expand Down Expand Up @@ -82,8 +82,9 @@ See the [features comparison](#compare) and [benchmarks](#benchmark) of most pop
- [Strip ANSI codes](#strip) method `ansis.strip()`
- [Correct style break](#new-line) at the `end of line` when used `\n` in string
- Supports [environment variables](#cli-vars) `NO_COLOR` `FORCE_COLOR` and flags `--no-color` `--color`
- Detect [color support](#color-support) using `ansis.isSupported()` method
- Up to **x3 faster** than **Chalk**, [see benchmarks](#benchmark)
- Code bundle is only **3.4 KB**
- Code bundle is only **3.5 KB**
- Doesn't extend `String.prototype`
- Zero dependencies

Expand Down Expand Up @@ -622,6 +623,14 @@ Ansis automatically detects the supported color space:
- ANSI 16 colors
- black & white (no colors)

Ansis has the method `isSupported()` that returns a `boolean` value whether the output supports ANSI color and styles.

```js
import ansis from 'ansis';

console.log('Color output: ', ansis.isSupported());
```

There is no standard way to detect which color space is supported.
The most common way to detect color support is to check the `TERM` and `COLORTERM` environment variables.
CI systems can be detected by checking for the existence of the `CI` and other specifically environment variables.
Expand Down Expand Up @@ -677,7 +686,7 @@ npm run compare
| [`kleur`][kleur]<br>**2.7KB**<br><nobr>`✅ named import`</nobr><br>`✅ standard` | `8` colors |||||| no colors | `NO_COLOR`<br>`FORCE_COLOR` |
| [`kolorist`][kolorist]<br>**6.8KB**<br><nobr>`✅ named import`</nobr><br>`❌ standard` | `16` colors |||||| 256 color<br>❌<br>no colors | `NO_COLOR`<br>`FORCE_COLOR` |
| [`chalk`][chalk]<br>**15KB**<br><nobr>`❌ named import`</nobr><br>`✅ standard` | `16` colors |||||| 256 color<br>16 colors<br>no colors | `NO_COLOR`<br>`FORCE_COLOR`<br>`--no-color`<br>`--color` |
| [`ansis`][ansis]<br>**3.4KB**<br><nobr>`✅ named import`</nobr><br>`✅ standard` | `16` colors |||||| 256 color<br>16 colors<br>no colors | `NO_COLOR`<br>`FORCE_COLOR`<br>`--no-color`<br>`--color` |
| [`ansis`][ansis]<br>**3.5KB**<br><nobr>`✅ named import`</nobr><br>`✅ standard` | `16` colors |||||| 256 color<br>16 colors<br>no colors | `NO_COLOR`<br>`FORCE_COLOR`<br>`--no-color`<br>`--color` |

> **Note**
>
Expand Down
1 change: 1 addition & 0 deletions README.npm.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ See the [features comparison](https://github.com/webdiscus/ansis#compare) and [b
- [ANSI codes](https://github.com/webdiscus/ansis#escape-codes) as `open` and `close` properties ``` `Hello ${red.open}World${red.close}!` ```
- [Strip ANSI codes](https://github.com/webdiscus/ansis#strip) method `ansis.strip()`
- [Correct style break](https://github.com/webdiscus/ansis#new-line) at the `end of line` when used `\n` in string
- Detect [color support](https://github.com/webdiscus/ansis#color-support) using `ansis.isSupported()` method
- Supports [CLI](https://github.com/webdiscus/ansis#cli-vars) `NO_COLOR` `FORCE_COLOR` `--no-color` `--color`
- Doesn't extend `String.prototype`
- Zero dependencies
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ansis",
"version": "3.1.1",
"version": "3.2.0",
"description": "Colorize terminal with ANSI colors & styles",
"keywords": [
"ansi",
Expand Down
2 changes: 1 addition & 1 deletion package.npm.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ansis",
"version": "3.1.1",
"version": "3.2.0",
"description": "Colorize terminal with ANSI colors & styles",
"keywords": [
"ansi",
Expand Down
4 changes: 2 additions & 2 deletions src/ansi-codes.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { hexToRgb, rgbToAnsi256, rgbToAnsi16, ansi256To16 } from './utils.js';
import { getColorSpace } from './color-support.js';

const colorSpace = getColorSpace();
const hasColor = colorSpace > 0;
export const isSupported = colorSpace > 0;
const mono = { open: '', close: '' };
const monoFn = () => mono;
const esc = hasColor ? (open, close) => ({ open: `\x1b[${open}m`, close: `\x1b[${close}m` }) : monoFn;
const esc = isSupported ? (open, close) => ({ open: `\x1b[${open}m`, close: `\x1b[${close}m` }) : monoFn;
const closeCode = 39;
const bgCloseCode = 49;

Expand Down
7 changes: 7 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
type ColorExtend = Record<string, string | { open: string, close: string }>

interface Ansis {
/**
* Whether the output supports ANSI color and styles.
*
* @return {boolean}
*/
isSupported: () => boolean;

/**
* Return styled string.
*
Expand Down
9 changes: 8 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { baseStyles, styleMethods, rgb } from './ansi-codes.js';
import { baseStyles, styleMethods, rgb, isSupported } from './ansi-codes.js';
import { hexToRgb, replaceAll } from './utils.js';

/**
Expand Down Expand Up @@ -76,6 +76,13 @@ const createStyle = ({ _p: props }, { open, close }) => {
const Ansis = function() {
const self = (str) => str + '';

/**
* Whether the output supports ANSI color and styles.
*
* @return {boolean}
*/
self.isSupported = () => isSupported;

/**
* Remove ANSI styling codes.
* @param {string} str
Expand Down
2 changes: 2 additions & 0 deletions test/env/color-space.mono.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// set env variable to simulate no color
process.env.NO_COLOR = '1';
6 changes: 6 additions & 0 deletions test/functional.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import './env/color-space.truecolor.js';
import ansis, { Ansis, red, yellow, green, bold, hex } from '../src/index.mjs';

describe('style tests', () => {
test(`ansis.isSupported()`, () => {
const received = ansis.isSupported();
const expected = true;
expect(received).toEqual(expected);
});

test(`ansis.visible('foo')`, () => {
const received = ansis.visible('foo');
const expected = 'foo';
Expand Down
20 changes: 20 additions & 0 deletions test/no-color.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, describe, test } from 'vitest';

// import env variables to simulate no color
import './env/color-space.mono.js';

import ansis, { red } from '../src/index.mjs';

describe('color space', () => {
test(`ansis.isSupported()`, () => {
const received = ansis.isSupported();
const expected = false;
expect(received).toEqual(expected);
});

test(`red('foo')`, () => {
const received = red`foo`;
const expected = 'foo';
expect(received).toEqual(expected);
});
});

0 comments on commit 7400c8a

Please sign in to comment.