Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support CSS-based %c coloring? #1

Open
jcbhmr opened this issue Jul 8, 2023 · 4 comments
Open

Support CSS-based %c coloring? #1

jcbhmr opened this issue Jul 8, 2023 · 4 comments

Comments

@jcbhmr
Copy link
Member

jcbhmr commented Jul 8, 2023

I'd be interested in contributing code to do this

To enable more cross-platform stuff (Firefox, Safari, etc.) it would be nice to treat Node.js as the "special case" due to Node.js' lack of support for %c and treat console.log("%cHi", "color:red") as the "most correct" way of doing things.

For instance, the provided example code in the README.md doesn't work in Firefox due to it using ANSI which only works on TTYs and Chrome-related browsers.

My estimated support table of ANSI vs %c-based colors:

Support ANSI colors Support %c specifier
Node.js 🟨 nodejs/node#29605
Deno
Chrome
Firefox
Safari unknown*
Opera

* I don't have an Apple device to test this on. Apple doesn't release Safari for Windows 😭

Since this package doesn't have any dependents on npm (and 0 DLs/week) I think it'd be very non-breaking to revamp the API surface for a v2 or whatever without angering any users.

image

Some ideas for how it might look as a user:

import { c, log, debug, info, error, warn } from "tinyrainbow"

// This returns an array to spread over multiple console.log() args
c`<green>SUCCESS</> <i>${message} <gray>${new Date()}</gray></i>`
//=> ["%cSUCCESS%c %c%s %c%s%c%c", "color:green", "",
//    "font-style:italic", message, "font-style:italic;color:gray",
//    new Date(), "font-style:italic", ""]

// and might be used like this?
console.log(...c`<green>SUCCESS</> <i>${message} <gray>${new Date()}</gray></i>`)

// or maybe a shortcut for every console.* method?
log`<red>UH OH</red> something went <i>wrong</>`
debug`Hello <b>WORLD</b>`
warn`<yellow>Oh no</yellow> <i>anyway...</i>`
error`<b><red>CATASROPHIC FAILURE`

image
image
image

Keep in mind that this lets you do WAYYYY more than just color the text! You can make it bigger, bolder, center it, add background color, and even add images! Obviously some properties like background-image are only supported in browsers and not in Deno 🤣

image
https://www.bennadel.com/blog/3941-styling-console-log-output-formatting-with-css.htm

This would also help this library establish a niche that isn't already claimed by another library! For the Google search "npm console colors" there's already like 10 different libraries that do ANSI codes, but all of the popular ones seem to fall flat in Firefox since they rely on ANSI codes.

I think this is a great time to pivot and make a name/identity as the library for cross-platform log coloration
image

@jcbhmr
Copy link
Member Author

jcbhmr commented Jul 18, 2023

📬 @sheremet-va since i notice you're not 👁 watching this repo https://github.com/tinylibs/tinyrainbow/watchers

@sheremet-va
Copy link
Member

sheremet-va commented Jul 18, 2023

This library was created to support Jest assertions which use ANSI colors to display errors even though it's not used in an actual project yet.

Changing the API will render this library useless. Especially because it doesn't work in Node.

@jcbhmr
Copy link
Member Author

jcbhmr commented Jul 18, 2023

Changing the API will render this library useless. Especially because it doesn't work in Node.

it would be nice to treat Node.js as the "special case"

What I meant by this ☝️ was that by using the spread pattern, you can support %c specifiers while also adding a special case for Nodejs to only use ANSI if it's nodejs otherwise use CSS

Like this in browsers:

// This returns an array to spread over multiple console.log() args
c`<green>SUCCESS</> <i>${message} <gray>${new Date()}</gray></i>`
//=> ["%cSUCCESS%c %c%s %c%s%c%c", "color:green", "",
//    "font-style:italic", message, "font-style:italic;color:gray",
//    new Date(), "font-style:italic", ""]

But then the same code in nodejs gives you this

// This returns an array to spread over multiple console.log() args
c`<green>SUCCESS</> <i>${message} <gray>${new Date()}</gray></i>`
//=> ["%sSUCCESS%c %s%s %s%s%s%s", "\x33[...m", "\x33[...m",
//    "\x33...m", message, "\x33...m\x33...m",
//    new Date(), "\x33...m", "\x33...m"]

That's my idea basically. Something like that either with functions or tagged templates or something.

This library was created to support Jest assertions which use ANSI colors to display errors even though it's not used in an actual project yet.

That's really cool! 🎉

@sheremet-va
Copy link
Member

sheremet-va commented Jul 18, 2023

I do like the general premise and the idea as a whole. This was my initial idea for the package, but there are a few problems with it that lead me to just fork picocolors instead.

But then the same code in nodejs gives you this

The problem with this is backward compatibility. This package is made primarily for Vitest to use in browser and node modes. Our expect.extend supports matcherHint function and color variables: EXPECTED_COLOR, RECEIVED_COLOR, INVERTED_COLOR, BOLD_WEIGHT, DIM_COLOR. Used like this: Some ${BOLD_WEIGHT('important') message. And only a single string is returned from the failing assertion, which makes it impossible to split this into an array.

While we could rewrite the implementation to support this style of color, we cannot rewrite custom implementations. Packages that were written for Jest but work in Vitest will stop working.

If we can find a way to bypass this, I'm fine with a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants