Skip to content

Commit

Permalink
Introduce new API to allow instance reuse (#42)
Browse files Browse the repository at this point in the history
- New createColors function creates a Colorette instance
  - Color support is automatically detected, but you can
    override it via the useColor boolean property.
- New isColorSupported property. true if the terminal
  supports color or false otherwise.
- Remove options.enabled
  • Loading branch information
jorgebucaran committed Sep 17, 2021
1 parent 9e40f1b commit dcef277
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 80 deletions.
41 changes: 24 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Colorette

> Easily set the text color and style in the terminal.
> Easily set your terminal text color & styles.
- No wonky prototype method-chain API.
- Automatic color support detection.
- Up to [2x faster](#benchmarks) than alternatives.
- [`NO_COLOR`](https://no-color.org) friendly. 👌
- [`NO_COLOR`](https://no-color.org) friendly.

Here's the first example to get you started.

Expand Down Expand Up @@ -36,10 +36,14 @@ Of course, you can nest styles without breaking existing color sequences.
console.log(bold(`I'm ${blue(`da ba ${underline("dee")} da ba`)} daa`))
```

Feeling adventurous? Try the [pipeline operator](https://github.com/tc39/proposal-pipeline-operator).
Need to dynamically enable or disable color? You can do that too.

```js
console.log("Da ba dee da ba daa" |> blue |> bold)
import { createColors } from "colorette"

const { blue } = createColors({ useColor: false })

console.log(blue("Blue, not, nope, nah"))
```

## Installation
Expand All @@ -50,34 +54,37 @@ npm install colorette

## API

### `<style>(string)`
### `blue(text)`

See [supported styles](#supported-styles).
> See all [supported colors](#supported-colors).
```js
import { blue } from "colorette"

blue("I'm blue") //=> \x1b[34mI'm blue\x1b[39m
```

### `options.enabled`
### `isColorSupported`

Colorette automatically detects if your terminal can display color, but you can toggle color as needed.
`true` if your terminal supports color or `false` otherwise. Used internally and handled for you, but exposed for convenience.

### `createColors({ useColor })`

Create a reusable instance of Colorette. Color support is automatically detected, but you can override it by setting the `useColor` boolean property.

```js
import { options } from "colorette"
import { createColors } from "colorette"

options.enabled = false
const { blue } = createColors({ useColor: false })
```

You can also force the use of color globally by setting `FORCE_COLOR=` or `NO_COLOR=` from the CLI.
## Environment

You can override automatic color detection from the CLI via `NO_COLOR=` or `FORCE_COLOR=`.

```console
$ FORCE_COLOR= node example.js >log
$ NO_COLOR= node example.js
$ FORCE_COLOR= node example.js | ./consumer.js
```

## Supported styles
## Supported colors

| Colors | Background Colors | Bright Colors | Bright Background Colors | Modifiers |
| ------- | ----------------- | ------------- | ------------------------ | ----------------- |
Expand All @@ -91,7 +98,7 @@ $ NO_COLOR= node example.js
| white | bgWhite | whiteBright | bgWhiteBright | |
| gray | | | | |

## Benchmarks
## [Benchmarks](https://github.com/jorgebucaran/colorette/actions/workflows/bench.yml)

```console
npm --prefix bench start
Expand Down
138 changes: 91 additions & 47 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,93 @@
interface Style {
(string: string): string
}
declare module "colorette" {
type Color = (text: string | number) => string

export const options: {
enabled: boolean
}
interface Colorette {
reset: Color
bold: Color
dim: Color
italic: Color
underline: Color
inverse: Color
hidden: Color
strikethrough: Color
black: Color
red: Color
green: Color
yellow: Color
blue: Color
magenta: Color
cyan: Color
white: Color
gray: Color
bgBlack: Color
bgRed: Color
bgGreen: Color
bgYellow: Color
bgBlue: Color
bgMagenta: Color
bgCyan: Color
bgWhite: Color
blackBright: Color
redBright: Color
greenBright: Color
yellowBright: Color
blueBright: Color
magentaBright: Color
cyanBright: Color
whiteBright: Color
bgBlackBright: Color
bgRedBright: Color
bgGreenBright: Color
bgYellowBright: Color
bgBlueBright: Color
bgMagentaBright: Color
bgCyanBright: Color
bgWhiteBright: Color
}

const reset: Color
const bold: Color
const dim: Color
const italic: Color
const underline: Color
const inverse: Color
const hidden: Color
const strikethrough: Color
const black: Color
const red: Color
const green: Color
const yellow: Color
const blue: Color
const magenta: Color
const cyan: Color
const white: Color
const gray: Color
const bgBlack: Color
const bgRed: Color
const bgGreen: Color
const bgYellow: Color
const bgBlue: Color
const bgMagenta: Color
const bgCyan: Color
const bgWhite: Color
const blackBright: Color
const redBright: Color
const greenBright: Color
const yellowBright: Color
const blueBright: Color
const magentaBright: Color
const cyanBright: Color
const whiteBright: Color
const bgBlackBright: Color
const bgRedBright: Color
const bgGreenBright: Color
const bgYellowBright: Color
const bgBlueBright: Color
const bgMagentaBright: Color
const bgCyanBright: Color
const bgWhiteBright: Color

export const reset: Style
export const bold: Style
export const dim: Style
export const italic: Style
export const underline: Style
export const inverse: Style
export const hidden: Style
export const strikethrough: Style
export const black: Style
export const red: Style
export const green: Style
export const yellow: Style
export const blue: Style
export const magenta: Style
export const cyan: Style
export const white: Style
export const gray: Style
export const bgBlack: Style
export const bgRed: Style
export const bgGreen: Style
export const bgYellow: Style
export const bgBlue: Style
export const bgMagenta: Style
export const bgCyan: Style
export const bgWhite: Style
export const blackBright: Style
export const redBright: Style
export const greenBright: Style
export const yellowBright: Style
export const blueBright: Style
export const magentaBright: Style
export const cyanBright: Style
export const whiteBright: Style
export const bgBlackBright: Style
export const bgRedBright: Style
export const bgGreenBright: Style
export const bgYellowBright: Style
export const bgBlueBright: Style
export const bgMagentaBright: Style
export const bgCyanBright: Style
export const bgWhiteBright: Style
const isColorSupported: boolean

function createColors(options: { useColor: boolean }): Colorette
}
75 changes: 59 additions & 16 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,23 @@ const isCI =
"CI" in env &&
("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env)

let enabled =
export const isColorSupported =
!isDisabled && (isForced || isWindows || isCompatibleTerminal || isCI)

const raw = (open, close, searchRegex, replaceValue) => (s) =>
enabled
? open +
(~(s += "").indexOf(close, 4) // skip opening \x1b[
? s.replace(searchRegex, replaceValue)
: s) +
close
: s
open +
(~(s += "").indexOf(close, 4) // skip opening \x1b[
? s.replace(searchRegex, replaceValue)
: s) +
close

const init = (open, close) => {
return raw(
const init = (open, close) =>
raw(
`\x1b[${open}m`,
`\x1b[${close}m`,
new RegExp(`\\x1b\\[${close}m`, "g"),
`\x1b[${open}m`
)
}

export const options = Object.defineProperty({}, "enabled", {
get: () => enabled,
set: (value) => (enabled = value),
})

export const reset = init(0, 0)
export const bold = raw("\x1b[1m", "\x1b[22m", /\x1b\[22m/g, "\x1b[22m\x1b[1m")
Expand Down Expand Up @@ -80,3 +72,54 @@ export const bgBlueBright = init(104, 49)
export const bgMagentaBright = init(105, 49)
export const bgCyanBright = init(106, 49)
export const bgWhiteBright = init(107, 49)

const none = (any) => any

export const createColors = ({ useColor = isColorSupported } = {}) => ({
...Object.entries({
reset,
bold,
dim,
italic,
underline,
inverse,
hidden,
strikethrough,
black,
red,
green,
yellow,
blue,
magenta,
cyan,
white,
gray,
bgBlack,
bgRed,
bgGreen,
bgYellow,
bgBlue,
bgMagenta,
bgCyan,
bgWhite,
blackBright,
redBright,
greenBright,
yellowBright,
blueBright,
magentaBright,
cyanBright,
whiteBright,
bgBlackBright,
bgRedBright,
bgGreenBright,
bgYellowBright,
bgBlueBright,
bgMagentaBright,
bgCyanBright,
bgWhiteBright,
}).reduce((colorMap, [key, color]) => ({
...colorMap,
[key]: useColor ? color : none,
})),
})

0 comments on commit dcef277

Please sign in to comment.