Skip to content

Commit b160a24

Browse files
authored
Merge pull request #47 from mll-lab/hsla-opacity
feat: allow controlling opacity in `stringToHslaColor`
2 parents cb6dc97 + fc36880 commit b160a24

File tree

4 files changed

+44
-29
lines changed

4 files changed

+44
-29
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
},
4040
"dependencies": {
4141
"date-fns": "3.0.1",
42-
"lodash": "4.17.15"
42+
"lodash": "4.17.21"
4343
},
4444
"devDependencies": {
4545
"@babel/core": "^7.13.1",
@@ -79,5 +79,5 @@
7979
"ts-node": "^9.1.1",
8080
"typescript": "^5.3.3"
8181
},
82-
"packageManager": "yarn@4.1.1"
82+
"packageManager": "yarn@4.4.0"
8383
}

src/stringToColor.test.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { uniq } from 'lodash';
22

3-
import { randomString, stringToHslaColor } from './stringToColor';
3+
import { stringToHslaColor } from './stringToColor';
44

55
describe('stringToHslaColor', () => {
66
it.each(['test', 'test'])(
@@ -12,11 +12,17 @@ describe('stringToHslaColor', () => {
1212
},
1313
);
1414

15+
it('allows setting the opacity', () => {
16+
expect(stringToHslaColor('test', { opacity: 1.23 })).toStrictEqual(
17+
'hsla(58, 98%, 48%, 1.23)',
18+
);
19+
});
20+
1521
it('returns various hsla colors for various inputs', () => {
1622
const testStrings = ['t', 'te', 'tes', 'test'];
17-
expect(uniq(testStrings.map(stringToHslaColor)).length).toBe(
18-
testStrings.length,
19-
);
23+
expect(
24+
uniq(testStrings.map((string) => stringToHslaColor(string))).length,
25+
).toBe(testStrings.length);
2026
});
2127

2228
it('returns a valid color for a random string', () => {
@@ -32,3 +38,14 @@ function isValidColor(color: string): boolean {
3238

3339
return element.style.borderColor.length !== 0;
3440
}
41+
42+
/** Generates a random string with a length of 1-11 chars. */
43+
function randomString(): string {
44+
// Cut off the constant 0. from the beginning
45+
const fractionStart = 2;
46+
47+
// Unequal distribution at the edges, but sufficiently random for the purposes of this function
48+
const randomLengthEnd = Math.round(Math.random() * 11) + 3;
49+
50+
return Math.random().toString(36).substring(fractionStart, randomLengthEnd);
51+
}

src/stringToColor.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ function hashCode(string: string): number {
99
return hash;
1010
}
1111

12-
function getHslColor(hash: number): string {
12+
function hashToHslaColor(hash: number, opacity: number): string {
1313
const h = range(hash, 0, 360);
1414
const s = range(hash, 50, 100);
1515
const l = range(hash, 20, 50);
16+
const a = opacity.toString();
1617

17-
return `hsla(${h}, ${s}%, ${l}%, 1)`;
18+
// https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl#values
19+
return `hsla(${h}, ${s}%, ${l}%, ${a})`;
1820
}
1921

2022
function range(hash: number, min: number, max: number): number {
@@ -24,19 +26,22 @@ function range(hash: number, min: number, max: number): number {
2426
return x + min;
2527
}
2628

27-
export function stringToHslaColor(string: string): string {
28-
return getHslColor(hashCode(string));
29-
}
29+
export type StringToHslaColorOptions = { opacity?: number };
3030

3131
/**
32-
* Generates a random string with a length of 1-11 chars.
32+
* Provides a hsla color value for use in CSS, based on the contents of the given string.
33+
*
34+
* See https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl.
35+
*
36+
* @example stringToHslaColor('test') becomes 'hsla(58, 98%, 48%, 1)' (yellow)
37+
*
38+
* This function tries to provide a good spread of colors for different inputs.
39+
* However, it does not guarantee uniqueness - think of it like hashing.
40+
* It is pure, meaning that the result is only dependent on the inputs.
3341
*/
34-
export function randomString(): string {
35-
// Cut off the constant 0. from the beginning
36-
const fractionStart = 2;
37-
38-
// Unequal distribution at the edges, but sufficiently random for the purposes of this function
39-
const randomLengthEnd = Math.round(Math.random() * 11) + 3;
40-
41-
return Math.random().toString(36).substring(fractionStart, randomLengthEnd);
42+
export function stringToHslaColor(
43+
string: string,
44+
{ opacity = 1 }: StringToHslaColorOptions = {},
45+
): string {
46+
return hashToHslaColor(hashCode(string), opacity);
4247
}

yarn.lock

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,7 +1805,7 @@ __metadata:
18051805
eslint-plugin-unused-imports: "npm:^3.1.0"
18061806
jest: "npm:^29.7.0"
18071807
jest-environment-jsdom: "npm:^29.7.0"
1808-
lodash: "npm:4.17.15"
1808+
lodash: "npm:4.17.21"
18091809
prettier: "npm:^3.1.0"
18101810
rollup: "npm:^2.45.2"
18111811
rollup-plugin-peer-deps-external: "npm:^2.2.4"
@@ -7406,14 +7406,7 @@ __metadata:
74067406
languageName: node
74077407
linkType: hard
74087408

7409-
"lodash@npm:4.17.15":
7410-
version: 4.17.15
7411-
resolution: "lodash@npm:4.17.15"
7412-
checksum: 10c0/c029ab298357d007252d5802348f1deb343099ba734ae6e6776a908e4995db5b8ed4ae51ff83a2937a1f6e3c41a0c8941eb941926e1a7f2ddfc3d235ec1e8aa7
7413-
languageName: node
7414-
linkType: hard
7415-
7416-
"lodash@npm:^4.17.4":
7409+
"lodash@npm:4.17.21, lodash@npm:^4.17.4":
74177410
version: 4.17.21
74187411
resolution: "lodash@npm:4.17.21"
74197412
checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c

0 commit comments

Comments
 (0)