Gathering detailed insights and metrics for material-chalk
Gathering detailed insights and metrics for material-chalk
Gathering detailed insights and metrics for material-chalk
Gathering detailed insights and metrics for material-chalk
Generate beautiful colors from namespaces based on color theory
npm install material-chalk
Typescript
Module System
Node Version
NPM Version
72.8
Supply Chain
98.4
Quality
88.6
Maintenance
100
Vulnerability
94.8
License
TypeScript (94.87%)
Shell (5.13%)
Total Downloads
459
Last Day
6
Last Week
13
Last Month
459
Last Year
459
2 Stars
24 Commits
1 Watching
1 Branches
1 Contributors
Latest Version
1.1.1
Package Id
material-chalk@1.1.1
Unpacked Size
45.55 kB
Size
10.09 kB
File Count
23
NPM Version
10.9.0
Node Version
22.10.0
Publised On
15 Dec 2024
Cumulative downloads
Total Downloads
Last day
-45.5%
6
Compared to previous day
Last week
-82.9%
13
Compared to previous week
Last month
0%
459
Compared to previous month
Last year
0%
459
Compared to previous year
1
1
7
material-chalk
is a library for generating beautiful colors for namespaces based on color theory in a way that is deterministic and extensible.
It is built using the latest Typescript and ESM standards, while being compatible with older standards when needed.
It is focused on being an opinionated standard to encourage consistent colors for the same namespace across different programming languages and tools, while still being composable with any frontend from terminal-focused libraries to full GUI applications.
:warning: your terminal must support
truecolor
to see all possible colors. Although tools likechalk
attempt to detect this automatically, you may have to set chalk.level manually or setexport COLORTERM=truecolor
in your shell (many shells usexterm-256color
by default which limits the color range).
1import chalk from 'chalk'; 2import { createMaterial, Format } from 'material-chalk' 3 4const chalkFormat = Format.Chalk(chalk) 5const namespaceFoo = createMaterial('foo').formatAs(chalkFormat); 6console.log( 7 namespaceFoo(`Hello, world!`) 8);
There are multiple format options available, notably:
Format.Htc
for the direct HCT (hue, chroma, tone) representation from Material DesignFormat.Hex
for a hex color representation (ex: #ff0000
)Format.Custom
for a custom format function that you provideFormat.Chalk
for to use Chalk to print with colorFormat.Scheme
for generating palettes (see below)material-chalk
allows you to define namespaces both statically and dynamically.
Static nested namespaces
1const nestedNamespace = 2 createMaterial(['parent', 'child']) 3 .formatAs(chalkFormat);
Dynamic nested namespaces
1const parentNamespace = createMaterial('parent'); 2const nestedNamespace = parentNamespace 3 .subMaterial('child') 4 .formatAs(chalkFormat);
Namespaces leverage the blend
concept in Material Design which shifts the hue of the children towards that of the parent.
You can easily build full UIs around the color generated for a namespace using Material Design v3 dynamic color schemes.
Material Design allows you to create your own color scheme manually, but it also comes with many built-in schemes.
Material Design will modify the hue/chroma/tone of your colors as needed for (this is by design), but we provide a helper function to convert a scheme to one that more strongly retains the color generated for the namespace: sourceAsPrimary
.
1import chalk from 'chalk'; 2import { createMaterial, sourceAsPrimary, Format } from 'material-chalk' 3import { hexFromArgb, SchemeVibrant } from "@material/material-color-utilities"; 4 5// convert one of the many built-in schemes 6// to one that more accurately uses the namespace's color 7const SchemeVibrantNamespace = Format.Scheme(sourceAsPrimary(SchemeVibrant))( 8 true, // isDark 9 0 // contrast level (for accessibility). 0 is normal contrast 10) 11 12// instantiate our new color scheme on a specific namespace 13const namespaceFoo = createMaterial('foo').formatAs(SchemeVibrantNamespace); 14 15// utility function just to demo functionality 16function printWithChalk(color: number, text: string) { 17 console.log(chalk.hex(hexFromArgb(color)).bold(text)); 18} 19 20printWithChalk(namespaceFoo.primaryPaletteKeyColor, 'Primary'); 21printWithChalk(namespaceFoo.secondaryPaletteKeyColor, 'Secondary'); 22printWithChalk(namespaceFoo.tertiaryPaletteKeyColor, 'Tertiary'); 23printWithChalk(namespaceFoo.neutralPaletteKeyColor, 'Neutral'); 24printWithChalk(namespaceFoo.neutralVariantPaletteKeyColor, 'Neutral Variant');
Here are some examples of how a namespace looks like under different schemes:
If you're still using Material Design v2, you can still use this library to generate your palette
1import chalk from 'chalk'; 2import { createMaterial, Format } from "@material/material-color-utilities"; 3import { hctForNamespace } from 'material-chalk' 4 5const namespaceFoo = createMaterial('foo').formatAs(Format.Hct); 6 7// utility function just to demo functionality 8function printWithChalk(color: number, text: string) { 9 console.log(chalk.hex(hexFromArgb(color)).bold(text)); 10} 11 12const corePalette = CorePalette.of(namespaceFoo.toInt()); 13printWithChalk(corePalette.a1.keyColor.toInt(), "Primary"); 14printWithChalk(corePalette.a2.keyColor.toInt(), "Secondary"); 15printWithChalk(corePalette.a3.keyColor.toInt(), "Tertiary"); 16printWithChalk(corePalette.n1.keyColor.toInt(), "Neutral 1"); 17printWithChalk(corePalette.n2.keyColor.toInt(), "Neutral 2");
material-chalk
provides a few utility functions to make it easier to work with colors.
registerBrand
and matchColor
Sometimes, for business reasons, you need to enforce that a namespace is associated with a specific brand color. In those cases, you can registerBrand
to override cache the color that should be generated for a specific namespace.
If you want to make sure your color matches the same brightness as other colors in material-chalk
, you can use the matchColor
function to adjust the brightness (internally, this will try its best to maintain your brand color)
1import { createMaterial, matchColor, registerBrand, Format } from 'material-chalk' 2 3const brandColor = matchColor("#ff0000"); 4registerBrand("my-brand", brandColor.formatAs(Format.Hct)); 5 6// this will retrieve the cached color 7const namespace = createMaterial("my-brand").formatAs(Format.Hct);
chainedMessage
Often times you want to print a chain of all the namespaces leading up to a specific message. You can use chainedMessage
to do this:
1import chalk from 'chalk'; 2import { createMaterial, chainedMessage, Format } from 'material-chalk' 3 4const chalkFormat = Format.Chalk(chalk) 5const namespaceFoo = createMaterial('foo').formatAs(chalkFormat); 6console.log( 7 chainedMessage(chalk, ['root-namespace', 'middle', 'child'], 'Hello, world!') 8);
Here is a preview of what it looks like for different chain lengths:
material-chalk
caches namespaces generated by default, meaning the performance hit is negligible for the majority of use-cases.
Performance does matter in the not-so-realistic scenarios that you are generating millions of random strings as namespaces. In this case:
0.01
milliseconds per namespace color generation (cached)If you need to save memory, you can disable the cache:
1import { createMaterial } from 'material-chalk' 2 3const namespaceFoo = createMaterial( 4 'foo', 5 { cache: false } 6);
There are other ad-hoc implementations of generating colors from strings, but they generally have at least one of the following issues:
Issue | Other libraries | material-chalk |
---|---|---|
Legacy code | old and do not have Typescript/ESM support | built on the latest best practices |
Poor color choices | no justification based on color theory for why a specific choice was made, leading to poor color choices | full justification for choices here |
Not extensible ex: color sub-namespaces | provide no opinionated way on how to extend it for a given namespace | leverage Material Design to build for palettes for your namespace |
Lack of standardization | provide too many configurations leading to inconsistent colors across tools & languages for the same namespace | opinionated deterministic choices based on color theory |
Limited to RGB | only support the RGB range | supports colors outside the standard RGB range |
Poor randomness | depend on non-deterministic poor sources of randomness like Math.random() internally | uses fnv-1a for good deterministic seeding of randomness |
No vulnerabilities found.
No security vulnerabilities found.