@esmalley/ts-utils 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +2 -0
- package/dist/Arithmetic.d.ts +4 -0
- package/dist/Arithmetic.d.ts.map +1 -0
- package/dist/Arithmetic.js +5 -0
- package/dist/Arrayifier.d.ts +29 -0
- package/dist/Arrayifier.d.ts.map +1 -0
- package/dist/Arrayifier.js +65 -0
- package/dist/CSV.d.ts +10 -0
- package/dist/CSV.d.ts.map +1 -0
- package/dist/CSV.js +35 -0
- package/dist/Color.d.ts +93 -0
- package/dist/Color.d.ts.map +1 -0
- package/dist/Color.js +344 -0
- package/dist/Dates.d.ts +51 -0
- package/dist/Dates.d.ts.map +1 -0
- package/dist/Dates.js +354 -0
- package/dist/Kontororu/Socket.d.ts +44 -0
- package/dist/Kontororu/Socket.d.ts.map +1 -0
- package/dist/Kontororu/Socket.js +218 -0
- package/dist/Kontororu.d.ts +8 -0
- package/dist/Kontororu.d.ts.map +1 -0
- package/dist/Kontororu.js +23 -0
- package/dist/Objector.d.ts +32 -0
- package/dist/Objector.d.ts.map +1 -0
- package/dist/Objector.js +120 -0
- package/dist/Sorter.d.ts +8 -0
- package/dist/Sorter.d.ts.map +1 -0
- package/dist/Sorter.js +28 -0
- package/dist/Style.d.ts +63 -0
- package/dist/Style.d.ts.map +1 -0
- package/dist/Style.js +471 -0
- package/dist/Text.d.ts +5 -0
- package/dist/Text.d.ts.map +1 -0
- package/dist/Text.js +35 -0
- package/dist/Theme.d.ts +1413 -0
- package/dist/Theme.d.ts.map +1 -0
- package/dist/Theme.js +503 -0
- package/dist/Toaster.d.ts +24 -0
- package/dist/Toaster.d.ts.map +1 -0
- package/dist/Toaster.js +46 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Arithmetic.d.ts","sourceRoot":"","sources":["../src/Arithmetic.ts"],"names":[],"mappings":"AACA,qBAAa,UAAU;WACP,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;CAGtE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare class Arrayifier {
|
|
2
|
+
/**
|
|
3
|
+
* Shuffle / ranomize elements in an array
|
|
4
|
+
* @param {array} array The array to shuffle
|
|
5
|
+
* @return array
|
|
6
|
+
*/
|
|
7
|
+
shuffle(array: Array<unknown>): Array<unknown>;
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {Array} arr
|
|
11
|
+
* @param {number} n
|
|
12
|
+
* @param {number} r
|
|
13
|
+
* @param {number} index
|
|
14
|
+
* @param {Array} data
|
|
15
|
+
* @param {number} i
|
|
16
|
+
* @param {Array} results
|
|
17
|
+
* @returns Array
|
|
18
|
+
*/
|
|
19
|
+
combination(arr: Array<number>, n: number, r: number, index: number, data: number[], i: number, results: number[][]): number[][];
|
|
20
|
+
/**
|
|
21
|
+
* Get all combinations of every value in the provided array for a specified number
|
|
22
|
+
* @param {Array} arr
|
|
23
|
+
* @param {number} n
|
|
24
|
+
* @param {number} r
|
|
25
|
+
* @returns Array
|
|
26
|
+
*/
|
|
27
|
+
getCombinations(arr: Array<number>, n: number, r: number): number[][];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=Arrayifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Arrayifier.d.ts","sourceRoot":"","sources":["../src/Arrayifier.ts"],"names":[],"mappings":"AACA,qBAAa,UAAU;IAKrB;;;;QAII;IACJ,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;IAkB9C;;;;;;;;;;QAUI;IACJ,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;IAqBnH;;;;;;QAMI;IACJ,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;CAOzD"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export class Arrayifier {
|
|
2
|
+
// constructor() {
|
|
3
|
+
// }
|
|
4
|
+
/**
|
|
5
|
+
* Shuffle / ranomize elements in an array
|
|
6
|
+
* @param {array} array The array to shuffle
|
|
7
|
+
* @return array
|
|
8
|
+
*/
|
|
9
|
+
shuffle(array) {
|
|
10
|
+
let currentIndex = array.length;
|
|
11
|
+
let randomIndex;
|
|
12
|
+
// While there remain elements to shuffle.
|
|
13
|
+
while (currentIndex !== 0) {
|
|
14
|
+
// Pick a remaining element.
|
|
15
|
+
randomIndex = Math.floor(Math.random() * currentIndex);
|
|
16
|
+
currentIndex--;
|
|
17
|
+
// And swap it with the current element.
|
|
18
|
+
[array[currentIndex], array[randomIndex]] = [
|
|
19
|
+
array[randomIndex], array[currentIndex]
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
return array;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param {Array} arr
|
|
27
|
+
* @param {number} n
|
|
28
|
+
* @param {number} r
|
|
29
|
+
* @param {number} index
|
|
30
|
+
* @param {Array} data
|
|
31
|
+
* @param {number} i
|
|
32
|
+
* @param {Array} results
|
|
33
|
+
* @returns Array
|
|
34
|
+
*/
|
|
35
|
+
combination(arr, n, r, index, data, i, results) {
|
|
36
|
+
if (index === r) {
|
|
37
|
+
const result = [];
|
|
38
|
+
for (let j = 0; j < r; j++) {
|
|
39
|
+
result.push(data[j]);
|
|
40
|
+
}
|
|
41
|
+
results.push(result);
|
|
42
|
+
return results;
|
|
43
|
+
}
|
|
44
|
+
if (i >= n) {
|
|
45
|
+
return results;
|
|
46
|
+
}
|
|
47
|
+
data[index] = arr[i];
|
|
48
|
+
this.combination(arr, n, r, index + 1, data, i + 1, results);
|
|
49
|
+
this.combination(arr, n, r, index, data, i + 1, results);
|
|
50
|
+
return results;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get all combinations of every value in the provided array for a specified number
|
|
54
|
+
* @param {Array} arr
|
|
55
|
+
* @param {number} n
|
|
56
|
+
* @param {number} r
|
|
57
|
+
* @returns Array
|
|
58
|
+
*/
|
|
59
|
+
getCombinations(arr, n, r) {
|
|
60
|
+
const data = new Array(r);
|
|
61
|
+
let results = [];
|
|
62
|
+
results = this.combination(arr, n, r, 0, data, 0, results);
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
}
|
package/dist/CSV.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everything to help with CSV generation
|
|
3
|
+
*/
|
|
4
|
+
export declare class CSV {
|
|
5
|
+
/**
|
|
6
|
+
* Convert an object to a CSV file and then download it
|
|
7
|
+
*/
|
|
8
|
+
static download(data: Record<string, Record<string, unknown>>): void;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=CSV.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CSV.d.ts","sourceRoot":"","sources":["../src/CSV.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,qBAAa,GAAG;IACd;;OAEG;WACW,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI;CAiC5E"}
|
package/dist/CSV.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everything to help with CSV generation
|
|
3
|
+
*/
|
|
4
|
+
export class CSV {
|
|
5
|
+
/**
|
|
6
|
+
* Convert an object to a CSV file and then download it
|
|
7
|
+
*/
|
|
8
|
+
static download(data) {
|
|
9
|
+
const rows = [];
|
|
10
|
+
let setHeaders = false;
|
|
11
|
+
let headers = [];
|
|
12
|
+
for (const id in data) {
|
|
13
|
+
const row = data[id];
|
|
14
|
+
if (!setHeaders) {
|
|
15
|
+
headers = Object.keys(row);
|
|
16
|
+
rows.push(headers.join(','));
|
|
17
|
+
setHeaders = true;
|
|
18
|
+
}
|
|
19
|
+
const values = headers.map((header) => JSON.stringify(row[header] || ''));
|
|
20
|
+
rows.push(values.join(','));
|
|
21
|
+
}
|
|
22
|
+
const content = rows.join('\n');
|
|
23
|
+
// Create a Blob and trigger download
|
|
24
|
+
const blob = new Blob([content], { type: 'text/csv' });
|
|
25
|
+
const url = URL.createObjectURL(blob);
|
|
26
|
+
const a = document.createElement('a');
|
|
27
|
+
a.href = url;
|
|
28
|
+
a.download = 'srating-data.csv';
|
|
29
|
+
// Trigger download and clean up
|
|
30
|
+
document.body.appendChild(a);
|
|
31
|
+
a.click();
|
|
32
|
+
URL.revokeObjectURL(url);
|
|
33
|
+
a.remove();
|
|
34
|
+
}
|
|
35
|
+
}
|
package/dist/Color.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export declare class Color {
|
|
2
|
+
/**
|
|
3
|
+
* A linear interpolator for hexadecimal colors
|
|
4
|
+
* @param {string} a
|
|
5
|
+
* @param {string} b
|
|
6
|
+
* @param {number} amount
|
|
7
|
+
* @example
|
|
8
|
+
* // returns #7F7F7F
|
|
9
|
+
* lerpColor('#000000', '#ffffff', 0.5)
|
|
10
|
+
* @return {string}
|
|
11
|
+
*/
|
|
12
|
+
static lerpColor(a: string, b: string, amount: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Get a color that will look readable based on a background color
|
|
15
|
+
*/
|
|
16
|
+
static getTextColor(color: string, backgroundColor: string, debug?: boolean): string;
|
|
17
|
+
static getContrastRatio(rgb1: [number, number, number], rgb2: [number, number, number]): number;
|
|
18
|
+
/**
|
|
19
|
+
* Take a hex (#fff) and an amount and darken the color, return a hex
|
|
20
|
+
* @param {string} hex
|
|
21
|
+
* @param {number} amount
|
|
22
|
+
* @return {string} hex
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Take a hex (#fff) and an amount and lighten the color, return a hex
|
|
26
|
+
* @param {string} hex
|
|
27
|
+
* @param {number} amount
|
|
28
|
+
* @return {string} hex
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Mixes the color with black to create a Shade.
|
|
32
|
+
* Prevents the "muddy/brown" look of HSL darkening.
|
|
33
|
+
* @param {string} hex - The color to darken
|
|
34
|
+
* @param {number} amount - 0 to 1 (e.g. 0.1 is 10% darker)
|
|
35
|
+
* @return {string} hex
|
|
36
|
+
*/
|
|
37
|
+
static darken(hex: string, amount?: number): string;
|
|
38
|
+
/**
|
|
39
|
+
* Mixes the color with white to create a Tint.
|
|
40
|
+
* cleaner and less "washed out" than HSL lightness adjustment.
|
|
41
|
+
* @param {string} hex - The color to lighten
|
|
42
|
+
* @param {number} amount - 0 to 1 (e.g. 0.1 is 10% lighter)
|
|
43
|
+
* @return {string} hex
|
|
44
|
+
*/
|
|
45
|
+
static lighten(hex: string, amount?: number): string;
|
|
46
|
+
static shadeColor(hex: string, percent: number): string;
|
|
47
|
+
/**
|
|
48
|
+
* Are 2 colors similar to each other?
|
|
49
|
+
* @param {string} color1
|
|
50
|
+
* @param {string} color2
|
|
51
|
+
* @param {number} threshold
|
|
52
|
+
* @return {boolean}
|
|
53
|
+
*/
|
|
54
|
+
static areColorsSimilar(color1: string, color2: string, threshold?: number): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Inverts a hex color
|
|
57
|
+
* @param {string} hex
|
|
58
|
+
* @return {string} hex
|
|
59
|
+
*/
|
|
60
|
+
static invertColor(hex: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Takes a hex (#fff) and returns an rgba with the provided alpha
|
|
63
|
+
* @param {string} hex
|
|
64
|
+
* @param {number} alpha
|
|
65
|
+
* @return {string} rgba()
|
|
66
|
+
*/
|
|
67
|
+
static alphaColor(hex: string, alpha: number): string;
|
|
68
|
+
/**
|
|
69
|
+
* Gets analogous colors
|
|
70
|
+
* @param {string} hex
|
|
71
|
+
* @return {Array<string>}
|
|
72
|
+
*/
|
|
73
|
+
static getAnalogousColors(hex: string): string[];
|
|
74
|
+
/**
|
|
75
|
+
* Convert hex to rgb
|
|
76
|
+
* @param {string} hex
|
|
77
|
+
* @return {Array} rgb
|
|
78
|
+
*/
|
|
79
|
+
static hexToRgb(hex: string): Array<number>;
|
|
80
|
+
/**
|
|
81
|
+
* Convert rgb to hex
|
|
82
|
+
* @param {number} r
|
|
83
|
+
* @param {number} g
|
|
84
|
+
* @param {number} b
|
|
85
|
+
* @return {string}
|
|
86
|
+
*/
|
|
87
|
+
private static rgbToHex;
|
|
88
|
+
private static rgbToHsl;
|
|
89
|
+
private static hslToRgb;
|
|
90
|
+
private static calculateBrightness;
|
|
91
|
+
private static colorDistance;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=Color.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Color.d.ts","sourceRoot":"","sources":["../src/Color.ts"],"names":[],"mappings":"AAIA,qBAAa,KAAK;IAKhB;;;;;;;;;OASG;WACW,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAkBrE;;OAEG;WACW,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,UAAQ;WAoFlE,gBAAgB,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAiBtG;;;;;OAKG;IAWH;;;;;OAKG;IAWH;;;;;;OAMG;WACW,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAY,GAAG,MAAM;IAa/D;;;;;;OAMG;WACW,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAY,GAAG,MAAM;WAalD,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAWrD;;;;;;OAMG;WACW,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAK;IAM7E;;;;OAIG;WACW,WAAW,CAAC,GAAG,EAAE,MAAM;IAYrC;;;;;OAKG;WACW,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAO5D;;;;OAIG;WACW,kBAAkB,CAAC,GAAG,EAAE,MAAM;IAmB5C;;;;OAIG;WACW,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAwBlD;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;IAIvB,OAAO,CAAC,MAAM,CAAC,QAAQ;IAyBvB,OAAO,CAAC,MAAM,CAAC,QAAQ;IA8BvB,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAKlC,OAAO,CAAC,MAAM,CAAC,aAAa;CAU7B"}
|
package/dist/Color.js
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/* eslint-disable no-mixed-operators */
|
|
2
|
+
/* eslint-disable no-bitwise */
|
|
3
|
+
export class Color {
|
|
4
|
+
// constructor() {
|
|
5
|
+
// }
|
|
6
|
+
/**
|
|
7
|
+
* A linear interpolator for hexadecimal colors
|
|
8
|
+
* @param {string} a
|
|
9
|
+
* @param {string} b
|
|
10
|
+
* @param {number} amount
|
|
11
|
+
* @example
|
|
12
|
+
* // returns #7F7F7F
|
|
13
|
+
* lerpColor('#000000', '#ffffff', 0.5)
|
|
14
|
+
* @return {string}
|
|
15
|
+
*/
|
|
16
|
+
static lerpColor(a, b, amount) {
|
|
17
|
+
const ah = +a.replace('#', '0x');
|
|
18
|
+
const ar = ah >> 16;
|
|
19
|
+
const ag = ah >> 8 & 0xff;
|
|
20
|
+
const ab = ah & 0xff;
|
|
21
|
+
const bh = +b.replace('#', '0x');
|
|
22
|
+
const br = bh >> 16;
|
|
23
|
+
const bg = bh >> 8 & 0xff;
|
|
24
|
+
const bb = bh & 0xff;
|
|
25
|
+
const rr = ar + amount * (br - ar);
|
|
26
|
+
const rg = ag + amount * (bg - ag);
|
|
27
|
+
const rb = ab + amount * (bb - ab);
|
|
28
|
+
return `#${((1 << 24) + (rr << 16) + (rg << 8) + rb | 0).toString(16).slice(1)}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get a color that will look readable based on a background color
|
|
32
|
+
*/
|
|
33
|
+
static getTextColor(color, backgroundColor, debug = false) {
|
|
34
|
+
// Convert hex colors to RGB
|
|
35
|
+
/*
|
|
36
|
+
let [r1, g1, b1] = Color.hexToRgb(color);
|
|
37
|
+
const [r2, g2, b2] = Color.hexToRgb(backgroundColor);
|
|
38
|
+
|
|
39
|
+
const brightnessBg = Color.calculateBrightness(r2, g2, b2);
|
|
40
|
+
|
|
41
|
+
const targetBrightness = brightnessBg > 128 ? 50 : 150; // target brightness threshold for contrast
|
|
42
|
+
|
|
43
|
+
while (true) {
|
|
44
|
+
const brightnessColor = Color.calculateBrightness(r1, g1, b1);
|
|
45
|
+
|
|
46
|
+
if (
|
|
47
|
+
(brightnessBg > 128 && brightnessColor < targetBrightness) ||
|
|
48
|
+
(brightnessBg <= 128 && brightnessColor > targetBrightness)
|
|
49
|
+
) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (brightnessBg > 128) {
|
|
54
|
+
r1 = Math.max(0, r1 - 25);
|
|
55
|
+
g1 = Math.max(0, g1 - 25);
|
|
56
|
+
b1 = Math.max(0, b1 - 25);
|
|
57
|
+
} else {
|
|
58
|
+
r1 = Math.min(255, r1 + 25);
|
|
59
|
+
g1 = Math.min(255, g1 + 25);
|
|
60
|
+
b1 = Math.min(255, b1 + 25);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if ((r1 === 0 && g1 === 0 && b1 === 0) || (r1 === 255 && g1 === 255 && b1 === 255)) {
|
|
64
|
+
break; // avoid infinite loop
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Convert back to hex
|
|
69
|
+
return Color.rgbToHex(r1, g1, b1);
|
|
70
|
+
*/
|
|
71
|
+
let [r, g, b] = Color.hexToRgb(color);
|
|
72
|
+
const [br, bg, bb] = Color.hexToRgb(backgroundColor);
|
|
73
|
+
const contrastTarget = 4.5;
|
|
74
|
+
if (debug) {
|
|
75
|
+
console.log('Color.getContrastRatio([r, g, b], [br, bg, bb])', Color.getContrastRatio([r, g, b], [br, bg, bb]));
|
|
76
|
+
}
|
|
77
|
+
if (Color.getContrastRatio([r, g, b], [br, bg, bb]) >= contrastTarget) {
|
|
78
|
+
return Color.rgbToHex(r, g, b);
|
|
79
|
+
}
|
|
80
|
+
const contrastToBlack = Color.getContrastRatio([0, 0, 0], [br, bg, bb]);
|
|
81
|
+
const contrastToWhite = Color.getContrastRatio([255, 255, 255], [br, bg, bb]);
|
|
82
|
+
const direction = contrastToWhite > contrastToBlack ? 'lighter' : 'darker';
|
|
83
|
+
if (debug) {
|
|
84
|
+
console.log('contrastToBlack', contrastToBlack);
|
|
85
|
+
console.log('contrastToWhite', contrastToWhite);
|
|
86
|
+
console.log('direction', direction);
|
|
87
|
+
}
|
|
88
|
+
const adjust = (c, lighter) => {
|
|
89
|
+
return lighter ? Math.min(255, c + 10) : Math.max(0, c - 10);
|
|
90
|
+
};
|
|
91
|
+
for (let i = 0; i < 25; i++) {
|
|
92
|
+
r = adjust(r, direction === 'lighter');
|
|
93
|
+
g = adjust(g, direction === 'lighter');
|
|
94
|
+
b = adjust(b, direction === 'lighter');
|
|
95
|
+
if (debug) {
|
|
96
|
+
console.log('Color.getContrastRatio([r, g, b], [br, bg, bb]) 2', Color.getContrastRatio([r, g, b], [br, bg, bb]));
|
|
97
|
+
}
|
|
98
|
+
if (Color.getContrastRatio([r, g, b], [br, bg, bb]) >= contrastTarget) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return Color.rgbToHex(r, g, b);
|
|
103
|
+
}
|
|
104
|
+
static getContrastRatio(rgb1, rgb2) {
|
|
105
|
+
const luminance = (r, g, b) => {
|
|
106
|
+
const a = [r, g, b].map((v) => {
|
|
107
|
+
v /= 255;
|
|
108
|
+
return v <= 0.03928
|
|
109
|
+
? v / 12.92
|
|
110
|
+
: Math.pow((v + 0.055) / 1.055, 2.4);
|
|
111
|
+
});
|
|
112
|
+
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
|
|
113
|
+
};
|
|
114
|
+
const lum1 = luminance(...rgb1) + 0.05;
|
|
115
|
+
const lum2 = luminance(...rgb2) + 0.05;
|
|
116
|
+
return lum1 > lum2 ? lum1 / lum2 : lum2 / lum1;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Take a hex (#fff) and an amount and darken the color, return a hex
|
|
120
|
+
* @param {string} hex
|
|
121
|
+
* @param {number} amount
|
|
122
|
+
* @return {string} hex
|
|
123
|
+
*/
|
|
124
|
+
// public static darken(hex: string, amount: number = 0.02): string {
|
|
125
|
+
// const [r, g, b] = this.hexToRgb(hex);
|
|
126
|
+
// const [h, s, l] = this.rgbToHsl(r, g, b);
|
|
127
|
+
// const newL = Math.max(0, (l / 100) - amount) * 100;
|
|
128
|
+
// const [r2, g2, b2] = this.hslToRgb(h, s, newL);
|
|
129
|
+
// return this.rgbToHex(r2, g2, b2);
|
|
130
|
+
// }
|
|
131
|
+
/**
|
|
132
|
+
* Take a hex (#fff) and an amount and lighten the color, return a hex
|
|
133
|
+
* @param {string} hex
|
|
134
|
+
* @param {number} amount
|
|
135
|
+
* @return {string} hex
|
|
136
|
+
*/
|
|
137
|
+
// public static lighten(hex: string, amount: number = 0.02): string {
|
|
138
|
+
// const [r, g, b] = this.hexToRgb(hex);
|
|
139
|
+
// const [h, s, l] = this.rgbToHsl(r, g, b);
|
|
140
|
+
// const newL = Math.min(1, (l / 100) + amount) * 100;
|
|
141
|
+
// const [r2, g2, b2] = this.hslToRgb(h, s, newL);
|
|
142
|
+
// return this.rgbToHex(r2, g2, b2);
|
|
143
|
+
// }
|
|
144
|
+
/**
|
|
145
|
+
* Mixes the color with black to create a Shade.
|
|
146
|
+
* Prevents the "muddy/brown" look of HSL darkening.
|
|
147
|
+
* @param {string} hex - The color to darken
|
|
148
|
+
* @param {number} amount - 0 to 1 (e.g. 0.1 is 10% darker)
|
|
149
|
+
* @return {string} hex
|
|
150
|
+
*/
|
|
151
|
+
static darken(hex, amount = 0.1) {
|
|
152
|
+
const [r, g, b] = this.hexToRgb(hex);
|
|
153
|
+
// Calculate new color by mixing with black (0)
|
|
154
|
+
// Formula: Current * (1 - amount)
|
|
155
|
+
const remaining = 1 - amount;
|
|
156
|
+
const r2 = Math.round(r * remaining);
|
|
157
|
+
const g2 = Math.round(g * remaining);
|
|
158
|
+
const b2 = Math.round(b * remaining);
|
|
159
|
+
return this.rgbToHex(r2, g2, b2);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Mixes the color with white to create a Tint.
|
|
163
|
+
* cleaner and less "washed out" than HSL lightness adjustment.
|
|
164
|
+
* @param {string} hex - The color to lighten
|
|
165
|
+
* @param {number} amount - 0 to 1 (e.g. 0.1 is 10% lighter)
|
|
166
|
+
* @return {string} hex
|
|
167
|
+
*/
|
|
168
|
+
static lighten(hex, amount = 0.1) {
|
|
169
|
+
const [r, g, b] = this.hexToRgb(hex);
|
|
170
|
+
// Calculate new color by mixing with white (255)
|
|
171
|
+
// Formula: Current + ((Target - Current) * amount)
|
|
172
|
+
const r2 = Math.round(r + (255 - r) * amount);
|
|
173
|
+
const g2 = Math.round(g + (255 - g) * amount);
|
|
174
|
+
const b2 = Math.round(b + (255 - b) * amount);
|
|
175
|
+
return this.rgbToHex(r2, g2, b2);
|
|
176
|
+
}
|
|
177
|
+
static shadeColor(hex, percent) {
|
|
178
|
+
let [r, g, b] = Color.hexToRgb(hex);
|
|
179
|
+
r = Math.min(255, Math.max(0, Math.round(r + (r * (percent / 100)))));
|
|
180
|
+
g = Math.min(255, Math.max(0, Math.round(g + (g * (percent / 100)))));
|
|
181
|
+
b = Math.min(255, Math.max(0, Math.round(b + (b * (percent / 100)))));
|
|
182
|
+
return Color.rgbToHex(r, g, b);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Are 2 colors similar to each other?
|
|
186
|
+
* @param {string} color1
|
|
187
|
+
* @param {string} color2
|
|
188
|
+
* @param {number} threshold
|
|
189
|
+
* @return {boolean}
|
|
190
|
+
*/
|
|
191
|
+
static areColorsSimilar(color1, color2, threshold = 50) {
|
|
192
|
+
const distance = Color.colorDistance(color1, color2);
|
|
193
|
+
return distance < threshold;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Inverts a hex color
|
|
197
|
+
* @param {string} hex
|
|
198
|
+
* @return {string} hex
|
|
199
|
+
*/
|
|
200
|
+
static invertColor(hex) {
|
|
201
|
+
const [r, g, b] = Color.hexToRgb(hex);
|
|
202
|
+
// Invert each color component
|
|
203
|
+
const invertedR = 255 - r;
|
|
204
|
+
const invertedG = 255 - g;
|
|
205
|
+
const invertedB = 255 - b;
|
|
206
|
+
return Color.rgbToHex(invertedR, invertedG, invertedB);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Takes a hex (#fff) and returns an rgba with the provided alpha
|
|
210
|
+
* @param {string} hex
|
|
211
|
+
* @param {number} alpha
|
|
212
|
+
* @return {string} rgba()
|
|
213
|
+
*/
|
|
214
|
+
static alphaColor(hex, alpha) {
|
|
215
|
+
const [r, g, b] = this.hexToRgb(hex);
|
|
216
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Gets analogous colors
|
|
220
|
+
* @param {string} hex
|
|
221
|
+
* @return {Array<string>}
|
|
222
|
+
*/
|
|
223
|
+
static getAnalogousColors(hex) {
|
|
224
|
+
const [r, g, b] = Color.hexToRgb(hex);
|
|
225
|
+
const [h, s, l] = Color.rgbToHsl(r, g, b);
|
|
226
|
+
const analogousColors = [];
|
|
227
|
+
const offset = 30; // Offset for analogous colors, usually 30 degrees
|
|
228
|
+
for (let i = -1; i <= 1; i++) {
|
|
229
|
+
if (i !== 0) {
|
|
230
|
+
const newHue = (h + i * offset + 360) % 360;
|
|
231
|
+
const [newR, newG, newB] = Color.hslToRgb(newHue, s, l);
|
|
232
|
+
analogousColors.push(Color.rgbToHex(newR, newG, newB));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return analogousColors;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Convert hex to rgb
|
|
239
|
+
* @param {string} hex
|
|
240
|
+
* @return {Array} rgb
|
|
241
|
+
*/
|
|
242
|
+
static hexToRgb(hex) {
|
|
243
|
+
// Remove the hash at the start if it's there
|
|
244
|
+
let h = hex.replace(/^#/, '');
|
|
245
|
+
// Handle 3-character hex codes by expanding them to 6-character
|
|
246
|
+
if (h.length === 3) {
|
|
247
|
+
h = h.split('').map((char) => { return char + char; }).join('');
|
|
248
|
+
}
|
|
249
|
+
// Ensure it's a valid 6-character hex code
|
|
250
|
+
if (h.length !== 6) {
|
|
251
|
+
throw new Error(`Invalid hex color format: ${hex}`);
|
|
252
|
+
}
|
|
253
|
+
// Parse r, g, b values
|
|
254
|
+
const bigint = parseInt(h, 16);
|
|
255
|
+
const r = (bigint >> 16) & 255;
|
|
256
|
+
const g = (bigint >> 8) & 255;
|
|
257
|
+
const b = bigint & 255;
|
|
258
|
+
return [r, g, b];
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Convert rgb to hex
|
|
262
|
+
* @param {number} r
|
|
263
|
+
* @param {number} g
|
|
264
|
+
* @param {number} b
|
|
265
|
+
* @return {string}
|
|
266
|
+
*/
|
|
267
|
+
static rgbToHex(r, g, b) {
|
|
268
|
+
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()}`;
|
|
269
|
+
}
|
|
270
|
+
static rgbToHsl(r, g, b) {
|
|
271
|
+
r /= 255;
|
|
272
|
+
g /= 255;
|
|
273
|
+
b /= 255;
|
|
274
|
+
const max = Math.max(r, g, b);
|
|
275
|
+
const min = Math.min(r, g, b);
|
|
276
|
+
let h = 0;
|
|
277
|
+
let s = 0;
|
|
278
|
+
const l = (max + min) / 2;
|
|
279
|
+
if (max === min) {
|
|
280
|
+
h = s = 0; // achromatic
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
const d = max - min;
|
|
284
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
285
|
+
switch (max) {
|
|
286
|
+
case r:
|
|
287
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
288
|
+
break;
|
|
289
|
+
case g:
|
|
290
|
+
h = (b - r) / d + 2;
|
|
291
|
+
break;
|
|
292
|
+
case b:
|
|
293
|
+
h = (r - g) / d + 4;
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
h /= 6;
|
|
297
|
+
}
|
|
298
|
+
return [h * 360, s * 100, l * 100];
|
|
299
|
+
}
|
|
300
|
+
static hslToRgb(h, s, l) {
|
|
301
|
+
let r;
|
|
302
|
+
let g;
|
|
303
|
+
let b;
|
|
304
|
+
h /= 360;
|
|
305
|
+
s /= 100;
|
|
306
|
+
l /= 100;
|
|
307
|
+
if (s === 0) {
|
|
308
|
+
r = g = b = l; // achromatic
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
const hue2rgb = (p, q, t) => {
|
|
312
|
+
if (t < 0)
|
|
313
|
+
t += 1;
|
|
314
|
+
if (t > 1)
|
|
315
|
+
t -= 1;
|
|
316
|
+
if (t < 1 / 6)
|
|
317
|
+
return p + (q - p) * 6 * t;
|
|
318
|
+
if (t < 1 / 3)
|
|
319
|
+
return q;
|
|
320
|
+
if (t < 1 / 2)
|
|
321
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
322
|
+
return p;
|
|
323
|
+
};
|
|
324
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
325
|
+
const p = 2 * l - q;
|
|
326
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
327
|
+
g = hue2rgb(p, q, h);
|
|
328
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
329
|
+
}
|
|
330
|
+
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
|
|
331
|
+
}
|
|
332
|
+
static calculateBrightness(r, g, b) {
|
|
333
|
+
// Calculate the brightness of the color
|
|
334
|
+
return (r * 299 + g * 587 + b * 114) / 1000;
|
|
335
|
+
}
|
|
336
|
+
static colorDistance(color1, color2) {
|
|
337
|
+
const [r1, g1, b1] = Color.hexToRgb(color1);
|
|
338
|
+
const [r2, g2, b2] = Color.hexToRgb(color2);
|
|
339
|
+
const dr = r1 - r2;
|
|
340
|
+
const dg = g1 - g2;
|
|
341
|
+
const db = b1 - b2;
|
|
342
|
+
return Math.sqrt(dr * dr + dg * dg + db * db);
|
|
343
|
+
}
|
|
344
|
+
}
|
package/dist/Dates.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare class Dates {
|
|
2
|
+
static parse(str?: Date | string | number | undefined | null, utc?: boolean): Date;
|
|
3
|
+
static utc(date: Date | string | number): Date;
|
|
4
|
+
static getMonthsShort(): string[];
|
|
5
|
+
static getMonths(): string[];
|
|
6
|
+
static getDaysShort(): string[];
|
|
7
|
+
static getDays(): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Format a date using php syntax
|
|
10
|
+
*
|
|
11
|
+
| Token | Meaning | Example |
|
|
12
|
+
| ----- | ------------------------- | ------- |
|
|
13
|
+
| `Y` | 4-digit year | 2025 |
|
|
14
|
+
| `y` | 2-digit year | 25 |
|
|
15
|
+
| `m` | 2-digit month | 03 |
|
|
16
|
+
| `n` | month (no leading zero) | 3 |
|
|
17
|
+
| `d` | day (2-digit) | 09 |
|
|
18
|
+
| `j` | day (no leading zero) | 9 |
|
|
19
|
+
| `S` | Ordinal suffix | th |
|
|
20
|
+
| `H` | 24-hour | 14 |
|
|
21
|
+
| `G` | 24-hour (no leading zero) | 14 |
|
|
22
|
+
| `h` | 12-hour | 02 |
|
|
23
|
+
| `g` | 12-hour (no leading zero) | 2 |
|
|
24
|
+
| `i` | minutes | 05 |
|
|
25
|
+
| `s` | seconds | 09 |
|
|
26
|
+
| `A` | AM/PM | PM |
|
|
27
|
+
| `a` | am/pm | pm |
|
|
28
|
+
| `w` | day of week (0–6) | 1 |
|
|
29
|
+
| `N` | day of week (1–7) | 2 |
|
|
30
|
+
| `M` | short month name | Mar |
|
|
31
|
+
| `F` | full month name | March |
|
|
32
|
+
| `D` | short weekday | Mon |
|
|
33
|
+
| `l` | full weekday | Monday |
|
|
34
|
+
*/
|
|
35
|
+
static format(dateInput: Date | string, format: string): string;
|
|
36
|
+
static add(date: Date | string, amount: number, unit: 'years' | 'months' | 'days' | 'hours' | 'minutes'): Date;
|
|
37
|
+
static subtract(date: Date | string, amount: number, unit: 'years' | 'months' | 'days' | 'hours' | 'minutes'): Date;
|
|
38
|
+
static fromNow(date: Date | string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Find the closest date in an array of dates
|
|
41
|
+
*/
|
|
42
|
+
static getClosestDate(dateToMatch: string | Date, datesArray: string[]): string | null;
|
|
43
|
+
static getTodayEST(): string;
|
|
44
|
+
static getStartOfDay(date: Date | string): Date;
|
|
45
|
+
static getStartOfMonth(date: Date | string): Date;
|
|
46
|
+
static getStartOfGrid(date: Date | string): Date;
|
|
47
|
+
static isSameDay(date1: Date | string, date2: Date | string): boolean;
|
|
48
|
+
static isBeforeDay(date1: Date | string, date2: Date | string): boolean;
|
|
49
|
+
static isAfterDay(date1: Date | string, date2: Date | string): boolean;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=Dates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dates.d.ts","sourceRoot":"","sources":["../src/Dates.ts"],"names":[],"mappings":"AAIA,qBAAa,KAAK;WAYF,KAAK,CACjB,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,EAC/C,GAAG,UAAQ,GACV,IAAI;WA8FO,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;WAKvC,cAAc,IAAI,MAAM,EAAE;WAI1B,SAAS,IAAI,MAAM,EAAE;WAIrB,YAAY,IAAI,MAAM,EAAE;WAIxB,OAAO,IAAI,MAAM,EAAE;IAIjC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;WACW,MAAM,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM;WAgG/C,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS;WAkChG,QAAQ,CACpB,IAAI,EAAE,IAAI,GAAG,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS;WAK3C,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IA6BzC;;OAEG;WACW,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI;WA+B/E,WAAW;WAIX,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;WAMjC,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;WAOnC,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;WAWlC,SAAS,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM;WAepD,WAAW,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM;WAQtD,UAAU,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM;CAMpE"}
|